Merge remote-tracking branch 'kwolf/block-stable' into staging

This commit is contained in:
Anthony Liguori 2011-11-28 11:15:10 -06:00
commit 13bd0b5026
12 changed files with 99 additions and 13 deletions

View File

@ -26,6 +26,7 @@
#include "module.h" #include "module.h"
#include <zlib.h> #include <zlib.h>
#include "aes.h" #include "aes.h"
#include "migration.h"
/**************************************************************/ /**************************************************************/
/* QEMU COW block driver with compression and encryption support */ /* QEMU COW block driver with compression and encryption support */
@ -74,6 +75,7 @@ typedef struct BDRVQcowState {
AES_KEY aes_encrypt_key; AES_KEY aes_encrypt_key;
AES_KEY aes_decrypt_key; AES_KEY aes_decrypt_key;
CoMutex lock; CoMutex lock;
Error *migration_blocker;
} BDRVQcowState; } BDRVQcowState;
static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); 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'; 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); qemu_co_mutex_init(&s->lock);
return 0; return 0;
@ -604,10 +612,14 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
static void qcow_close(BlockDriverState *bs) static void qcow_close(BlockDriverState *bs)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
g_free(s->l1_table); g_free(s->l1_table);
g_free(s->l2_cache); g_free(s->l2_cache);
g_free(s->cluster_cache); g_free(s->cluster_cache);
g_free(s->cluster_data); 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) static int qcow_create(const char *filename, QEMUOptionParameter *options)

View File

@ -1116,6 +1116,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
/* send a header */ /* send a header */
ret = do_write(s->fd, &hdr, sizeof(hdr)); ret = do_write(s->fd, &hdr, sizeof(hdr));
if (ret) { if (ret) {
qemu_co_mutex_unlock(&s->lock);
error_report("failed to send a req, %s", strerror(errno)); error_report("failed to send a req, %s", strerror(errno));
return -EIO; return -EIO;
} }
@ -1123,6 +1124,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
if (wlen) { if (wlen) {
ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset); ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset);
if (ret) { if (ret) {
qemu_co_mutex_unlock(&s->lock);
error_report("failed to send a data, %s", strerror(errno)); error_report("failed to send a data, %s", strerror(errno));
return -EIO; return -EIO;
} }

View File

@ -52,6 +52,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "block_int.h" #include "block_int.h"
#include "module.h" #include "module.h"
#include "migration.h"
#if defined(CONFIG_UUID) #if defined(CONFIG_UUID)
#include <uuid/uuid.h> #include <uuid/uuid.h>
@ -203,6 +204,8 @@ typedef struct {
uint32_t bmap_sector; uint32_t bmap_sector;
/* VDI header (converted to host endianness). */ /* VDI header (converted to host endianness). */
VdiHeader header; VdiHeader header;
Error *migration_blocker;
} BDRVVdiState; } BDRVVdiState;
/* Change UUID from little endian (IPRT = VirtualBox format) to big endian /* 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; 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; return 0;
fail_free_bmap: fail_free_bmap:
@ -939,6 +948,12 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
static void vdi_close(BlockDriverState *bs) 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);
} }
static coroutine_fn int vdi_co_flush(BlockDriverState *bs) static coroutine_fn int vdi_co_flush(BlockDriverState *bs)

View File

@ -26,6 +26,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "block_int.h" #include "block_int.h"
#include "module.h" #include "module.h"
#include "migration.h"
#include <zlib.h> #include <zlib.h>
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
@ -97,6 +98,7 @@ typedef struct BDRVVmdkState {
int num_extents; int num_extents;
/* Extent array with num_extents entries, ascend ordered by address */ /* Extent array with num_extents entries, ascend ordered by address */
VmdkExtent *extents; VmdkExtent *extents;
Error *migration_blocker;
} BDRVVmdkState; } BDRVVmdkState;
typedef struct VmdkMetaData { typedef struct VmdkMetaData {
@ -659,7 +661,14 @@ static int vmdk_open(BlockDriverState *bs, int flags)
} }
s->parent_cid = vmdk_read_cid(bs, 1); s->parent_cid = vmdk_read_cid(bs, 1);
qemu_co_mutex_init(&s->lock); 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: fail:
vmdk_free_extents(bs); vmdk_free_extents(bs);
@ -1504,7 +1513,12 @@ exit:
static void vmdk_close(BlockDriverState *bs) static void vmdk_close(BlockDriverState *bs)
{ {
BDRVVmdkState *s = bs->opaque;
vmdk_free_extents(bs); vmdk_free_extents(bs);
migrate_del_blocker(s->migration_blocker);
error_free(s->migration_blocker);
} }
static coroutine_fn int vmdk_co_flush(BlockDriverState *bs) static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)

