qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Programmingkid <programmingkidx@gmail.com>
To: qemu-devel qemu-devel <qemu-devel@nongnu.org>,
	Qemu-block <qemu-block@nongnu.org>
Cc: Laurent Vivier <lvivier@redhat.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	Stefan Hajnoczi <stefanha@gmail.com>
Subject: [Qemu-devel] [PATCH v2] raw-posix.c: Make physical devices usable in QEMU under Mac OS X host
Date: Thu, 16 Jul 2015 16:46:07 -0400	[thread overview]
Message-ID: <99ECAD58-C9CC-4780-B63C-AF975AECCED6@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 6979 bytes --]

Mac OS X can be picky when it comes to allowing the user to use physical devices
in QEMU. This patch fixes that issue by testing each physical device first
before using it in QEMU. If an issue is detected, a message is displayed
showing the user how to unmount a volume. 

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>

---
Removed volume unmounting code.
Removed automatic remounting code.
Displays helpful error message in place of remounting code.

 block/raw-posix.c |  115 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 88 insertions(+), 27 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index cbe6574..9de37ea 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -42,9 +42,8 @@
 #include <IOKit/storage/IOMediaBSDClient.h>
 #include <IOKit/storage/IOMedia.h>
 #include <IOKit/storage/IOCDMedia.h>
-//#include <IOKit/storage/IOCDTypes.h>
 #include <CoreFoundation/CoreFoundation.h>
-#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,67 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma
     return kernResult;
 }
 
-#endif
+/* Sets up a physical device for use in QEMU */
+static void setupDevice(const char *bsdPath)
+{
+   /*
+    * Mac OS X does not like allowing QEMU to use physical devices that are
+    * mounted. Attempts to do so result in 'Resource busy' errors.
+    */
+
+    int fd;
+    fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
+
+    /* if the device fails to open */
+    if (fd < 0) {
+        printf("Error: failed to open %s\n", bsdPath);
+        printf("If device %s is mounted on the desktop, unmount it"
+               " first before using it in QEMU.\n", bsdPath);
+        printf("\nCommand to unmount device: diskutil unmountDisk %s", bsdPath);
+        printf("\nCommand to mount device: diskutil mountDisk %s\n\n", bsdPath);
+    }
+
+    /* if the device opens */
+    else {
+        qemu_close(fd);
+    }
+}
+
+/* Sets up a real cdrom for use in QEMU */
+static void 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++) {
+        strncpy(testPartition, bsdPath, MAXPATHLEN);
+        snprintf(testPartition, MAXPATHLEN, "%ss%d", testPartition, 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");
+        printf("If your disc is mounted on the desktop, trying unmounting it"
+               " first before using it in QEMU.\n");
+        printf("\nCommand to unmount disc: "
+                "diskutil unmountDisk %s\n", bsdPath);
+        printf("Command to mount disc: "
+               "diskutil mountDisk %s\n\n", bsdPath);
+    }
+
+    DPRINTF("Using %s as CDROM\n", testPartition);
+    strncpy(bsdPath, testPartition, MAXPATHLEN);
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
 
 static int hdev_probe_device(const char *filename)
 {
@@ -2119,30 +2182,28 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
 #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';
-            } else {
-                qemu_close(fd);
+    /* If using a physical device */
+    if (strstart(filename, "/dev/", NULL)) {
+
+        /* If the physical device is a cdrom */
+        if (strcmp(filename, "/dev/cdrom") == 0) {
+            char bsdPath[MAXPATHLEN];
+            io_iterator_t mediaIterator;
+            FindEjectableCDMedia(&mediaIterator);
+            GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), flags);
+            if (mediaIterator) {
+                IOObjectRelease(mediaIterator);
             }
+            setupCDROM(bsdPath);
             filename = bsdPath;
-            qdict_put(options, "filename", qstring_from_str(filename));
         }
 
-        if ( mediaIterator )
-            IOObjectRelease( mediaIterator );
+        /* Setup any other physical device e.g. USB flash drive */
+        else {
+            setupDevice(filename);
+        }
+
+        qdict_put(options, "filename", qstring_from_str(filename));
     }
 #endif
 
-- 
1.7.5.4


[-- Attachment #2: Type: text/html, Size: 35141 bytes --]

             reply	other threads:[~2015-07-16 20:46 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-16 20:46 Programmingkid [this message]
2015-07-17 13:41 ` [Qemu-devel] [PATCH v2] raw-posix.c: Make physical devices usable in QEMU under Mac OS X host Stefan Hajnoczi
2015-07-17 19:24   ` Programmingkid
2015-07-19 20:38     ` Peter Maydell
2015-07-20 10:48     ` Stefan Hajnoczi
2015-07-20 12:46       ` Laurent Vivier
2015-07-20 16:17         ` Programmingkid
2015-07-24 14:22           ` Stefan Hajnoczi
2015-07-24 14:30             ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=99ECAD58-C9CC-4780-B63C-AF975AECCED6@gmail.com \
    --to=programmingkidx@gmail.com \
    --cc=lvivier@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).