From 55a31469eb168539ae1a8ce546060a445cdd8bdf Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Wed, 26 Oct 2016 23:16:34 +0000
Subject: [PATCH] libutil-47.30.1.tar.gz

---
 libutil.xcodeproj/project.pbxproj |   8 --
 wipefs.cpp                        | 224 +++++-------------------------
 2 files changed, 36 insertions(+), 196 deletions(-)

diff --git a/libutil.xcodeproj/project.pbxproj b/libutil.xcodeproj/project.pbxproj
index c89e33f..269a18b 100644
--- a/libutil.xcodeproj/project.pbxproj
+++ b/libutil.xcodeproj/project.pbxproj
@@ -46,8 +46,6 @@
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
-		7259A9731D519322008F83F6 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7259A9721D519322008F83F6 /* IOKit.framework */; };
-		7259A9751D51932B008F83F6 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7259A9741D51932B008F83F6 /* CoreFoundation.framework */; };
 		BA79F9CB13BB7207006A292D /* ExtentManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A313BB70FF006A292D /* ExtentManager.cpp */; };
 		BA79F9CC13BB7207006A292D /* getmntopts.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A613BB70FF006A292D /* getmntopts.c */; };
 		BA79F9CD13BB7207006A292D /* humanize_number.c in Sources */ = {isa = PBXBuildFile; fileRef = BA79F9A813BB70FF006A292D /* humanize_number.c */; };
@@ -175,8 +173,6 @@
 
 /* Begin PBXFileReference section */
 		3F09C378186D1F73007AF93C /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = base.xcconfig; path = xcconfigs/base.xcconfig; sourceTree = "<group>"; };
-		7259A9721D519322008F83F6 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
-		7259A9741D51932B008F83F6 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
 		BA79F9A313BB70FF006A292D /* ExtentManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ExtentManager.cpp; sourceTree = "<group>"; };
 		BA79F9A413BB70FF006A292D /* ExtentManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtentManager.h; sourceTree = "<group>"; };
 		BA79F9A513BB70FF006A292D /* getmntopts.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getmntopts.3; sourceTree = "<group>"; };
@@ -219,8 +215,6 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				7259A9751D51932B008F83F6 /* CoreFoundation.framework in Frameworks */,
-				7259A9731D519322008F83F6 /* IOKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -245,8 +239,6 @@
 		7259A9711D519321008F83F6 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				7259A9741D51932B008F83F6 /* CoreFoundation.framework */,
