@@ -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 )
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 <programmingkidx@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(-)