6

Это похоже на вопрос, заданный здесь:

Как изменить UUID тома в Mac OS X 10.6?

Разница лишь в том, что я хочу изменить его на конкретное значение, а не на случайное. Hfs.util только кажется случайным.

Я подумал об изменении источника hfs.util, чтобы позволить мне указывать значения. Пока я искал код и искал, с чего начать вносить изменения, я вспомнил, почему C не мой любимый язык. Несколько ошибок компиляции и ошибки позже, я потерял энтузиазм, пытаясь изменить этот инструмент. Я готов снова попробовать это после того, как я немного отдохну, но я думаю, что должен быть более простой способ изменить UUID тома, о котором я просто не знаю.

Итак, прежде чем я потрачу больше времени, кто-нибудь знает простой способ сделать это? Или кто-нибудь из экспертов C хотел бы присоединиться к моим усилиям, чтобы hfs.util изменил UUID на указанное значение?

Вот изменения, которые я сделал, чтобы иметь возможность скомпилировать инструмент из исходной версии OS X 10.6.8:

hfsutil_jnl.c:

47: #include <hfs_fsctl.h>

hfsutil_main.c:

80: #include <uuid/uuid.h>
81: /* REMOVED */

И, как указывалось в этой статье, добавлено следующее из строки 166 в файле fs.c в файл hfsutil_main.c (поскольку namespace.h нет в системе):

static unsigned char kFSUUIDNamespaceSHA1[] = {0xB3,0xE2,0x0F,0x39,0xF2,0x92,0x11,0xD6,0x97,0xA4,0x00,0x30,0x65,0x43,0xEC,0xAC};

Наконец, я взял этот файл и добавил его в рабочий каталог http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/hfs/hfs_fsctl.h

2 ответа2

6

Я взялся за это. Я скачал исходный код для hfs.util , внес изменения, которые вы упомянули (чтобы он мог скомпилироваться), снова включил функцию UUID (например, -s, которая отключена в текущем источнике), и добавил новую команду (-S, которая используется для указания UUID).

Формат новой команды такой:

sudo hfs.util -S disk0s2 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Вы должны использовать sudo или запускать с правами root, но вам НЕ нужно отключать том (даже если это ваш текущий системный том).

Однако, я все еще отлаживаю это (я ужасен с C). Я могу запустить его без ошибок, но он все еще эффективно рандомизирует новый UUID с -S. Независимо от того, какой UUID я указал, я все равно получаю другой.

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

Если я потерплю неудачу, я, вероятно, все еще выложу diff, и, возможно, кто-то еще (кто лучше с C) может это исправить.

РЕДАКТИРОВАТЬ: ОК. Я обнаружил, что, как представляется, главная ошибка в функциях, которые обрабатывают двоичные функции UUID string <-> в исходном коде Apple для hfs.util . В качестве двоичного значения для хранения 128-битного UUID требуется 4 (без знака) 32-разрядных слова. Похоже, что источник Apple обрабатывает только 16 шестнадцатеричных символов (это должно быть 16 октетов по 2 шестнадцатеричных символа каждый).

Похоже, что он также использует дефектную структуру для хранения UUID (он, похоже, хранит только «старшее» 32-битное слово и «младшее» 32-битное слово, но потребуется 4 (без знака) 32-битных слова). Я могу думать, что могу это исправить, но я должен изменить структуру и все функции, которые используют структуру (так что это может занять некоторое время).

РЕДАКТИРОВАТЬ # 2: После того, как вы потратили слишком много времени на отладку исходного кода Apple для hfs.util (я действительно не программист на C), похоже, что Apple намеренно обрабатывает только 64-битные при обработке UUID. Остальное генерируется из хэша 64-битной константы, значений компонентов компьютера, текущего времени и т.д. Таким образом, если вы использовали один и тот же 64-битный «ключ» дважды, вы все равно получили бы два разных UUID (даже если вы использовали один и тот же компьютер, время все равно изменилось). Пока фактическая запись в заголовок тома отправляет фактический UUID (а не просто ключ), и пока заголовок тома хранит фактический UUID (а не только ключ и / или значения, которые могут использоваться для вычисления UUID), то есть надежда. Моя отладка еще не прошла так далеко. Я отправлю еще раз, когда узнаю больше.

6

Я не изучал исходный код hfs.util, и, вероятно, уже слишком поздно, чтобы быть полезным для вас, но я думаю, что могу внести что-то полезное.

UUID, используемые для томов HFS+, по-видимому, представляют собой все варианты, охватываемые спецификацией UUID, и относятся к типу версии 3, то есть к пространству имен и имени, преобразованному в UUID через MD5 (см. Подробности в википедии).

