Jak zmienić identyfikator UUID woluminu w systemie Mac OS X na wartość OKREŚLONĄ?

6

Jest to podobne do pytania zadanego tutaj:

Jak zmienić identyfikator UUID woluminu w systemie Mac OS X 10.6?

Jedyną różnicą jest to, że chcę ją zmienić na określoną, a nie losową wartość. Hfs.util wydaje się robić tylko losowo.

Rozważałem zmodyfikowanie źródła hfs.util, aby umożliwić mi określenie wartości. Kiedy grzebałem w kodzie, szukając od czego zacząć wprowadzanie zmian, przypomniałem sobie, dlaczego C nie jest moim ulubionym językiem. Kilka błędów kompilacji i segfaultów później straciłem entuzjazm do próby modyfikacji tego narzędzia. Jestem gotów spróbować ponownie po tym, jak trochę odpocznę, ale myślę, że musi być łatwiejszy sposób na zmianę UUID woluminu, o którym po prostu nie wiem.

Więc zanim zmarnuję więcej czasu, czy ktoś wie, jak to łatwo zrobić? Czy może eksperci C chcieliby dołączyć do moich starań, aby hfs.util zmienił UUID na określoną wartość?

Oto zmiany, które wprowadziłem, aby móc skompilować narzędzie ze źródłowego systemu OS X 10.6.8:

hfsutil_jnl.c:

47: #include <hfs_fsctl.h>

hfsutil_main.c:

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

I, jak wskazano w tym artykule , dodano następujący wiersz z wiersza 166 w fs.c do hfsutil_main.c (ponieważ przestrzeni nazw.h nie ma nigdzie w systemie):

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

Na koniec złapałem ten plik i dodałem go do działającego katalogu http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/hfs/hfs_fsctl.h

łucznicy
źródło
1
Dodałem dużą aktualizację do mojej odpowiedzi. Jeśli ty lub @chriv (lub ktokolwiek inny) nadal jesteś zainteresowany i / lub masz wątpliwości, możesz zapytać. Ale tak naprawdę nie powinno być nic więcej do dodania. Z moim wyjaśnieniem i linkami do kodu wszystko powinno być całkiem jasne.
Plik analogowy

Odpowiedzi:

7

Nie szukałem kodu źródłowego hfs.util i prawdopodobnie jest już za późno, aby był dla ciebie przydatny, ale myślę, że mogę coś wnieść.

Identyfikatory UUID używane dla woluminów HFS + wydają się być wszystkimi wariantami objętymi specyfikacją UUID i mają typ wersji 3, tj. Przestrzeń nazw i nazwa konwertowana na UUID przez MD5 (zobacz szczegóły na wikipedii ).

Wydaje się prawdopodobne, że rzeczywisty identyfikator dysku (zastępujący nazwę w specyfikacji) to zaledwie 64 bity, przekonwertowany na 128-bitowy identyfikator UUID zgodnie ze specyfikacją, poprzedzając identyfikator UUID dowolnej przestrzeni nazw, której Apple używa dla identyfikatorów woluminów, a następnie stosując skrót MD5.

Nie dotyczy to wartości elementów komputera, aktualnego czasu itp. Są one używane w przypadku innych rodzajów identyfikatorów UUID. Wymaga to jednak UUID „przestrzeni nazw” (w celu zidentyfikowania faktu, że „nazywamy” wolumin dysku), a następnie „nazwy” (faktyczny identyfikator dysku).

Jedną z rzeczy, które tak myślę, jest nie tylko stwierdzenie @ chriv, że kod wydaje się używać tylko 64 bitów, ale także sposób, w jaki identyfikatory UUID są obsługiwane przez „tajne” narzędzie dostarczane z SuperDuper!

SuperDuper! narzędzie do tworzenia kopii zapasowych dla systemu Mac OS X ma „ukryte” narzędzie wiersza poleceń, które pozwala pobrać i ustawić identyfikator UUID woluminu. Ale zarówno pobiera, jak i ustawia jako sekwencję 64 bitów (wyrażonych w postaci szesnastkowej). I wygląda na to, że te bity są zupełnie inne niż rzeczywiste wartości zgłaszane przez narzędzia dyskowe Apple.

