1. 程式人生 > 其它 >Linux下Ceph原始碼編譯和GDB除錯

Linux下Ceph原始碼編譯和GDB除錯

Linux下Ceph原始碼編譯和GDB除錯

Ceph版本:14.2.22
Linux版本:ubuntu-server 18.04


第一部分 下載Ceph原始碼

1.1 配置Ceph原始碼映象源

Ceph原始碼是託管在Github上,由於某些原因,國內訪問Github網站很慢,所以需要從其他途徑加速獲取原始碼。Github官方給出了幾個Github的映象網站:

  1. https://github.com.cnpmjs.org/
  2. https://hub.fastgit.org/

本地需要修改~/.gitconfig檔案,才可以從上面映象網站獲取原始碼,相關配置如下:

#Github映象源
[url "https://hub.fastgit.org/"]
        insteadOf = https://github.com/

注:國內也有Ceph原始碼的映象,比如Gitee、Gitcode,但不建議從這些網站上獲取。因為Ceph原始碼中使用了大量的第三方原始碼作為自己的子模組,而Gitee、Gitcode不一定將這些子模組全部同步過來。相反,上面的兩個映象網站和Github完全是同步的,所以可以放心使用。

1.2 克隆ceph原始碼

Ceph原始碼很大,可根據需要,選擇性下載哪個版本或哪個分支。本案例拉取v14.2.22版本的原始碼。版本和分支的區別:版本的程式碼不會隨時間改變,被定格在打標籤的那一刻;分支的程式碼會隨時間不斷開發改變。

# 根據自己需要更換 v14.2.22 為自己需要的版本
git clone -b v14.2.22 --depth=1 https://github.com/ceph/ceph.git

1.3 同步子模組原始碼

Ceph原始碼中使用大量的子模組,在 ceph/.gitmodules 檔案中羅列出所有的子模組。在後面執行do_cmake.sh 指令碼生成 build 目錄時,do_cmake.sh 首先同步子模組原始碼到指定目錄。根據經驗,在同步子模組原始碼時很容易出現同步不全,或同步失敗,這直接會導致構建 build 目錄失敗。為了防止此狀況發生,建議提前手動去同步子模組原始碼。

git submodule update --init --recursive

注:如果發現同步子模組原始碼失敗,重複執行上面命令即可。如果中斷同步子模組原始碼,此時必須要到相應目錄下刪除該子模組所有檔案,尤其是 .git 檔案。如果不刪除 .git,重複執行上面命令時,則會直接跳過同步該子模組,導致子模組原始碼缺失。這個問題無法被檢測到,因為執行完上面命令後,依然會顯示同步成功,而不會提示哪個子模組沒有被同步。

第二部分 原始碼編譯

2.1 安裝依賴

Ceph原始碼安裝依賴很簡單,直接執行原始碼根目錄下install-deps.sh指令碼,根據經驗發現,該指令碼存在一些問題,需要稍微修改一下。

2.1.1 修改launchpad源

指令碼會安裝gcc環境,安裝包源url只需要保留一個即可,修改install-deps.sh指令碼中的函式ensure_decent_gcc_on_ubuntu

deb [lang=none] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu $codename main
#deb [arch=amd64 lang=none] http://mirror.cs.uchicago.edu/ubuntu-toolchain-r $codename main
#deb [arch=amd64,i386 lang=none] http://mirror.yandex.ru/mirrors/launchpad/ubuntu-toolchain-r $codename main

2.1.2 遮蔽呼叫安裝libboost的部分

指令碼會安裝 libboost 庫,編譯原始碼過程會再次下載 boost 原始碼包,因此指令碼中不應該再安裝 libboost,遮蔽install-deps.sh以下2個地方

 *Bionic*)
        #install_boost_on_ubuntu bionic
  ;;

2.1.3 設定pypi映象源

指令碼會安裝pypi庫,預設url下載很慢,需要設定pypi庫映象源。建立 ~/.pip/pip.conf 檔案,並追加以下內容

