Use volume UUIDs on macOS

This commit is contained in:
Nasado 2025-02-03 17:41:54 -06:00 • committed by Andrea Mazzoleni
parent 35ab0ba542
commit 3c87474aa2
6 changed files with 66 additions and 5 deletions

View file

@ -3,6 +3,12 @@ check_PROGRAMS = mktest mkstream
AM_CPPFLAGS = -DSYSCONFDIR="\"${sysconfdir}\""
if HAVE_DISK_ARBITRATION
snapraid_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
mktest_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
mkstream_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
endif
snapraid_SOURCES = \
raid/raid.c \
raid/check.c \

View file

@ -1693,8 +1693,10 @@ int windows_readlink(const char* file, char* buffer, size_t size)
return len;
}
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
{
(void)path;
/* just use the volume serial number returned in the device parameter */
snprintf(uuid, uuid_size, "%08x", (unsigned)device);

View file

@ -238,6 +238,11 @@
#include <execinfo.h>
#endif
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <DiskArbitration/DiskArbitration.h>
#endif
/**
* Enable thread use.
*/
@ -338,7 +343,7 @@ static inline int hardlink(const char* a, const char* b)
* Get the device UUID.
* Return 0 on success.
*/
int devuuid(uint64_t device, char* uuid, size_t size);
int devuuid(uint64_t device, const char* path, char* uuid, size_t size);
/**
* Physical offset not yet read.

View file

@ -948,7 +948,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
dev = st.st_dev;
/* read the uuid, if unsupported use an empty one */
if (devuuid(dev, uuid, sizeof(uuid)) != 0) {
if (devuuid(dev, dir, uuid, sizeof(uuid)) != 0) {
*uuid = 0;
}
@ -1450,7 +1450,8 @@ static void state_map(struct snapraid_state* state)
char uuid[UUID_MAX];
int ret;
ret = devuuid(state->parity[l].split_map[s].device, uuid, sizeof(uuid));
ret = devuuid(state->parity[l].split_map[s].device, state->parity[l].split_map[s].path, uuid, sizeof(uuid));
if (ret != 0) {
/* uuid not available, just ignore */
continue;

View file

@ -512,8 +512,54 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
}
#endif
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
#ifdef __APPLE__
static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
{
CFStringRef path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
CFURLRef path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
DADiskRef disk;
do {
disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
if (disk) {
CFRelease(path_appler);
break;
} else {
CFURLRef parent_path_appler = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
CFRelease(path_appler);
path_appler = parent_path_appler;
}
} while (true); // This is guaranteed to succeed eventually because it'll hit `/`.
CFDictionaryRef description = DADiskCopyDescription(disk);
CFUUIDRef uuid_apple = CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, uuid_apple);
bool success = CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8);
CFRelease(uuid_string);
CFRelease(description);
CFRelease(disk);
CFRelease(session);
CFRelease(path_apple);
if (success) {
return 0;
} else {
return 1;
}
}
#endif
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
{
(void)path;
(void)device;
#ifdef __APPLE__
if (devuuid_darwin(path, uuid, uuid_size) == 0)
return 0;
#endif
#if HAVE_LINUX_DEVICE
/* if the major is the null device */
if (major(device) == 0) {

View file

@ -241,6 +241,7 @@ AS_CASE([$host],
[POSIX=1]
)
AM_CONDITIONAL(HAVE_POSIX, [test x"$POSIX" != x])
AM_CONDITIONAL(HAVE_DISK_ARBITRATION, [test "$(uname)" == Darwin])
AC_ARG_ENABLE([profiler],
[AS_HELP_STRING([--enable-profiler],[enable the use of gprof for code coverage])],