From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56839) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aA4ug-00035R-36 for qemu-devel@nongnu.org; Fri, 18 Dec 2015 18:58:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aA4uc-0003K7-OA for qemu-devel@nongnu.org; Fri, 18 Dec 2015 18:58:18 -0500 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Apple Message framework v1084) From: Programmingkid In-Reply-To: <56307511-53E2-4B28-BCF5-423DCDABD0FC@gmail.com> Date: Fri, 18 Dec 2015 18:58:10 -0500 Content-Transfer-Encoding: quoted-printable Message-Id: References: <69D59CD8-84A3-4C9E-93F4-D366C412F4C6@gmail.com> <20151211220053.GA30085@localhost.localdomain> <56307511-53E2-4B28-BCF5-423DCDABD0FC@gmail.com> Subject: [Qemu-devel] ping Re: [PATCH v12] block/raw-posix.c: Make physical devices usable in QEMU under Mac OS X host List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kevin Wolf , qemu-devel qemu-devel , Qemu-block https://patchwork.ozlabs.org/patch/555945/ On Dec 11, 2015, at 10:27 PM, Programmingkid wrote: > 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. Now QEMU uses both CD and DVD media. >=20 > Signed-off-by: John Arbuckle >=20 > --- > Removed mediaType parameter from FindEjectableOpticalMedia(). > Added goto statements to hdev_open. > Replaced snprintf() with g_strdup() in FindEjectableOpticalMedia(). > Put back return statement in hdev_open for Linux compatibility. >=20 > block/raw-posix.c | 163 = ++++++++++++++++++++++++++++++++++++++++------------- > 1 files changed, 124 insertions(+), 39 deletions(-) >=20 > diff --git a/block/raw-posix.c b/block/raw-posix.c > index d9162fd..82e8e62 100644 > --- a/block/raw-posix.c > +++ b/block/raw-posix.c > @@ -43,6 +43,7 @@ > #include > #include > //#include > +#include > #include > #endif >=20 > @@ -1975,33 +1976,46 @@ BlockDriver bdrv_file =3D { > /* host device */ >=20 > #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, int flags); > -kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) > +static char *FindEjectableOpticalMedia(io_iterator_t *mediaIterator) > { > - kern_return_t kernResult; > + kern_return_t kernResult =3D KERN_FAILURE; > mach_port_t masterPort; > CFMutableDictionaryRef classesToMatch; > + const char *matching_array[] =3D {kIODVDMediaClass, = kIOCDMediaClass}; > + char *mediaType =3D NULL; >=20 > kernResult =3D IOMasterPort( MACH_PORT_NULL, &masterPort ); > if ( KERN_SUCCESS !=3D kernResult ) { > printf( "IOMasterPort returned %d\n", kernResult ); > } >=20 > - classesToMatch =3D IOServiceMatching( kIOCDMediaClass ); > - if ( classesToMatch =3D=3D NULL ) { > - printf( "IOServiceMatching returned a NULL dictionary.\n" ); > - } else { > - CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey = ), kCFBooleanTrue ); > - } > - kernResult =3D IOServiceGetMatchingServices( masterPort, = classesToMatch, mediaIterator ); > - if ( KERN_SUCCESS !=3D kernResult ) > - { > - printf( "IOServiceGetMatchingServices returned %d\n", = kernResult ); > - } > + int index; > + for (index =3D 0; index < ARRAY_SIZE(matching_array); index++) { > + classesToMatch =3D IOServiceMatching(matching_array[index]); > + if (classesToMatch =3D=3D NULL) { > + error_report("IOServiceMatching returned NULL for %s", > + matching_array[index]); > + continue; > + } > + CFDictionarySetValue(classesToMatch, = CFSTR(kIOMediaEjectableKey), > + kCFBooleanTrue); > + kernResult =3D IOServiceGetMatchingServices(masterPort, = classesToMatch, > + mediaIterator); > + if (kernResult !=3D KERN_SUCCESS) { > + error_report("Note: IOServiceGetMatchingServices returned = %d", > + kernResult); > + } >=20 > - return kernResult; > + /* If a match was found, leave the loop */ > + if (*mediaIterator !=3D 0) { > + DPRINTF("Matching using %s\n", matching_array[index]); > + mediaType =3D g_strdup(matching_array[index]); > + break; > + } > + } > + return mediaType; > } >=20 > kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath, > @@ -2033,7 +2047,35 @@ kern_return_t GetBSDPath(io_iterator_t = mediaIterator, char *bsdPath, > return kernResult; > } >=20 > -#endif > +/* Sets up a real cdrom for use in QEMU */ > +static bool setup_cdrom(char *bsd_path, Error **errp) > +{ > + int index, num_of_test_partitions =3D 2, fd; > + char test_partition[MAXPATHLEN]; > + bool partition_found =3D false; > + > + /* look for a working partition */ > + for (index =3D 0; index < num_of_test_partitions; index++) { > + snprintf(test_partition, sizeof(test_partition), "%ss%d", = bsd_path, > + index); > + fd =3D qemu_open(test_partition, O_RDONLY | O_BINARY | = O_LARGEFILE); > + if (fd >=3D 0) { > + partition_found =3D true; > + qemu_close(fd); > + break; > + } > + } > + > + /* if a working partition on the device was not found */ > + if (partition_found =3D=3D false) { > + error_setg(errp, "Failed to find a working partition on = disc"); > + } else { > + DPRINTF("Using %s as optical disc\n", test_partition); > + pstrcpy(bsd_path, MAXPATHLEN, test_partition); > + } > + return partition_found; > +} > +#endif /* defined(__APPLE__) && defined(__MACH__) */ >=20 > static int hdev_probe_device(const char *filename) > { > @@ -2115,6 +2157,16 @@ static bool hdev_is_sg(BlockDriverState *bs) > return false; > } >=20 > +/* Prints directions on mounting and unmounting a device */ > +static void print_unmounting_directions(const char *file_name) > +{ > + error_report("If device %s is mounted on the desktop, unmount" > + " it first before using it in QEMU", file_name); > + error_report("Command to unmount device: diskutil unmountDisk = %s", > + file_name); > + error_report("Command to mount device: diskutil mountDisk %s", = file_name); > +} > + > static int hdev_open(BlockDriverState *bs, QDict *options, int flags, > Error **errp) > { > @@ -2125,32 +2177,55 @@ static int hdev_open(BlockDriverState *bs, = QDict *options, int flags, > #if defined(__APPLE__) && defined(__MACH__) > const char *filename =3D qdict_get_str(options, "filename"); >=20 > - if (strstart(filename, "/dev/cdrom", NULL)) { > - kern_return_t kernResult; > - io_iterator_t mediaIterator; > - char bsdPath[ MAXPATHLEN ]; > - int fd; > - > - kernResult =3D FindEjectableCDMedia( &mediaIterator ); > - kernResult =3D GetBSDPath(mediaIterator, bsdPath, = sizeof(bsdPath), > - flags); > - if ( bsdPath[ 0 ] !=3D '\0' ) { > - strcat(bsdPath,"s0"); > - /* some CDs don't have a partition 0 */ > - fd =3D qemu_open(bsdPath, O_RDONLY | O_BINARY | = O_LARGEFILE); > - if (fd < 0) { > - bsdPath[strlen(bsdPath)-1] =3D '1'; > - } else { > - qemu_close(fd); > - } > - filename =3D bsdPath; > - qdict_put(options, "filename", = qstring_from_str(filename)); > + /* If using a real cdrom */ > + if (strcmp(filename, "/dev/cdrom") =3D=3D 0) { > + char bsd_path[MAXPATHLEN]; > + char *mediaType =3D NULL; > + kern_return_t ret_val; > + io_iterator_t mediaIterator =3D 0; > + > + mediaType =3D FindEjectableOpticalMedia(&mediaIterator); > + if (mediaType =3D=3D NULL) { > + error_setg(errp, "Please make sure your CD/DVD is in the = optical" > + " drive"); > + goto hdev_open_Mac_error; > + } > + > + ret_val =3D GetBSDPath(mediaIterator, bsd_path, = sizeof(bsd_path), flags); > + if (ret_val !=3D KERN_SUCCESS) { > + error_setg(errp, "Could not get BSD path for optical = drive"); > + goto hdev_open_Mac_error; > + } > + > + /* If a real optical drive was not found */ > + if (bsd_path[0] =3D=3D '\0') { > + error_setg(errp, "Failed to obtain bsd path for optical = drive"); > + goto hdev_open_Mac_error; > + } > + > + /* If using a cdrom disc and finding a partition on the disc = failed */ > + if (strncmp(mediaType, "IOCDMedia", 9) =3D=3D 0 && > + setup_cdrom(bsd_path, errp) = =3D=3D false) { > + print_unmounting_directions(bsd_path); > + goto hdev_open_Mac_error; > } >=20 > - if ( mediaIterator ) > - IOObjectRelease( mediaIterator ); > + g_free(mediaType); > + filename =3D bsd_path; > + qdict_put(options, "filename", qstring_from_str(filename)); > + goto continue_as_normal; /* skip over error handling code */ > + > + /* If an error occurred above */ > + hdev_open_Mac_error: > + if (mediaIterator) { > + IOObjectRelease(mediaIterator); > + } > + g_free(mediaType); > + return -1; > + > + continue_as_normal: ; > } > -#endif > +#endif /* defined(__APPLE__) && defined(__MACH__) */ >=20 > s->type =3D FTYPE_FILE; >=20 > @@ -2159,8 +2234,18 @@ static int hdev_open(BlockDriverState *bs, = QDict *options, int flags, > if (local_err) { > error_propagate(errp, local_err); > } > + #if !defined(__APPLE__) && !defined(__MACH__) > return ret; > + #endif /* !defined(__APPLE__) && !defined(__MACH__) */ > + } > + > +#if defined(__APPLE__) && defined(__MACH__) > + /* if a physical device experienced an error while being opened = */ > + if (strncmp(filename, "/dev/", 5) =3D=3D 0 && ret !=3D 0) { > + print_unmounting_directions(filename); > + return -1; > } > +#endif /* defined(__APPLE__) && defined(__MACH__) */ >=20 > /* Since this does ioctl the device must be already opened */ > bs->sg =3D hdev_is_sg(bs); > --=20 > 1.7.5.4 >=20 >=20