1#include <fcntl.h> 2#include <util.h> 3#include <unistd.h> 4#include <string.h> 5#include <sys/mount.h> 6#include <uuid/uuid.h> 7#include <IOKit/IOBSD.h> 8#include <IOKit/IOKitLib.h> 9#include <IOKit/storage/IOMedia.h> 10 11extern char debug; 12extern void plog(const char *, ...); 13 14/* 15 * Given a uuid string, look up the BSD device and open it. 16 * This code comes from DanM. 17 * 18 * Essentially, it is given a UUID string (from the journal header), 19 * and then looks it up via IOKit. From there, it then gets the 20 * BSD name (e.g., /dev/dsik3), and opens it read-only. 21 * 22 * It returns the file descriptor, or -1 on error. 23 */ 24int 25OpenDeviceByUUID(void *uuidp, char **namep) 26{ 27 char devname[ MAXPATHLEN ]; 28 CFStringRef devname_string; 29 int fd = -1; 30 CFMutableDictionaryRef matching; 31 io_service_t media; 32 uuid_string_t uuid_cstring; 33 CFStringRef uuid_string; 34 35 memcpy(&uuid_cstring, uuidp, sizeof(uuid_cstring)); 36 37 uuid_string = CFStringCreateWithCString( kCFAllocatorDefault, uuid_cstring, kCFStringEncodingUTF8 ); 38 if ( uuid_string ) { 39 matching = IOServiceMatching( kIOMediaClass ); 40 if ( matching ) { 41 CFDictionarySetValue( matching, CFSTR( kIOMediaUUIDKey ), uuid_string ); 42 media = IOServiceGetMatchingService( kIOMasterPortDefault, matching ); 43 if ( media ) { 44 devname_string = IORegistryEntryCreateCFProperty( media, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); 45 if ( devname_string ) { 46 if ( CFStringGetCString( devname_string, devname, sizeof( devname ), kCFStringEncodingUTF8 ) ) { 47 if (debug) 48 plog("external journal device name = `%s'\n", devname); 49 50 fd = opendev( devname, O_RDONLY, 0, NULL ); 51 if (fd != -1 && namep != NULL) { 52 *namep = strdup(devname); 53 } 54 } 55 CFRelease( devname_string ); 56 } 57 IOObjectRelease( media ); 58 } 59 /* do not CFRelease( matching ); */ 60 } 61 CFRelease( uuid_string ); 62 } 63 64 return fd; 65} 66