Aby uzyskać więcej informacji zobacz:

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

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

Uwaga: przeczytaj te dyskusje dotyczące wsparcia przez cały czas, ponieważ wydaje się, że istnieją pewne problemy, na przykład czasami konieczne ponowne uruchomienie.


Aktualizacja

Spojrzałem na źródła Apple. Potwierdzam to, co napisałem powyżej. Na dysku zapisywany jest 64-bitowy identyfikator woluminu (generowany losowo przez pobranie pierwszych 64 bitów skrótu SHA1 zestawu pseudolosowych bitów danych: czas działania, czas uruchamiania, identyfikator hosta, nazwa hosta, nazwa jądra ciąg, ciąg wersji jądra, średnia wartość obciążenia, statystyki VM i aktualny czas).

W języku UUID w wersji 3 jest to „nazwa”. Zatem na dysku zapisana jest 64-bitowa „nazwa” woluminu, a nie UUID.

UUID 128-bitowy zgłaszany przez narzędzia nie jest zapisywany, jest obliczany za każdym razem, do celów wyświetlania, z „nazwy” i „przestrzeni nazw” (przestrzeń nazw jest stała i jest to stała kFSUUIDNamespaceSHA1, do której OP musiał ręcznie dodać źródło, ponieważ brakuje nagłówka, który go zawiera: reprezentuje „przestrzeń nazw” dla „nazw woluminów”, które są 64-bitowymi rzeczami zapisanymi na woluminach w celu ich identyfikacji).

Przejście z „nazwy” na UUID jest łatwe (w zasadzie stosuje się standardowy algorytm dla UUID wersji 3), ale w zasadzie nie można wrócić z UUID do „nazwy”. Innymi słowy, odpowiedź na OP jest możliwa: jeśli znasz „nazwę” woluminu (na przykład, jeśli chcesz przywrócić kopię zapasową na nowy dysk ORAZ zapisałeś jej nazwę i dane) , ale nie, jeśli znasz tylko UUID. Prawidłowe ustawienie nazwy spowoduje oczekiwany UUID, ale potrzebujesz nazwy i nie możesz jej obliczyć na podstawie UUID.


Uwagi na temat kodu Apple (przeczytaj je i spójrz na kod, a wszystko stanie się jasne):

Jak napisałem, wszystko na dysku to „nazwa”. Identyfikator UUID jest obliczany tylko do wizualizacji przy użyciu algorytmu w wersji 3 (identyfikator UUID dla „nazwy” w „przestrzeni nazw”).

  • kFSUUIDNamespaceSHA1 jest stałą „przestrzeni nazw”, jak wyjaśniono powyżej.
  • uuid_create_md5_from_name to algorytm UUID wersji 3, który oblicza identyfikator UUID wersji 3, biorąc pod uwagę „przestrzeń nazw” i „nazwę”.
  • GenerateVolumeUUID generuje nową losową „nazwę” (uwaga: tylko „nazwa”, a nie UUID, pomimo nazwy funkcji).

Ustawienie i przeniesienie „nazwy” na dysk różni się w zależności od tego, czy wolumin jest aktualnie podłączony. „Nazwa” jest przechowywana w „Informacji o Finderze” woluminu. Pobieranie i ustawianie danych „Finder Info” dla zamontowanego woluminu można wykonać za pomocą getattrlist i setattrlist, ale jeśli wolumin nie jest zamontowany, uciekają się do bezpośredniego dostępu do danych woluminu (w końcu jest to unix, a niezamontowany wolumin jest blokiem urządzenie dostępne jako root jako plik root).

  • SetVolumeUUID , SetVolumeUUIDRaw , SetVolumeUUIDAttr , GetVolumeUUID , GetVolumeUUIDRaw , GetVolumeUUIDAttr czytają / zapisują „nazwę” (ponownie, pomimo swojej nazwy, obsługują tylko „nazwę” woluminu, a nie UUID). Funkcje * Raw obsługują bezpośredni dostęp za pośrednictwem „pliku” urządzenia dla niezmontowanych woluminów, te * Attr używają interfejsu API get / setattrlist. Zwykłe sprawdzają, czy wolumin jest zamontowany i wywołują odpowiednią wersję * Raw / * Attr.

