mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches: - vmdk: Support for blockdev-create - block: Apply auto-read-only for ro-whitelist drivers - virtio-scsi: Fixes related to attaching/detaching iothreads - scsi-disk: Fixed erroneously detected multipath setup with multiple disks created with node-names. Added device_id property. - block: Fix hangs in synchronous APIs with iothreads - block: Fix invalidate_cache error path for parent activation - block-backend, mirror, qcow2, vpc, vdi, qemu-iotests: Minor fixes and code improvements # gpg: Signature made Fri 01 Feb 2019 15:23:10 GMT # gpg: using RSA key 7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (27 commits) scsi-disk: Add device_id property scsi-disk: Don't use empty string as device id qtest.py: Wait for the result of qtest commands block: Fix invalidate_cache error path for parent activation iotests/236: fix transaction kwarg order iotests: Filter second BLOCK_JOB_ERROR from 229 virtio-scsi: Forbid devices with different iothreads sharing a blockdev scsi-disk: Acquire the AioContext in scsi_*_realize() virtio-scsi: Move BlockBackend back to the main AioContext on unplug block: Eliminate the S_1KiB, S_2KiB, ... macros block: Remove blk_attach_dev_legacy() / legacy_dev code block: Apply auto-read-only for ro-whitelist drivers uuid: Make qemu_uuid_bswap() take and return a QemuUUID block/vdi: Don't take address of fields in packed structs block/vpc: Don't take address of fields in packed structs vmdk: Reject excess extents in blockdev-create iotests: Add VMDK tests for blockdev-create iotests: Filter cid numbers in VMDK extent info vmdk: Implement .bdrv_co_create callback vmdk: Refactor vmdk_create_extent ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -1438,13 +1438,19 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
|
||||
bs->read_only = !(bs->open_flags & BDRV_O_RDWR);
|
||||
|
||||
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {
|
||||
error_setg(errp,
|
||||
!bs->read_only && bdrv_is_whitelisted(drv, true)
|
||||
? "Driver '%s' can only be used for read-only devices"
|
||||
: "Driver '%s' is not whitelisted",
|
||||
drv->format_name);
|
||||
ret = -ENOTSUP;
|
||||
goto fail_opts;
|
||||
if (!bs->read_only && bdrv_is_whitelisted(drv, true)) {
|
||||
ret = bdrv_apply_auto_read_only(bs, NULL, NULL);
|
||||
} else {
|
||||
ret = -ENOTSUP;
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_setg(errp,
|
||||
!bs->read_only && bdrv_is_whitelisted(drv, true)
|
||||
? "Driver '%s' can only be used for read-only devices"
|
||||
: "Driver '%s' is not whitelisted",
|
||||
drv->format_name);
|
||||
goto fail_opts;
|
||||
}
|
||||
}
|
||||
|
||||
/* bdrv_new() and bdrv_close() make it so */
|
||||
@@ -3725,6 +3731,7 @@ static void bdrv_check_co_entry(void *opaque)
|
||||
{
|
||||
CheckCo *cco = opaque;
|
||||
cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int bdrv_check(BlockDriverState *bs,
|
||||
@@ -3743,7 +3750,7 @@ int bdrv_check(BlockDriverState *bs,
|
||||
bdrv_check_co_entry(&cco);
|
||||
} else {
|
||||
co = qemu_coroutine_create(bdrv_check_co_entry, &cco);
|
||||
qemu_coroutine_enter(co);
|
||||
bdrv_coroutine_enter(bs, co);
|
||||
BDRV_POLL_WHILE(bs, cco.ret == -EINPROGRESS);
|
||||
}
|
||||
|
||||
@@ -4690,6 +4697,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
|
||||
if (parent->role->activate) {
|
||||
parent->role->activate(parent, &local_err);
|
||||
if (local_err) {
|
||||
bs->open_flags |= BDRV_O_INACTIVE;
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
@@ -4708,6 +4716,7 @@ static void coroutine_fn bdrv_invalidate_cache_co_entry(void *opaque)
|
||||
InvalidateCacheCo *ico = opaque;
|
||||
bdrv_co_invalidate_cache(ico->bs, ico->errp);
|
||||
ico->done = true;
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||
@@ -4724,7 +4733,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||
bdrv_invalidate_cache_co_entry(&ico);
|
||||
} else {
|
||||
co = qemu_coroutine_create(bdrv_invalidate_cache_co_entry, &ico);
|
||||
qemu_coroutine_enter(co);
|
||||
bdrv_coroutine_enter(bs, co);
|
||||
BDRV_POLL_WHILE(bs, !ico.done);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,10 +295,9 @@ static void blk_log_writes_refresh_filename(BlockDriverState *bs,
|
||||
qdict_put_str(opts, "driver", "blklogwrites");
|
||||
|
||||
qobject_ref(bs->file->bs->full_open_options);
|
||||
qdict_put_obj(opts, "file", QOBJECT(bs->file->bs->full_open_options));
|
||||
qdict_put(opts, "file", bs->file->bs->full_open_options);
|
||||
qobject_ref(s->log_file->bs->full_open_options);
|
||||
qdict_put_obj(opts, "log",
|
||||
QOBJECT(s->log_file->bs->full_open_options));
|
||||
qdict_put(opts, "log", s->log_file->bs->full_open_options);
|
||||
qdict_put_int(opts, "log-sector-size", s->sectorsize);
|
||||
|
||||
bs->full_open_options = opts;
|
||||
|
||||
+14
-45
@@ -47,9 +47,7 @@ struct BlockBackend {
|
||||
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
|
||||
BlockBackendPublic public;
|
||||
|
||||
void *dev; /* attached device model, if any */
|
||||
bool legacy_dev; /* true if dev is not a DeviceState */
|
||||
/* TODO change to DeviceState when all users are qdevified */
|
||||
DeviceState *dev; /* attached device model, if any */
|
||||
const BlockDevOps *dev_ops;
|
||||
void *dev_opaque;
|
||||
|
||||
@@ -836,7 +834,11 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
|
||||
*shared_perm = blk->shared_perm;
|
||||
}
|
||||
|
||||
static int blk_do_attach_dev(BlockBackend *blk, void *dev)
|
||||
/*
|
||||
* Attach device model @dev to @blk.
|
||||
* Return 0 on success, -EBUSY when a device model is attached already.
|
||||
*/
|
||||
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
|
||||
{
|
||||
if (blk->dev) {
|
||||
return -EBUSY;
|
||||
@@ -851,40 +853,16 @@ static int blk_do_attach_dev(BlockBackend *blk, void *dev)
|
||||
|
||||
blk_ref(blk);
|
||||
blk->dev = dev;
|
||||
blk->legacy_dev = false;
|
||||
blk_iostatus_reset(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach device model @dev to @blk.
|
||||
* Return 0 on success, -EBUSY when a device model is attached already.
|
||||
*/
|
||||
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
|
||||
{
|
||||
return blk_do_attach_dev(blk, dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach device model @dev to @blk.
|
||||
* @blk must not have a device model attached already.
|
||||
* TODO qdevified devices don't use this, remove when devices are qdevified
|
||||
*/
|
||||
void blk_attach_dev_legacy(BlockBackend *blk, void *dev)
|
||||
{
|
||||
if (blk_do_attach_dev(blk, dev) < 0) {
|
||||
abort();
|
||||
}
|
||||
blk->legacy_dev = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach device model @dev from @blk.
|
||||
* @dev must be currently attached to @blk.
|
||||
*/
|
||||
void blk_detach_dev(BlockBackend *blk, void *dev)
|
||||
/* TODO change to DeviceState *dev when all users are qdevified */
|
||||
void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
|
||||
{
|
||||
assert(blk->dev == dev);
|
||||
blk->dev = NULL;
|
||||
@@ -898,8 +876,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
|
||||
/*
|
||||
* Return the device model attached to @blk if any, else null.
|
||||
*/
|
||||
void *blk_get_attached_dev(BlockBackend *blk)
|
||||
/* TODO change to return DeviceState * when all users are qdevified */
|
||||
DeviceState *blk_get_attached_dev(BlockBackend *blk)
|
||||
{
|
||||
return blk->dev;
|
||||
}
|
||||
@@ -908,10 +885,7 @@ void *blk_get_attached_dev(BlockBackend *blk)
|
||||
* device attached to the BlockBackend. */
|
||||
char *blk_get_attached_dev_id(BlockBackend *blk)
|
||||
{
|
||||
DeviceState *dev;
|
||||
|
||||
assert(!blk->legacy_dev);
|
||||
dev = blk->dev;
|
||||
DeviceState *dev = blk->dev;
|
||||
|
||||
if (!dev) {
|
||||
return g_strdup("");
|
||||
@@ -949,11 +923,6 @@ BlockBackend *blk_by_dev(void *dev)
|
||||
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
|
||||
void *opaque)
|
||||
{
|
||||
/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep
|
||||
* it that way, so we can assume blk->dev, if present, is a DeviceState if
|
||||
* blk->dev_ops is set. Non-device users may use dev_ops without device. */
|
||||
assert(!blk->legacy_dev);
|
||||
|
||||
blk->dev_ops = ops;
|
||||
blk->dev_opaque = opaque;
|
||||
|
||||
@@ -979,8 +948,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
|
||||
bool tray_was_open, tray_is_open;
|
||||
Error *local_err = NULL;
|
||||
|
||||
assert(!blk->legacy_dev);
|
||||
|
||||
tray_was_open = blk_dev_is_tray_open(blk);
|
||||
blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err);
|
||||
if (local_err) {
|
||||
@@ -1220,6 +1187,7 @@ static void blk_read_entry(void *opaque)
|
||||
|
||||
rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, qiov->size,
|
||||
qiov, rwco->flags);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static void blk_write_entry(void *opaque)
|
||||
@@ -1229,6 +1197,7 @@ static void blk_write_entry(void *opaque)
|
||||
|
||||
rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, qiov->size,
|
||||
qiov, rwco->flags);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
|
||||
@@ -1540,6 +1509,7 @@ static void blk_ioctl_entry(void *opaque)
|
||||
|
||||
rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
|
||||
qiov->iov[0].iov_base);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
|
||||
@@ -1586,6 +1556,7 @@ static void blk_flush_entry(void *opaque)
|
||||
{
|
||||
BlkRwCo *rwco = opaque;
|
||||
rwco->ret = blk_co_flush(rwco->blk);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int blk_flush(BlockBackend *blk)
|
||||
@@ -1779,9 +1750,6 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
|
||||
BlockDriverState *bs = blk_bs(blk);
|
||||
char *id;
|
||||
|
||||
/* blk_eject is only called by qdevified devices */
|
||||
assert(!blk->legacy_dev);
|
||||
|
||||
if (bs) {
|
||||
bdrv_eject(bs, eject_flag);
|
||||
}
|
||||
@@ -2018,6 +1986,7 @@ static void blk_pdiscard_entry(void *opaque)
|
||||
QEMUIOVector *qiov = rwco->iobuf;
|
||||
|
||||
rwco->ret = blk_co_pdiscard(rwco->blk, rwco->offset, qiov->size);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
|
||||
|
||||
+7
-1
@@ -806,6 +806,7 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
|
||||
rwco->qiov->size, rwco->qiov,
|
||||
rwco->flags);
|
||||
}
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2279,6 +2280,7 @@ static void coroutine_fn bdrv_block_status_above_co_entry(void *opaque)
|
||||
data->offset, data->bytes,
|
||||
data->pnum, data->map, data->file);
|
||||
data->done = true;
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2438,6 +2440,7 @@ static void coroutine_fn bdrv_co_rw_vmstate_entry(void *opaque)
|
||||
{
|
||||
BdrvVmstateCo *co = opaque;
|
||||
co->ret = bdrv_co_rw_vmstate(co->bs, co->qiov, co->pos, co->is_read);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -2559,6 +2562,7 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
|
||||
FlushCo *rwco = opaque;
|
||||
|
||||
rwco->ret = bdrv_co_flush(rwco->bs);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
|
||||
@@ -2704,6 +2708,7 @@ static void coroutine_fn bdrv_pdiscard_co_entry(void *opaque)
|
||||
DiscardCo *rwco = opaque;
|
||||
|
||||
rwco->ret = bdrv_co_pdiscard(rwco->child, rwco->offset, rwco->bytes);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int bytes)
|
||||
@@ -3217,6 +3222,7 @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
|
||||
TruncateCo *tco = opaque;
|
||||
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->prealloc,
|
||||
tco->errp);
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
|
||||
@@ -3236,7 +3242,7 @@ int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
|
||||
bdrv_truncate_co_entry(&tco);
|
||||
} else {
|
||||
co = qemu_coroutine_create(bdrv_truncate_co_entry, &tco);
|
||||
qemu_coroutine_enter(co);
|
||||
bdrv_coroutine_enter(child->bs, co);
|
||||
BDRV_POLL_WHILE(child->bs, tco.ret == NOT_DONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1612,6 +1612,14 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = block_job_add_bdrv(&s->common, "source", bs, 0,
|
||||
BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE |
|
||||
BLK_PERM_CONSISTENT_READ,
|
||||
errp);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Required permissions are already taken with blk_new() */
|
||||
block_job_add_bdrv(&s->common, "target", target, 0, BLK_PERM_ALL,
|
||||
&error_abort);
|
||||
@@ -1649,6 +1657,9 @@ fail:
|
||||
g_free(s->replaces);
|
||||
blk_unref(s->target);
|
||||
bs_opaque->job = NULL;
|
||||
if (s->dirty_bitmap) {
|
||||
bdrv_release_dirty_bitmap(bs, s->dirty_bitmap);
|
||||
}
|
||||
job_early_fail(&s->common.job);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
|
||||
s->quit = true;
|
||||
nbd_recv_coroutines_wake_all(s);
|
||||
s->read_reply_co = NULL;
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static int nbd_co_send_request(BlockDriverState *bs,
|
||||
|
||||
@@ -390,6 +390,7 @@ static void nvme_cmd_sync_cb(void *opaque, int ret)
|
||||
{
|
||||
int *pret = opaque;
|
||||
*pret = ret;
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,
|
||||
|
||||
@@ -368,6 +368,9 @@ static int alloc_refcount_block(BlockDriverState *bs,
|
||||
return new_block;
|
||||
}
|
||||
|
||||
/* The offset must fit in the offset field of the refcount table entry */
|
||||
assert((new_block & REFT_OFFSET_MASK) == new_block);
|
||||
|
||||
/* If we're allocating the block at offset 0 then something is wrong */
|
||||
if (new_block == 0) {
|
||||
qcow2_signal_corruption(bs, true, -1, -1, "Preventing invalid "
|
||||
|
||||
@@ -1671,6 +1671,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
/* From bdrv_co_create. */
|
||||
qcow2_open_entry(&qoc);
|
||||
} else {
|
||||
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
||||
qemu_coroutine_enter(qemu_coroutine_create(qcow2_open_entry, &qoc));
|
||||
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
|
||||
}
|
||||
|
||||
+5
-5
@@ -50,11 +50,11 @@
|
||||
|
||||
/* 8 MB refcount table is enough for 2 PB images at 64k cluster size
|
||||
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
|
||||
#define QCOW_MAX_REFTABLE_SIZE S_8MiB
|
||||
#define QCOW_MAX_REFTABLE_SIZE (8 * MiB)
|
||||
|
||||
/* 32 MB L1 table is enough for 2 PB images at 64k cluster size
|
||||
* (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
|
||||
#define QCOW_MAX_L1_SIZE S_32MiB
|
||||
#define QCOW_MAX_L1_SIZE (32 * MiB)
|
||||
|
||||
/* Allow for an average of 1k per snapshot table entry, should be plenty of
|
||||
* space for snapshot names and IDs */
|
||||
@@ -81,15 +81,15 @@
|
||||
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
#define DEFAULT_L2_CACHE_MAX_SIZE S_32MiB
|
||||
#define DEFAULT_L2_CACHE_MAX_SIZE (32 * MiB)
|
||||
#define DEFAULT_CACHE_CLEAN_INTERVAL 600 /* seconds */
|
||||
#else
|
||||
#define DEFAULT_L2_CACHE_MAX_SIZE S_8MiB
|
||||
#define DEFAULT_L2_CACHE_MAX_SIZE (8 * MiB)
|
||||
/* Cache clean interval is currently available only on Linux, so must be 0 */
|
||||
#define DEFAULT_CACHE_CLEAN_INTERVAL 0
|
||||
#endif
|
||||
|
||||
#define DEFAULT_CLUSTER_SIZE S_64KiB
|
||||
#define DEFAULT_CLUSTER_SIZE 65536
|
||||
|
||||
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
|
||||
#define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
|
||||
|
||||
@@ -559,6 +559,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
if (qemu_in_coroutine()) {
|
||||
bdrv_qed_open_entry(&qoc);
|
||||
} else {
|
||||
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
||||
qemu_coroutine_enter(qemu_coroutine_create(bdrv_qed_open_entry, &qoc));
|
||||
BDRV_POLL_WHILE(bs, qoc.ret == -EINPROGRESS);
|
||||
}
|
||||
|
||||
+35
-22
@@ -85,7 +85,8 @@
|
||||
#define BLOCK_OPT_STATIC "static"
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define DEFAULT_CLUSTER_SIZE S_1MiB
|
||||
#define DEFAULT_CLUSTER_SIZE 1048576
|
||||
/* Note: can't use 1 * MiB, because it's passed to stringify() */
|
||||
|
||||
#if defined(CONFIG_VDI_DEBUG)
|
||||
#define VDI_DEBUG 1
|
||||
@@ -203,10 +204,10 @@ static void vdi_header_to_cpu(VdiHeader *header)
|
||||
header->block_extra = le32_to_cpu(header->block_extra);
|
||||
header->blocks_in_image = le32_to_cpu(header->blocks_in_image);
|
||||
header->blocks_allocated = le32_to_cpu(header->blocks_allocated);
|
||||
qemu_uuid_bswap(&header->uuid_image);
|
||||
qemu_uuid_bswap(&header->uuid_last_snap);
|
||||
qemu_uuid_bswap(&header->uuid_link);
|
||||
qemu_uuid_bswap(&header->uuid_parent);
|
||||
header->uuid_image = qemu_uuid_bswap(header->uuid_image);
|
||||
header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
|
||||
header->uuid_link = qemu_uuid_bswap(header->uuid_link);
|
||||
header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
|
||||
}
|
||||
|
||||
static void vdi_header_to_le(VdiHeader *header)
|
||||
@@ -227,15 +228,16 @@ static void vdi_header_to_le(VdiHeader *header)
|
||||
header->block_extra = cpu_to_le32(header->block_extra);
|
||||
header->blocks_in_image = cpu_to_le32(header->blocks_in_image);
|
||||
header->blocks_allocated = cpu_to_le32(header->blocks_allocated);
|
||||
qemu_uuid_bswap(&header->uuid_image);
|
||||
qemu_uuid_bswap(&header->uuid_last_snap);
|
||||
qemu_uuid_bswap(&header->uuid_link);
|
||||
qemu_uuid_bswap(&header->uuid_parent);
|
||||
header->uuid_image = qemu_uuid_bswap(header->uuid_image);
|
||||
header->uuid_last_snap = qemu_uuid_bswap(header->uuid_last_snap);
|
||||
header->uuid_link = qemu_uuid_bswap(header->uuid_link);
|
||||
header->uuid_parent = qemu_uuid_bswap(header->uuid_parent);
|
||||
}
|
||||
|
||||
static void vdi_header_print(VdiHeader *header)
|
||||
{
|
||||
char uuid[37];
|
||||
char uuidstr[37];
|
||||
QemuUUID uuid;
|
||||
logout("text %s", header->text);
|
||||
logout("signature 0x%08x\n", header->signature);
|
||||
logout("header size 0x%04x\n", header->header_size);
|
||||
@@ -254,14 +256,18 @@ static void vdi_header_print(VdiHeader *header)
|
||||
logout("block extra 0x%04x\n", header->block_extra);
|
||||
logout("blocks tot. 0x%04x\n", header->blocks_in_image);
|
||||
logout("blocks all. 0x%04x\n", header->blocks_allocated);
|
||||
qemu_uuid_unparse(&header->uuid_image, uuid);
|
||||
logout("uuid image %s\n", uuid);
|
||||
qemu_uuid_unparse(&header->uuid_last_snap, uuid);
|
||||
logout("uuid snap %s\n", uuid);
|
||||
qemu_uuid_unparse(&header->uuid_link, uuid);
|
||||
logout("uuid link %s\n", uuid);
|
||||
qemu_uuid_unparse(&header->uuid_parent, uuid);
|
||||
logout("uuid parent %s\n", uuid);
|
||||
uuid = header->uuid_image;
|
||||
qemu_uuid_unparse(&uuid, uuidstr);
|
||||
logout("uuid image %s\n", uuidstr);
|
||||
uuid = header->uuid_last_snap;
|
||||
qemu_uuid_unparse(&uuid, uuidstr);
|
||||
logout("uuid snap %s\n", uuidstr);
|
||||
uuid = header->uuid_link;
|
||||
qemu_uuid_unparse(&uuid, uuidstr);
|
||||
logout("uuid link %s\n", uuidstr);
|
||||
uuid = header->uuid_parent;
|
||||
qemu_uuid_unparse(&uuid, uuidstr);
|
||||
logout("uuid parent %s\n", uuidstr);
|
||||
}
|
||||
|
||||
static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
@@ -368,6 +374,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
size_t bmap_size;
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
QemuUUID uuid_link, uuid_parent;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
@@ -395,6 +402,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uuid_link = header.uuid_link;
|
||||
uuid_parent = header.uuid_parent;
|
||||
|
||||
if (header.disk_size % SECTOR_SIZE != 0) {
|
||||
/* 'VBoxManage convertfromraw' can create images with odd disk sizes.
|
||||
We accept them but round the disk size to the next multiple of
|
||||
@@ -444,11 +454,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
(uint64_t)header.blocks_in_image * header.block_size);
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
} else if (!qemu_uuid_is_null(&header.uuid_link)) {
|
||||
} else if (!qemu_uuid_is_null(&uuid_link)) {
|
||||
error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
} else if (!qemu_uuid_is_null(&header.uuid_parent)) {
|
||||
} else if (!qemu_uuid_is_null(&uuid_parent)) {
|
||||
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
@@ -733,6 +743,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
|
||||
BlockDriverState *bs_file = NULL;
|
||||
BlockBackend *blk = NULL;
|
||||
uint32_t *bmap = NULL;
|
||||
QemuUUID uuid;
|
||||
|
||||
assert(create_options->driver == BLOCKDEV_DRIVER_VDI);
|
||||
vdi_opts = &create_options->u.vdi;
|
||||
@@ -819,8 +830,10 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
|
||||
if (image_type == VDI_TYPE_STATIC) {
|
||||
header.blocks_allocated = blocks;
|
||||
}
|
||||
qemu_uuid_generate(&header.uuid_image);
|
||||
qemu_uuid_generate(&header.uuid_last_snap);
|
||||
qemu_uuid_generate(&uuid);
|
||||
header.uuid_image = uuid;
|
||||
qemu_uuid_generate(&uuid);
|
||||
header.uuid_last_snap = uuid;
|
||||
/* There is no need to set header.uuid_link or header.uuid_parent here. */
|
||||
if (VDI_DEBUG) {
|
||||
vdi_header_print(&header);
|
||||
|
||||
+384
-154
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -979,6 +979,7 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
|
||||
int64_t total_size;
|
||||
int disk_type;
|
||||
int ret = -EIO;
|
||||
QemuUUID uuid;
|
||||
|
||||
assert(opts->driver == BLOCKDEV_DRIVER_VPC);
|
||||
vpc_opts = &opts->u.vpc;
|
||||
@@ -1062,7 +1063,8 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOptions *opts,
|
||||
|
||||
footer->type = cpu_to_be32(disk_type);
|
||||
|
||||
qemu_uuid_generate(&footer->uuid);
|
||||
qemu_uuid_generate(&uuid);
|
||||
footer->uuid = uuid;
|
||||
|
||||
footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
|
||||
|
||||
|
||||
+2
-4
@@ -30,8 +30,7 @@ void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid,
|
||||
* first, since that's what the guest expects
|
||||
*/
|
||||
g_array_set_size(guid, VMGENID_FW_CFG_SIZE - ARRAY_SIZE(guid_le.data));
|
||||
guid_le = vms->guid;
|
||||
qemu_uuid_bswap(&guid_le);
|
||||
guid_le = qemu_uuid_bswap(vms->guid);
|
||||
/* The GUID is written at a fixed offset into the fw_cfg file
|
||||
* in order to implement the "OVMF SDT Header probe suppressor"
|
||||
* see docs/specs/vmgenid.txt for more details
|
||||
@@ -149,8 +148,7 @@ static void vmgenid_update_guest(VmGenIdState *vms)
|
||||
* however, will expect the fields to be little-endian.
|
||||
* Perform a byte swap immediately before writing.
|
||||
*/
|
||||
guid_le = vms->guid;
|
||||
qemu_uuid_bswap(&guid_le);
|
||||
guid_le = qemu_uuid_bswap(vms->guid);
|
||||
/* The GUID is written at a fixed offset into the fw_cfg file
|
||||
* in order to implement the "OVMF SDT Header probe suppressor"
|
||||
* see docs/specs/vmgenid.txt for more details.
|
||||
|
||||
+43
-16
@@ -104,6 +104,7 @@ typedef struct SCSIDiskState
|
||||
char *serial;
|
||||
char *vendor;
|
||||
char *product;
|
||||
char *device_id;
|
||||
bool tray_open;
|
||||
bool tray_locked;
|
||||
/*
|
||||
@@ -642,22 +643,19 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf)
|
||||
|
||||
case 0x83: /* Device identification page, mandatory */
|
||||
{
|
||||
const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
|
||||
int max_len = s->serial ? 20 : 255 - 8;
|
||||
int id_len = strlen(str);
|
||||
int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0;
|
||||
|
||||
if (id_len > max_len) {
|
||||
id_len = max_len;
|
||||
}
|
||||
DPRINTF("Inquiry EVPD[Device identification] "
|
||||
"buffer size %zd\n", req->cmd.xfer);
|
||||
|
||||
outbuf[buflen++] = 0x2; /* ASCII */
|
||||
outbuf[buflen++] = 0; /* not officially assigned */
|
||||
outbuf[buflen++] = 0; /* reserved */
|
||||
outbuf[buflen++] = id_len; /* length of data following */
|
||||
memcpy(outbuf + buflen, str, id_len);
|
||||
buflen += id_len;
|
||||
if (id_len) {
|
||||
outbuf[buflen++] = 0x2; /* ASCII */
|
||||
outbuf[buflen++] = 0; /* not officially assigned */
|
||||
outbuf[buflen++] = 0; /* reserved */
|
||||
outbuf[buflen++] = id_len; /* length of data following */
|
||||
memcpy(outbuf + buflen, s->device_id, id_len);
|
||||
buflen += id_len;
|
||||
}
|
||||
|
||||
if (s->qdev.wwn) {
|
||||
outbuf[buflen++] = 0x1; /* Binary */
|
||||
@@ -2361,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
|
||||
if (!s->vendor) {
|
||||
s->vendor = g_strdup("QEMU");
|
||||
}
|
||||
if (!s->device_id) {
|
||||
if (s->serial) {
|
||||
s->device_id = g_strdup_printf("%.20s", s->serial);
|
||||
} else {
|
||||
const char *str = blk_name(s->qdev.conf.blk);
|
||||
if (str && *str) {
|
||||
s->device_id = g_strdup(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blk_is_sg(s->qdev.conf.blk)) {
|
||||
error_setg(errp, "unwanted /dev/sg*");
|
||||
@@ -2381,10 +2389,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
|
||||
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
AioContext *ctx = NULL;
|
||||
/* can happen for devices without drive. The error message for missing
|
||||
* backend will be issued in scsi_realize
|
||||
*/
|
||||
if (s->qdev.conf.blk) {
|
||||
ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||||
aio_context_acquire(ctx);
|
||||
blkconf_blocksizes(&s->qdev.conf);
|
||||
}
|
||||
s->qdev.blocksize = s->qdev.conf.logical_block_size;
|
||||
@@ -2393,11 +2404,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||||
s->product = g_strdup("QEMU HARDDISK");
|
||||
}
|
||||
scsi_realize(&s->qdev, errp);
|
||||
if (ctx) {
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
AioContext *ctx;
|
||||
int ret;
|
||||
|
||||
if (!dev->conf.blk) {
|
||||
@@ -2408,6 +2423,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
ctx = blk_get_aio_context(dev->conf.blk);
|
||||
aio_context_acquire(ctx);
|
||||
s->qdev.blocksize = 2048;
|
||||
s->qdev.type = TYPE_ROM;
|
||||
s->features |= 1 << SCSI_DISK_F_REMOVABLE;
|
||||
@@ -2415,6 +2432,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
|
||||
s->product = g_strdup("QEMU CD-ROM");
|
||||
}
|
||||
scsi_realize(&s->qdev, errp);
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
|
||||
@@ -2553,6 +2571,7 @@ static int get_device_type(SCSIDiskState *s)
|
||||
static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
{
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||
AioContext *ctx;
|
||||
int sg_version;
|
||||
int rc;
|
||||
|
||||
@@ -2567,6 +2586,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
"be removed in a future version");
|
||||
}
|
||||
|
||||
ctx = blk_get_aio_context(s->qdev.conf.blk);
|
||||
aio_context_acquire(ctx);
|
||||
|
||||
/* check we are using a driver managing SG_IO (version 3 and after) */
|
||||
rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
|
||||
if (rc < 0) {
|
||||
@@ -2574,18 +2596,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
if (rc != -EPERM) {
|
||||
error_append_hint(errp, "Is this a SCSI device?\n");
|
||||
}
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (sg_version < 30000) {
|
||||
error_setg(errp, "scsi generic interface too old");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get device type from INQUIRY data */
|
||||
rc = get_device_type(s);
|
||||
if (rc < 0) {
|
||||
error_setg(errp, "INQUIRY failed");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Make a guess for the block size, we'll fix it when the guest sends.
|
||||
@@ -2605,6 +2627,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
|
||||
|
||||
scsi_realize(&s->qdev, errp);
|
||||
scsi_generic_read_device_inquiry(&s->qdev);
|
||||
|
||||
out:
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
typedef struct SCSIBlockReq {
|
||||
@@ -2902,7 +2927,9 @@ static const TypeInfo scsi_disk_base_info = {
|
||||
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
|
||||
DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
|
||||
DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
|
||||
DEFINE_PROP_STRING("product", SCSIDiskState, product)
|
||||
DEFINE_PROP_STRING("product", SCSIDiskState, product), \
|
||||
DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id)
|
||||
|
||||
|
||||
static Property scsi_hd_properties[] = {
|
||||
DEFINE_SCSI_DISK_PROPERTIES(),
|
||||
|
||||
@@ -791,9 +791,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
SCSIDevice *sd = SCSI_DEVICE(dev);
|
||||
|
||||
if (s->ctx && !s->dataplane_fenced) {
|
||||
AioContext *ctx;
|
||||
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
||||
return;
|
||||
}
|
||||
ctx = blk_get_aio_context(sd->conf.blk);
|
||||
if (ctx != s->ctx && ctx != qemu_get_aio_context()) {
|
||||
error_setg(errp, "Cannot attach a blockdev that is using "
|
||||
"a different iothread");
|
||||
return;
|
||||
}
|
||||
virtio_scsi_acquire(s);
|
||||
blk_set_aio_context(sd->conf.blk, s->ctx);
|
||||
virtio_scsi_release(s);
|
||||
@@ -824,6 +831,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
if (s->ctx) {
|
||||
virtio_scsi_acquire(s);
|
||||
blk_set_aio_context(sd->conf.blk, qemu_get_aio_context());
|
||||
virtio_scsi_release(s);
|
||||
}
|
||||
|
||||
qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,77 +17,4 @@
|
||||
#define PiB (INT64_C(1) << 50)
|
||||
#define EiB (INT64_C(1) << 60)
|
||||
|
||||
/*
|
||||
* The following lookup table is intended to be used when a literal string of
|
||||
* the number of bytes is required (for example if it needs to be stringified).
|
||||
* It can also be used for generic shortcuts of power-of-two sizes.
|
||||
* This table is generated using the AWK script below:
|
||||
*
|
||||
* BEGIN {
|
||||
* suffix="KMGTPE";
|
||||
* for(i=10; i<64; i++) {
|
||||
* val=2**i;
|
||||
* s=substr(suffix, int(i/10), 1);
|
||||
* n=2**(i%10);
|
||||
* pad=21-int(log(n)/log(10));
|
||||
* printf("#define S_%d%siB %*d\n", n, s, pad, val);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
#define S_1KiB 1024
|
||||
#define S_2KiB 2048
|
||||
#define S_4KiB 4096
|
||||
#define S_8KiB 8192
|
||||
#define S_16KiB 16384
|
||||
#define S_32KiB 32768
|
||||
#define S_64KiB 65536
|
||||
#define S_128KiB 131072
|
||||
#define S_256KiB 262144
|
||||
#define S_512KiB 524288
|
||||
#define S_1MiB 1048576
|
||||
#define S_2MiB 2097152
|
||||
#define S_4MiB 4194304
|
||||
#define S_8MiB 8388608
|
||||
#define S_16MiB 16777216
|
||||
#define S_32MiB 33554432
|
||||
#define S_64MiB 67108864
|
||||
#define S_128MiB 134217728
|
||||
#define S_256MiB 268435456
|
||||
#define S_512MiB 536870912
|
||||
#define S_1GiB 1073741824
|
||||
#define S_2GiB 2147483648
|
||||
#define S_4GiB 4294967296
|
||||
#define S_8GiB 8589934592
|
||||
#define S_16GiB 17179869184
|
||||
#define S_32GiB 34359738368
|
||||
#define S_64GiB 68719476736
|
||||
#define S_128GiB 137438953472
|
||||
#define S_256GiB 274877906944
|
||||
#define S_512GiB 549755813888
|
||||
#define S_1TiB 1099511627776
|
||||
#define S_2TiB 2199023255552
|
||||
#define S_4TiB 4398046511104
|
||||
#define S_8TiB 8796093022208
|
||||
#define S_16TiB 17592186044416
|
||||
#define S_32TiB 35184372088832
|
||||
#define S_64TiB 70368744177664
|
||||
#define S_128TiB 140737488355328
|
||||
#define S_256TiB 281474976710656
|
||||
#define S_512TiB 562949953421312
|
||||
#define S_1PiB 1125899906842624
|
||||
#define S_2PiB 2251799813685248
|
||||
#define S_4PiB 4503599627370496
|
||||
#define S_8PiB 9007199254740992
|
||||
#define S_16PiB 18014398509481984
|
||||
#define S_32PiB 36028797018963968
|
||||
#define S_64PiB 72057594037927936
|
||||
#define S_128PiB 144115188075855872
|
||||
#define S_256PiB 288230376151711744
|
||||
#define S_512PiB 576460752303423488
|
||||
#define S_1EiB 1152921504606846976
|
||||
#define S_2EiB 2305843009213693952
|
||||
#define S_4EiB 4611686018427387904
|
||||
#define S_8EiB 9223372036854775808
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -56,6 +56,6 @@ char *qemu_uuid_unparse_strdup(const QemuUUID *uuid);
|
||||
|
||||
int qemu_uuid_parse(const char *str, QemuUUID *uuid);
|
||||
|
||||
void qemu_uuid_bswap(QemuUUID *uuid);
|
||||
QemuUUID qemu_uuid_bswap(QemuUUID uuid);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -110,9 +110,8 @@ void blk_iostatus_disable(BlockBackend *blk);
|
||||
void blk_iostatus_reset(BlockBackend *blk);
|
||||
void blk_iostatus_set_err(BlockBackend *blk, int error);
|
||||
int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
|
||||
void blk_attach_dev_legacy(BlockBackend *blk, void *dev);
|
||||
void blk_detach_dev(BlockBackend *blk, void *dev);
|
||||
void *blk_get_attached_dev(BlockBackend *blk);
|
||||
void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
|
||||
DeviceState *blk_get_attached_dev(BlockBackend *blk);
|
||||
char *blk_get_attached_dev_id(BlockBackend *blk);
|
||||
BlockBackend *blk_by_dev(void *dev);
|
||||
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user