View File

@ -25,6 +25,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "block_int.h" #include "block_int.h"
#include "module.h" #include "module.h"
#include "migration.h"
/**************************************************************/ /**************************************************************/
@ -128,6 +129,8 @@ typedef struct BDRVVPCState {
uint64_t last_bitmap; uint64_t last_bitmap;
#endif #endif
Error *migration_blocker;
} BDRVVPCState; } BDRVVPCState;
static uint32_t vpc_checksum(uint8_t* buf, size_t size) static uint32_t vpc_checksum(uint8_t* buf, size_t size)
@ -228,6 +231,13 @@ static int vpc_open(BlockDriverState *bs, int flags)
#endif #endif
qemu_co_mutex_init(&s->lock); 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; return 0;
fail: fail:
return err; return err;
@ -352,8 +362,11 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
// Initialize the block's bitmap // Initialize the block's bitmap
memset(bitmap, 0xff, s->bitmap_size); 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); s->bitmap_size);
if (ret < 0) {
return ret;
}
// Write new footer (the old one will be overwritten) // Write new footer (the old one will be overwritten)
s->free_data_block_offset += s->block_size + s->bitmap_size; s->free_data_block_offset += s->block_size + s->bitmap_size;
@ -651,6 +664,9 @@ static void vpc_close(BlockDriverState *bs)
#ifdef CACHE #ifdef CACHE
g_free(s->pageentry_u8); g_free(s->pageentry_u8);
#endif #endif
migrate_del_blocker(s->migration_blocker);
error_free(s->migration_blocker);
} }
static QEMUOptionParameter vpc_create_options[] = { static QEMUOptionParameter vpc_create_options[] = {

View File

@ -27,6 +27,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "block_int.h" #include "block_int.h"
#include "module.h" #include "module.h"
#include "migration.h"
#ifndef S_IWGRP #ifndef S_IWGRP
#define S_IWGRP 0 #define S_IWGRP 0
@ -350,6 +351,8 @@ typedef struct BDRVVVFATState {
array_t commits; array_t commits;
const char* path; const char* path;
int downcase_short_names; int downcase_short_names;
Error *migration_blocker;
} BDRVVVFATState; } BDRVVVFATState;
/* take the sector position spos and convert it to Cylinder/Head/Sector position /* 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)); // assert(is_consistent(s));
qemu_co_mutex_init(&s->lock); 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; return 0;
} }
@ -2829,6 +2841,11 @@ static void vvfat_close(BlockDriverState *bs)
array_free(&(s->directory)); array_free(&(s->directory));
array_free(&(s->mapping)); array_free(&(s->mapping));
g_free(s->cluster_buffer); g_free(s->cluster_buffer);
if (s->qcow) {
migrate_del_blocker(s->migration_blocker);
error_free(s->migration_blocker);
}
} }
static BlockDriver bdrv_vvfat = { static BlockDriver bdrv_vvfat = {

View File

@ -91,7 +91,8 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
*/ */
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
dinfo->bus = scsibus->busnr; 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) { if (!scsidev) {
return -1; return -1;
} }

