![](/img/trans.png)
[英]Error installing Nix on macOS Catalina and Big Sur on FileVault-encrypted boot volume on Mac without T2 chip
[英]Determine Volume Groups in macOS Catalina, Big Sur and later
從 macOS 10.15 (Catalina) 開始,一個卷,如用戶所見,實際上可能由多個卷組成,例如 System 和 Data 卷。
我正在編寫一個需要分別識別這些卷的工具,因為當使用特定的文件操作時,例如searchfs
和fts_read
,它們不會跨越這些卷邊界,我需要了解哪些卷屬於一起,以便在用戶需要時要搜索系統卷,我知道在文件操作中包括“系統”和它的“數據”卷。
如何安全地確定哪些卷屬於一起?
[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]
使用[NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]
並沒有多大幫助,因為它不會在/System/Volumes/Data
包含根系統的數據卷(但可能包括隱藏的/System/Volumes/Data/home
卷)。 使用命令行工具(例如df
。
我需要考慮當前未啟動的其他系統卷。 例如,如果我同時擁有 BigSur 和 Catalina 系統,並且從前者開始,我希望能夠識別這四個卷:
/ BigSur System volume
/System/Volumes/Data BigSur Data volume
/Volumes/Catalina Catalina System volume
/Volumes/Catalina - Daten Catalina Data volume (created on a German system)
我如何判斷包含“Catalina”的兩卷實際上屬於同一組? 我不喜歡用部分名稱來匹配它們,因為這對我來說似乎相當隨機且不可靠。 如果數據量不是在英文系統上創建的,那么它的名稱中甚至不使用“Data”這一事實使得這已經太難以正確處理了。
是否有其他一些卷屬性可以幫助識別這些卷組?
Mike Bombich為我提供了以下解決方案:
您可以從 IOKit 獲取卷 UUID 和卷組 UUID。 同一組中的兩個卷將具有相同的組 UUID。 請注意,組 UUID 始終與數據卷的 UUID 相同(至少在實踐中是這樣)。
這是獲取已安裝卷列表的代碼,包括屬於卷組的隱藏卷:
- (void)listVolumes
{
NSArray<NSURL*> *vols = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:nil options: 0 ];
vols = [vols arrayByAddingObject:[NSURL fileURLWithPath:@"/System/Volumes/Data"]]; // the root's Data vol isn't added by default
NSMutableArray<NSString*> *lines = [NSMutableArray new];
for (NSURL *vol in vols) {
NSDictionary *d = [vol resourceValuesForKeys:@[
NSURLVolumeIsBrowsableKey,
NSURLVolumeIsRootFileSystemKey,
NSURLVolumeIdentifierKey,
NSURLVolumeNameKey
] error:nil];
struct statfs fsinfo;
statfs(vol.path.UTF8String, &fsinfo);
NSString *bsdName = [NSString stringWithUTF8String:fsinfo.f_mntfromname];
bsdName = [bsdName lastPathComponent];
[lines addObject:[NSString stringWithFormat:@"%@, %@, %@, %@", bsdName, vol.path, d[NSURLVolumeIsBrowsableKey], d[NSURLVolumeNameKey]]];
}
NSLog(@"\n%@", [lines componentsJoinedByString:@"\n"]);
}
以及用於列出卷組 ID 及其角色的代碼:
- (void)listGroupIDs
{
io_iterator_t iterator; io_object_t obj;
IOServiceGetMatchingServices (kIOMasterPortDefault, IOServiceMatching("IOMediaBSDClient"), &iterator);
while ((obj = IOIteratorNext (iterator)) != 0) {
io_object_t obj2;
IORegistryEntryGetParentEntry (obj, kIOServicePlane, &obj2);
NSString *bsdName = CFBridgingRelease(IORegistryEntryCreateCFProperty(obj2, CFSTR("BSD Name"), kCFAllocatorDefault, 0));
//NSString *volID = CFBridgingRelease(IORegistryEntryCreateCFProperty(obj2, CFSTR("UUID"), kCFAllocatorDefault, 0));
NSString *groupID = CFBridgingRelease(IORegistryEntryCreateCFProperty(obj2, CFSTR("VolGroupUUID"), kCFAllocatorDefault, 0));
NSArray *roles = CFBridgingRelease(IORegistryEntryCreateCFProperty(obj2, CFSTR("Role"), kCFAllocatorDefault, 0));
if (groupID != nil && ![groupID isEqualToString:@"00000000-0000-0000-0000-000000000000"]) {
NSLog(@"%@: %@, %@", bsdName, groupID, roles);
}
}
}
有了這些信息,來自 IOKit 的卷就可以通過它們的 BSD 名稱與 NSURL 匹配。
但是,還有一種特殊情況:在 macOS Big Sur 上,根系統的設備不是常規的“diskXsY”而是快照設備,例如“diskXsYsZ”。 雖然 IOKit 代碼也列出了這一點,但它的條目缺少角色信息。
這是來自 Mac 的示例輸出,帶有 Big Sur 和 Catalina 系統,如問題所示(為了可讀性稍作編輯):
disk3s1s1, /, 1, BigSur
disk3s5, /System/Volumes/VM, 0, VM
disk3s3, /System/Volumes/Preboot, 0, Preboot
disk3s6, /System/Volumes/Update, 0, Update
disk4s1, /Volumes/Catalina - Daten, 0, Catalina - Daten
disk4s2, /Volumes/Catalina, 1, Catalina
disk3s2, /System/Volumes/Data, 1, BigSur
disk4s1: 18464FE4-8321-4D36-B87A-53AC38EF6AEF, 18464FE4-8321-4D36-B87A-53AC38EF6AEF, ("Data")
disk3s1: 86812DBD-9252-4A2E-8887-752418DECE13, 058517A6-48DD-46AB-8A78-C1F115AE6E13, ("System")
disk4s2: 51DEC6AC-2D68-4B60-AE23-74BCA2C3A484, 18464FE4-8321-4D36-B87A-53AC38EF6AEF, ("System")
disk3s2: 058517A6-48DD-46AB-8A78-C1F115AE6E13, 058517A6-48DD-46AB-8A78-C1F115AE6E13, ("Data")
disk3s1s1: C26440B0-0207-4227-A4B1-EBDD62C90D24, 058517A6-48DD-46AB-8A78-C1F115AE6E13, (null)
我發布了一個工作代碼示例,用於確定所有已安裝的卷及其組關系。 完整的可編譯代碼(您可以在新的 Obj-C App 項目的AppDelegate.m
文件中替換它,可以在這里找到: https : //gist.github.com/tempelmann/80efc2eb84f0171a96822290dee7d8d9
以下 shell 命令列出卷組:
diskutil apfs listVolumeGroups
對於通過代碼進行解析,可以附加選項作為 plist 輸出,然后可以使用CFPropertyListCreateWithData
以format:kCFPropertyListXMLFormat_v1_0
:
diskutil apfs listVolumeGroups -plist
(答案在Howard Oakley的推文中提供)
使用diskutil list
檢查卷及其名稱。 system_profiler
顯示很多信息,但您必須解析 Volume 信息的輸出,使用system_profiler -xml > output.xml
將創建一個文件以了解特定查詢的可用值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.