From 3a395142ba99197429a2378930d3c1551fc053cc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 18 Nov 2011 16:31:59 +0100 Subject: virtio-blk: fix cross-endian config space Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- hw/virtio-blk.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 19e89e7..d6d1f87 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -485,6 +485,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) struct virtio_blk_config blkcfg; uint64_t capacity; int cylinders, heads, secs; + int blk_size = s->conf->logical_block_size; bdrv_get_geometry(s->bs, &capacity); bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs); @@ -492,14 +493,14 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config) stq_raw(&blkcfg.capacity, capacity); stl_raw(&blkcfg.seg_max, 128 - 2); stw_raw(&blkcfg.cylinders, cylinders); + stl_raw(&blkcfg.blk_size, blk_size); + stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size); + stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size); blkcfg.heads = heads; blkcfg.sectors = secs & ~s->sector_mask; - blkcfg.blk_size = s->conf->logical_block_size; blkcfg.size_max = 0; blkcfg.physical_block_exp = get_physical_block_exp(s->conf); blkcfg.alignment_offset = 0; - blkcfg.min_io_size = s->conf->min_io_size / blkcfg.blk_size; - blkcfg.opt_io_size = s->conf->opt_io_size / blkcfg.blk_size; memcpy(config, &blkcfg, sizeof(struct virtio_blk_config)); } -- cgit v1.1 From ce4e7e4661af433674f349ccdd5709b4b7a8b2fd Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 18 Nov 2011 16:32:00 +0100 Subject: usb-msd: do not register twice in the boot order USB mass storage devices are registered twice in the boot order. To avoid having to keep the two paths in sync, pass the bootindex property down to the scsi-disk device and let it register itself. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- hw/pci-hotplug.c | 3 ++- hw/scsi-bus.c | 7 +++++-- hw/scsi.h | 2 +- hw/usb-msd.c | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index b59be2a..12f61fe 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -91,7 +91,8 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, */ dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); dinfo->bus = scsibus->busnr; - scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit, false); + scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit, + false, -1); if (!scsidev) { return -1; } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 3a2a7bb..2feeaa2 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -162,7 +162,7 @@ void scsi_qdev_register(SCSIDeviceInfo *info) /* handle legacy '-drive if=scsi,...' cmd line args */ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, - int unit, bool removable) + int unit, bool removable, int bootindex) { const char *driver; DeviceState *dev; @@ -170,6 +170,9 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk"; dev = qdev_create(&bus->qbus, driver); qdev_prop_set_uint32(dev, "scsi-id", unit); + if (bootindex >= 0) { + qdev_prop_set_int32(dev, "bootindex", bootindex); + } if (qdev_prop_exists(dev, "removable")) { qdev_prop_set_bit(dev, "removable", removable); } @@ -195,7 +198,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus) continue; } qemu_opts_loc_restore(dinfo->opts); - if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false)) { + if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1)) { res = -1; break; } diff --git a/hw/scsi.h b/hw/scsi.h index 61c64d5..ab6e952 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -128,7 +128,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) } SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, - int unit, bool removable); + int unit, bool removable, int bootindex); int scsi_bus_legacy_handle_cmdline(SCSIBus *bus); /* diff --git a/hw/usb-msd.c b/hw/usb-msd.c index 68e3756..4c06950 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -546,7 +546,8 @@ static int usb_msd_initfn(USBDevice *dev) usb_desc_init(dev); scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info); - s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable); + s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable, + s->conf.bootindex); if (!s->scsi_dev) { return -1; } @@ -562,7 +563,6 @@ static int usb_msd_initfn(USBDevice *dev) } } - add_boot_device_path(s->conf.bootindex, &dev->qdev, "/disk@0,0"); return 0; } -- cgit v1.1 From 795928f61daff10b06bb21e837bc5bf0227cf076 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 18 Nov 2011 17:03:45 +0100 Subject: scsi: fix fw path The pre-1.0 firmware path for SCSI devices already included the LUN using the suffix argument to add_boot_device_path. Avoid that it is included twice, and convert the colons to commas for consistency with other kinds of devices Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- hw/scsi-bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 2feeaa2..64e709e 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -1370,8 +1370,8 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev); char path[100]; - snprintf(path, sizeof(path), "%s@%d,%d,%d", qdev_fw_name(dev), - d->channel, d->id, d->lun); + snprintf(path, sizeof(path), "channel@%x/%s@%x,%x", d->channel, + qdev_fw_name(dev), d->id, d->lun); return strdup(path); } -- cgit v1.1 From 28b77657cfb44cdcc379997340701d73432b9007 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 18 Nov 2011 16:32:02 +0100 Subject: scsi-generic: add as boot device There is no reason why a scsi-generic device cannot boot if it has the right type, and indeed it provides already a bootindex property. So register those devices too. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- hw/scsi-generic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 9594cc1..e62044f 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -413,6 +413,10 @@ static int scsi_generic_initfn(SCSIDevice *s) /* define device state */ s->type = scsiid.scsi_type; DPRINTF("device type %d\n", s->type); + if (s->type == TYPE_DISK || s->type == TYPE_ROM) { + add_boot_device_path(s->conf.bootindex, &s->qdev, NULL); + } + switch (s->type) { case TYPE_TAPE: s->blocksize = get_stream_blocksize(s->conf.bs); @@ -459,6 +463,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, static SCSIDeviceInfo scsi_generic_info = { .qdev.name = "scsi-generic", + .qdev.fw_name = "disk", .qdev.desc = "pass through generic scsi device (/dev/sg*)", .qdev.size = sizeof(SCSIDevice), .qdev.reset = scsi_generic_reset, -- cgit v1.1 From c3fecea50dc0f27198b8658a0c9c4fbfdd0f95db Mon Sep 17 00:00:00 2001 From: Dong Xu Wang Date: Tue, 22 Nov 2011 10:56:58 +0800 Subject: sheepdog: Avoid deadlock in error path s->lock should be unlocked before leaving add_aio_request. Signed-off-by: Dong Xu Wang Signed-off-by: Kevin Wolf --- block/sheepdog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/sheepdog.c b/block/sheepdog.c index 9f80609..62f1f3a 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1116,6 +1116,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, /* send a header */ ret = do_write(s->fd, &hdr, sizeof(hdr)); if (ret) { + qemu_co_mutex_unlock(&s->lock); error_report("failed to send a req, %s", strerror(errno)); return -EIO; } @@ -1123,6 +1124,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, if (wlen) { ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset); if (ret) { + qemu_co_mutex_unlock(&s->lock); error_report("failed to send a data, %s", strerror(errno)); return -EIO; } -- cgit v1.1 From fd9f102c3e38ac606ef8ee2a5ba0130f7c87422f Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:44:45 +0100 Subject: qcow: Add migration blocker qcow caches L2 tables. For migration to work, they would have to be invalidated. Block migration for now. Signed-off-by: Kevin Wolf --- block/qcow.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/qcow.c b/block/qcow.c index adecee0..4814ed0 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -26,6 +26,7 @@ #include "module.h" #include #include "aes.h" +#include "migration.h" /**************************************************************/ /* QEMU COW block driver with compression and encryption support */ @@ -74,6 +75,7 @@ typedef struct BDRVQcowState { AES_KEY aes_encrypt_key; AES_KEY aes_decrypt_key; CoMutex lock; + Error *migration_blocker; } BDRVQcowState; static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); @@ -160,6 +162,12 @@ static int qcow_open(BlockDriverState *bs, int flags) bs->backing_file[len] = '\0'; } + /* Disable migration when qcow images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "qcow", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + qemu_co_mutex_init(&s->lock); return 0; @@ -604,10 +612,14 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, static void qcow_close(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; + g_free(s->l1_table); g_free(s->l2_cache); g_free(s->cluster_cache); g_free(s->cluster_data); + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static int qcow_create(const char *filename, QEMUOptionParameter *options) -- cgit v1.1 From fc9d106c8dfe1c4afe0e127dfcd2764e63f0efb0 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:46:26 +0100 Subject: vdi: Add migration blocker vdi caches the block map. For migration to work, it would have to be invalidated. Block migration for now. Signed-off-by: Kevin Wolf --- block/vdi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/vdi.c b/block/vdi.c index 684a4a8..7dda522 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -52,6 +52,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" #if defined(CONFIG_UUID) #include @@ -203,6 +204,8 @@ typedef struct { uint32_t bmap_sector; /* VDI header (converted to host endianness). */ VdiHeader header; + + Error *migration_blocker; } BDRVVdiState; /* Change UUID from little endian (IPRT = VirtualBox format) to big endian @@ -454,6 +457,12 @@ static int vdi_open(BlockDriverState *bs, int flags) goto fail_free_bmap; } + /* Disable migration when vdi images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vdi", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + return 0; fail_free_bmap: @@ -939,6 +948,9 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) static void vdi_close(BlockDriverState *bs) { + BDRVVdiState *s = bs->opaque; + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static coroutine_fn int vdi_co_flush(BlockDriverState *bs) -- cgit v1.1 From 2bc3166c22aeeb5cd7b8f21104f4744f08c7a288 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:50:27 +0100 Subject: vmdk: Add migration blocker VMDK caches L2 tables. For migration to work, they would have to be invalidated. Block migration for now. Signed-off-by: Kevin Wolf --- block/vmdk.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/block/vmdk.c b/block/vmdk.c index 96f7d5d..f544159 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -26,6 +26,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" #include #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') @@ -97,6 +98,7 @@ typedef struct BDRVVmdkState { int num_extents; /* Extent array with num_extents entries, ascend ordered by address */ VmdkExtent *extents; + Error *migration_blocker; } BDRVVmdkState; typedef struct VmdkMetaData { @@ -659,7 +661,14 @@ static int vmdk_open(BlockDriverState *bs, int flags) } s->parent_cid = vmdk_read_cid(bs, 1); qemu_co_mutex_init(&s->lock); - return ret; + + /* Disable migration when VMDK images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vmdk", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + + return 0; fail: vmdk_free_extents(bs); @@ -1504,7 +1513,12 @@ exit: static void vmdk_close(BlockDriverState *bs) { + BDRVVmdkState *s = bs->opaque; + vmdk_free_extents(bs); + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static coroutine_fn int vmdk_co_flush(BlockDriverState *bs) -- cgit v1.1 From 612ff3d8876a6df0484aa6ebb5cae4575f7514c5 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:51:12 +0100 Subject: vpc: Add migration blocker vpc caches the BAT. For migration to work, it would have to be invalidated. Block migration for now. Signed-off-by: Kevin Wolf --- block/vpc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/block/vpc.c b/block/vpc.c index 39a3247..75d7d4a 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -25,6 +25,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" /**************************************************************/ @@ -128,6 +129,8 @@ typedef struct BDRVVPCState { uint64_t last_bitmap; #endif + + Error *migration_blocker; } BDRVVPCState; static uint32_t vpc_checksum(uint8_t* buf, size_t size) @@ -228,6 +231,13 @@ static int vpc_open(BlockDriverState *bs, int flags) #endif qemu_co_mutex_init(&s->lock); + + /* Disable migration when VHD images are used */ + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vpc", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + return 0; fail: return err; @@ -651,6 +661,9 @@ static void vpc_close(BlockDriverState *bs) #ifdef CACHE g_free(s->pageentry_u8); #endif + + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); } static QEMUOptionParameter vpc_create_options[] = { -- cgit v1.1 From 3397f0cb483b40785678d2328da584c8a35c358c Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:52:13 +0100 Subject: vvfat: Add migration blocker vvfat caches more or less everything when in writable mode. For migration to work, it would have to be invalidated. Block migration for now when in writable mode (default is readonly). Signed-off-by: Kevin Wolf --- block/vvfat.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/block/vvfat.c b/block/vvfat.c index 131680f..a310ce8 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -27,6 +27,7 @@ #include "qemu-common.h" #include "block_int.h" #include "module.h" +#include "migration.h" #ifndef S_IWGRP #define S_IWGRP 0 @@ -350,6 +351,8 @@ typedef struct BDRVVVFATState { array_t commits; const char* path; int downcase_short_names; + + Error *migration_blocker; } BDRVVVFATState; /* take the sector position spos and convert it to Cylinder/Head/Sector position @@ -1073,6 +1076,15 @@ DLOG(if (stderr == NULL) { // assert(is_consistent(s)); qemu_co_mutex_init(&s->lock); + + /* Disable migration when vvfat is used rw */ + if (s->qcow) { + error_set(&s->migration_blocker, + QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + "vvfat (rw)", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + } + return 0; } @@ -2829,6 +2841,11 @@ static void vvfat_close(BlockDriverState *bs) array_free(&(s->directory)); array_free(&(s->mapping)); g_free(s->cluster_buffer); + + if (s->qcow) { + migrate_del_blocker(s->migration_blocker); + error_free(s->migration_blocker); + } } static BlockDriver bdrv_vvfat = { -- cgit v1.1 From 6ac5f3881fd9880f55e30c5f5bd9984d9d47fd62 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 22 Nov 2011 16:57:34 +0100 Subject: vdi: Fix memory leak The block map is allocated in vdi_open, but was never freed. Signed-off-by: Kevin Wolf --- block/vdi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/vdi.c b/block/vdi.c index 7dda522..02da6b4 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -949,6 +949,9 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) static void vdi_close(BlockDriverState *bs) { BDRVVdiState *s = bs->opaque; + + g_free(s->bmap); + migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); } -- cgit v1.1 From 5bb1cbac4fdb1ca28f33c8d68538d03e3db7c160 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 23 Nov 2011 11:38:01 +0100 Subject: vpc: Add missing error handling in alloc_block Signed-off-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi --- block/vpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block/vpc.c b/block/vpc.c index 75d7d4a..89a5ee2 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -362,8 +362,11 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num) // Initialize the block's bitmap memset(bitmap, 0xff, s->bitmap_size); - bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap, + ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap, s->bitmap_size); + if (ret < 0) { + return ret; + } // Write new footer (the old one will be overwritten) s->free_data_block_offset += s->block_size + s->bitmap_size; -- cgit v1.1