From patchwork Wed Nov 25 05:43:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Programmingkid X-Patchwork-Id: 548396 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BA41B1401F6 for ; Wed, 25 Nov 2015 16:43:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=xRdFVmdm; dkim-atps=neutral Received: from localhost ([::1]:43091 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1SrZ-0002Nj-P0 for incoming@patchwork.ozlabs.org; Wed, 25 Nov 2015 00:43:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33610) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1SrJ-000231-Ov for qemu-devel@nongnu.org; Wed, 25 Nov 2015 00:43:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a1SrI-0008CC-7w for qemu-devel@nongnu.org; Wed, 25 Nov 2015 00:43:13 -0500 Received: from mail-qg0-x22a.google.com ([2607:f8b0:400d:c04::22a]:34973) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a1SrC-0008Ba-SG; Wed, 25 Nov 2015 00:43:06 -0500 Received: by qgec40 with SMTP id c40so25884625qge.2; Tue, 24 Nov 2015 21:43:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:content-transfer-encoding:subject:date:message-id :cc:to:mime-version; bh=SqQMt5LyebfO5UAf4G9DAbSdSI4zOwX0GOUNcQpqjfA=; b=xRdFVmdmvHTgjH+wUDmZqE2en8T3SkF3/cx7OuoIEIjXWBPLrw5b2PxB/SzUmVk3/o rcNbpsTC2KUsM2GcuPPo+0wVoiscQk2xtUrNF+BITOSdItPhsbyBVGHG0ve6BodlTewt N14CqAS9dVGwvlwWBDBDQJR2v/92x9cDi3h2Q5kIkRNNO5r8DnKht6cQjnkh/SPN4562 vOcuYMxRMZE+a2dSSBUl/W8qSWggOM5WINaHFXiYJljRXcCoJxL7y/cK/u/xNbwan1TW FjUJbq8tOOa0xe0ENjxNscKK4juBRGOgGV2PJD2PnBK3poiMX8KulJZe2hQuO0KVY/3a xfUg== X-Received: by 10.140.151.145 with SMTP id 139mr34804060qhx.95.1448430186496; Tue, 24 Nov 2015 21:43:06 -0800 (PST) Received: from [192.168.0.3] (d199-74-164-53.col.wideopenwest.com. [74.199.53.164]) by smtp.gmail.com with ESMTPSA id b35sm5132862qkb.16.2015.11.24.21.43.05 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Nov 2015 21:43:05 -0800 (PST) From: Programmingkid Date: Wed, 25 Nov 2015 00:43:04 -0500 Message-Id: To: Kevin Wolf Mime-Version: 1.0 (Apple Message framework v1084) X-Mailer: Apple Mail (2.1084) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c04::22a Cc: qemu-devel qemu-devel , Qemu-block Subject: [Qemu-devel] [PATCH] block/raw-posix.c: Make physical devices usable in QEMU under Mac OS X host X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Mac OS X can be picky when it comes to allowing the user to use physical devices in QEMU. Most mounted volumes appear to be off limits to QEMU. If an issue is detected, a message is displayed showing the user how to unmount a volume. Signed-off-by: John Arbuckle --- Changed cdromOK variable to cdrom_ok. Set initial value of cdrom_ok to false. Moved declaration of cdrom_ok variable to Mac OS X code block. Replaced printf() calls with error_report(). Changed if (ret < 0) to if (ret != 0). block/raw-posix.c | 102 ++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 73 insertions(+), 29 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index aec9ec6..3625f35 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -42,9 +42,8 @@ #include #include #include -//#include #include -#endif +#endif /* (__APPLE__) && (__MACH__) */ #ifdef __sun__ #define _POSIX_PTHREAD_SEMANTICS 1 @@ -1975,9 +1974,9 @@ BlockDriver bdrv_file = { /* host device */ #if defined(__APPLE__) && defined(__MACH__) -static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ); -static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ); - +static kern_return_t FindEjectableCDMedia(io_iterator_t *mediaIterator); +static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, + CFIndex maxPathSize, int flags); kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) { kern_return_t kernResult; @@ -2004,7 +2003,8 @@ kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) return kernResult; } -kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ) +kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, + CFIndex maxPathSize, int flags) { io_object_t nextMedia; kern_return_t kernResult = KERN_FAILURE; @@ -2017,7 +2017,9 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma if ( bsdPathAsCFString ) { size_t devPathLength; strcpy( bsdPath, _PATH_DEV ); - strcat( bsdPath, "r" ); + if (flags & BDRV_O_NOCACHE) { + strcat(bsdPath, "r"); + } devPathLength = strlen( bsdPath ); if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { kernResult = KERN_SUCCESS; @@ -2030,7 +2032,34 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma return kernResult; } -#endif +/* Sets up a real cdrom for use in QEMU */ +static bool setupCDROM(char *bsdPath) +{ + int index, numOfTestPartitions = 2, fd; + char testPartition[MAXPATHLEN]; + bool partitionFound = false; + + /* look for a working partition */ + for (index = 0; index < numOfTestPartitions; index++) { + snprintf(testPartition, sizeof(testPartition), "%ss%d", bsdPath, index); + fd = qemu_open(testPartition, O_RDONLY | O_BINARY | O_LARGEFILE); + if (fd >= 0) { + partitionFound = true; + qemu_close(fd); + break; + } + } + + /* if a working partition on the device was not found */ + if (partitionFound == false) { + error_report("Error: Failed to find a working partition on disc!\n"); + } else { + DPRINTF("Using %s as optical disc\n", testPartition); + pstrcpy(bsdPath, MAXPATHLEN, testPartition); + } + return partitionFound; +} +#endif /* defined(__APPLE__) && defined(__MACH__) */ static int hdev_probe_device(const char *filename) { @@ -2120,32 +2149,31 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, int ret; #if defined(__APPLE__) && defined(__MACH__) + bool cdrom_ok = false; const char *filename = qdict_get_str(options, "filename"); - if (strstart(filename, "/dev/cdrom", NULL)) { - kern_return_t kernResult; - io_iterator_t mediaIterator; - char bsdPath[ MAXPATHLEN ]; - int fd; - - kernResult = FindEjectableCDMedia( &mediaIterator ); - kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) ); - - if ( bsdPath[ 0 ] != '\0' ) { - strcat(bsdPath,"s0"); - /* some CDs don't have a partition 0 */ - fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); - if (fd < 0) { - bsdPath[strlen(bsdPath)-1] = '1'; + /* If using a physical device */ + if (strstart(filename, "/dev/", NULL)) { + char bsdPath[MAXPATHLEN]; + + /* If the physical device is a cdrom */ + if (strcmp(filename, "/dev/cdrom") == 0) { + io_iterator_t mediaIterator; + FindEjectableCDMedia(&mediaIterator); + GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), flags); + if (bsdPath[0] == '\0') { + error_report("Error: failed to obtain bsd path for optical" + " drive!\n"); } else { - qemu_close(fd); + cdrom_ok = setupCDROM(bsdPath); + filename = bsdPath; + } + + if (mediaIterator) { + IOObjectRelease(mediaIterator); } - filename = bsdPath; qdict_put(options, "filename", qstring_from_str(filename)); } - - if ( mediaIterator ) - IOObjectRelease( mediaIterator ); } #endif @@ -2156,7 +2184,23 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, if (local_err) { error_propagate(errp, local_err); } - return ret; + } + +#if defined(__APPLE__) && defined(__MACH__) + /* if a physical device experienced an error while being opened */ + if (strncmp(filename, "/dev/", 5) == 0 && (cdrom_ok == false || ret != 0)) { + error_report("Error: If device %s is mounted on the desktop, unmount" + " it first before using it in QEMU.\n", filename); + error_report("Command to unmount device: diskutil unmountDisk %s\n", + filename); + error_report("Command to mount device: diskutil mountDisk %s\n", + filename); + } +#endif /* defined(__APPLE__) && defined(__MACH__) */ + + /* End execution of this function if an error took place */ + if (ret != 0) { + return ret; } /* Since this does ioctl the device must be already opened */