diff mbox

[v5] block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it reports the correct length of a real CD

Message ID F2F94F74-08B4-420F-8952-66FDEA2BB4AA@gmail.com
State New
Headers show

Commit Message

Programmingkid Jan. 13, 2015, 6:26 p.m. UTC
Allows for using real cdrom disc in QEMU under Mac OS X.

This command was used to see if this patch worked:
./qemu-system-i386 -drive if=none,id=drive0,file=/dev/null,format=raw

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>

---
Replaced -errno with 0 for ioctl() failure return value.
"make check" now passes with this patch.


 block/raw-posix.c |   18 +++++++++++++++++-
 configure         |    2 +-
 2 files changed, 18 insertions(+), 2 deletions(-)

Comments

Peter Maydell Jan. 13, 2015, 6:34 p.m. UTC | #1
On 13 January 2015 at 18:26, Programmingkid <programmingkidx@gmail.com> wrote:
> Allows for using real cdrom disc in QEMU under Mac OS X.
>
> This command was used to see if this patch worked:
> ./qemu-system-i386 -drive if=none,id=drive0,file=/dev/null,format=raw
>
> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>
> ---
> Replaced -errno with 0 for ioctl() failure return value.
> "make check" now passes with this patch.
>
>
>  block/raw-posix.c |   18 +++++++++++++++++-
>  configure         |    2 +-
>  2 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index e51293a..16fa0a4 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -1312,7 +1312,23 @@ again:
>          if (size == 0)
>  #endif
>  #if defined(__APPLE__) && defined(__MACH__)
> -        size = LLONG_MAX;
> +    {
> +        uint64_t sectors = 0;
> +        uint32_t sector_size = 0;
> +
> +        /* Query the number of sectors on the disk */
> +        ret = ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors);
> +        if (ret == -1) {
> +            return 0;

We should be falling back to lseek, not returning 0...

thanks
-- PMM
Programmingkid Jan. 13, 2015, 6:45 p.m. UTC | #2
On Jan 13, 2015, at 1:34 PM, Peter Maydell wrote:

> On 13 January 2015 at 18:26, Programmingkid <programmingkidx@gmail.com> wrote:
>> Allows for using real cdrom disc in QEMU under Mac OS X.
>> 
>> This command was used to see if this patch worked:
>> ./qemu-system-i386 -drive if=none,id=drive0,file=/dev/null,format=raw
>> 
>> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>> 
>> ---
>> Replaced -errno with 0 for ioctl() failure return value.
>> "make check" now passes with this patch.
>> 
>> 
>> block/raw-posix.c |   18 +++++++++++++++++-
>> configure         |    2 +-
>> 2 files changed, 18 insertions(+), 2 deletions(-)
>> 
>> diff --git a/block/raw-posix.c b/block/raw-posix.c
>> index e51293a..16fa0a4 100644
>> --- a/block/raw-posix.c
>> +++ b/block/raw-posix.c
>> @@ -1312,7 +1312,23 @@ again:
>>         if (size == 0)
>> #endif
>> #if defined(__APPLE__) && defined(__MACH__)
>> -        size = LLONG_MAX;
>> +    {
>> +        uint64_t sectors = 0;
>> +        uint32_t sector_size = 0;
>> +
>> +        /* Query the number of sectors on the disk */
>> +        ret = ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors);
>> +        if (ret == -1) {
>> +            return 0;
> 
> We should be falling back to lseek, not returning 0...
> 
> thanks
> -- PMM

I did try using lseek, but it doesn't work with Mac OS X block devices. It would always fail. Here is some more information on the problem: http://stackoverflow.com/questions/9073614/open-raw-disk-and-get-size-os-x. 

I thought things would be as simple as using fopen() with a block device as the argument, but Apple decided to make things more difficult. It looks like they are forcing developers to use the IOKit for device communications. Simple posix functions like lseek don't work.
Peter Maydell Jan. 13, 2015, 6:54 p.m. UTC | #3
On 13 January 2015 at 18:45, Programmingkid <programmingkidx@gmail.com> wrote:
>
> On Jan 13, 2015, at 1:34 PM, Peter Maydell wrote:
>
>> On 13 January 2015 at 18:26, Programmingkid <programmingkidx@gmail.com> wrote:
>>> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>>> +        uint64_t sectors = 0;
>>> +        uint32_t sector_size = 0;
>>> +
>>> +        /* Query the number of sectors on the disk */
>>> +        ret = ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors);
>>> +        if (ret == -1) {
>>> +            return 0;
>>
>> We should be falling back to lseek, not returning 0...

> I did try using lseek, but it doesn't work with Mac OS X block
> devices. It would always fail.

Right, but for block devices the ioctl will succeed, I thought?
We'll only try lseek() if the ioctl fails (hence "fall back").

-- PMM
diff mbox

Patch

diff --git a/block/raw-posix.c b/block/raw-posix.c
index e51293a..16fa0a4 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1312,7 +1312,23 @@  again:
         if (size == 0)
 #endif
 #if defined(__APPLE__) && defined(__MACH__)
-        size = LLONG_MAX;
+    {
+        uint64_t sectors = 0;
+        uint32_t sector_size = 0;
+
+        /* Query the number of sectors on the disk */
+        ret = ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors);
+        if (ret == -1) {
+            return 0;
+        }
+
+        /* Query the size of each sector */
+        ret = ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size);
+        if (ret == -1) {
+            return 0;
+        }
+        size = sectors * sector_size;
+    }
 #else
         size = lseek(fd, 0LL, SEEK_END);
         if (size < 0) {
diff --git a/configure b/configure
index cae588c..32d3d3f 100755
--- a/configure
+++ b/configure
@@ -611,7 +611,7 @@  Darwin)
   cocoa="yes"
   audio_drv_list="coreaudio"
   audio_possible_drivers="coreaudio sdl fmod"
-  LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
+  LDFLAGS="-framework CoreFoundation -framework IOKit -framework ApplicationServices $LDFLAGS"
   libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
   # Disable attempts to use ObjectiveC features in os/object.h since they
   # won't work when we're compiling with gcc as a C compiler.