From patchwork Fri Jul 24 17:53:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Programmingkid X-Patchwork-Id: 499825 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 6D5C21402BC for ; Sat, 25 Jul 2015 03:54:33 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=SZQW5y+o; dkim-atps=neutral Received: from localhost ([::1]:46237 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIhAz-0007ZA-BQ for incoming@patchwork.ozlabs.org; Fri, 24 Jul 2015 13:54:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIhAc-000767-1F for qemu-devel@nongnu.org; Fri, 24 Jul 2015 13:54:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZIhAW-0005ue-Pj for qemu-devel@nongnu.org; Fri, 24 Jul 2015 13:54:05 -0400 Received: from mail-qg0-x22a.google.com ([2607:f8b0:400d:c04::22a]:35856) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIhAW-0005t6-Ha; Fri, 24 Jul 2015 13:54:00 -0400 Received: by qgy5 with SMTP id 5so14042848qgy.3; Fri, 24 Jul 2015 10:53:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-type:subject:date:message-id:cc:to:mime-version; bh=2c0BgzlQ2c60S3dHvy9JKbmTPG6ByffHFpfSsJ3Ko3M=; b=SZQW5y+oSzuzmm+/qp0q6P5cy0/O2eDSE3MDeFusF1U5vYCnKQc9cDVKC9m8IBPE6a EcMeG523u3IgqNn+1Kx+ZXrVok2vyXEmiOGMKtTXoPArtIniLn6t1wHcOonhxyBzlHeJ 0kRrNPA/OKcCjS6gY5uHsyFWudZKW8Yt9zFTEJfnFA3WVO9cAhLgSE9ZAJnFF+MT56Qa hbalfn9rvt/ch9c+TmdTDWM6o6+c1N9asvImrT1jSSeLVdGokKLSAFBJOT9ffIk3xIHU AOj/ZM2FkICn74y3Sn+AjO/qT6VK7bxOPvw1gD0/aW6syngur2xuZvsYbeH44ITEMnrI 2csA== X-Received: by 10.140.195.20 with SMTP id q20mr23395540qha.82.1437760439893; Fri, 24 Jul 2015 10:53:59 -0700 (PDT) Received: from [192.168.0.6] (d199-74-164-53.col.wideopenwest.com. [74.199.53.164]) by smtp.gmail.com with ESMTPSA id k85sm4368520qhk.39.2015.07.24.10.53.58 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 24 Jul 2015 10:53:59 -0700 (PDT) From: Programmingkid Date: Fri, 24 Jul 2015 13:53:57 -0400 Message-Id: <31C10702-8353-4DC8-8F06-A18DB3126D87@gmail.com> To: Stefan Hajnoczi , qemu-devel qemu-devel , Qemu-block 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: Kevin Wolf Subject: [Qemu-devel] [PATCH v4] 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 --- Removed a call to snprintf(). Argument changes for pstrcpy(). block/raw-posix.c | 99 ++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 71 insertions(+), 28 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index cbe6574..023b102 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 @@ -1972,8 +1971,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 ) { @@ -2001,7 +2001,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; @@ -2014,7 +2015,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; @@ -2027,7 +2030,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) { + printf("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) { @@ -2115,34 +2145,33 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, BDRVRawState *s = bs->opaque; Error *local_err = NULL; int ret; + bool cdromOK = true; #if defined(__APPLE__) && defined(__MACH__) 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') { + printf("Error: failed to obtain bsd path for optical drive!\n"); } else { - qemu_close(fd); + cdromOK = setupCDROM(bsdPath); + filename = bsdPath; + } + + if (mediaIterator) { + IOObjectRelease(mediaIterator); } - filename = bsdPath; - qdict_put(options, "filename", qstring_from_str(filename)); } - if ( mediaIterator ) - IOObjectRelease( mediaIterator ); + qdict_put(options, "filename", qstring_from_str(filename)); } #endif @@ -2153,7 +2182,21 @@ 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 && (cdromOK == false || ret != 0)) { + printf("If device %s is mounted on the desktop, unmount it" + " first before using it in QEMU.\n", filename); + printf("Command to unmount device: diskutil unmountDisk %s\n", + filename); + printf("Command to mount device: diskutil mountDisk %s\n", filename); + } +#endif /* defined(__APPLE__) && defined(__MACH__) */ + + if (ret < 0) { + return ret; } /* Since this does ioctl the device must be already opened */