Następnie są funkcje „wysokiego poziomu”, które implementują funkcjonalność narzędzia:

  • DoGetUUIDKey pobiera „nazwę”, dostosowuje się do endianowości, a następnie oblicza UUID do wyświetlenia.
  • DoChangeUUIDKey tworzy nową, losową „nazwę” i zapisuje ją w woluminie.

Najlepsze, co możesz zrobić, to ponownie zakodować tę samą funkcjonalność małego narzędzia wiersza poleceń wbudowanego w SuperDuper Shirt Pocket! (patrz linki, które zamieściłem powyżej).

Plik analogowy
źródło
6

Poradziłem sobie z tym. Pobrałem źródło dla hfs.util, wprowadziłem zmiany, o których wspomniałeś (aby mógł się skompilować), ponownie włączyłem funkcję UUID (jak -s, która jest wyłączona w bieżącym źródle) i dodałem nowe polecenie (-S, które służy do podaj UUID).

Format nowego polecenia jest następujący:

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

Musisz użyć sudo lub uruchomić jako root, ale NIE musisz odinstalowywać woluminu (nawet jeśli jest to bieżący wolumin systemowy).

Nadal jednak debuguję go (jestem okropny z C). Mogę uruchomić go bezbłędnie, ale nadal skutecznie losuje nowy UUID za pomocą -S. Niezależnie od podanego przeze mnie identyfikatora UUID wciąż otrzymuję inny.

Jeśli go uruchomię, albo opublikuję tutaj różnicę, albo znajdę miejsce do przesłania zmodyfikowanego źródła i link do niego stąd.

Jeśli mi się nie uda, prawdopodobnie nadal opublikuję różnicę i być może ktoś inny (lepszy z C) może to naprawić.

EDYCJA: OK. Znalazłem coś, co wydaje się być poważnym błędem w funkcjach, które obsługują ciąg UUID <--> funkcje binarne w kodzie źródłowym Apple hfs.util. Jako wartość binarna do przechowywania 128-bitowego UUID potrzeba 4 (niepodpisanych) 32-bitowych słów. Źródło Apple wydaje się przetwarzać tylko 16 znaków szesnastkowych (powinno być 16 oktetów po 2 znaki szesnastkowe).

Wydaje się również, że używa uszkodzonej struktury do przechowywania UUID (wydaje się, że przechowuje tylko „wysokie” 32-bitowe słowo i „niskie” 32-bitowe słowo, ale potrzebne byłyby 4 (niepodpisane) 32-bitowe słowa). Mogę myśleć, że mogę to naprawić, ale muszę zmienić strukturę i wszystkie funkcje, które używają tej struktury (więc może to trochę potrwać).

EDYCJA 2: Po spędzeniu zbyt dużo czasu na debugowaniu źródła Apple dla hfs.util (tak naprawdę nie jestem programistą C) wydaje się, że Apple celowo obsługuje tylko 64 bity podczas obsługi UUID. Reszta jest generowana z sumy 64-bitowej stałej, wartości komponentów komputera, aktualnego czasu i tak dalej. Jeśli więc użyjesz tego samego 64-bitowego „klucza” dwa razy, nadal będziesz mieć dwa różne identyfikatory UUID (nawet jeśli używałeś tego samego komputera, czas się zmienił). Tak długo, jak rzeczywisty zapis do nagłówka woluminu wysyła rzeczywisty UUID (a nie tylko klucz), i tak długo, jak nagłówek woluminu przechowuje rzeczywisty UUID (a nie tylko klucz i / lub wartości, których można użyć do obliczenia UUID), wtedy jest nadzieja. Moje debugowanie jeszcze nie zaszło. Napiszę ponownie, gdy dowiem się więcej.

chriv
źródło