-				7259A9721D519322008F83F6 /* IOKit.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
diff --git a/wipefs.cpp b/wipefs.cpp
index b96e7b8..fb48474 100644
--- a/wipefs.cpp
+++ b/wipefs.cpp
@@ -31,14 +31,8 @@
 #include <sys/disk.h>
 #include <sys/stat.h>
 #include <sys/syslimits.h>
-#include <uuid/uuid.h>
-#include <paths.h>
 #include <string.h>
 #include <spawn.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
-#include <CoreFoundation/CFNumber.h>
 #include <os/log.h>
 
 #include "ExtentManager.h"
@@ -51,9 +45,7 @@ struct __wipefs_ctx {
 	class ExtentManager extMan;
     
 	// xartutil information
-	bool have_xartutil_info;
-	uuid_string_t uuid_str;
-	bool is_internal;
+	char *diskname;
 };
 
 static void
@@ -150,170 +142,42 @@ AddExtentsForCoreStorage(class ExtentManager *extMan)
 	extMan->AddByteRangeExtent(extMan->totalBytes - 512, 512);
 }
 
-static bool
-is_disk_device(const char *pathname) {
-	bool is_disk_dev = false;
-
-	if (strncmp(pathname, "/dev/disk", strlen("/dev/disk")) == 0) {
-		is_disk_dev = true;
-	} else if (strncmp(pathname, "/dev/rdisk", strlen("/dev/rdisk")) == 0) {
-		is_disk_dev = true;
-	}
-
-	return (is_disk_dev);
-}
-
-static int
-query_disk_info(int fd, char *uuid_str, int uuid_len, bool *is_internal) {
-	io_service_t obj;
-	io_iterator_t iter;
-	kern_return_t error;
-	CFBooleanRef removableRef;
-	CFStringRef uuidRef;
-	CFStringRef locationRef;
-	CFDictionaryRef protocolCharacteristics;
-	bool deviceInternal, mediaRemovable;
-	int result;
+static char *
+query_disk_info(int fd) {
 	char disk_path[PATH_MAX];
 	char *disk_name;
 
-	result = EINVAL;
-	deviceInternal = false;
-	mediaRemovable = false;
-	removableRef = NULL;
-	protocolCharacteristics = NULL;
-	uuidRef = NULL;
-	obj = IO_OBJECT_NULL;
-	iter = IO_OBJECT_NULL;
-
 	// Fetch the path
 	if (fcntl(fd, F_GETPATH, disk_path) == -1) {
-		goto out;
+		return (NULL);
 	}
 
-	// Make sure path begins with /dev/disk or /dev/rdisk
-	if (is_disk_device(disk_path) == false) {
-		goto out;
-	}
-
-	// Derive device name
-	disk_name = disk_path;
-	if(strncmp(disk_path, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
-		// Skip over leading "/dev/"
-		disk_name += strlen(_PATH_DEV);
-	}
-	if (strncmp(disk_name, "r", strlen("r")) == 0) {
-		// Raw device, skip over leading "r"
-		disk_name += strlen("r");
-	}
-    
-	// Get an iterator object
-	error = IOServiceGetMatchingServices(kIOMasterPortDefault,
-										 IOBSDNameMatching(kIOMasterPortDefault, 0, disk_name), &iter);
-	if (error) {
-		os_log_error(OS_LOG_DEFAULT, "Warning, unable to obtain UUID info (iterator), device %s", disk_name);
-		goto out;
-	}
-    
-	// Get the matching device object
-	obj = IOIteratorNext(iter);
-	if (!obj) {
-		os_log_error(OS_LOG_DEFAULT, "Warning, unable to obtain UUID info (dev obj), device %s", disk_name);
-		goto out;
-	}
-	
-	// Get a protocol characteristics dictionary
-	protocolCharacteristics = (CFDictionaryRef) IORegistryEntrySearchCFProperty(obj,
-																				kIOServicePlane,
-																				CFSTR(kIOPropertyProtocolCharacteristicsKey),
-																				kCFAllocatorDefault,
-																				kIORegistryIterateRecursively|kIORegistryIterateParents);
-
-	if ((protocolCharacteristics == NULL) || (CFDictionaryGetTypeID() != CFGetTypeID(protocolCharacteristics)))
-	{
-		os_log_error(OS_LOG_DEFAULT, "Warning, failed to obtain UUID info (protocol characteristics), device %s\n", disk_name);
-		goto out;
-	}
-	
-	// Check for kIOPropertyInternalKey
-	locationRef = (CFStringRef) CFDictionaryGetValue(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectLocationKey));
-	
-	if ((locationRef == NULL) || (CFStringGetTypeID() != CFGetTypeID(locationRef))) {
-		os_log_error(OS_LOG_DEFAULT, "Warning, failed to obtain UUID info (location), device %s\n", disk_name);
-		goto out;
-	}
-	
-	if (CFEqual(locationRef, CFSTR(kIOPropertyInternalKey))) {
-		deviceInternal = true;
-	}
-
-	// Check for kIOMediaRemovableKey
-	removableRef = (CFBooleanRef)IORegistryEntrySearchCFProperty(obj,
-																 kIOServicePlane,
-																 CFSTR(kIOMediaRemovableKey),
-																 kCFAllocatorDefault,
-																 0);
-	
-	if ((removableRef == NULL) || (CFBooleanGetTypeID() != CFGetTypeID(removableRef))) {
-		os_log_error(OS_LOG_DEFAULT, "Warning, unable to obtain UUID info (MediaRemovable key), device %s", disk_name);
-		goto out;
-	}
-    
-	if (CFBooleanGetValue(removableRef)) {
-		mediaRemovable = true;
-	}
-	
-	// is_internal ==> DeviceInternal && !MediaRemovable
-	if ((deviceInternal == true) && (mediaRemovable == false)) {
-		*is_internal = true;
+	// Find the last pathname component.
+	disk_name = strrchr(disk_path, '/');
+	if (disk_name == NULL) {
+		// Not that we expect this to happen...
+		disk_name = disk_path;
 	} else {
-		*is_internal = false;
-	}
-
-	// Get the UUID
-	uuidRef = (CFStringRef)IORegistryEntrySearchCFProperty(obj,
-														   kIOServicePlane,
-														   CFSTR(kIOMediaUUIDKey),
-														   kCFAllocatorDefault,
-														   0);
-	if ((uuidRef == NULL) || (CFStringGetTypeID() != CFGetTypeID(uuidRef)))
-	{
-		os_log_error(OS_LOG_DEFAULT, "Warning, unable to obtain UUID info (MediaUUID key), device %s", disk_name);
-		goto out;
+		// Skip over the '/'.
+		disk_name++;
 	}
 
-	if (!CFStringGetCString(uuidRef, uuid_str, uuid_len, kCFStringEncodingASCII)) {
-		os_log_error(OS_LOG_DEFAULT, "Warning, unable to obtain UUID info (convert UUID), device %s", disk_name);
-		goto out;
+	if (*disk_name == 'r') {
+		// Raw device; skip over leading 'r'.
+		disk_name++;
 	}
 
-	// Success
-	result = 0;
-
-out:
-	if (obj != IO_OBJECT_NULL) {
-		IOObjectRelease(obj);
-	}
-	if (iter != IO_OBJECT_NULL) {
-		IOObjectRelease(iter);
-	}
-	if (removableRef != NULL) {
-		CFRelease(removableRef);
-	}
-	if (protocolCharacteristics != NULL) {
-		CFRelease(protocolCharacteristics);
-	}
-	if (uuidRef != NULL) {
-		CFRelease(uuidRef);
+	// ...and make sure it's really a disk.
+	if (strncmp(disk_name, "disk", strlen("disk")) != 0) {
+		return (NULL);
 	}
 
-	return (result);
+	return (strdup(disk_name));
 }
 
 static
-int run_xartutil(uuid_string_t uuid_str, bool is_internal)
+int run_xartutil(char *const diskname)
 {
-	char external[2];
 	pid_t child_pid, wait_pid;
 	posix_spawn_file_actions_t fileActions;
 	bool haveFileActions = false;
@@ -321,13 +185,9 @@ int run_xartutil(uuid_string_t uuid_str, bool is_internal)
 	int result = 0;
 
 	char arg1[] = "xartutil";
-	char arg2[] = "--erase";
-	char arg4[] = "--is-external";
-
-	external[0] = (is_internal == false) ? '1' : '0';
-	external[1] = 0;
+	char arg2[] = "--erase-disk";
 
-	char *xartutil_argv[] = {arg1, arg2, uuid_str, arg4, external, NULL};
+	char *const xartutil_argv[] = {arg1, arg2, diskname, NULL};
 
 	result = posix_spawn_file_actions_init(&fileActions);
 	if (result) {
@@ -397,13 +257,9 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
 	off_t totalSizeInBytes = 0;
 	class ExtentManager *extMan = NULL;
 	struct stat sbuf = { 0 };
-	bool have_xartutil_info = false;
-	uuid_string_t  uuid_str;
-	bool is_internal;
-	int uuid_err = 0;
+	char *diskname = NULL;
 
 	*handle = NULL;
-	uuid_str[0] = 0;
 	(void)fstat(fd, &sbuf);
 	switch (sbuf.st_mode & S_IFMT) {
 	case S_IFCHR:
@@ -418,10 +274,7 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
 		}
 		totalSizeInBytes = numBlocks * nativeBlockSize;
 
-		uuid_err = query_disk_info(fd, uuid_str, sizeof(uuid_str), &is_internal);
-		if (uuid_err == 0) {
-			have_xartutil_info = true;
-		}
+		diskname = query_disk_info(fd);
 		break;
 	case S_IFREG:
 		nativeBlockSize = sbuf.st_blksize;
@@ -448,6 +301,7 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
 		}
 
 		(*handle)->fd = fd;
+		(*handle)->diskname = NULL;
 		extMan = &(*handle)->extMan;
 
 		extMan->Init(block_size, nativeBlockSize, totalSizeInBytes);
@@ -460,14 +314,8 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
 		AddExtentsForZFS(extMan);
 		AddExtentsForPartitions(extMan);
 		AddExtentsForCoreStorage(extMan);
-        
-		(*handle)->have_xartutil_info = false;
 
-		if (have_xartutil_info == true) {
-			(*handle)->have_xartutil_info = true;
-			(*handle)->is_internal = is_internal;
-			memcpy((*handle)->uuid_str, uuid_str, sizeof(uuid_str));
-		}
+		(*handle)->diskname = diskname;
 	}
 	catch (bad_alloc &e) {
 		err = ENOMEM;
@@ -478,6 +326,8 @@ wipefs_alloc(int fd, size_t block_size, wipefs_ctx *handle)
 
   labelExit:
 	if (err != 0) {
+		if (diskname != NULL)
+			free(diskname);
 		wipefs_free(handle);
 	}
 	return err;
@@ -524,7 +374,11 @@ wipefs_wipe(wipefs_ctx handle)
 	size_t bufSize;
 	dk_extent_t extent;
 	dk_unmap_t unmap;
-	bool did_write = false;
+
+	if (handle->diskname != NULL) {
+		// Remove this disk's entry from the xART.
+		run_xartutil(handle->diskname);
+	}
 
 	memset(&extent, 0, sizeof(dk_extent_t));
 	extent.length = handle->extMan.totalBytes;
@@ -538,7 +392,6 @@ wipefs_wipe(wipefs_ctx handle)
 	// informational for the lower-level drivers.
 	//
 	ioctl(handle->fd, DKIOCUNMAP, (caddr_t)&unmap);
-	
 
 	bufSize = 128 * 1024; // issue large I/O to get better performance
 	if (handle->extMan.nativeBlockSize > bufSize) {
@@ -577,10 +430,6 @@ wipefs_wipe(wipefs_ctx handle)
 			}
 			numBytes -= numBytesToWrite;
 			byteOffset += numBytesToWrite;
-
-			if (did_write == false) {
-				did_write = true;
-			}
 		}
 	}
 
@@ -590,11 +439,6 @@ wipefs_wipe(wipefs_ctx handle)
 	if (bufZero != NULL)
 		delete[] bufZero;
 
-	if ((did_write == true) && (handle->have_xartutil_info == true)) {
-		// We wrote some zero bytes and have UUID info, notify xART now.
-		run_xartutil(handle->uuid_str, handle->is_internal);
-	}
-
 	return err;
 } // wipefs_wipe
 
@@ -602,6 +446,10 @@ extern "C" void
 wipefs_free(wipefs_ctx *handle)
 {
 	if (*handle != NULL) {
+		char *diskname;
+
+		if ((diskname = (*handle)->diskname) != NULL)
+			free(diskname);
 		delete *handle;
 		*handle = NULL;
 	}
-- 
2.47.2