Allows QEMU running on Mac OS X guest to use the real CD-ROM drive. This patch doesn't actually remove raw device access. I'm just using the same name as the last patch.
Why should we test for /dev/disk1s0 when /dev/rdisk1s0 works? By avoiding using the raw device we gain speed. When a read takes place for the raw CD-ROM device, it has to start spinning up if it went to sleep. This takes time to do. Plus there is that annoying spin up sound. With the non-raw access, QEMU can use the operating system's buffers to do its reading. This means faster and quieter access. I have noticed that in order to use /dev/disk1s0, the CD-ROM had to be unmounted (but not ejected) from the desktop. Disk Utility is what I used to accomplish this. Signed-off-by: John Arbuckle <programmingk...@gmail.com> --- Tries more permutations of the CD-ROM device file. Sets the needs_alignment variable. Removes the unused kernResult variable. block/raw-posix.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 52 insertions(+), 10 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index cbe6574..2088c1f 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -484,6 +484,19 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, filename = qemu_opt_get(opts, "filename"); +#ifdef __APPLE__ + + /* + * Raw CD-ROM access on a Macintosh needs to be aligned + * or reads will fail. + */ + + if (strncmp(filename, "/dev/r", 6) == 0) { + s->needs_alignment = true; + } + +#endif /* __APPLE__ */ + ret = raw_normalize_devicepath(&filename); if (ret != 0) { error_setg_errno(errp, -ret, "Could not normalize device path"); @@ -2014,7 +2027,6 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma if ( bsdPathAsCFString ) { size_t devPathLength; strcpy( bsdPath, _PATH_DEV ); - strcat( bsdPath, "r" ); devPathLength = strlen( bsdPath ); if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { kernResult = KERN_SUCCESS; @@ -2120,25 +2132,55 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, 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 ) ); + FindEjectableCDMedia(&mediaIterator); + 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 { + int devStringLength = strlen("/dev/"); + char baseDeviceName[MAXPATHLEN]; + int numberOfOptions = 4; + char deviceNameArray[numberOfOptions][MAXPATHLEN]; + int i = 0; + + /* remove the "/dev/" part from the device file's name */ + strcpy(baseDeviceName, bsdPath + devStringLength); + + /* /dev/disk*s0 */ + sprintf(deviceNameArray[i++], "/dev/%ss0", baseDeviceName); + + /* /dev/disk*s1 */ + sprintf(deviceNameArray[i++], "/dev/%ss1", baseDeviceName); + + /* /dev/rdisk*s0 */ + sprintf(deviceNameArray[i++], "/dev/r%ss0", baseDeviceName); + + /* /dev/rdisk*s1 */ + sprintf(deviceNameArray[i++], "/dev/r%ss1", baseDeviceName); + + /* Try device file permutions until one works */ + for (i = 0; i < numberOfOptions; i++) { + fd = qemu_open(deviceNameArray[i], O_RDONLY | O_BINARY + | O_LARGEFILE); + if (fd < 0) { + DPRINTF("Error opening %s: %s\n", deviceNameArray[i] + , strerror(errno)); + } else { + strcpy(bsdPath, (char *)deviceNameArray[i]); + break; + } + } + + if (fd > 0) { qemu_close(fd); } + filename = bsdPath; qdict_put(options, "filename", qstring_from_str(filename)); + DPRINTF("cdrom is using %s\n", filename); } if ( mediaIterator ) -- 1.7.5.4