Skip to content

Commit 3c87474

Browse files
hatzka-nezumiamadvance
authored andcommitted
Use volume UUIDs on macOS
1 parent 35ab0ba commit 3c87474

File tree

6 files changed

+66
-5
lines changed

6 files changed

+66
-5
lines changed

Makefile.am

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ check_PROGRAMS = mktest mkstream
33

44
AM_CPPFLAGS = -DSYSCONFDIR="\"${sysconfdir}\""
55

6+
if HAVE_DISK_ARBITRATION
7+
snapraid_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
8+
mktest_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
9+
mkstream_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
10+
endif
11+
612
snapraid_SOURCES = \
713
raid/raid.c \
814
raid/check.c \

cmdline/mingw.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1693,8 +1693,10 @@ int windows_readlink(const char* file, char* buffer, size_t size)
16931693
return len;
16941694
}
16951695

1696-
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
1696+
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
16971697
{
1698+
(void)path;
1699+
16981700
/* just use the volume serial number returned in the device parameter */
16991701
snprintf(uuid, uuid_size, "%08x", (unsigned)device);
17001702

cmdline/portable.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,11 @@
238238
#include <execinfo.h>
239239
#endif
240240

241+
#ifdef __APPLE__
242+
#include <CoreFoundation/CoreFoundation.h>
243+
#include <DiskArbitration/DiskArbitration.h>
244+
#endif
245+
241246
/**
242247
* Enable thread use.
243248
*/
@@ -338,7 +343,7 @@ static inline int hardlink(const char* a, const char* b)
338343
* Get the device UUID.
339344
* Return 0 on success.
340345
*/
341-
int devuuid(uint64_t device, char* uuid, size_t size);
346+
int devuuid(uint64_t device, const char* path, char* uuid, size_t size);
342347

343348
/**
344349
* Physical offset not yet read.

cmdline/state.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
948948
dev = st.st_dev;
949949

950950
/* read the uuid, if unsupported use an empty one */
951-
if (devuuid(dev, uuid, sizeof(uuid)) != 0) {
951+
if (devuuid(dev, dir, uuid, sizeof(uuid)) != 0) {
952952
*uuid = 0;
953953
}
954954

@@ -1450,7 +1450,8 @@ static void state_map(struct snapraid_state* state)
14501450
char uuid[UUID_MAX];
14511451
int ret;
14521452

1453-
ret = devuuid(state->parity[l].split_map[s].device, uuid, sizeof(uuid));
1453+
ret = devuuid(state->parity[l].split_map[s].device, state->parity[l].split_map[s].path, uuid, sizeof(uuid));
1454+
14541455
if (ret != 0) {
14551456
/* uuid not available, just ignore */
14561457
continue;

cmdline/unix.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,54 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
512512
}
513513
#endif
514514

515-
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
515+
#ifdef __APPLE__
516+
static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
516517
{
518+
CFStringRef path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
519+
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
520+
521+
CFURLRef path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
522+
DADiskRef disk;
523+
do {
524+
disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
525+
if (disk) {
526+
CFRelease(path_appler);
527+
break;
528+
} else {
529+
CFURLRef parent_path_appler = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
530+
CFRelease(path_appler);
531+
path_appler = parent_path_appler;
532+
}
533+
} while (true); // This is guaranteed to succeed eventually because it'll hit `/`.
534+
535+
CFDictionaryRef description = DADiskCopyDescription(disk);
536+
CFUUIDRef uuid_apple = CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
537+
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, uuid_apple);
538+
bool success = CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8);
539+
CFRelease(uuid_string);
540+
CFRelease(description);
541+
CFRelease(disk);
542+
CFRelease(session);
543+
CFRelease(path_apple);
544+
545+
if (success) {
546+
return 0;
547+
} else {
548+
return 1;
549+
}
550+
}
551+
#endif
552+
553+
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
554+
{
555+
(void)path;
556+
(void)device;
557+
558+
#ifdef __APPLE__
559+
if (devuuid_darwin(path, uuid, uuid_size) == 0)
560+
return 0;
561+
#endif
562+
517563
#if HAVE_LINUX_DEVICE
518564
/* if the major is the null device */
519565
if (major(device) == 0) {

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ AS_CASE([$host],
241241
[POSIX=1]
242242
)
243243
AM_CONDITIONAL(HAVE_POSIX, [test x"$POSIX" != x])
244+
AM_CONDITIONAL(HAVE_DISK_ARBITRATION, [test "$(uname)" == Darwin])
244245

245246
AC_ARG_ENABLE([profiler],
246247
[AS_HELP_STRING([--enable-profiler],[enable the use of gprof for code coverage])],

0 commit comments

Comments
 (0)