[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com

2.1.4 安裝其他依賴

編譯原始碼過程中會遇到很多函式用到zstd庫,預設情況下ubuntu18.04只安裝了libzstd1,但沒有用,需要安裝 libzstd1-dev

sudo apt install libzstd1-dev

2.1.5 執行指令碼

./install-deps.sh

2.2 編譯Ceph原始碼

2.2.1 開啟debug模式

如果想要除錯Ceph原始碼,需要設定編譯原始碼模式為debug模式,預設編譯模式為release模式,該模式是不能除錯原始碼。向 ceph/CMakeList 檔案的 set(VERSION 14.2.22) 後追加以下內容

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -Wall -g")
set(CMAKE_CXX_FLAGS "-O0 -Wall -g")
set(CMAKE_C_FLAGS "-O0 -Wall -g ")

2.2.2 構建build目錄

直接執行do_cmake指令碼,該指令碼會進行一系列檢測,包括原始碼是不是完整,依賴是不是都安裝了等等。如果出現問題,構建出的build目錄是不完整的,最直接的影響是無法生成makefile檔案,導致無法編譯。

./do_cmake.sh

2.2.3 下載boost原始碼包

在執行make編譯的時候,指令碼會自動下載 boost_1_72_0.tar.bz2,由於下載地址和網路問題,下載很慢,為了節省時間,提前手動下載,下載地址:https://download.ceph.com/qa/boost_1_72_0.tar.bz2,將下載的好的包放在ceph/build/boost/src即可。

2.2.4 編譯

使用make編譯必須要到ceph/build目錄下執行,ceph原始碼可以單獨編譯某一個模組,也可以全部編譯。使用make可以指定多執行緒編譯,提高編譯速度,但要合理分配執行緒數,建議使用4執行緒編譯即可。

#方式1:全部編譯
make all -j4
#方式2:單獨編譯osd某塊
make ceph-osd -j4
#檢視所有模組
make help

注:原始碼編譯會生成很多庫檔案和二進位制檔案,分別放在ceph/build/lib和ceph/build/bin目錄下

第三部分 部署Debug版本的叢集

3.1 叢集部署

Cpeh原始碼提供了一個部署開發叢集的指令碼:vstart.sh,該指令碼會利用本地IP和不同埠來配置MON、MGR、OSD等。切換到切換到build目錄下,執行以下命令,部署一個新的叢集

MON=1 OSD=6 MDS=0 MGR=1 RGW=0 ../src/vstart.sh -d -n  -x  --without-dashboard

引數解釋:

  1. MON、 OSD、 MDS、 MGR是配置相應的個數
  2. -d:debug,開啟debug模式
  3. -n:new,新建一個叢集
  4. -x:cephx,cephx認證
  5. --without-dashboard,mgr的一個配置,自測發現如果這個不關閉,部署會報錯

3.2 檢視叢集狀態

切換到build目錄下,執行以下命令,檢視叢集狀態

./bin/ceph -s 

結果如下

  cluster:
    id:     88b11a21-7dd1-49d8-bb24-c18821ff09ae
    health: HEALTH_OK
 
  services:
    mon: 1 daemons, quorum a (age 5m)
    mgr: x(active, since 5m)
    osd: 6 osds: 6 up (since 4m), 6 in (since 4m)
 
  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   12 GiB used, 594 GiB / 606 GiB avail
    pgs:   

注:ceph 14.2.22版本的vstart.sh指令碼並沒有將ceph可執行檔案新增到系統環境變數中,所有的ceph命令都必須在build目錄下執行

3.3 部署ceph分級儲存結構

本案例需要除錯ceph分級儲存功能,因此簡單的搭建一個分層儲存結構。為叢集分配6個OSD,建立2個pool,cache pool和ec pool,每個pool分配了3個osd。
詳細部署請參考(文章還在編寫中)

第四部分 程式碼除錯

4.1 檢視PG-OSD對映關係

如果仔細閱讀原始碼,會發現ceph分級儲存主要是由主OSD程序來負責。如果不是主OSD,是無法除錯到程式碼中的。所以需要檢視分級儲存中快取池的PG對映關係。

#切換到build目錄下,執行以下命令
./bin/ceph pg ls-by-pool cache_pool

PG  OBJECTS DEGRADED MISPLACED UNFOUND BYTES OMAP_BYTES* OMAP_KEYS* LOG STATE        SINCE VERSION REPORTED UP        ACTING    SCRUB_STAMP                DEEP_SCRUB_STAMP           
5.0       0        0         0       0     0           0          0  18 active+clean   22h  323'18   323:76 [2,4,0]p2 [2,4,0]p2 2021-09-25 16:55:28.572062 2021-09-24 11:30:14.717641 

從結果可以看到PG5.0對應的主OSD為OSD 2

4.2 檢視主OSD程序

執行以下命令

ps -ef | grep ceph

結果如下

admins   10961 19680  0 15:12 pts/0    00:00:00 grep --color=auto ceph
admins   18474     1  1 Sep24 ?        01:02:09 /home/admins/code/ceph/build/bin/ceph-mon -i a -c /home/admins/code/ceph/build/ceph.conf
admins   18582     1  1 Sep24 ?        00:33:41 /home/admins/code/ceph/build/bin/ceph-mgr -i x -c /home/admins/code/ceph/build/ceph.conf
admins   18806     1  1 Sep24 ?        00:41:15 /home/admins/code/ceph/build/bin/ceph-osd -i 1 -c /home/admins/code/ceph/build/ceph.conf
admins   19096     1  1 Sep24 ?        00:41:06 /home/admins/code/ceph/build/bin/ceph-osd -i 3 -c /home/admins/code/ceph/build/ceph.conf
admins   19242     1  1 Sep24 ?        00:40:37 /home/admins/code/ceph/build/bin/ceph-osd -i 4 -c /home/admins/code/ceph/build/ceph.conf
admins   19415     1  1 Sep24 ?        00:41:00 /home/admins/code/ceph/build/bin/ceph-osd -i 5 -c /home/admins/code/ceph/build/ceph.conf
admins   20385     1  1 Sep24 ?        00:39:47 /home/admins/code/ceph/build/bin/ceph-osd -i 0 -c /home/admins/code/ceph/build/ceph.conf
admins   22235     1  1 Sep24 ?        00:40:24 /home/admins/code/ceph/build/bin/ceph-osd -i 2 -c /home/admins/code/ceph/build/ceph.conf

從結果可以看到,主OSD程序號為 22235

4.3 GDB多執行緒除錯

關於linux gdb多執行緒除錯具體用法這裡就不多介紹,需要學習瞭解的,請百度。以下僅為本案例除錯步驟

4.3.1 進入gdb模式

gdb除錯需要以管理員許可權,執行以下命令,進入gdb模式

sudo gdb

結果如下

[sudo] password for admins: 
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) 

