[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH][QEMU] Shared CD-Rom Support
In response to the cdrom discussion going on today: Attached is a port of a patch we have against 3.1This patch plumbs the cdrom info through QEMU such that a QEMU monitor command may switch the domain owning the physiical 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 CDRom) Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx> Signed-off-by: Joshua Nicholas <jnicholas@xxxxxxxxxxxxxxx> diff -r 7953164cebb6 tools/ioemu/block.c --- a/tools/ioemu/block.c Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/block.c Thu Aug 16 15:49:49 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[1024]; + int is_media_inserted; char backing_filename[1024]; 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; } } @@ -754,6 +791,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) { @@ -770,6 +829,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) @@ -854,6 +923,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) @@ -1231,6 +1305,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 7953164cebb6 tools/ioemu/block_int.h --- a/tools/ioemu/block_int.h Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/block_int.h Thu Aug 16 15:49:49 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 7953164cebb6 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/hw/ide.c Thu Aug 16 15:49:49 2007 -0400 @@ -23,11 +23,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 @@ -295,6 +309,7 @@ typedef struct IDEState { typedef struct IDEState { /* ide config */ int is_cdrom; + int is_physical_media_present; int cylinders, heads, sectors; int64_t nb_sectors; int mult_sectors; @@ -1081,7 +1096,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); @@ -1322,6 +1341,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 { @@ -1329,11 +1354,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; @@ -1349,12 +1523,19 @@ static void ide_atapi_cmd(IDEState *s) #endif switch(s->io_buffer[0]) { case GPCMD_TEST_UNIT_READY: - if (bdrv_is_inserted(s->bs)) { - ide_atapi_cmd_ok(s); + is_media_present = ascertain_is_media_present(s); + if (is_media_present) { + if (is_media_present > 0) + ide_atapi_cmd_ok(s); + else { + DEBUG_CDROM_PRINT("CDrom : present : GPCMD_TEST_UNIT_READY : was_inserted %s : SENSE_UNIT_ATTENTION !\n", bdrv_get_device_name(s->bs)); + ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION, 0); + } } else { ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - xenstore_check_new_media_present(1000); + if (!s->is_cdrom || !bdrv_is_shared(s->bs)) // Prevent timer initiated open() as it closes physical cdrom drive door + xenstore_check_new_media_present(1000); } break; case GPCMD_MODE_SENSE_10: @@ -1527,7 +1708,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); @@ -1637,9 +1827,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; } @@ -2298,6 +2510,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 7953164cebb6 tools/ioemu/monitor.c --- a/tools/ioemu/monitor.c Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/monitor.c Thu Aug 16 15:49:49 2007 -0400 @@ -397,6 +397,40 @@ void do_change(const char *device, const term_printf("invalid password\n"); } } +} + +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_screen_dump(const char *filename) @@ -1217,7 +1251,10 @@ static term_cmd_t term_cmds[] = { "filename", "save screen into PPM image 'filename'" }, { "log", "s", do_log, "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, -#ifndef CONFIG_DM +#ifdef CONFIG_DM + { "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" }, +#else { "savevm", "s?", do_savevm, "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" }, { "loadvm", "s", do_loadvm, diff -r 7953164cebb6 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/vl.c Thu Aug 16 15:49:49 2007 -0400 @@ -6436,6 +6436,7 @@ enum { QEMU_OPTION_hdd, QEMU_OPTION_cdrom, #endif /* !CONFIG_DM */ + QEMU_OPTION_cdrom_shared_with_eject, QEMU_OPTION_boot, QEMU_OPTION_snapshot, #ifdef TARGET_I386 @@ -6519,6 +6520,7 @@ const QEMUOption qemu_options[] = { { "hdd", HAS_ARG, QEMU_OPTION_hdd }, { "cdrom", HAS_ARG, QEMU_OPTION_cdrom }, #endif /* !CONFIG_DM */ + { "cdrom-shared-with-eject", 0, QEMU_OPTION_cdrom_shared_with_eject }, { "boot", HAS_ARG, QEMU_OPTION_boot }, { "snapshot", 0, QEMU_OPTION_snapshot }, #ifdef TARGET_I386 @@ -7279,6 +7281,9 @@ int main(int argc, char **argv) } break; #endif /* !CONFIG_DM */ + case QEMU_OPTION_cdrom_shared_with_eject: + // XXX Temporarily ignore this option + break; case QEMU_OPTION_boot: boot_device = strdup(optarg); if (strspn(boot_device, "a" diff -r 7953164cebb6 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/vl.h Thu Aug 16 15:49:49 2007 -0400 @@ -678,10 +678,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); @@ -700,6 +704,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); diff -r 7953164cebb6 tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Tue Aug 07 09:07:29 2007 +0100 +++ b/tools/ioemu/xenstore.c Thu Aug 16 15:56:02 2007 -0400 @@ -85,6 +85,7 @@ void xenstore_parse_domain_config(int do *dev = NULL, *params = NULL, *type = NULL; int i, is_scsi; unsigned int len, num, hd_index; + int is_cdrom_shared_with_eject, is_cdrom_owner; for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) media_filename[i] = NULL; @@ -166,10 +167,29 @@ void xenstore_parse_domain_config(int do bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev); /* check if it is a cdrom */ - if (type && !strcmp(type, "cdrom")) { + if (type && !strcmp(type, "cdrom")) { + is_cdrom_shared_with_eject = is_cdrom_owner = 0; + /* read the cdrom param is_cdrom_shared_with_eject (if any) */ + if (pasprintf(&buf, "%s/device/vbd/%s/cdrom-shared-witheject", path, e[i]) == -1) + continue; + free(type); + type = xs_read(xsh, XBT_NULL, buf, &len); + if (type != NULL) + is_cdrom_shared_with_eject = (atoi(type))?1:0; + /* read the cdrom param is_cdrom_shared_with_eject (if any) */ + if (pasprintf(&buf, "%s/device/vbd/%s/cdrom-owner", path, e[i]) == -1) + continue; + free(type); + type = xs_read(xsh, XBT_NULL, buf, &len); + if (type != NULL) + is_cdrom_owner = (atoi(type))?1:0; + /* indicate that this device is a cdrom */ bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM); - if (pasprintf(&buf, "%s/params", bpath) != -1) - xs_watch(xsh, buf, dev); + if (is_cdrom_shared_with_eject) + bdrv_set_shared_owner_hint(bs_table[hd_index], is_cdrom_owner); + + if (pasprintf(&buf, "%s/params", bpath) != -1) + xs_watch(xsh, buf, dev); } /* open device now if media present */ if (params[0]) { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |