vscode(gdb) + qemu 单步调试 Lustre 文件系统

这里介绍使用 vscode(gdb) + qemu 调试 Lustre文件系统,前置操作需要确定使用的 Linux 内核版本源代码,并能成功编译 Lustre. 具体可以参考 Ubuntu 下编译安装 Lustre

以下内容以 ubuntu 5.19.0-41.42 源代码为例

一、获取源代码

1. 获取 Linux 内核源代码

这里同样以 ubuntu 5.19.0-41.42 源代码(linux kernel 5.19.17)为例

sudo apt install linux-source-5.19.0=5.19.0-41.42\~22.04.1

下载的源码会在/usr/src目录下,解压获得 linux

tar jxvf /usr/src/linux-source-5.19.0.tar.bz2

2. 获取 Lustre 源代码

将 lustre 源代码放到 linux 源码 fs 目录下

cd fs
git clone git://git.whamcloud.com/fs/lustre-release.git

二、调试 Linux 内核

调试 lustre 方法主要是将 lustre 作为可加载的内核模块同 linux 内核一同调试,首先是先实现 linux 内核的调试

1. 配置内核编译选项

为了方便安装后续使用 lustre 所需要的相关依赖,需要支持debian在线软件包的根文件系统,我这里采用runninglinuxkernel制作的根文件系统。

runninglinuxkernel的内核版本是5.0。首先从中获取几个需要用到的文件,用于编译调试上一步获得的内核源代码:

1. 配置文件 .config
2. 脚本 run_debian_x86_64.sh
3. 半成品的根文件系统分片 rootfs_debian_x86_64.part00/01

将上面的几个文件放到内核代码根目录上

make menuconfig

修改下面两个选项:

│ Symbol: VERSION_SIGNATURE [=]
│ Type : string
│ Defined at init/Kconfig:360
│ Prompt: Arbitrary version signature
│ Location:
│ Main menu
│ (1) -> General setup

│ Symbol: GDB_SCRIPTS [=y]
│ Type : bool
│ Defined at lib/Kconfig.debug:383
│ Prompt: Provide GDB scripts for kernel debugging
│ Depends on: DEBUG_INFO [=y]
│ Location:
│ Main menu
│ -> Kernel hacking
│ (1) -> Compile-time checks and compiler options

  1. Arbitrary version signature 修改为 Ubuntu (我这的源代码是 Ubuntu ),目的是后续 lustre 进行 configure时能检测出发行版是 Ubuntu
  2. 包含 Provide GDB scripts for kernel debugging 生成 vmlinux-gdb.py 脚本

2. 编译内核

make -j$(nproc)

3. 制作根文件系统

sudo ./run_debian_x86_64.sh build_rootfs

运行成功后会得到一个 rootfs_debian_x86_64.ext4 的文件,这个是制作得到的根文件系统。

注:runninglinuxkernel里面的 rootfs_debian_x86_64.part 是基于 debian10,其中一些 lustre 依赖的软件包过旧无法满足较新版本的 lustre. 所以后面启动后可以将debian10 升级到 debian12. 可以参考从Debian10升级到Debian12

打开 run_debian_x86_64.sh 文件,删除下面两行内容

--fsdev local,id=kmod_dev,path=./kmodules,security_model=none \
-device virtio-9p-pci,fsdev=kmod_dev,mount_tag=kmod_mount\

4. 运行和调试

使用 runrun debug 来运行或调试内核

./run_debian_x86_64.sh run
./run_debian_x86_64.sh run debug

调试时,运行 run debug 后即可用 vscode 或 gdb 远程连接 :1234 调试

vscode调试launchconfigurations 可以配置为以下内容,其它的可以根据自己需求配置。

{
	"name": "kernel-debug",
	"type": "cppdbg",
	"request": "launch",
	"program": "${workspaceFolder}/vmlinux",
	"args": [],
	"stopAtEntry": false,
	"cwd": "${workspaceFolder}",
	"environment": [],
	"externalConsole": false,
	"miDebuggerServerAddress": "127.0.0.1:1234",
	"miDebuggerPath": "/usr/bin/gdb",
	"MIMode": "gdb",
	"logging": {
		"engineLogging": false
	},
}

