Skip to content

Commit

Permalink
Use volume UUIDs on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
na-sa-do committed Feb 6, 2025
1 parent e4e733c commit 150da4b
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 3 deletions.
10 changes: 8 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ check_PROGRAMS = mktest mkstream

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

if HAVE_DISK_ARBITRATION
snapraid_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
endif

snapraid_SOURCES = \
raid/raid.c \
raid/check.c \
Expand Down Expand Up @@ -44,7 +48,8 @@ snapraid_SOURCES = \
cmdline/import.c \
cmdline/search.c \
cmdline/mingw.c \
cmdline/unix.c
cmdline/unix.c \
cmdline/mac.c

noinst_HEADERS = \
raid/raid.h \
Expand Down Expand Up @@ -88,7 +93,8 @@ noinst_HEADERS = \
cmdline/import.h \
cmdline/search.h \
cmdline/mingw.h \
cmdline/unix.h
cmdline/unix.h \
cmdline/mac.h

mktest_SOURCES = \
cmdline/mktest.c \
Expand Down
58 changes: 58 additions & 0 deletions cmdline/mac.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2011 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifdef __APPLE__

#include "mac.h"
#include <CoreFoundation/CoreFoundation.h>
#include <DiskArbitration/DiskArbitration.h>

int devuuid_macos(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
28 changes: 28 additions & 0 deletions cmdline/mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2011 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __MAC_H
#define __MAC_H
#ifdef __APPLE__

#include <stdint.h>
#include <stdlib.h>

int devuuid_macos(char *path, char* uuid, size_t uuid_size);

#endif
#endif
2 changes: 2 additions & 0 deletions cmdline/portable.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,13 @@ static inline int hardlink(const char* a, const char* b)
return link(a, b);
}

#ifndef __APPLE__ // Use devuuid_macos instead (different API).
/**
* Get the device UUID.
* Return 0 on success.
*/
int devuuid(uint64_t device, char* uuid, size_t size);
#endif

/**
* Physical offset not yet read.
Expand Down
13 changes: 12 additions & 1 deletion cmdline/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "io.h"
#include "raid/raid.h"
#include "raid/cpu.h"
#include "mac.h"

/**
* Configure the multithread support.
Expand Down Expand Up @@ -948,7 +949,13 @@ 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 (
#ifdef __APPLE__
devuuid_macos(dir, uuid, sizeof(uuid))
#else
devuuid(dev, uuid, sizeof(uuid))
#endif
!= 0) {
*uuid = 0;
}

Expand Down Expand Up @@ -1450,7 +1457,11 @@ static void state_map(struct snapraid_state* state)
char uuid[UUID_MAX];
int ret;

#ifdef __APPLE__
ret = devuuid_macos(state->parity[l].split_map[s].path, uuid, sizeof(uuid));
#else
ret = devuuid(state->parity[l].split_map[s].device, uuid, sizeof(uuid));
#endif
if (ret != 0) {
/* uuid not available, just ignore */
continue;
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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])],
Expand Down

0 comments on commit 150da4b

Please sign in to comment.