分区管理中如何在没有partprobe命令的极简系统中通过ioctl强制内核同步新分区表

作者:袖梨 2026-09-02

在无partprobe的极简系统中,可通过BLKRRPART ioctl强制内核重读分区表,推荐使用blockdev --rereadpt /dev/sda;若无blockdev,可用C程序调用ioctl实现,操作前须确保设备未挂载且有root权限。

在没有 partprobe 的极简系统(如嵌入式 BusyBox 环境、initramfs 或定制精简内核)中,可通过直接调用 BLKRRPART ioctl 强制内核重新读取分区表。这本质上是 partprobe 的底层机制,无需额外工具,仅依赖 ioctl 系统调用能力。

确认设备节点与权限

确保目标块设备(如 /dev/sda)存在且可被 root 用户访问。注意:不能对已挂载或正被使用的设备执行此操作,否则会返回 EBUSY(设备忙)。

  1. 检查设备是否存在:ls -l /dev/sd*
  2. 验证是否被占用:lsof /dev/sdacat /proc/mounts | grep sda
  3. 若设备正用于根文件系统或 swap,需先卸载或禁用相关分区

使用 blockdev 命令触发重读(最简替代)

多数极简系统仍包含 blockdev(比 partprobe 更轻量),它封装了 BLKRRPART ioctl:

  1. 强制重读单个磁盘:blockdev --rereadpt /dev/sda
  2. 重读全部块设备(谨慎使用):for d in /dev/sd[a-z]; do blockdev --rereadpt "$d" 2>/dev/null; done
  3. 成功无输出;失败时通常显示 Operation not permitted(权限不足)或 Device or resource busy

手动调用 ioctl(无 blockdev 时)

若连 blockdev 都不可用,可用 C 小程序或 Python(若有解释器)调用 ioctl。以下为最小可行 C 实现:

#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>#include <linux/fs.h>int main(int argc, char *argv[]) {if (argc != 2) {fprintf(stderr, "Usage: %s /dev/sdXn", argv[0]);return 1;}int fd = open(argv[1], O_RDONLY);if (fd == -1) {perror("open");return 1;}if (ioctl(fd, BLKRRPART, 0) == -1) {perror("ioctl BLKRRPART");close(fd);return 1;}printf("Partition table re-read OK for %sn", argv[1]);close(fd);return 0;}

编译运行:gcc -o reread reread.c && ./reread /dev/sda。静态链接可避免依赖 libc 动态库。

验证分区是否生效

执行后立即检查内核是否识别新分区:

  1. 查看设备节点是否生成:ls /dev/sda*(应出现 /dev/sda1/dev/sda2 等)
  2. 检查内核日志:dmesg | tail -10,正常会有类似 sda: sda1 sda2 的识别记录
  3. 确认 sysfs 信息:ls /sys/block/sda/sda*/start,有输出即表示分区已注册

相关文章

精彩推荐