【问题标题】:Opening disk device file for write access on Mac OS X在 Mac OS X 上打开磁盘设备文件以进行写访问
【发布时间】:2012-02-09 16:47:59
【问题描述】:

我正在尝试对 Mac 上磁盘的分区表进行细微的修改;特别是,我需要更改分区的类型。 diskutil 不支持这个,所以我不能用。如果磁盘未在使用中,它可以正常工作(例如,通过修改后的gpt 命令行实用程序)。如果是,则打开设备文件失败:

int fd = open("/dev/disk1", O_RDWR);

fd 为 -1,errno 表示错误“资源忙”。

我意识到我可以从另一个驱动器重新启动机器,从那里修改原始磁盘,然后重新启动。然而,从我的应用程序内部实现自动化/可靠并不容易。另外diskutil修改直播设备分区表没有问题,bootcamp安装程序也没有。

有没有已知的方法可以做到这一点?最坏的情况,我可以尝试在内核中进行,但 kext 并不是真正为一次性完成而设计的,我需要做的实际上是在用户空间中概念上非常简单,但在内核中却很难。

有什么想法吗?

注意:我使用sudo 运行所有程序,所以这应该不是权限问题。

【问题讨论】:

  • 你看过 fdisk 的源码了吗?
  • fdisk 实际上不适用于我测试过的任何 Mac。它试图打开一个不存在的文件/usr/standalone/i386/boot0。即使除此之外,它似乎也没有做任何聪明的事情。
  • 好的,所以如果不是 fdisk,那么 freebsd 等价物(我猜是苹果的磁盘工具前端)
  • Intel Mac 默认使用 GUID 分区方案,因此我使用源自 BSD 的 gpt 实用程序进行了实验。 diskutil 似乎不是 gpt 的前端,但是,正如我所提到的,gpt 实际上并不起作用。 diskutil 的来源不可用。

标签: macos posix iokit


【解决方案1】:

Apple 是如何做到的

在对otool 和反汇编程序进行了一些调查之后,我确定Apple 的diskutil 使用了一些私有框架来完成这项工作。 (我查看了命令行版本,但 GUI Disk Utility 的功能集和状态/错误消息非常匹配,我怀疑有区别)特别是 Objective-C DiskManagement.framework 包含将 1:1 映射到 diskutil 命令的类和方法。很多错误消息似乎来自 MediaKit.framework,它不是基于 Objective-C 的,所以它的 API 在 otool 中不可见。

简单看一下部分函数的反汇编,貌似Mach Ports和MIG用的比较多。我不知道逆向工程的兔子洞有多深,以及它是否会导致任何有用的地方。毕竟,DiskManagement.framework 似乎与diskutil 完全一样,仅此而已,因此不包括直接编辑分区表。即使我知道它是如何做到的,也可能无法帮助我解决问题。

我是怎么做的

因此,为了避免在成功机会存疑的活动上浪费更多时间,我最终通过内核扩展来实现,这正是我试图避免的。我基本上构建了一个通用的IOService 子类和一个IOUserClient 伴随子类。这向以 root 身份运行的用户空间进程公开了一些用新分区表替换现有分区表的方法。它搜索与设备名称相对应的IOMedia 对象,并通过一些技巧直接对其进行读/写操作。我将旧的分区表传递给它,以便它可以验证它确实在更新正确的东西。在用户空间方面,我修改了gpt 实用程序以使用用户空间 I/O Kit 库与 kext 对话。我只是暂时加载 kext 进行更改,然后再次卸载它。我花了 2 天的时间,但效果很好。

【讨论】:

    【解决方案2】:

    您需要使用原始磁盘设备 - 在您的情况下是 /dev/rdisk1。此外,很明显,您需要成为root

    【讨论】:

    • 我对@9​​87654323@ 或disk 都感到“资源繁忙”。它适用于未使用的磁盘。是的,我正在使用sudo(否则我会收到权限错误,而不是“资源繁忙”)。
    • 好的,然后确保卸载该磁盘上的所有卷。如果它是您的启动盘(我不禁想到 ;))那么您可能想要从 OS X DVD 启动。
    • 哪个磁盘取决于用户,是的,主引导磁盘将是一个流行的选择。这都连接到安装在旁边的(内核)驱动程序。在分区类型匹配之前,驱动程序不会加载,所以我想避免编写 another 内核模块只是为了重新分区。不过,看来我不得不这样做了。
    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2012-02-22
    • 2011-10-19
    • 2014-01-23
    相关资源
    最近更新 更多