Message ID | F11A2BB4-9674-46A0-8ED0-352A8AEEA7F9@gmail.com |
---|---|
State | New |
Headers | show |
On 07/07/2015 19:33, Programmingkid wrote: > Make physical devices like a USB flash drive or a CDROM drive work in > QEMU. With > this patch I can use a USB flash drive like a hard drive. Before this > patch, > QEMU would just quit with a message like "resource busy". Now it handles > issues > like these for the user. This patch unmounts volumes of physical devices > before > using them in QEMU. When QEMU quits, the physical devices are mounted again > for the user. The user can find out which device files to use for their > physical > devices by running the mount command in the terminal. This patch makes > "qemu-system-ppc -cdrom /dev/cdrom" work again on Mac OS X. > > Signed-off-by: John Arbuckle <programmingkidx@gmail.com > <mailto:programmingkidx@gmail.com>> Two comments: - you should not mix several fixes in one patch (raw block device management, partition seek, unmount/mount cdrom...) - according to Stefan answer, I think you should not unmount the CDROM but you should inform the user he must unmount it manually to be able to use it. Laurent > --- > block/raw-posix.c | 155 > ++++++++++++++++++++++++++++++++++++++++++++-------- > 1 files changed, 131 insertions(+), 24 deletions(-) > > diff --git a/block/raw-posix.c b/block/raw-posix.c > index cbe6574..af0981a 100644 > --- a/block/raw-posix.c > +++ b/block/raw-posix.c > @@ -42,9 +42,10 @@ > #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 > +#include <sys/syslimits.h> > +#include <fcntl.h> > +#endif /* (__APPLE__) && (__MACH__) */ > > > > #ifdef __sun__ > #define _POSIX_PTHREAD_SEMANTICS 1 > @@ -162,6 +163,25 @@ typedef struct BDRVRawState { > bool needs_alignment; > } BDRVRawState; > > > > +#ifdef __APPLE__ > + > +#define MAX_NUM_DEVICES 7 > + > +/* > + * Keeps track of devices that need to be mounted > + * when QEMU exists. > + */ > +typedef struct { > + int fd; > + char filePath[MAXPATHLEN]; > +} PhysicalDevice; > + > +PhysicalDevice deviceArray[MAX_NUM_DEVICES]; > +int numberOfDevices; > + > +#endif /* __APPLE__ */ > + > + > typedef struct BDRVRawReopenState { > int fd; > int open_flags; > @@ -1972,8 +1992,10 @@ 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); > +void mountDevice(void); > > > > kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) > { > @@ -2001,7 +2023,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 +2037,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 +2052,54 @@ kern_return_t GetBSDPath( io_iterator_t > mediaIterator, char *bsdPath, CFIndex ma > return kernResult; > } > > > > -#endif > +/* Mounts unmounted devices onto host computer's desktop */ > +void mountDevice(void) > +{ > + char commandBuffer[MAXPATHLEN]; > + int result, index; > + > + for (index = 0; index < numberOfDevices; index++) { > + qemu_close(deviceArray[index].fd); > + sprintf(commandBuffer, "diskutil mountDisk %s", > + > deviceArray[index].filePath); > + DPRINTF("Issuing command: %s\n", commandBuffer); > + result = system(commandBuffer); > + if (result != 0) { > + printf("Warning: problem detected while mounting %s\n", > + > deviceArray[index].filePath); > + } > + } > +} > + > +/* 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++) { > + strcpy(testPartition, bsdPath); > + sprintf(testPartition, "%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 found */ > + if (partitionFound == false) { > + printf("Error: Failed to find a working partition on CD!\n"); > + exit(EXIT_FAILURE); > + } > + > + strcpy(bsdPath, testPartition); > +} > + > +#endif /* defined(__APPLE__) && defined(__MACH__) */ > > > > static int hdev_probe_device(const char *filename) > { > @@ -2119,30 +2191,52 @@ 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; > + /* If using a physical device */ > + if (strstart(filename, "/dev/", NULL)) { > char bsdPath[ MAXPATHLEN ]; > - int fd; > > > > - kernResult = FindEjectableCDMedia( &mediaIterator ); > - kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( > bsdPath ) ); > + /* If the physical device is a cdrom */ > + if (strcmp(filename, "/dev/cdrom") == 0) { > + io_iterator_t mediaIterator; > + FindEjectableCDMedia(&mediaIterator); > + GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), flags); > + if (mediaIterator) { > + IOObjectRelease(mediaIterator); > + } > + } > > > > - 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 the physical device is something else */ > + else { > + strcpy(bsdPath, filename); > + } > + > + /* if accessing a buffered device */ > + if ((flags & BDRV_O_NOCACHE) == 0) { > + /* > + * Unmount the device from the desktop before > + * using the buffered device. A resource busy error > + * would happen if we don't. > + */ > + char commandBuffer[MAXPATHLEN]; > + int result; > + sprintf(commandBuffer, "diskutil unmountDisk %s", bsdPath); > + DPRINTF("Issuing command: %s\n", commandBuffer); > + result = system(commandBuffer); > + if (result != 0) { > + printf("Warning: problem detected while unmounting %s\n", > + > bsdPath); > } > + } > + > + atexit(mountDevice); > + > + /* Setup a CDROM device if found */ > + if (bsdPath[0] != '\0' && (strcmp(filename, "/dev/cdrom") == 0)) { > + setupCDROM(bsdPath); > + DPRINTF("Using %s as CDROM\n", bsdPath); > filename = bsdPath; > qdict_put(options, "filename", qstring_from_str(filename)); > } > - > - if ( mediaIterator ) > - IOObjectRelease( mediaIterator ); > } > #endif > > > > @@ -2156,6 +2250,19 @@ static int hdev_open(BlockDriverState *bs, QDict > *options, int flags, > return ret; > } > > > > +#ifdef __APPLE__ > + > + /* Add the fd to the fd array for mounting at exit */ > + if (strncmp(filename, "/dev/", 5) == 0) { > + int mountFD = ((BDRVRawState *) bs->opaque)->fd; > + DPRINTF("Queuing %s (fd: %d) for mounting at exit\n", > + filename, > mountFD); > + deviceArray[numberOfDevices].fd = mountFD; > + strcpy(deviceArray[numberOfDevices++].filePath, filename); > + } > + > +#endif /* __APPLE__ */ > + > /* Since this does ioctl the device must be already opened */ > bs->sg = hdev_is_sg(bs); > > > > -- > 1.7.5.4 >
On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: > Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With > this patch I can use a USB flash drive like a hard drive. Before this patch, > QEMU would just quit with a message like "resource busy". The commit message and the description are missing "on Mac OS X". It should be clear right away that this applies to Mac only. This works fine on Linux and probably other host OSes.
On Jul 9, 2015, at 6:52 AM, Stefan Hajnoczi wrote: > On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: >> Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With >> this patch I can use a USB flash drive like a hard drive. Before this patch, >> QEMU would just quit with a message like "resource busy". > > The commit message and the description are missing "on Mac OS X". It > should be clear right away that this applies to Mac only. This works > fine on Linux and probably other host OSes. Yeah, that should have been done. Did you see any issues with the code?
On Jul 9, 2015, at 5:35 AM, Laurent Vivier wrote: > > > On 07/07/2015 19:33, Programmingkid wrote: >> Make physical devices like a USB flash drive or a CDROM drive work in >> QEMU. With >> this patch I can use a USB flash drive like a hard drive. Before this >> patch, >> QEMU would just quit with a message like "resource busy". Now it handles >> issues >> like these for the user. This patch unmounts volumes of physical devices >> before >> using them in QEMU. When QEMU quits, the physical devices are mounted again >> for the user. The user can find out which device files to use for their >> physical >> devices by running the mount command in the terminal. This patch makes >> "qemu-system-ppc -cdrom /dev/cdrom" work again on Mac OS X. >> >> Signed-off-by: John Arbuckle <programmingkidx@gmail.com >> <mailto:programmingkidx@gmail.com>> > > Two comments: > - you should not mix several fixes in one patch (raw block device > management, partition seek, unmount/mount cdrom...) I consider this patch one fix with several related changes. > - according to Stefan answer, I think you should not unmount the CDROM > but you should inform the user he must unmount it manually to be able to > use it. Having the user unmount the CDROM manually isn't as user friendly as having QEMU doing it for him or her.
On Thu, Jul 09, 2015 at 10:02:26AM -0400, Programmingkid wrote: > > On Jul 9, 2015, at 6:52 AM, Stefan Hajnoczi wrote: > > > On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: > >> Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With > >> this patch I can use a USB flash drive like a hard drive. Before this patch, > >> QEMU would just quit with a message like "resource busy". > > > > The commit message and the description are missing "on Mac OS X". It > > should be clear right away that this applies to Mac only. This works > > fine on Linux and probably other host OSes. > > Yeah, that should have been done. Did you see any issues with the code? QEMU shouldn't silently open a different file than the one given by the user. The user should give the exact device file they want. If there is magic behavior it needs to be documented, but I don't see a reason why that's necessary in the case of device files. QEMU shouldn't mount/unmount the CD-ROM. atexit(3) doesn't handle crashes or abort(). Users may be confused to find their CD-ROM unmounted in those cases and would see this as a bug. Instead we should refuse mounted CD-ROMs so the user understands that block-level access requires them to unmount first. The strcpy/sprintf usage in this patch is unsafe and can lead to buffer overflow, for example in the case of generating command-lines. The command-line buffer is only MAXPATHLEN so prepending the command to the filename could exceed the buffer size. There is also a buffer overflow in the array of devices that need to be mounted. What happens if there are more than 7 devices?
On Jul 16, 2015, at 9:19 AM, Stefan Hajnoczi wrote: > On Thu, Jul 09, 2015 at 10:02:26AM -0400, Programmingkid wrote: >> >> On Jul 9, 2015, at 6:52 AM, Stefan Hajnoczi wrote: >> >>> On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: >>>> Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With >>>> this patch I can use a USB flash drive like a hard drive. Before this patch, >>>> QEMU would just quit with a message like "resource busy". >>> >>> The commit message and the description are missing "on Mac OS X". It >>> should be clear right away that this applies to Mac only. This works >>> fine on Linux and probably other host OSes. >> >> Yeah, that should have been done. Did you see any issues with the code? > > QEMU shouldn't silently open a different file than the one given by the > user. The user should give the exact device file they want. If there > is magic behavior it needs to be documented, but I don't see a reason > why that's necessary in the case of device files. I think you are reviewing an older patch. The newest one doesn't do that. > > QEMU shouldn't mount/unmount the CD-ROM. atexit(3) doesn't handle > crashes or abort(). Users may be confused to find their CD-ROM > unmounted in those cases and would see this as a bug. Instead we should > refuse mounted CD-ROMs so the user understands that block-level access > requires them to unmount first. That can be done. It just wouldn't be as user friendly as having QEMU do it for the user :( > > The strcpy/sprintf usage in this patch is unsafe and can lead to buffer > overflow, for example in the case of generating command-lines. The > command-line buffer is only MAXPATHLEN so prepending the command to the > filename could exceed the buffer size. > > There is also a buffer overflow in the array of devices that need to be > mounted. What happens if there are more than 7 devices? Ok. Will correct this issue.
On Thu, Jul 16, 2015 at 6:26 PM, Programmingkid <programmingkidx@gmail.com> wrote: > > On Jul 16, 2015, at 9:19 AM, Stefan Hajnoczi wrote: > >> On Thu, Jul 09, 2015 at 10:02:26AM -0400, Programmingkid wrote: >>> >>> On Jul 9, 2015, at 6:52 AM, Stefan Hajnoczi wrote: >>> >>>> On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: >>>>> Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With >>>>> this patch I can use a USB flash drive like a hard drive. Before this patch, >>>>> QEMU would just quit with a message like "resource busy". >>>> >>>> The commit message and the description are missing "on Mac OS X". It >>>> should be clear right away that this applies to Mac only. This works >>>> fine on Linux and probably other host OSes. >>> >>> Yeah, that should have been done. Did you see any issues with the code? >> >> QEMU shouldn't silently open a different file than the one given by the >> user. The user should give the exact device file they want. If there >> is magic behavior it needs to be documented, but I don't see a reason >> why that's necessary in the case of device files. > > I think you are reviewing an older patch. The newest one doesn't do that. I don't see a more recent patch on the mailing list. What is the Message-Id of your latest patch email?
On Jul 16, 2015, at 3:43 PM, Stefan Hajnoczi wrote: > On Thu, Jul 16, 2015 at 6:26 PM, Programmingkid > <programmingkidx@gmail.com> wrote: >> >> On Jul 16, 2015, at 9:19 AM, Stefan Hajnoczi wrote: >> >>> On Thu, Jul 09, 2015 at 10:02:26AM -0400, Programmingkid wrote: >>>> >>>> On Jul 9, 2015, at 6:52 AM, Stefan Hajnoczi wrote: >>>> >>>>> On Tue, Jul 07, 2015 at 01:33:23PM -0400, Programmingkid wrote: >>>>>> Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With >>>>>> this patch I can use a USB flash drive like a hard drive. Before this patch, >>>>>> QEMU would just quit with a message like "resource busy". >>>>> >>>>> The commit message and the description are missing "on Mac OS X". It >>>>> should be clear right away that this applies to Mac only. This works >>>>> fine on Linux and probably other host OSes. >>>> >>>> Yeah, that should have been done. Did you see any issues with the code? >>> >>> QEMU shouldn't silently open a different file than the one given by the >>> user. The user should give the exact device file they want. If there >>> is magic behavior it needs to be documented, but I don't see a reason >>> why that's necessary in the case of device files. >> >> I think you are reviewing an older patch. The newest one doesn't do that. > > I don't see a more recent patch on the mailing list. What is the > Message-Id of your latest patch email? Since I will be uploading a new patch shortly, it doesn't matter anymore.
diff --git a/block/raw-posix.c b/block/raw-posix.c index cbe6574..af0981a 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -42,9 +42,10 @@ #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 +#include <sys/syslimits.h> +#include <fcntl.h> +#endif /* (__APPLE__) && (__MACH__) */ #ifdef __sun__ #define _POSIX_PTHREAD_SEMANTICS 1 @@ -162,6 +163,25 @@ typedef struct BDRVRawState { bool needs_alignment; } BDRVRawState; +#ifdef __APPLE__ + +#define MAX_NUM_DEVICES 7 + +/* + * Keeps track of devices that need to be mounted + * when QEMU exists. + */ +typedef struct { + int fd; + char filePath[MAXPATHLEN]; +} PhysicalDevice; + +PhysicalDevice deviceArray[MAX_NUM_DEVICES]; +int numberOfDevices; + +#endif /* __APPLE__ */ + + typedef struct BDRVRawReopenState { int fd; int open_flags; @@ -1972,8 +1992,10 @@ 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); +void mountDevice(void); kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) { @@ -2001,7 +2023,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 +2037,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 +2052,54 @@ kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex ma return kernResult; } -#endif +/* Mounts unmounted devices onto host computer's desktop */ +void mountDevice(void) +{ + char commandBuffer[MAXPATHLEN]; + int result, index; + + for (index = 0; index < numberOfDevices; index++) { + qemu_close(deviceArray[index].fd); + sprintf(commandBuffer, "diskutil mountDisk %s", + deviceArray[index].filePath); + DPRINTF("Issuing command: %s\n", commandBuffer); + result = system(commandBuffer); + if (result != 0) { + printf("Warning: problem detected while mounting %s\n", + deviceArray[index].filePath); + } + } +} + +/* 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++) { + strcpy(testPartition, bsdPath); + sprintf(testPartition, "%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 found */ + if (partitionFound == false) { + printf("Error: Failed to find a working partition on CD!\n"); + exit(EXIT_FAILURE); + } + + strcpy(bsdPath, testPartition); +} + +#endif /* defined(__APPLE__) && defined(__MACH__) */ static int hdev_probe_device(const char *filename) { @@ -2119,30 +2191,52 @@ 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; + /* If using a physical device */ + if (strstart(filename, "/dev/", NULL)) { char bsdPath[ MAXPATHLEN ]; - int fd; - kernResult = FindEjectableCDMedia( &mediaIterator ); - kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) ); + /* If the physical device is a cdrom */ + if (strcmp(filename, "/dev/cdrom") == 0) { + io_iterator_t mediaIterator; + FindEjectableCDMedia(&mediaIterator); + GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath), flags); + if (mediaIterator) { + IOObjectRelease(mediaIterator); + } + } - 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 the physical device is something else */ + else { + strcpy(bsdPath, filename); + } + + /* if accessing a buffered device */ + if ((flags & BDRV_O_NOCACHE) == 0) { + /* + * Unmount the device from the desktop before + * using the buffered device. A resource busy error + * would happen if we don't. + */ + char commandBuffer[MAXPATHLEN]; + int result; + sprintf(commandBuffer, "diskutil unmountDisk %s", bsdPath); + DPRINTF("Issuing command: %s\n", commandBuffer); + result = system(commandBuffer); + if (result != 0) { + printf("Warning: problem detected while unmounting %s\n", + bsdPath); } + } + + atexit(mountDevice); + + /* Setup a CDROM device if found */ + if (bsdPath[0] != '\0' && (strcmp(filename, "/dev/cdrom") == 0)) { + setupCDROM(bsdPath); + DPRINTF("Using %s as CDROM\n", bsdPath); filename = bsdPath; qdict_put(options, "filename", qstring_from_str(filename)); } - - if ( mediaIterator ) - IOObjectRelease( mediaIterator ); } #endif @@ -2156,6 +2250,19 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags, return ret; } +#ifdef __APPLE__ + + /* Add the fd to the fd array for mounting at exit */ + if (strncmp(filename, "/dev/", 5) == 0) { + int mountFD = ((BDRVRawState *) bs->opaque)->fd; + DPRINTF("Queuing %s (fd: %d) for mounting at exit\n", + filename, mountFD); + deviceArray[numberOfDevices].fd = mountFD; + strcpy(deviceArray[numberOfDevices++].filePath, filename); + } + +#endif /* __APPLE__ */ + /* Since this does ioctl the device must be already opened */ bs->sg = hdev_is_sg(bs);
Make physical devices like a USB flash drive or a CDROM drive work in QEMU. With this patch I can use a USB flash drive like a hard drive. Before this patch, QEMU would just quit with a message like "resource busy". Now it handles issues like these for the user. This patch unmounts volumes of physical devices before using them in QEMU. When QEMU quits, the physical devices are mounted again for the user. The user can find out which device files to use for their physical devices by running the mount command in the terminal. This patch makes "qemu-system-ppc -cdrom /dev/cdrom" work again on Mac OS X. Signed-off-by: John Arbuckle <programmingkidx@gmail.com> --- block/raw-posix.c | 155 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 131 insertions(+), 24 deletions(-)