Skip to content

Commit 752295a

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

File tree

7 files changed

+83
-6
lines changed

7 files changed

+83
-6
lines changed

Makefile.am

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ check_PROGRAMS = mktest mkstream
33

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

6+
if HAVE_DISK_ARBITRATION
7+
snapraid_LDFLAGS = -framework CoreFoundation -framework DiskArbitration
8+
endif
9+
610
snapraid_SOURCES = \
711
raid/raid.c \
812
raid/check.c \
@@ -44,7 +48,8 @@ snapraid_SOURCES = \
4448
cmdline/import.c \
4549
cmdline/search.c \
4650
cmdline/mingw.c \
47-
cmdline/unix.c
51+
cmdline/unix.c \
52+
cmdline/darwin.c
4853

4954
noinst_HEADERS = \
5055
raid/raid.h \

cmdline/darwin.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (C) 2011 Andrea Mazzoleni
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include "portable.h"
19+
20+
#ifdef __APPLE__
21+
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
22+
{
23+
(void)device;
24+
25+
CFStringRef path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
26+
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
27+
28+
CFURLRef path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
29+
DADiskRef disk;
30+
do {
31+
disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
32+
if (disk) {
33+
CFRelease(path_appler);
34+
break;
35+
} else {
36+
CFURLRef parent_path_appler = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
37+
CFRelease(path_appler);
38+
path_appler = parent_path_appler;
39+
}
40+
} while (true); // This is guaranteed to succeed eventually because it'll hit `/`.
41+
42+
CFDictionaryRef description = DADiskCopyDescription(disk);
43+
CFUUIDRef uuid_apple = CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
44+
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, uuid_apple);
45+
bool success = CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8);
46+
CFRelease(uuid_string);
47+
CFRelease(description);
48+
CFRelease(disk);
49+
CFRelease(session);
50+
CFRelease(path_apple);
51+
52+
if (success) {
53+
return 0;
54+
} else {
55+
return 1;
56+
}
57+
}
58+
59+
#endif

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: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,11 @@ 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+
#ifndef __APPLE__
516+
int devuuid(uint64_t device, const char* path, char* uuid, size_t uuid_size)
516517
{
518+
(void)path;
519+
517520
#if HAVE_LINUX_DEVICE
518521
/* if the major is the null device */
519522
if (major(device) == 0) {
@@ -549,6 +552,7 @@ int devuuid(uint64_t device, char* uuid, size_t uuid_size)
549552
(void)uuid_size;
550553
return -1;
551554
}
555+
#endif
552556

553557
int filephy(const char* path, uint64_t size, uint64_t* physical)
554558
{

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)