View File

@ -162,7 +162,7 @@ void scsi_qdev_register(SCSIDeviceInfo *info)
/* handle legacy '-drive if=scsi,...' cmd line args */ /* handle legacy '-drive if=scsi,...' cmd line args */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
int unit, bool removable) int unit, bool removable, int bootindex)
{ {
const char *driver; const char *driver;
DeviceState *dev; 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"; driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";
dev = qdev_create(&bus->qbus, driver); dev = qdev_create(&bus->qbus, driver);
qdev_prop_set_uint32(dev, "scsi-id", unit); qdev_prop_set_uint32(dev, "scsi-id", unit);
if (bootindex >= 0) {
qdev_prop_set_int32(dev, "bootindex", bootindex);
}
if (qdev_prop_exists(dev, "removable")) { if (qdev_prop_exists(dev, "removable")) {
qdev_prop_set_bit(dev, "removable", removable); qdev_prop_set_bit(dev, "removable", removable);
} }
@ -195,7 +198,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
continue; continue;
} }
qemu_opts_loc_restore(dinfo->opts); 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; res = -1;
break; break;
} }
@ -1367,8 +1370,8 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev); SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
char path[100]; char path[100];
snprintf(path, sizeof(path), "%s@%d,%d,%d", qdev_fw_name(dev), snprintf(path, sizeof(path), "channel@%x/%s@%x,%x", d->channel,
d->channel, d->id, d->lun); qdev_fw_name(dev), d->id, d->lun);
return strdup(path); return strdup(path);
} }

View File

@ -413,6 +413,10 @@ static int scsi_generic_initfn(SCSIDevice *s)
/* define device state */ /* define device state */
s->type = scsiid.scsi_type; s->type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->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) { switch (s->type) {
case TYPE_TAPE: case TYPE_TAPE:
s->blocksize = get_stream_blocksize(s->conf.bs); 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 = { static SCSIDeviceInfo scsi_generic_info = {
.qdev.name = "scsi-generic", .qdev.name = "scsi-generic",
.qdev.fw_name = "disk",
.qdev.desc = "pass through generic scsi device (/dev/sg*)", .qdev.desc = "pass through generic scsi device (/dev/sg*)",
.qdev.size = sizeof(SCSIDevice), .qdev.size = sizeof(SCSIDevice),
.qdev.reset = scsi_generic_reset, .qdev.reset = scsi_generic_reset,

View File

@ -128,7 +128,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
} }
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, 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); int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
/* /*

View File

@ -546,7 +546,8 @@ static int usb_msd_initfn(USBDevice *dev)
usb_desc_init(dev); usb_desc_init(dev);
scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info); 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) { if (!s->scsi_dev) {
return -1; 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; return 0;
} }

View File

@ -485,6 +485,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
struct virtio_blk_config blkcfg; struct virtio_blk_config blkcfg;
uint64_t capacity; uint64_t capacity;
int cylinders, heads, secs; int cylinders, heads, secs;
int blk_size = s->conf->logical_block_size;
bdrv_get_geometry(s->bs, &capacity); bdrv_get_geometry(s->bs, &capacity);
bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs); 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); stq_raw(&blkcfg.capacity, capacity);
stl_raw(&blkcfg.seg_max, 128 - 2); stl_raw(&blkcfg.seg_max, 128 - 2);
stw_raw(&blkcfg.cylinders, cylinders); 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.heads = heads;
blkcfg.sectors = secs & ~s->sector_mask; blkcfg.sectors = secs & ~s->sector_mask;
blkcfg.blk_size = s->conf->logical_block_size;
blkcfg.size_max = 0; blkcfg.size_max = 0;
blkcfg.physical_block_exp = get_physical_block_exp(s->conf); blkcfg.physical_block_exp = get_physical_block_exp(s->conf);
blkcfg.alignment_offset = 0; 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)); memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
} }