Представляется вероятным, что фактический идентификатор диска (занимающий место имени в спецификации) составляет всего 64 бита, преобразуемого в 128-битный UUID в соответствии со спецификацией, добавляя UUID любого пространства имен, которое Apple использует для идентификаторов томов, и затем применяя хеш MD5.

Это не касается значений компонентов компьютера, текущего времени и т.д. Они используются для других типов UUID. Однако он включает в себя UUID "пространства имен" (для определения того, что мы "называем" том диска), а затем "имя" (фактический идентификатор диска).

Одна вещь, которая заставляет меня так думать, - это не только утверждение @ chriv о том, что код, похоже, использует только 64 бита, но и способ обработки UUID с помощью "секретной" утилиты, поставляемой с SuperDuper!

СуперДупер! Утилита резервного копирования для Mac OS X имеет "скрытый" инструмент командной строки, который позволит вам получить и установить UUID тома. Но он одновременно извлекает и устанавливает его как последовательность из 64 битов (выраженную в шестнадцатеричном формате). И кажется, что эти биты сильно отличаются от фактических значений, сообщаемых дисковыми утилитами Apple.

Для получения дополнительной информации см .:

http://www.shirt-pocket.com/forums/archive/index.php/t-1186.html

http://www.shirt-pocket.com/forums/archive/index.php/t-6173.html

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


Обновить

Я взглянул на источники Apple. Я подтверждаю, что я написал выше. На диске сохраняется 64-битный идентификатор тома (который генерируется случайным образом, беря первые 64 бита хэша SHA1 из набора псевдослучайных бит данных: время работы, время загрузки, идентификатор хоста, имя хоста, выпуск ядра). строка, строка версии ядра, средняя загрузка, статистика ВМ и текущее время).

В UUID версии 3 это "имя". Поэтому на диске сохраняется 64-битное "имя" тома, а не UUID.

UUID в 128 битов, который сообщается инструментами, не сохраняется, он вычисляется каждый раз, для целей отображения, из "имени" и "пространства имен" (пространство имен фиксировано и является константой kFSUUIDNamespaceSHA1, к которой ОП пришлось вручную добавить источник, потому что заголовок, содержащий его, отсутствует: он представляет "пространство имен" для "имен" томов, которые являются 64-битными объектами, которые фактически сохраняются на томах для их идентификации).

Легко перейти от "имени" к UUID (в основном вы применяете стандартный алгоритм для UUID версии 3), но в принципе невозможно вернуться от UUID к "имени". Другими словами, ответ на OP таков: это возможно, если вы знаете "имя" тома (например, если вы хотите восстановить резервную копию на новый диск и сохранили как имя, так и данные) , но не если вы знаете только UUID. Правильная установка имени приведет к ожидаемому UUID, но вам нужно имя и вы не можете вычислить его по UUID.


Примечания к коду Apple (прочитайте их, посмотрите на код, и все станет ясно):

Как я уже писал, все, что есть на диске, это "имя". UUID вычисляется только для визуализации с использованием алгоритма версии 3 (UUID для "имени" в "пространстве имен").

  • kFSUUIDNamespaceSHA1 - это константа "пространства имен", как описано выше.
  • uuid_create_md5_from_name - это алгоритм UUID версии 3, который вычисляет UUID версии 3 с учетом "пространства имен" и "имени".
  • GenerateVolumeUUID генерирует новое случайное "имя" (обратите внимание: только "имя", а не UUID, несмотря на имя функции).

Установка и получение "имени" на диск зависит от того, смонтирован ли том в данный момент. "Имя" хранится в "Finder Info" тома. Получение и настройка данных "Finder Info" для смонтированного тома может быть выполнено с помощью getattrlist и setattrlist, но если том не смонтирован, они обращаются к прямому доступу к данным тома (в конце концов, это unix, а размонтированный том - блок устройство, которое доступно, как root, в виде файла).

  • SetVolumeUUID, SetVolumeUUIDRaw, SetVolumeUUIDAttr, GetVolumeUUID, GetVolumeUUIDRaw, GetVolumeUUIDAttr выполняют чтение / запись "имени" (опять же, несмотря на их имя, они обрабатывают только "имя" тома, а не UUID). Функции * Raw обрабатывают прямой доступ через "файл" устройства для несмонтированных томов, а функции * Attr используют API get / setattrlist. Простые проверяют, смонтирован ли том, и вызывают соответствующую версию * Raw / * Attr.

Тогда есть функции "высокого уровня", которые реализуют функциональность инструмента:

  • DoGetUUIDKey получает "имя", корректирует порядковый номер, а затем вычисляет UUID для отображения.
  • DoChangeUUIDKey создает новое случайное имя и записывает его на том.

Поэтому лучшее, что вы можете сделать, это перекодировать ту же функциональность, что и маленький инструмент командной строки, встроенный в SuperDuper Shirt Pocket! (см. ссылки, которые я разместил выше).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .