From: Jeff Cody <jcody@redhat.com>
To: Programmingkid <programmingkidx@gmail.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
qemu-devel qemu-devel <qemu-devel@nongnu.org>,
Qemu-block <qemu-block@nongnu.org>
Subject: Re: [Qemu-devel] [Qemu-block] ping [PATCH v11] block/raw-posix.c: Make physical devices usable in QEMU under Mac OS X host
Date: Fri, 11 Dec 2015 17:00:53 -0500 [thread overview]
Message-ID: <20151211220053.GA30085@localhost.localdomain> (raw)
In-Reply-To: <69D59CD8-84A3-4C9E-93F4-D366C412F4C6@gmail.com>
On Thu, Dec 10, 2015 at 09:39:51AM -0500, Programmingkid wrote:
> https://patchwork.ozlabs.org/patch/550295/
>
> 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.
>
This commit message doesn't seem to really match the patch; it is more
than just a message displayed to the user. For instance, before it
looked for just kIOCDMediaClass - now, it searches for kIOCDMediaClass
and kIODVDMediaClass.
> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>
> ---
> error_report()'s had their \n, '.', and "Error:" removed.
> Indentations are now at the left parenthesis rather than
> at the 80 character mark.
> Added spaces between the + sign.
>
Also, this patch seems garbled. When saved via Mutt, or when I view
it "raw", there are '=20" and '=3D' all around, a sure sign that it is
(or once was) not plaintext.
I recommend using git format-patch [1] and git send-email [1] to
create and send patches - it'll do the Right Thing.
> block/raw-posix.c | 135 +++++++++++++++++++++++++++++++++++++++--------------
> 1 files changed, 99 insertions(+), 36 deletions(-)
>
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index ccfec1c..39e523b 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -43,6 +43,7 @@
> #include <IOKit/storage/IOMedia.h>
> #include <IOKit/storage/IOCDMedia.h>
> //#include <IOKit/storage/IOCDTypes.h>
> +#include <IOKit/storage/IODVDMedia.h>
> #include <CoreFoundation/CoreFoundation.h>
> #endif
>
> @@ -1975,32 +1976,46 @@ 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, int flags);
> -kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
> +static kern_return_t FindEjectableOpticalMedia(io_iterator_t *mediaIterator,
> + char *mediaType)
> {
> kern_return_t kernResult;
> mach_port_t masterPort;
> CFMutableDictionaryRef classesToMatch;
> + const char *matching_array[] = {kIODVDMediaClass, kIOCDMediaClass};
>
> kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
> if ( KERN_SUCCESS != kernResult ) {
> printf( "IOMasterPort returned %d\n", kernResult );
> }
>
> - classesToMatch = IOServiceMatching( kIOCDMediaClass );
> - if ( classesToMatch == NULL ) {
> - printf( "IOServiceMatching returned a NULL dictionary.\n" );
> - } else {
> - CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
> - }
> - kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
> - if ( KERN_SUCCESS != kernResult )
> - {
> - printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
> - }
> + int index;
> + for (index = 0; index < ARRAY_SIZE(matching_array); index++) {
> + classesToMatch = IOServiceMatching(matching_array[index]);
> + if (classesToMatch == NULL) {
> + error_report("IOServiceMatching returned NULL for %s",
> + matching_array[index]);
> + continue;
> + }
> + CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
> + kCFBooleanTrue);
> + kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch,
> + mediaIterator);
> + if (kernResult != KERN_SUCCESS) {
> + error_report("Note: IOServiceGetMatchingServices returned %d",
> + kernResult);
> + }
>
> + /* If a match was found, leave the loop */
> + if (*mediaIterator != 0) {
Since mediaIterator was not ever initialized in hdev_open, we can't
assume the value of mediaIterator as being 0 after kernResult !=
KERN_SUCCESS, can we? A quick google search [3] shows it ambiguous, so
best initialize mediaIterator down below...
> + DPRINTF("Matching using %s\n", matching_array[index]);
> + snprintf(mediaType, strlen(matching_array[index]) + 1, "%s",
> + matching_array[index]);
Just use g_strdup().
We use snprintf here, with a size limit of the string referenced in
the array, which references a string defined in an OS X system header...
> + break;
> + }
> + }
> return kernResult;
You may return garbage here, because kernResult is never initialized,
and your for() loop short circuits on a NULL return from
IOServiceMatching(). Does this compile with our flags? I don't have
OS X so I can't try it, but I thought at least with gcc and -werror, a
possible uninitialized usage would be flagged.
> }
>
> @@ -2033,7 +2048,35 @@ kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
> return kernResult;
> }
>
> -#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 = 2, fd;
What is the magic of 2 test partitions?
> + char test_partition[MAXPATHLEN];
> + bool partition_found = false;
> +
> + /* look for a working partition */
> + for (index = 0; index < num_of_test_partitions; index++) {
> + snprintf(test_partition, sizeof(test_partition), "%ss%d", bsd_path,
> + index);
> + fd = qemu_open(test_partition, O_RDONLY | O_BINARY | O_LARGEFILE);
> + if (fd >= 0) {
> + partition_found = true;
> + qemu_close(fd);
> + break;
> + }
> + }
> +
> + /* if a working partition on the device was not found */
> + if (partition_found == 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);
In OS X, is MAXPATHLEN including the terminating NULL?
> + }
> + return partition_found;
> +}
> +#endif /* defined(__APPLE__) && defined(__MACH__) */
>
> static int hdev_probe_device(const char *filename)
> {
> @@ -2115,6 +2158,17 @@ static bool hdev_is_sg(BlockDriverState *bs)
> return false;
> }
>
> +/* 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,30 +2179,32 @@ 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;
> + /* If using a real cdrom */
> + if (strcmp(filename, "/dev/cdrom") == 0) {
> + char bsd_path[MAXPATHLEN];
> + char mediaType[11]; /* IODVDMedia is the longest value */
... yet here we just hard code the array size to 11, which is prone to
an error later on by either a change in the system header (not very
likely, but possible), or by expanding the media types we support in
the future.
Just bypass that fragility, and use g_strdup() (and later g_free()),
so we are impervious to the exact string size. You'll likely want a
common exit for the g_free() call.
> io_iterator_t mediaIterator;
...Given your usage of mediaIterator, I think you need to initialize it
to 0 here.
> - char bsdPath[ MAXPATHLEN ];
> - int fd;
> -
> - kernResult = FindEjectableCDMedia( &mediaIterator );
> - kernResult = GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath),
> - flags);
> - 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);
> - }
> - filename = bsdPath;
> - qdict_put(options, "filename", qstring_from_str(filename));
> + FindEjectableOpticalMedia(&mediaIterator, mediaType);
Return value ignored here, don't ignore it.
> + GetBSDPath(mediaIterator, bsd_path, sizeof(bsd_path), flags);
Return value ignored here, don't ignore it.
> + if (mediaIterator) {
> + IOObjectRelease(mediaIterator);
> }
>
> - if ( mediaIterator )
> - IOObjectRelease( mediaIterator );
> + /* If a real optical drive was not found */
> + if (bsd_path[0] == '\0') {
> + error_setg(errp, "Failed to obtain bsd path for optical drive");
> + return -1;
> + }
> +
> + /* If using a cdrom disc and finding a partition on the disc failed */
> + if (strncmp(mediaType, "IOCDMedia", 9) == 0 &&
> + setup_cdrom(bsd_path, errp) == false) {
> + print_unmounting_directions(bsd_path);
> + return -1;
> + }
> +
> + filename = bsd_path;
> + qdict_put(options, "filename", qstring_from_str(filename));
> }
> #endif
>
> @@ -2159,9 +2215,16 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
> if (local_err) {
> error_propagate(errp, local_err);
> }
> - return ret;
Spurious line delete?
> }
>
> +#if defined(__APPLE__) && defined(__MACH__)
> + /* if a physical device experienced an error while being opened */
> + if (strncmp(filename, "/dev/", 5) == 0 && ret != 0) {
> + print_unmounting_directions(filename);
> + return -1;
> + }
> +#endif /* defined(__APPLE__) && defined(__MACH__) */
> +
> /* Since this does ioctl the device must be already opened */
> bs->sg = hdev_is_sg(bs);
>
> --
> 1.7.5.4
>
>
>
[1] https://git-scm.com/docs/git-format-patch
[2] https://git-scm.com/docs/git-send-email
[3] https://developer.apple.com/library/mac/documentation/IOKit/Reference/IOKitLib_header_reference/index.html#//apple_ref/doc/c_ref/IOServiceGetMatchingServices
next prev parent reply other threads:[~2015-12-11 22:01 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-10 14:39 [Qemu-devel] ping [PATCH v11] block/raw-posix.c: Make physical devices usable in QEMU under Mac OS X host Programmingkid
2015-12-11 22:00 ` Jeff Cody [this message]
2015-12-11 23:40 ` [Qemu-devel] [Qemu-block] " Programmingkid
2015-12-11 23:53 ` Eric Blake
2015-12-12 3:27 ` [Qemu-devel] [PATCH v12] " Programmingkid
2015-12-18 23:58 ` [Qemu-devel] ping " Programmingkid
2015-12-29 0:27 ` Programmingkid
2016-01-04 16:35 ` [Qemu-devel] [Qemu-block] " Max Reitz
2016-01-04 16:57 ` Programmingkid
2016-01-18 16:14 ` [Qemu-devel] " Kevin Wolf
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=20151211220053.GA30085@localhost.localdomain \
--to=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=programmingkidx@gmail.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.