三、单步调试 Lustre

1. 配置 Lustre

将 lustre 的源代码放到 linux 源代码的 fs 目录下

sh autogen.sh
./configure --with-linux=[linux-source-dir] --enable-client --enable-server --without-o2ib  --disable-strict-errors --disable-tests

linux-source-dir 是上一步的 Linux 代码目录

2. 获取 ldiskfs 源代码

进入ldiskfs 目录,应用补丁

cd ldiskfs
make

3. 在Linux中启用Lustre文件系统支持

在 lustre 目录下创建 Kconfig 文件,写入以下内容(其他内容可根据需要自定义)

config LUSTRE_FS
      tristate "Lustre filesystem support"
      help
        Lustre file system.

在 linux 目录的 fs/Kconfig 文件中添加

source "fs/lustre/Kconfig"

在 linux 目录的 fs/Makefile 文件中添加

obj-$(CONFIG_LUSTRE_FS) += lustre/

接着在 linux 目录下配置

make menuconfig

然后将 File systems -> Lustre filesystem support 选择为<M>内核模块方式编译

理论上也可以使用<Y>指定将 lustre 编译链接到内核中,但需要对 lustre 进行较大的修改。比如,ldiskfs是有ext4应用补丁得到,可能会存在相同的变量或函数定义,编译链接到内核中可能会导致重定义等问题。

4. 编译安装 Lustre 内核模块

linux 目录下编译内核

make -j$(nproc)

接着将 lustre 的内核模块安装到根文件系统中

sudo ./run_debian_x86_64.sh update_rootfs

5. 安装 lustre 工具包

以上步骤只是安装了 lustre 的内核模块,还需要安装以可执行文件方式存在的工具包(mkfs, mount, lfs…)

可以用以下两种方式安装

  1. lustre 目录下使用 make debs 制作deb安装包,然后复制 **-utils-**.deb 到根文件系统,qemu 启动系统后安装这个deb软件包
  2. 将编译好的 utils 目录下的可执行文件复制到根文件系统中使用

6. 调试

这里需要用到vmlinux-gdb.py脚本, Ubuntu 可能会将脚本的自动加载限制在已知的安全目录中。 如果gdb报告拒绝加载vmlinux-gdb.py,可修改.gdbinit使用add-auto-load-safe-path 添加安全目录。

启动调试的时候,可以在 init/main.c 中的 start_kernel 打一个断点,触发断点后执行命令lx-symbolslx-symbols 包含在 vmlinux-gdb.py 脚本中,用于加载 Linux 内核和模块的符号表,方便调试内核与加载的模块。

使用 lx-symbols 后,当加载了内核模块后,会自动加载内核和已加载模块的符号信息,如

-exec lx-symbols
loading vmlinux
scanning for modules in …
loading @0xffffffffa0000000: … fs/lustre/libcfs/libcfs/libcfs.ko
loading @0xffffffffa0021000: … fs/lustre/lnet/lnet/lnet.ko

fs/lustre/lustre/llite/super25.c 文件的 lustre_fill_super 函数是挂载 lustre 的入口点,可在该函数打断点后执行挂载操作判断调试配置时候成功。

当修改了源代码,重新编译内核后更新根文件系统,使用 update_rootfs 即可安装新的模块到根文件系统

make -j$(nproc)
sudo ./run_debian_x86_64.sh update_rootfs

附:使用 vscode 单步调试示例

  1. 在终端中运行 ./run_debian_x86_64.sh run debug
  2. start_kernel 处设置断点,vscode启动调试连接 :1234
  3. 触发断点后在调试控制台执行命令 lx-symbols 自动加载调试符号信息

start_kernel 断点

  1. 在 vscode 中设置 lustre 代码断点,在qemu guest中执行 lustre 相关操作。

模块符合信息加载

可以在调试控制台中看到,模块的调试信息会被自动加载

👉 欢迎私信讨论交流!🤝
  • 25
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值