4.3.2 attach osd2 程序

(gdb) attach 22235
Attaching to process 22235
[New LWP 22237]
[New LWP 22238]
[New LWP 22239]
[New LWP 22248]
[New LWP 22249]
[New LWP 22250]
[New LWP 22251]
[New LWP 22254]
[New LWP 22255]
[New LWP 22256]
[New LWP 22257]
[New LWP 22258]
[New LWP 22259]
[New LWP 22260]
[New LWP 22269]
[New LWP 22270]
[New LWP 22271]
........
........
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fd026a7dad3 in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x55b3123d8910) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
88        ../sysdeps/unix/sysv/linux/futex-internal.h: No such file or directory.
(gdb)

4.3.3 設定斷點

#本例斷電設定在PrimaryLogPG::do_op函式開始
(gdb) b PrimaryLogPG.cc:1952
Breakpoint 1 at 0x55b305d28af2: file /home/admins/code/ceph/src/osd/PrimaryLogPG.cc, line 1952.

#設定完斷電之,執行continue
(gdb) c
Continuing.

4.3.4 測試

向儲存池中寫入資料,測試結果如下

[Switching to Thread 0x7fd0034cb700 (LWP 22364)]
Thread 57 "tp_osd_tp" hit Breakpoint 1, PrimaryLogPG::do_op (this=0x55b312519400, op=...) 
at /home/admins/code/ceph/src/osd/PrimaryLogPG.cc:1952
1952        {

從上面結果可以看到,當寫入資料時,函式停在程式碼的1952行,現在就可以使用gdb命令進行程式碼除錯,和正常除錯程式碼一樣。但需要值得注意的一點是,由於ceph osd存在心跳機制,當除錯某一個osd時,如果長時間沒有走完該走的流程,該osd會被標記為down,就無法再繼續除錯。需要重新進入gdb模式!