Открытие файла дискового устройства для доступа на запись в Mac OS X - PullRequest
5 голосов
/ 09 февраля 2012

Я пытаюсь слегка изменить таблицу разделов диска на Mac;в частности, мне нужно изменить тип раздела.diskutil не поддерживает это, поэтому я не могу его использовать.Он отлично работает (например, с помощью модифицированной утилиты командной строки gpt), если диск не используется.Если это так, происходит сбой при открытии файла устройства:

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

fd равно -1, а errno указывает на ошибку «ресурс занят».

Я понимаю, что могу перезагрузитьсямашину с другого диска, измените исходный диск оттуда, затем загрузитесь снова.Это, однако, не совсем легко автоматизировать / надежно из моего приложения.Кроме того, diskutil не имеет проблем с редактированием таблицы разделов живого устройства, а также не имеет установщика bootcamp.

Есть ли известный способ сделать это?В худшем случае, я могу попытаться сделать это в ядре, но кексы на самом деле не предназначены для выполнения одноразовых действий, и то, что мне нужно сделать, действительно довольно концептуально просто в пользовательском пространстве, но довольно сложно в ядре.

Есть идеи?

Примечание: Я запускаю все с sudo, поэтому не должно быть проблем с разрешениями.

Ответы [ 2 ]

6 голосов
/ 19 февраля 2012

Как Apple это делает

После некоторой работы с otool и дизассемблером, я решил, что diskutil от Apple использует некоторые частные фреймворки для работы. (Я посмотрел на версию командной строки, но набор функций и сообщения о состоянии / ошибках графического интерфейса пользователя Дисковая утилита так близко совпадают, я сомневаюсь, что есть разница) В частности, Objective-C DiskManagement.framework содержит классы и методы, которые отображают команды от 1: 1 до diskutil. Многие сообщения об ошибках появляются из MediaKit.framework, который не основан на Objective-C, поэтому его API не виден прямо в otool.

Вкратце рассмотрев разбор некоторых функций, кажется, что порты Маха и MIG используются интенсивно. Я понятия не имею, насколько глубока кроличья нора обратного инжиниринга, и насколько она полезна. В конце концов, DiskManagement.framework, кажется, делает именно то, что делает diskutil, и не более, так что это не включает прямое редактирование таблицы разделов. Даже если бы я понял, как это происходит под капотом, это может не помочь мне решить мою проблему.

Как я это делаю

Итак, чтобы не тратить больше времени на действия с сомнительными шансами на успех, я закончил тем, что делал это через расширение ядра, чего я и пытался избежать. Я в основном построил общий IOService подкласс вместе с IOUserClient вспомогательным подклассом. Это предоставляет некоторые методы для замены существующей таблицы разделов на новые процессы в пространстве пользователя, выполняющиеся от имени пользователя root. Он ищет объект IOMedia, соответствующий имени устройства, и с некоторой хитростью выполняет операции чтения / записи непосредственно над этим. Я передаю ему старую таблицу разделов, чтобы она могла убедиться, что она действительно обновляет нужные данные. Что касается пользовательского пространства, я изменил утилиту gpt, чтобы использовать библиотеки пользовательского пространства I / O Kit для связи с kext. Я только временно загружаю kext для внесения изменений, а затем снова выгружаю его. Это заняло у меня большую часть двух дней, но это хорошо работает.

0 голосов
/ 10 февраля 2012

Вам необходимо использовать устройство с необработанным диском - в вашем случае это будет /dev/rdisk1.Также, очевидно, вам нужно быть root.

...