直接链接libfdisk.a与使用-lfdisk的差异及fdisk分区问题咨询
问题解答
一、直接链接静态库与-lfdisk链接的差异
1. 链接对象类型不同
- 直接指定
libfdisk.a是链接静态库:会将库中的代码直接打包到你的目标文件(Python调用库属于动态共享对象)中。 - 使用
-lfdisk参数时,链接器默认优先查找并链接动态共享库libfdisk.so;仅当系统中无对应动态库时,才会尝试链接静态库libfdisk.a。
2. 位置无关代码(PIC)要求差异
- 你自行编译的
libfdisk.a未加-fPIC编译选项,生成的是位置相关代码。而构建动态共享对象(如Python扩展库)时,链接器要求所有依赖代码必须是位置无关的(PIC),否则无法在内存中完成地址重定位,因此出现relocation R_X86_64_32错误。 - 系统提供的
libfdisk.so(-lfdisk链接的对象)编译时已包含-fPIC,符合动态共享对象的链接要求,因此无报错。
3. 产物依赖与体积差异
- 静态链接后,目标库/程序会包含
libfdisk的全部代码,体积更大,但运行时不依赖系统的libfdisk库。 - 动态链接后,目标库/程序仅包含对
libfdisk.so的引用,体积更小,但运行时需要系统中存在对应的动态库文件。
二、fdisk_add_partition返回错误28的问题
错误码28对应ENOSPC(设备无剩余空间),但无法创建两个分区可能并非单纯空间不足,以下是常见原因和排查方案:
常见错误代码示例
#include <libfdisk.h> #include <stdio.h> int create_two_partitions(const char *dev) { struct fdisk_context *cxt = fdisk_new_context(); if (!cxt) return -1; // 挂载设备 if (fdisk_assign_device(cxt, dev, 1) != 0) { fprintf(stderr, "Assign device failed: %s\n", fdisk_strerror(fdisk_get_error(cxt))); fdisk_free_context(cxt); return -2; } // 创建第一个分区 struct fdisk_partition *p1 = fdisk_partition_new(); fdisk_partition_set_start(p1, 2048); // 对齐到扇区 fdisk_partition_set_size(p1, 1048576); // 1GB(假设扇区大小512B) fdisk_partition_set_type(p1, "Linux"); if (fdisk_add_partition(cxt, p1, NULL) != 0) { fprintf(stderr, "Add partition 1 failed: %s\n", fdisk_strerror(fdisk_get_error(cxt))); fdisk_partition_free(p1); fdisk_free_context(cxt); return -3; } fdisk_partition_free(p1); // 创建第二个分区(错误示例:起始位置重叠/大小超出剩余空间) struct fdisk_partition *p2 = fdisk_partition_new(); // 错误:起始位置与第一个分区重叠 fdisk_partition_set_start(p2, 2048); fdisk_partition_set_size(p2, 2097152); // 2GB,超过剩余空间 fdisk_partition_set_type(p2, "Linux"); int ret = fdisk_add_partition(cxt, p2, NULL); if (ret != 0) { fprintf(stderr, "Add partition 2 failed: code=%d, msg=%s\n", ret, fdisk_strerror(fdisk_get_error(cxt))); } fdisk_partition_free(p2); // 必须提交分区表才能生效 if (fdisk_write_disklabel(cxt) != 0) { fprintf(stderr, "Write disklabel failed\n"); fdisk_free_context(cxt); return -4; } fdisk_free_context(cxt); return ret; }
排查与解决方向
校验分区参数合法性
- 获取第一个分区的结束位置:
fdisk_partition_get_end(p1),第二个分区的起始位置应设为该值+1(同时满足分区对齐要求)。 - 用
fdisk_get_disk_size(cxt)获取设备总容量,计算剩余空间后再设置第二个分区的大小。
- 获取第一个分区的结束位置:
确保提交分区表
添加分区后必须调用fdisk_write_disklabel(cxt)将更改写入磁盘,否则分区仅存在于内存中,后续操作会误以为空间已被占用。检查分区表类型限制
- MBR分区表最多支持4个主分区,若已创建4个主分区,需先创建扩展分区再添加逻辑分区。
- GPT分区表无此限制,但需确保GPT表头和分区表项有足够空间。
打印详细错误信息
不要仅依赖错误码,调用fdisk_strerror(fdisk_get_error(cxt))获取具体错误描述,能更精准定位问题。
内容的提问来源于stack exchange,提问作者FirowMD
相关产品推荐
相关产品推荐

