Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches:

- Copy offloading fixes for when the copy increases the image size
- Temporary revert of the removal of deprecated -drive options
- Fix request serialisation in the image fleecing scenario
- Fix copy-on-read crash with unaligned image size
- Fix another drain crash

# gpg: Signature made Tue 10 Jul 2018 16:37:52 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (24 commits)
  block: Use common write req handling in truncate
  block: Fix bdrv_co_truncate overlap check
  block: Use common req handling in copy offloading
  block: Use common req handling for discard
  block: Fix handling of image enlarging write
  block: Extract common write req handling
  block: Use uint64_t for BdrvTrackedRequest byte fields
  block: Use BdrvChild to discard
  block: Add copy offloading trace points
  block: Prefix file driver trace points with "file_"
  Revert "block: Remove deprecated -drive geometry options"
  Revert "block: Remove deprecated -drive option addr"
  Revert "block: Remove deprecated -drive option serial"
  Revert "block: Remove dead deprecation warning code"
  block/blklogwrites: Make sure the log sector size is not too small
  qapi/block-core.json: Add missing documentation for blklogwrites log-append option
  block/backup: fix fleecing scheme: use serialized writes
  block: add BDRV_REQ_SERIALISING flag
  block: split flags in copy_range
  block/io: fix copy_range
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2018-07-10 17:28:29 +01:00
42 changed files with 646 additions and 176 deletions
+1 -1
View File
@@ -2066,7 +2066,7 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
}
assert(num >= 0);
for (i = 0; i < num; i++) {
child->role->drained_begin(child);
bdrv_parent_drained_begin_single(child, true);
}
}
+14 -6
View File
@@ -47,6 +47,8 @@ typedef struct BackupBlockJob {
HBitmap *copy_bitmap;
bool use_copy_range;
int64_t copy_range_size;
bool serialize_target_writes;
} BackupBlockJob;
static const BlockJobDriver backup_job_driver;
@@ -102,6 +104,8 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
QEMUIOVector qiov;
BlockBackend *blk = job->common.blk;
int nbytes;
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
nbytes = MIN(job->cluster_size, job->len - start);
@@ -112,8 +116,7 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
iov.iov_len = nbytes;
qemu_iovec_init_external(&qiov, &iov, 1);
ret = blk_co_preadv(blk, start, qiov.size, &qiov,
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
if (ret < 0) {
trace_backup_do_cow_read_fail(job, start, ret);
if (error_is_read) {
@@ -124,11 +127,11 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
if (qemu_iovec_is_zero(&qiov)) {
ret = blk_co_pwrite_zeroes(job->target, start,
qiov.size, BDRV_REQ_MAY_UNMAP);
qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
} else {
ret = blk_co_pwritev(job->target, start,
qiov.size, &qiov,
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
qiov.size, &qiov, write_flags |
(job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
}
if (ret < 0) {
trace_backup_do_cow_write_fail(job, start, ret);
@@ -156,6 +159,8 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
int nr_clusters;
BlockBackend *blk = job->common.blk;
int nbytes;
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
nbytes = MIN(job->copy_range_size, end - start);
@@ -163,7 +168,7 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
nr_clusters);
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
read_flags, write_flags);
if (ret < 0) {
trace_backup_do_cow_copy_range_fail(job, start, ret);
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
@@ -701,6 +706,9 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
sync_bitmap : NULL;
job->compress = compress;
/* Detect image-fleecing (and similar) schemes */
job->serialize_target_writes = bdrv_chain_contains(target, bs);
/* If there is no backing file on the target, we cannot rely on COW if our
* backup cluster size is smaller than the target cluster size. Even for
* targets with a backing file, try to avoid COW if possible. */
+1 -1
View File
@@ -625,7 +625,7 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
return err;
}
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
+5 -2
View File
@@ -89,7 +89,10 @@ static inline uint32_t blk_log_writes_log2(uint32_t value)
static inline bool blk_log_writes_sector_size_valid(uint32_t sector_size)
{
return sector_size < (1ull << 24) && is_power_of_2(sector_size);
return is_power_of_2(sector_size) &&
sector_size >= sizeof(struct log_write_super) &&
sector_size >= sizeof(struct log_write_entry) &&
sector_size < (1ull << 24);
}
static uint64_t blk_log_writes_find_cur_log_sector(BdrvChild *log,
@@ -483,7 +486,7 @@ static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
static int coroutine_fn
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
{
return bdrv_co_pdiscard(fr->bs->file->bs, fr->offset, fr->bytes);
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
}
static int coroutine_fn
+1 -1
View File
@@ -113,7 +113,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pdiscard(bs->file->bs, offset, bytes);
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield();
+5 -3
View File
@@ -419,6 +419,7 @@ static void drive_info_del(DriveInfo *dinfo)
return;
}
qemu_opts_del(dinfo->opts);
g_free(dinfo->serial);
g_free(dinfo);
}
@@ -1559,7 +1560,7 @@ int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
return ret;
}
return bdrv_co_pdiscard(blk_bs(blk), offset, bytes);
return bdrv_co_pdiscard(blk->root, offset, bytes);
}
int blk_co_flush(BlockBackend *blk)
@@ -2218,7 +2219,8 @@ void blk_unregister_buf(BlockBackend *blk, void *host)
int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
BlockBackend *blk_out, int64_t off_out,
int bytes, BdrvRequestFlags flags)
int bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int r;
r = blk_check_byte_request(blk_in, off_in, bytes);
@@ -2231,5 +2233,5 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
}
return bdrv_co_copy_range(blk_in->root, off_in,
blk_out->root, off_out,
bytes, flags);
bytes, read_flags, write_flags);
}
+1 -1
View File
@@ -116,7 +116,7 @@ static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
+16 -9
View File
@@ -1488,6 +1488,8 @@ static ssize_t handle_aiocb_copy_range(RawPosixAIOData *aiocb)
ssize_t ret = copy_file_range(aiocb->aio_fildes, &in_off,
aiocb->aio_fd2, &out_off,
bytes, 0);
trace_file_copy_file_range(aiocb->bs, aiocb->aio_fildes, in_off,
aiocb->aio_fd2, out_off, bytes, 0, ret);
if (ret == 0) {
/* No progress (e.g. when beyond EOF), let the caller fall back to
* buffer I/O. */
@@ -1743,7 +1745,7 @@ static int paio_submit_co_full(BlockDriverState *bs, int fd,
assert(qiov->size == bytes);
}
trace_paio_submit_co(offset, bytes, type);
trace_file_paio_submit_co(offset, bytes, type);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_co(pool, aio_worker, acb);
}
@@ -2589,18 +2591,23 @@ static void raw_abort_perm_update(BlockDriverState *bs)
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
}
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
static int coroutine_fn raw_co_copy_range_from(
BlockDriverState *bs, BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset, uint64_t bytes,
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
{
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
}
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
BDRVRawState *s = bs->opaque;
BDRVRawState *src_s;
+1 -1
View File
@@ -162,7 +162,7 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
acb->aio_nbytes = count;
acb->aio_offset = offset;
trace_paio_submit(acb, opaque, offset, count, type);
trace_file_paio_submit(acb, opaque, offset, count, type);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
+218 -98
View File
File diff suppressed because it is too large Load Diff
+9 -3
View File
@@ -44,6 +44,7 @@
#include "qapi/qmp/qstring.h"
#include "crypto/secret.h"
#include "scsi/utils.h"
#include "trace.h"
/* Conflict between scsi/utils.h and libiscsi! :( */
#define SCSI_XFER_NONE ISCSI_XFER_NONE
@@ -2193,9 +2194,11 @@ static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags flags)
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
}
static struct scsi_task *iscsi_xcopy_task(int param_len)
@@ -2332,7 +2335,8 @@ static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags flags)
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
IscsiLun *dst_lun = dst->bs->opaque;
IscsiLun *src_lun;
@@ -2396,6 +2400,8 @@ retry:
}
out_unlock:
trace_iscsi_xcopy(src_lun, src_offset, dst_lun, dst_offset, bytes, r);
g_free(iscsi_task.task);
qemu_mutex_unlock(&dst_lun->mutex);
g_free(iscsi_task.err_str);
+1 -1
View File
@@ -1333,7 +1333,7 @@ static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
break;
case MIRROR_METHOD_DISCARD:
ret = bdrv_co_pdiscard(bs->backing->bs, offset, bytes);
ret = bdrv_co_pdiscard(bs->backing, offset, bytes);
break;
default:
+1 -1
View File
@@ -734,7 +734,7 @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
/* Discard is optional, ignore the return value */
if (ret >= 0) {
bdrv_pdiscard(bs->file->bs, d->offset, d->bytes);
bdrv_pdiscard(bs->file, d->offset, d->bytes);
}
g_free(d);
+11 -9
View File
@@ -3259,13 +3259,14 @@ static int coroutine_fn
qcow2_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
uint64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
BDRVQcow2State *s = bs->opaque;
int ret;
unsigned int cur_bytes; /* number of bytes in current iteration */
BdrvChild *child = NULL;
BdrvRequestFlags cur_flags;
BdrvRequestFlags cur_write_flags;
assert(!bs->encrypted);
qemu_co_mutex_lock(&s->lock);
@@ -3274,7 +3275,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
uint64_t copy_offset = 0;
/* prepare next request */
cur_bytes = MIN(bytes, INT_MAX);
cur_flags = flags;
cur_write_flags = write_flags;
ret = qcow2_get_cluster_offset(bs, src_offset, &cur_bytes, &copy_offset);
if (ret < 0) {
@@ -3286,20 +3287,20 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
if (bs->backing && bs->backing->bs) {
int64_t backing_length = bdrv_getlength(bs->backing->bs);
if (src_offset >= backing_length) {
cur_flags |= BDRV_REQ_ZERO_WRITE;
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
} else {
child = bs->backing;
cur_bytes = MIN(cur_bytes, backing_length - src_offset);
copy_offset = src_offset;
}
} else {
cur_flags |= BDRV_REQ_ZERO_WRITE;
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
}
break;
case QCOW2_CLUSTER_ZERO_PLAIN:
case QCOW2_CLUSTER_ZERO_ALLOC:
cur_flags |= BDRV_REQ_ZERO_WRITE;
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
break;
case QCOW2_CLUSTER_COMPRESSED:
@@ -3322,7 +3323,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
ret = bdrv_co_copy_range_from(child,
copy_offset,
dst, dst_offset,
cur_bytes, cur_flags);
cur_bytes, read_flags, cur_write_flags);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto out;
@@ -3343,7 +3344,8 @@ static int coroutine_fn
qcow2_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
uint64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
BDRVQcow2State *s = bs->opaque;
int offset_in_cluster;
@@ -3386,7 +3388,7 @@ qcow2_co_copy_range_to(BlockDriverState *bs,
ret = bdrv_co_copy_range_to(src, src_offset,
bs->file,
cluster_offset + offset_in_cluster,
cur_bytes, flags);
cur_bytes, read_flags, write_flags);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto fail;
+17 -9
View File
@@ -297,7 +297,7 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
if (ret) {
return ret;
}
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int64_t raw_getlength(BlockDriverState *bs)
@@ -498,9 +498,13 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
}
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;
@@ -509,13 +513,17 @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
return ret;
}
return bdrv_co_copy_range_from(bs->file, src_offset, dst, dst_offset,
bytes, flags);
bytes, read_flags, write_flags);
}
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, uint64_t src_offset,
BdrvChild *dst, uint64_t dst_offset,
uint64_t bytes, BdrvRequestFlags flags)
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;
@@ -524,7 +532,7 @@ static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
return ret;
}
return bdrv_co_copy_range_to(src, src_offset, bs->file, dst_offset, bytes,
flags);
read_flags, write_flags);
}
BlockDriver bdrv_raw = {
+1 -1
View File
@@ -149,7 +149,7 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true);
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static int throttle_co_flush(BlockDriverState *bs)
+8 -2
View File
@@ -15,6 +15,8 @@ bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs
bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x"
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64
bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
# block/stream.c
stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
@@ -55,8 +57,9 @@ qmp_block_stream(void *bs, void *job) "bs %p job %p"
# block/file-win32.c
# block/file-posix.c
paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
file_paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_off, int64_t bytes, int flags, int64_t ret) "bs %p src_fd %d offset %"PRIu64" dst_fd %d offset %"PRIu64" bytes %"PRIu64" flags %d ret %"PRId64
# block/qcow2.c
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
@@ -150,3 +153,6 @@ nvme_free_req_queue_wait(void *q) "q %p"
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pages %d"
# block/iscsi.c
iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_lun, uint64_t dst_off, uint64_t bytes, int ret) "src_lun %p offset %"PRIu64" dst_lun %p offset %"PRIu64" bytes %"PRIu64" ret %d"
+110
View File
@@ -730,6 +730,30 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "if",
.type = QEMU_OPT_STRING,
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
},{
.name = "cyls",
.type = QEMU_OPT_NUMBER,
.help = "number of cylinders (ide disk geometry)",
},{
.name = "heads",
.type = QEMU_OPT_NUMBER,
.help = "number of heads (ide disk geometry)",
},{
.name = "secs",
.type = QEMU_OPT_NUMBER,
.help = "number of sectors (ide disk geometry)",
},{
.name = "trans",
.type = QEMU_OPT_STRING,
.help = "chs translation (auto, lba, none)",
},{
.name = "addr",
.type = QEMU_OPT_STRING,
.help = "pci address (virtio only)",
},{
.name = "serial",
.type = QEMU_OPT_STRING,
.help = "disk serial number",
},{
.name = "file",
.type = QEMU_OPT_STRING,
@@ -768,13 +792,19 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
QemuOpts *legacy_opts;
DriveMediaType media = MEDIA_DISK;
BlockInterfaceType type;
int cyls, heads, secs, translation;
int max_devs, bus_id, unit_id, index;
const char *devaddr;
const char *werror, *rerror;
bool read_only = false;
bool copy_on_read;
const char *serial;
const char *filename;
Error *local_err = NULL;
int i;
const char *deprecated[] = {
"serial", "trans", "secs", "heads", "cyls", "addr"
};
/* Change legacy command line options into QMP ones */
static const struct {
@@ -851,6 +881,16 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
goto fail;
}
/* Other deprecated options */
if (!qtest_enabled()) {
for (i = 0; i < ARRAY_SIZE(deprecated); i++) {
if (qemu_opt_get(legacy_opts, deprecated[i]) != NULL) {
error_report("'%s' is deprecated, please use the corresponding "
"option of '-device' instead", deprecated[i]);
}
}
}
/* Media type */
value = qemu_opt_get(legacy_opts, "media");
if (value) {
@@ -892,6 +932,57 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
type = block_default_type;
}
/* Geometry */
cyls = qemu_opt_get_number(legacy_opts, "cyls", 0);
heads = qemu_opt_get_number(legacy_opts, "heads", 0);
secs = qemu_opt_get_number(legacy_opts, "secs", 0);
if (cyls || heads || secs) {
if (cyls < 1) {
error_report("invalid physical cyls number");
goto fail;
}
if (heads < 1) {
error_report("invalid physical heads number");
goto fail;
}
if (secs < 1) {
error_report("invalid physical secs number");
goto fail;
}
}
translation = BIOS_ATA_TRANSLATION_AUTO;
value = qemu_opt_get(legacy_opts, "trans");
if (value != NULL) {
if (!cyls) {
error_report("'%s' trans must be used with cyls, heads and secs",
value);
goto fail;
}
if (!strcmp(value, "none")) {
translation = BIOS_ATA_TRANSLATION_NONE;
} else if (!strcmp(value, "lba")) {
translation = BIOS_ATA_TRANSLATION_LBA;
} else if (!strcmp(value, "large")) {
translation = BIOS_ATA_TRANSLATION_LARGE;
} else if (!strcmp(value, "rechs")) {
translation = BIOS_ATA_TRANSLATION_RECHS;
} else if (!strcmp(value, "auto")) {
translation = BIOS_ATA_TRANSLATION_AUTO;
} else {
error_report("'%s' invalid translation type", value);
goto fail;
}
}
if (media == MEDIA_CDROM) {
if (cyls || secs || heads) {
error_report("CHS can't be set with media=cdrom");
goto fail;
}
}
/* Device address specified by bus/unit or index.
* If none was specified, try to find the first free one. */
bus_id = qemu_opt_get_number(legacy_opts, "bus", 0);
@@ -931,6 +1022,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
goto fail;
}
/* Serial number */
serial = qemu_opt_get(legacy_opts, "serial");
/* no id supplied -> create one */
if (qemu_opts_id(all_opts) == NULL) {
char *new_id;
@@ -950,6 +1044,12 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
}
/* Add virtio block device */
devaddr = qemu_opt_get(legacy_opts, "addr");
if (devaddr && type != IF_VIRTIO) {
error_report("addr is not supported by this bus type");
goto fail;
}
if (type == IF_VIRTIO) {
QemuOpts *devopts;
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
@@ -961,6 +1061,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
}
qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
&error_abort);
if (devaddr) {
qemu_opt_set(devopts, "addr", devaddr, &error_abort);
}
}
filename = qemu_opt_get(legacy_opts, "file");
@@ -1002,9 +1105,16 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
dinfo = g_malloc0(sizeof(*dinfo));
dinfo->opts = all_opts;
dinfo->cyls = cyls;
dinfo->heads = heads;
dinfo->secs = secs;
dinfo->trans = translation;
dinfo->type = type;
dinfo->bus = bus_id;
dinfo->unit = unit_id;
dinfo->devaddr = devaddr;
dinfo->serial = g_strdup(serial);
blk_set_legacy_dinfo(blk, dinfo);
+4
View File
@@ -69,6 +69,10 @@ void hmp_drive_add(Monitor *mon, const QDict *qdict)
if (!dinfo) {
goto err;
}
if (dinfo->devaddr) {
monitor_printf(mon, "Parameter addr not supported\n");
goto err;
}
switch (dinfo->type) {
case IF_NONE:
+1
View File
@@ -1306,6 +1306,7 @@ ETEXI
.params = "[-n] [[<domain>:]<bus>:]<slot>\n"
"[file=file][,if=type][,bus=n]\n"
"[,unit=m][,media=d][,index=i]\n"
"[,cyls=c,heads=h,secs=s[,trans=t]]\n"
"[,snapshot=on|off][,cache=on|off]\n"
"[,readonly=on|off][,copy-on-read=on|off]",
.help = "add drive to PCI storage controller",

Some files were not shown because too many files have changed in this diff Show More