All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Shared CD-Rom Support
@ 2007-08-28 14:12 Ben Guthro
  0 siblings, 0 replies; only message in thread
From: Ben Guthro @ 2007-08-28 14:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Josh Nicholas

[-- Attachment #1: Type: text/plain, Size: 598 bytes --]

This patch adds a QEMU monitor command may switch the  domain owning the 
physical cdrom, such that an eject command on the guest command line 
will physically eject the drive door.

Monitor command example:
set_cdrom_owner 1 hdd
(for the time being the "hdd" parameter is a constant, as we only 
support a singular CD-Rom)

NOTE: This was also submitted to the Xen list, with a couple additional 
xen-specific changes, that are not necessarily applicable here (xenstore 
entries, etc)

Signed-off-by: Ben Guthro <bguthro@virtualiron.com>
Signed-off-by: Joshua Nicholas <jnicholas@virtualiron.com>

[-- Attachment #2: qemu-shared-cdrom.patch --]
[-- Type: text/x-patch, Size: 20318 bytes --]

diff -r 106bc46793ca block.c
--- a/block.c	Mon Aug 27 16:20:33 2007 -0400
+++ b/block.c	Tue Aug 28 09:48:05 2007 -0400
@@ -56,6 +56,8 @@ static BlockDriverState *bdrv_first;
 static BlockDriverState *bdrv_first;
 static BlockDriver *first_drv;
 
+static BlockDriver *get_bdrv_raw(void);
+
 int path_is_absolute(const char *path)
 {
     const char *p;
@@ -323,6 +325,7 @@ int bdrv_open2(BlockDriverState *bs, con
 {
     int ret, open_flags;
     char tmp_filename[PATH_MAX];
+    int is_media_inserted;
     char backing_filename[PATH_MAX];
     
     bs->read_only = 0;
@@ -359,6 +362,10 @@ int bdrv_open2(BlockDriverState *bs, con
     }
 
     pstrcpy(bs->filename, sizeof(bs->filename), filename);
+    if (bs->type == BDRV_TYPE_CDROM && !drv && bs->is_shared) {
+        drv = get_bdrv_raw();
+    }else{
+
     if (flags & BDRV_O_FILE) {
         drv = find_protocol(filename);
         if (!drv)
@@ -370,16 +377,27 @@ int bdrv_open2(BlockDriverState *bs, con
                 return -1;
         }
     }
+
+    }
     bs->drv = drv;
     bs->opaque = qemu_mallocz(drv->instance_size);
     if (bs->opaque == NULL && drv->instance_size > 0)
         return -1;
+    is_media_inserted = 1;
     /* Note: for compatibility, we open disk image files as RDWR, and
        RDONLY as fallback */
     if (!(flags & BDRV_O_FILE))
         open_flags = BDRV_O_RDWR;
     else
         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
+
+    if (bs->type == BDRV_TYPE_CDROM && bs->is_shared) {
+        if (!bs->is_owner) {
+            bs->total_sectors = 0;
+            return ENOMEDIUM;
+        }
+    }
+
     ret = drv->bdrv_open(bs, filename, open_flags);
     if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
         ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
@@ -391,6 +409,20 @@ int bdrv_open2(BlockDriverState *bs, con
         bs->drv = NULL;
         return ret;
     }
+
+    if (bs->type == BDRV_TYPE_CDROM && ret < 1) {
+        if (!bs->is_owner) {
+            bs->total_sectors = 0;
+            if (errno == ENOMEDIUM )
+                return ENOMEDIUM;
+            else
+                return -1;
+        }
+    }
+
+    if (bs->type == BDRV_TYPE_CDROM && ret == ENOMEDIUM)
+        is_media_inserted = 0;
+
     if (drv->bdrv_getlength) {
         bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
     }
@@ -413,8 +445,12 @@ int bdrv_open2(BlockDriverState *bs, con
             goto fail;
     }
 
+    if (is_media_inserted)
+        bs->media_changed = 1;
+    else
+        bs->media_changed = 0;
+
     /* call the change callback */
-    bs->media_changed = 1;
     if (bs->change_cb)
         bs->change_cb(bs->change_opaque);
 
@@ -427,19 +463,20 @@ void bdrv_close(BlockDriverState *bs)
         if (bs->backing_hd)
             bdrv_delete(bs->backing_hd);
         bs->drv->bdrv_close(bs);
-        qemu_free(bs->opaque);
+        bs->drv = NULL;
 #ifdef _WIN32
         if (bs->is_temporary) {
             unlink(bs->filename);
         }
 #endif
-        bs->opaque = NULL;
-        bs->drv = NULL;
 
         /* call the change callback */
         bs->media_changed = 1;
         if (bs->change_cb)
             bs->change_cb(bs->change_opaque);
+ 
+        qemu_free(bs->opaque);
+        bs->opaque = NULL;
     }
 }
 
@@ -749,6 +786,28 @@ void bdrv_set_translation_hint(BlockDriv
     bs->translation = translation;
 }
 
+void bdrv_set_shared_owner_hint(BlockDriverState *bs, int is_owner)
+{
+    bs->is_shared = 1;
+    bs->is_owner = is_owner;
+}
+
+void bdrv_change_shared_owner(BlockDriverState *bs, int new_owner_state)
+{
+    if (!bs->is_shared)
+        return;
+
+    if (bs->is_owner == new_owner_state)
+        return;
+
+    bs->is_owner = new_owner_state;
+
+    if (!new_owner_state) {
+        bdrv_close(bs);
+        return;
+    }
+}
+
 void bdrv_get_geometry_hint(BlockDriverState *bs, 
                             int *pcyls, int *pheads, int *psecs)
 {
@@ -765,6 +824,16 @@ int bdrv_get_translation_hint(BlockDrive
 int bdrv_get_translation_hint(BlockDriverState *bs)
 {
     return bs->translation;
+}
+
+int bdrv_is_shared(BlockDriverState *bs)
+{
+    return bs->is_shared;
+}
+
+int bdrv_is_owner(BlockDriverState *bs)
+{
+    return bs->is_owner;
 }
 
 int bdrv_is_removable(BlockDriverState *bs)
@@ -849,6 +918,11 @@ const char *bdrv_get_device_name(BlockDr
 const char *bdrv_get_device_name(BlockDriverState *bs)
 {
     return bs->device_name;
+}
+
+const char *bdrv_get_filename(BlockDriverState *bs)
+{
+    return bs->filename;
 }
 
 void bdrv_flush(BlockDriverState *bs)
@@ -1226,6 +1300,11 @@ static int bdrv_write_em(BlockDriverStat
     return async_ret;
 }
 
+static BlockDriver *get_bdrv_raw(void)
+{
+    return &bdrv_raw ;
+}
+
 void bdrv_init(void)
 {
     bdrv_register(&bdrv_raw);
diff -r 106bc46793ca block_int.h
--- a/block_int.h	Mon Aug 27 16:20:33 2007 -0400
+++ b/block_int.h	Tue Aug 28 09:48:05 2007 -0400
@@ -87,6 +87,8 @@ struct BlockDriverState {
     int removable; /* if true, the media can be removed */
     int locked;    /* if true, the media cannot temporarily be ejected */
     int encrypted; /* if true, the media is encrypted */
+    int is_shared; /* if true, the media is shared across multiple QEMU instances */
+    int is_owner;  /* if true, the media is sharable and currently owned by this QEMU instance */
     /* event callback when inserting/removing */
     void (*change_cb)(void *opaque);
     void *change_opaque;
diff -r 106bc46793ca hw/ide.c
--- a/hw/ide.c	Mon Aug 27 16:20:33 2007 -0400
+++ b/hw/ide.c	Tue Aug 28 09:56:21 2007 -0400
@@ -24,11 +24,25 @@
  */
 #include "vl.h"
 
+#include <linux/cdrom.h>
+#include <linux/fs.h>
+#include <scsi/sg.h>
+#include <scsi/scsi.h>
+#include <sys/ioctl.h>
+
 /* debug IDE devices */
 //#define DEBUG_IDE
 //#define DEBUG_IDE_ATAPI
 //#define DEBUG_AIO
 #define USE_DMA_CDROM
+
+#define DEBUG_CDROM
+#ifdef  DEBUG_CDROM
+#include "exec-all.h"   // for FILE* logfile
+#define DEBUG_CDROM_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
+#else
+#define DEBUG_CDROM_PRINT( formatCstr, args... )
+#endif
 
 /* Bits of HD_STATUS */
 #define ERR_STAT		0x01
@@ -306,6 +320,7 @@ typedef struct IDEState {
 typedef struct IDEState {
     /* ide config */
     int is_cdrom;
+    int is_physical_media_present;
     int is_cf;
     int cylinders, heads, sectors;
     int64_t nb_sectors;
@@ -1054,7 +1069,11 @@ static int cd_read_sector(BlockDriverSta
                            int sector_size)
 {
     int ret;
-
+    if (bdrv_is_shared(bs) && !bdrv_is_owner(bs)) {
+        DEBUG_CDROM_PRINT("CDrom : own : cd_read_sector(%d %ld %d) not owner = ignored | fn: %s devN: %s\n", lba, (long)((int64_t)lba << 2), sector_size, bdrv_get_filename(bs), bdrv_get_device_name(bs));
+        memset(buf, -1, sector_size); // Make sure the data looks bad
+        return;
+    }
     switch(sector_size) {
     case 2048:
         ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
@@ -1295,6 +1314,12 @@ static void ide_atapi_cmd_read(IDEState 
     printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
 	lba, nb_sectors);
 #endif
+    if (s->is_cdrom && bdrv_is_shared(s->bs) && !bdrv_is_owner(s->bs)) {
+        DEBUG_CDROM_PRINT("CDrom : own : ide_atapi_cmd_read() not owner = request denied | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+        ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                            ASC_MEDIUM_NOT_PRESENT);
+        return;
+    }
     if (s->atapi_dma) {
         ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
     } else {
@@ -1302,11 +1327,160 @@ static void ide_atapi_cmd_read(IDEState 
     }
 }
 
+static void unlock_physical_cdrom_door(const char* filename)
+{
+    int status;
+    int cdrom_fd;
+
+	cdrom_fd = open(filename, O_RDONLY | O_NONBLOCK);
+	if (cdrom_fd >= 0) {
+		status = ioctl(cdrom_fd, CDROM_LOCKDOOR, 0); // Always unlock the door regardless of ownership
+		if (status < 0)
+			DEBUG_CDROM_PRINT( "CDrom : %s : ERROR? : could NOT unlock CD door : %s : %d %s\n", __FUNCTION__, filename, errno, strerror(errno));
+		close(cdrom_fd);
+	} else {
+		DEBUG_CDROM_PRINT("CDrom : %s : open(%s) failed : door NOT unlocked : %d %s\n", __FUNCTION__, filename, errno, strerror(errno));
+	}
+}
+
+/* Eject using SCSI SG_IO commands. Return 1 if successful, 0 otherwise. From /usr/bin/eject sources */
+static int perform_physical_cdrom_eject_via_scsi(int fd)
+{
+    int status, k;
+    sg_io_hdr_t io_hdr;
+    unsigned char allowRmBlk[6] = {ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0};
+    unsigned char startStop1Blk[6] = {START_STOP, 0, 0, 0, 1, 0};
+    unsigned char startStop2Blk[6] = {START_STOP, 0, 0, 0, 2, 0};
+    unsigned char inqBuff[2];
+    unsigned char sense_buffer[32];
+
+    if ((ioctl(fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
+        return ENODEV;    // not an sg device, or old sg driver
+    }
+
+    memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+    io_hdr.interface_id = 'S';
+    io_hdr.cmd_len = 6;
+    io_hdr.mx_sb_len = sizeof(sense_buffer);
+    io_hdr.dxfer_direction = SG_DXFER_NONE;
+    io_hdr.dxfer_len = 0;
+    io_hdr.dxferp = inqBuff;
+    io_hdr.sbp = sense_buffer;
+    io_hdr.timeout = 2000;
+
+    io_hdr.cmdp = allowRmBlk;
+    status = ioctl(fd, SG_IO, (void *)&io_hdr);
+    if (status < 0)
+        return ((errno)?errno:status);
+
+    io_hdr.cmdp = startStop1Blk;
+    status = ioctl(fd, SG_IO, (void *)&io_hdr);
+    if (status < 0)
+        return ((errno)?errno:status);
+
+    io_hdr.cmdp = startStop2Blk;
+    status = ioctl(fd, SG_IO, (void *)&io_hdr);
+    if (status < 0)
+        return ((errno)?errno:status);
+
+    /* force kernel to reread partition table when new disc inserted */
+    status = ioctl(fd, BLKRRPART);
+    return 0;
+}
+
+static int perform_physical_cdrom_eject(const char* filename)
+{
+    int status;
+    int cdrom_fd;
+
+    status = 1;
+    cdrom_fd = open(filename, O_RDONLY | O_NONBLOCK);
+    if ( cdrom_fd >= 0 ) {
+        status = ioctl(cdrom_fd, CDROMEJECT, CDSL_CURRENT); // bdrv MUST be closed
+        if (status < 0) { // NOTE: ioctl fails when door is open
+            DEBUG_CDROM_PRINT("CDrom : ej : ioctl(%s, CDROMEJECT,CDSL_CURRENT) failed %d, trying eject_cdrom_via_scsi()\n", filename, errno);
+            status = perform_physical_cdrom_eject_via_scsi(cdrom_fd); // last resort
+        }
+        close(cdrom_fd);
+    }
+
+    return status;
+}
+
+static int is_cdrom_physical_media_present(const char* filename)
+{
+    int status;
+    int cdrom_fd;
+
+    cdrom_fd = open(filename, O_RDONLY | O_NONBLOCK); // O_NONBLOCK ignores ENOMEDIUM
+    if (cdrom_fd >= 0) {
+        status = ioctl(cdrom_fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+        if (status >= 0) {
+            if (status == CDS_DISC_OK) {
+                if (  ioctl(cdrom_fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 0 // trick to
+                   || ioctl(cdrom_fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 0 // verify media
+                   ) {
+                    close(cdrom_fd);
+                    return 1;
+                }
+            }
+        } else {
+            DEBUG_CDROM_PRINT("CDrom : %s : ioctl(%s, CDROM_MEDIA_CHANGED) failed %d %s\n", __FUNCTION__, filename, errno, strerror(errno));
+        }
+    } else {
+        DEBUG_CDROM_PRINT("CDrom : %s : open(%s, O_RDONLY|O_NONBLOCK) failed %d %s\n", __FUNCTION__, filename, errno, strerror(errno));
+    }
+
+    close(cdrom_fd);
+    return 0;
+}
+
+static int ascertain_is_media_present(IDEState *s)
+{
+    int is_physical_media_present_now;
+
+    if (!s->is_cdrom || !bdrv_is_shared(s->bs)) {
+        if (bdrv_is_inserted(s->bs))
+            return 1;
+        return 0;
+    }
+    if (!bdrv_is_owner(s->bs))
+        return 0;
+
+    is_physical_media_present_now = is_cdrom_physical_media_present(bdrv_get_filename(s->bs));
+    if (is_physical_media_present_now) {
+        if (s->is_physical_media_present) {
+//          DEBUG_CDROM_PRINT("CDrom : present : media still inserted | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+            return 1;
+        }
+        s->is_physical_media_present = 1;
+
+        if (!bdrv_is_inserted(s->bs))
+            bdrv_open(s->bs, bdrv_get_filename(s->bs), 0);
+        unlock_physical_cdrom_door(bdrv_get_filename(s->bs));
+
+        DEBUG_CDROM_PRINT("CDrom : present : media inserted | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+        return -1;
+    }
+
+    if (!s->is_physical_media_present) {
+//      DEBUG_CDROM_PRINT("CDrom : present : media is still NOT inserted | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+        return 0;
+    }
+    s->is_physical_media_present = 0;
+
+    bdrv_close(s->bs);
+
+    DEBUG_CDROM_PRINT("CDrom : present : media is NOT inserted | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+    return 0;
+}
+
 static void ide_atapi_cmd(IDEState *s)
 {
     const uint8_t *packet;
     uint8_t *buf;
     int max_len;
+    int is_media_present;
 
     packet = s->io_buffer;
     buf = s->io_buffer;
@@ -1499,7 +1673,16 @@ static void ide_atapi_cmd(IDEState *s)
             
             if (eject && !start) {
                 /* eject the disk */
-                bdrv_eject(s->bs, 1);
+                bdrv_close(s->bs); // close the device ( allows for eject AND flushes system cache )
+                if (bdrv_is_shared(s->bs) && bdrv_is_owner(s->bs)) {
+                    if (perform_physical_cdrom_eject(bdrv_get_filename(s->bs)) == 0) {
+                        s->is_physical_media_present = 0;
+                        DEBUG_CDROM_PRINT("CDrom : ej : sucesss | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+                    } else {
+                        DEBUG_CDROM_PRINT("CDrom : ej : FAILED | fn: %s devN: %s\n", bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+                    }
+                }
+
             } else if (eject && start) {
                 /* close the tray */
                 bdrv_eject(s->bs, 0);
@@ -1662,9 +1845,31 @@ static void cdrom_change_cb(void *opaque
 {
     IDEState *s = opaque;
     int64_t nb_sectors;
+    int cylinders;
+
+    if (bdrv_is_shared(s->bs) && !bdrv_is_owner(s->bs)) {
+        s->is_physical_media_present = 0;
+        return;
+    }
+    if (!bdrv_is_inserted(s->bs))
+        return;
 
     /* XXX: send interrupt too */
     bdrv_get_geometry(s->bs, &nb_sectors);
+
+    /* if no geometry, use a standard physical disk geometry */
+    cylinders = nb_sectors / (16 * 63);
+    if (cylinders > 16383)
+        cylinders = 16383;
+    else if (cylinders < 2)
+        cylinders = 2;
+    s->cylinders = cylinders;
+    s->heads = 16;
+    s->sectors = 63;
+    bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors); // Reset the geometry in case the media changed
+
+    DEBUG_CDROM_PRINT("CDrom : geometry change %ld [ %ld ] %d %d %d | fn: %s devN: %s\n", (long)nb_sectors, (long)s->nb_sectors, s->cylinders, s->heads, s->sectors, bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+
     s->nb_sectors = nb_sectors;
 }
 
@@ -2413,6 +2618,11 @@ static void ide_init2(IDEState *ide_stat
             if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
                 s->is_cdrom = 1;
 		bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
+                if (bdrv_is_shared(s->bs)) {
+                    unlock_physical_cdrom_door(bdrv_get_filename(s->bs));
+                    DEBUG_CDROM_PRINT("CDrom : init : geometry [ %ld ] %d %d %d | fn: %s devN: %s\n", (long)s->nb_sectors, s->cylinders, s->heads, s->sectors, bdrv_get_filename(s->bs), bdrv_get_device_name(s->bs));
+                }
+
             }
         }
         s->drive_serial = drive_serial++;
diff -r 106bc46793ca monitor.c
--- a/monitor.c	Mon Aug 27 16:20:33 2007 -0400
+++ b/monitor.c	Tue Aug 28 09:48:05 2007 -0400
@@ -192,6 +192,40 @@ static void help_cmd(const char *name)
             }
         }
     }
+}
+
+static void do_set_cdrom_owner(const char* new_owner_state_cstr, const char *device)
+{
+    BlockDriverState *bs;
+    int new_owner_state;
+
+    if (!new_owner_state_cstr || !device) {
+        term_printf("[set_cdrom_owner] ERROR : insufficient args (NULL) !?!\n");
+        return;
+    }
+
+    if (sscanf(new_owner_state_cstr, "%d", &new_owner_state) != 1) {
+        term_printf("[set_cdrom_owner] ERROR : bad arg '%s'\n", new_owner_state_cstr);
+        return;
+    }
+
+    if (new_owner_state)    // normalize given input
+        new_owner_state = 1;
+
+    bs = bdrv_find(device);
+    if (!bs) {
+        term_printf("[set_cdrom_owner] ERROR : cdrom device '%s' not found %d\n", device, new_owner_state);
+        return;
+    }
+
+    if (bdrv_is_owner(bs) == new_owner_state) {
+        term_printf("[set_cdrom_owner] IGNORED : no change to ownership %d\n", new_owner_state);
+        return;
+    }
+
+    bdrv_change_shared_owner(bs, new_owner_state);
+
+    term_printf("[set_cdrom_owner] done : (%d)\n", new_owner_state);
 }
 
 static void do_help(const char *name)
@@ -1250,6 +1284,8 @@ static term_cmd_t term_cmds[] = {
       "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" }, 
     { "loadvm", "s", do_loadvm,
       "tag|id", "restore a VM snapshot from its tag or id" }, 
+    { "set_cdrom_owner", "sB", do_set_cdrom_owner,
+      "<1|0> device", "1 to become the owner and acquire the physical drive or 0 to release it and no longer be the owner" },
     { "delvm", "s", do_delvm,
       "tag|id", "delete a VM snapshot from its tag or id" }, 
     { "stop", "", do_stop, 
diff -r 106bc46793ca vl.c
--- a/vl.c	Mon Aug 27 16:20:33 2007 -0400
+++ b/vl.c	Tue Aug 28 09:48:05 2007 -0400
@@ -7110,6 +7110,7 @@ enum {
     QEMU_OPTION_hdc,
     QEMU_OPTION_hdd,
     QEMU_OPTION_cdrom,
+    QEMU_OPTION_cdrom_shared_with_eject,
     QEMU_OPTION_mtdblock,
     QEMU_OPTION_sd,
     QEMU_OPTION_pflash,
@@ -7197,6 +7198,7 @@ const QEMUOption qemu_options[] = {
     { "hdc", HAS_ARG, QEMU_OPTION_hdc },
     { "hdd", HAS_ARG, QEMU_OPTION_hdd },
     { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
+    { "cdrom-shared-with-eject", 0, QEMU_OPTION_cdrom_shared_with_eject },
     { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
     { "sd", HAS_ARG, QEMU_OPTION_sd },
     { "pflash", HAS_ARG, QEMU_OPTION_pflash },
@@ -7778,6 +7780,9 @@ int main(int argc, char **argv)
                     hd_filename[cdrom_index] = optarg;
                 }
                 break;
+            case QEMU_OPTION_cdrom_shared_with_eject:
+               // XXX Temporarily ignore this option
+               break;
             case QEMU_OPTION_boot:
                 boot_device = optarg[0];
                 if (boot_device != 'a' && 
diff -r 106bc46793ca vl.h
--- a/vl.h	Mon Aug 27 16:20:33 2007 -0400
+++ b/vl.h	Tue Aug 28 09:48:05 2007 -0400
@@ -661,10 +661,14 @@ void bdrv_set_geometry_hint(BlockDriverS
                             int cyls, int heads, int secs);
 void bdrv_set_type_hint(BlockDriverState *bs, int type);
 void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
+void bdrv_set_shared_owner_hint(BlockDriverState *bs, int is_owner);
+void bdrv_change_shared_owner(BlockDriverState *bs, int new_owner_state);
 void bdrv_get_geometry_hint(BlockDriverState *bs, 
                             int *pcyls, int *pheads, int *psecs);
 int bdrv_get_type_hint(BlockDriverState *bs);
 int bdrv_get_translation_hint(BlockDriverState *bs);
+int bdrv_is_shared(BlockDriverState *bs);
+int bdrv_is_owner(BlockDriverState *bs);
 int bdrv_is_removable(BlockDriverState *bs);
 int bdrv_is_read_only(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);
@@ -683,6 +687,7 @@ void bdrv_iterate_format(void (*it)(void
 void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 
                          void *opaque);
 const char *bdrv_get_device_name(BlockDriverState *bs);
+const char *bdrv_get_filename(BlockDriverState *bs);
 int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, 
                           const uint8_t *buf, int nb_sectors);
 int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-08-28 14:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-28 14:12 [Qemu-devel] [PATCH] Shared CD-Rom Support Ben Guthro

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.