partprobe源码分析

partprobe源码分析partprobe 工具操作系统目录 usr sbin partprobe 程序安装包 parted 3 1 17 el7 x86 64 rpm 命令用法 partprobe 是用来告知操作系统内核分区表发生变化的工具 告知方式是请求内核重读分区表选项如下 d 不会让内核重读分区表 分区表发生变化后使用该命令 partproe d dev sdi 不会告知内核分区发生了变化 s 先让内

命令用法:

partprobe是用来告知操作系统内核 分区表发生变化的工具,告知方式是请求内核重读分区表
选项如下:
-d 不会让内核重读分区表,分区表发生变化后使用该命令partproe -d /dev/sdi不会告知内核分区发生了变化
-s 先让内核重读分区表,再显示设备已拥有的分区信息






[root@node1 ~]# partprobe -s /dev/hda /dev/hda: msdos partitions 1 2 3 4 <5 6 7 8 9> #4分区为扩展分区,符号 
  <内部的分区为逻辑分区 <="" code="">

-h 显示帮助选项信息
-v 显示程序的版本信息

源码分析

partprobe主要操作是 告知操作系统内核 磁盘分区表发生了变化,接下来操作由内核完成。内核会先删除当前系统缓存中的磁盘分区表,然后重新从磁盘中读取分区表,主要通过io驱动函数ioctl来完成
执行partprobe命令基本代码流程如下:

  1. 正常的getopt_long函数的命令行解析
  2. 根据是否传入磁盘进行判断,如果传入磁盘,如partprobe /dev/sdb则进行磁盘处理;如未传入制定磁盘,则先获取到当前设备所有的磁盘,并加入到链表中,然后顺序执行分区表处理
    partprobe.c中的主函数处理如下
    int n_dev = argc - optind; //获取是否传入磁盘参数 if (n_dev != 0) { 
          //如果传入则一个一个处理 int i; for (i = optind; i < argc; i++) { 
           PedDevice *dev = ped_device_get (argv[i]); if (dev == NULL || process_dev (dev) == 0) //process_dev分区处理的主函数 status = 1; } } else { 
          //否则先获取当前设备所有磁盘 ped_device_probe_all ();//将获取到的磁盘加入到全局链表中 PedDevice *dev; for (dev = ped_device_get_next (NULL); dev;//遍历链表,一个一个顺序执行分区检测 dev = ped_device_get_next (dev)) if (process_dev (dev) == 0) status = 1; } 


  3. 从磁盘将分区表读到内存中,并告知操作系统内核分区表的布局
    static int process_dev (PedDevice* dev) {       PedDiskType* disk_type; PedDisk* disk; disk_type = ped_disk_probe (dev); //获取分区类型,gpt?msdos? if (!disk_type || !strcmp (disk_type->name, "loop")) return 1; /*创建一个新的分区表,并存放在内存中。当调用ped_disk_commit_to_dev函数,由内核决定是否写入磁盘*/ disk = ped_disk_new (dev); if (!disk) goto error; /*该参数为我们的-d参数,即partprobe -d /dev/sdb 表示不会执行告知内核磁盘分区情况的操作,如传入-d参数,则当前数值为1*/ if (!opt_no_inform) {       if (!ped_disk_commit_to_os (disk)) //内核操作的主函数 goto error_destroy_disk; } /*该参数表示 partprobe -s参数,执行是否打印磁盘分区信息的操作*/ if (opt_summary) /*打印当前磁盘分区的情况*/ summary (disk); ped_disk_destroy (disk); return 1; error_destroy_disk: ped_disk_destroy (disk); error: return 0; } 
  4. 内核操作分区表版本如下,ped_disk_commit_to_os函数操作
    • 在内核版本为2.4之前,partprobe会调用BLKRRPART ioctl函数让内核重读分区表
    • 在2.4.x之后的内核已经更改为使用新的blkpg接口告诉内核每一个磁盘分区的起始,结束地址。所以,在新版本内核中,不会因为分区表类型不同而无法读取磁盘分区表
    //通过ped_disk_commit_to_os 函数调用的回掉函数disk_commit(disk)进行内核分区的处理 ped_disk_commit_to_os(PedDisk* disk){       ... if (!ped_architecture->disk_ops->disk_commit (disk)) } PedDiskArchOps linux_disk_ops = {       partition_get_path: linux_partition_get_path, partition_is_busy: linux_partition_is_busy, disk_commit: linux_disk_commit //通过改数据结构调用linux_disk_commit函数进行处理 }; /*告知内核磁盘分区的布局*/ static int linux_disk_commit (PedDisk* disk) {       if (!_has_partitions (disk)) return 1; /*若系统支持逻辑卷方式管理磁盘,且磁盘分区类型为支持dm,一般为msdos格式即mbr分区,则重读分区表。一半存放在/dev/mapper目录*/ #ifdef ENABLE_DEVICE_MAPPER  if (disk->dev->type == PED_DEVICE_DM) return _dm_reread_part_table (disk); #endif /*如果设备类型为普通文件类型,即文件形式存放的,一般为我们的gpt分区类型的磁盘*/ if (disk->dev->type != PED_DEVICE_FILE) {       /*要求当前内核支持blkpg的新特性,即使用blkpg接口告知内核磁盘分区表的起始地址,不需要内核自己去读。如果 当前内核不支持该特性,或者这里发现有断言退出,可以直接将改行注释掉*/ assert (_have_blkpg ()); /*内核同步磁盘分区表的主函数*/ if (!_disk_sync_part_table (disk)) return 0; } return 1; } 
  5. 内核同步磁盘分区表的操作,即我们partprobe的主要操作
    • 通过io设备驱动程序的通道管理函数ioctl,先从内核移除所有的分区表。但是当ioctl执行失败时,不会对此时失败的分区表进行移除
    • 从我们遍历到的磁盘中添加分区表。如果我们因为第一步移除分区表的失败无法添加(因为使用的是blkpg新特性,移除以及添加需要保证分区表的起始结束地址一直才能确定执行成功),则进行告警
      static int _disk_sync_part_table (PedDisk* disk) {         ... /*从/sys/block/dev_name/range文件中获取当前系统支持的单个磁盘最大分区数量,如果获取不到,则使用默认的64*/ lpn = _device_get_partition_range(disk->dev); ... /*对当前磁盘执行分区删除操作 通过调用_blkpg_part_command(disk->dev, &linux_part,BLKPG_DEL_PARTITION) 函数执行ioctl (arch_specific->fd, BLKPG, &ioctl_arg)的分区删除操作 */ _blkpg_remove_partition (disk, j + 1); ... /*同样通过 _blkpg_part_command (disk->dev, &linux_part, BLKPG_ADD_PARTITION) 函数执行ioctl (arch_specific->fd, BLKPG, &ioctl_arg)的分区添加操作 */ _blkpg_add_partition (disk, part); /*根据执行的结果是否抛出异常进行告警*/ } 

关于常见的两种问题的告警描述如下:

  1. “Error informing the kernel about modifications to “
    “partition %s – %s. This means Linux won’t know “
    “about any changes you made to %s until you reboot “
    “– so you shouldn’t mount it or use it in any way “
    “before rebooting.
    该问题为内核向磁盘添加分区过程中ioctl程序执行失败,一般为当前分区表x相关元数据信息错误










  2. Partition(s) %s on %s have been written, but we have “
    “been unable to inform the kernel of the change, “
    “probably because it/they are in use. As a result, “
    “the old partition(s) will remain in use. You “
    “should reboot now before making further changes.
    该问题为内核删除分区表时出现,因为分区仍然被占用,无法从缓存中清除该分区的起始和结束地址导致。










版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/176664.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午9:22
下一篇 2026年3月26日 下午9:22


相关推荐

  • sql2008“备份集中的数据库备份与现有的xx数据库不同”解决方法[通俗易懂]

    sql2008“备份集中的数据库备份与现有的xx数据库不同”解决方法[通俗易懂]原文链接:http://www.cnblogs.com/huangfr/archive/2012/08/09/2629687.html1.因为是在另一台电脑对同名数据库做的备份,用常规方法还原,提示不是相同数据库,不让还原,在网上找到下面的方法解决了:一、右击系统数据库master,新建查询执行以下SQL代码:RESTOREDATABASExxxFROMDI

    2022年6月6日
    39
  • js统计英文单词数量

    js统计英文单词数量js单词数量

    2025年5月26日
    5
  • OpenClaw 2026.3.12 版本更新发布:安全加固 + 稳定性提升!

    OpenClaw 2026.3.12 版本更新发布:安全加固 + 稳定性提升!

    2026年3月14日
    1
  • Matlab自定义颜色图

    Matlab自定义颜色图介绍Matlab自带颜色图比较单调,很多时候无法达到其它绘图工具,如:NCL、Pythonmatplotlib、GMT等绘图软件颜色图效果。下面就介绍如何将NCL等颜色图为己所用。颜色图下载NCL官网提供了上述绘图工具的颜色图合集,因此只需要将需要的颜色图下载后进行使用即可。选择颜色图WhiteBlueGreenYellowRed下载。Matlab读取下载的颜色表clc;clearall;closeallfiguremesh(peaks)colorbarcolor=n

    2022年5月6日
    46
  • mysql unpivot_UNPIVOT逆透视以及动态逆透视存储过程

    mysql unpivot_UNPIVOT逆透视以及动态逆透视存储过程今天练习 MSSQLServer 逆透视的功能 首先准备一些可以逆透视的数据 IFOBJECT ID tempdb dbo Part summary ISNOTNULLDRO Part summaryCREAT Part summary Item NVARCHAR 40 B DECIMAL 18 2 Q DECIMAL 18 2

    2026年3月17日
    2
  • Pycharm介绍_怎么用pycharm

    Pycharm介绍_怎么用pycharm一.开发环境介绍每一个项目可能有不同的开发环境,而为了解决这一冲突,pycharm采用了两种环境设置方式:一个是虚拟环境方式:也就是每一个项目配置一个环境,在项目中为venv文件夹创建项目时意味着每一个项目都copy一份新的开发环境,而彼此之间相互独立还有一种方式为采用公用的一个开发环境,常用于各项目之间不会互相影响的情况二.pycharm快捷键Ctrl+Alt+L注释Ctrl+/行注释Ctrl+Alt+L代码格式化Ctrl+D复制当前行三.注释

    2025年7月24日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号