mirror of https://gitee.com/openkylin/qemu.git
Merge remote-tracking branch 'kwolf/for-anthony' into staging
# By Kevin Wolf (6) and Stefan Hajnoczi (2) # Via Kevin Wolf * kwolf/for-anthony: ahci: Fix FLUSH command migration: Fail migration on bdrv_flush_all() error cpus: Add return value for vm_stop() block: Add return value for bdrv_flush_all() qemu-iotests: Update 051 reference output block: Don't parse protocol from file.filename block: add drive_backup HMP command blockdev: add sync mode to drive-backup QMP command Message-id: 1373887000-4488-1-git-send-email-kwolf@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
5699a02e01
27
block.c
27
block.c
|
@ -417,7 +417,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
|
||||||
{
|
{
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
|
|
||||||
drv = bdrv_find_protocol(filename);
|
drv = bdrv_find_protocol(filename, true);
|
||||||
if (drv == NULL) {
|
if (drv == NULL) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
@ -482,7 +482,8 @@ static BlockDriver *find_hdev_driver(const char *filename)
|
||||||
return drv;
|
return drv;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDriver *bdrv_find_protocol(const char *filename)
|
BlockDriver *bdrv_find_protocol(const char *filename,
|
||||||
|
bool allow_protocol_prefix)
|
||||||
{
|
{
|
||||||
BlockDriver *drv1;
|
BlockDriver *drv1;
|
||||||
char protocol[128];
|
char protocol[128];
|
||||||
|
@ -503,9 +504,10 @@ BlockDriver *bdrv_find_protocol(const char *filename)
|
||||||
return drv1;
|
return drv1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path_has_protocol(filename)) {
|
if (!path_has_protocol(filename) || !allow_protocol_prefix) {
|
||||||
return bdrv_find_format("file");
|
return bdrv_find_format("file");
|
||||||
}
|
}
|
||||||
|
|
||||||
p = strchr(filename, ':');
|
p = strchr(filename, ':');
|
||||||
assert(p != NULL);
|
assert(p != NULL);
|
||||||
len = p - filename;
|
len = p - filename;
|
||||||
|
@ -784,6 +786,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
const char *drvname;
|
const char *drvname;
|
||||||
|
bool allow_protocol_prefix = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* NULL means an empty set of options */
|
/* NULL means an empty set of options */
|
||||||
|
@ -800,6 +803,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
|
||||||
filename = qdict_get_try_str(options, "filename");
|
filename = qdict_get_try_str(options, "filename");
|
||||||
} else if (filename && !qdict_haskey(options, "filename")) {
|
} else if (filename && !qdict_haskey(options, "filename")) {
|
||||||
qdict_put(options, "filename", qstring_from_str(filename));
|
qdict_put(options, "filename", qstring_from_str(filename));
|
||||||
|
allow_protocol_prefix = true;
|
||||||
} else {
|
} else {
|
||||||
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
|
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and "
|
||||||
"'filename' options at the same time");
|
"'filename' options at the same time");
|
||||||
|
@ -813,7 +817,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
|
||||||
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
|
drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR));
|
||||||
qdict_del(options, "driver");
|
qdict_del(options, "driver");
|
||||||
} else if (filename) {
|
} else if (filename) {
|
||||||
drv = bdrv_find_protocol(filename);
|
drv = bdrv_find_protocol(filename, allow_protocol_prefix);
|
||||||
|
if (!drv) {
|
||||||
|
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
qerror_report(ERROR_CLASS_GENERIC_ERROR,
|
||||||
"Must specify either driver or file");
|
"Must specify either driver or file");
|
||||||
|
@ -2903,13 +2910,19 @@ int bdrv_get_flags(BlockDriverState *bs)
|
||||||
return bs->open_flags;
|
return bs->open_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_flush_all(void)
|
int bdrv_flush_all(void)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, list) {
|
||||||
bdrv_flush(bs);
|
int ret = bdrv_flush(bs);
|
||||||
|
if (ret < 0 && !result) {
|
||||||
|
result = ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_has_zero_init_1(BlockDriverState *bs)
|
int bdrv_has_zero_init_1(BlockDriverState *bs)
|
||||||
|
@ -4452,7 +4465,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_drv = bdrv_find_protocol(filename);
|
proto_drv = bdrv_find_protocol(filename, true);
|
||||||
if (!proto_drv) {
|
if (!proto_drv) {
|
||||||
error_setg(errp, "Unknown protocol '%s'", filename);
|
error_setg(errp, "Unknown protocol '%s'", filename);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1510,7 +1510,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
|
|
||||||
/* Currently, only Sheepdog backing image is supported. */
|
/* Currently, only Sheepdog backing image is supported. */
|
||||||
drv = bdrv_find_protocol(backing_file);
|
drv = bdrv_find_protocol(backing_file, true);
|
||||||
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
|
if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
|
||||||
error_report("backing_file must be a sheepdog image");
|
error_report("backing_file must be a sheepdog image");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
|
@ -936,6 +936,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
|
||||||
|
|
||||||
qmp_drive_backup(backup->device, backup->target,
|
qmp_drive_backup(backup->device, backup->target,
|
||||||
backup->has_format, backup->format,
|
backup->has_format, backup->format,
|
||||||
|
backup->sync,
|
||||||
backup->has_mode, backup->mode,
|
backup->has_mode, backup->mode,
|
||||||
backup->has_speed, backup->speed,
|
backup->has_speed, backup->speed,
|
||||||
backup->has_on_source_error, backup->on_source_error,
|
backup->has_on_source_error, backup->on_source_error,
|
||||||
|
@ -1421,6 +1422,7 @@ void qmp_block_commit(const char *device,
|
||||||
|
|
||||||
void qmp_drive_backup(const char *device, const char *target,
|
void qmp_drive_backup(const char *device, const char *target,
|
||||||
bool has_format, const char *format,
|
bool has_format, const char *format,
|
||||||
|
enum MirrorSyncMode sync,
|
||||||
bool has_mode, enum NewImageMode mode,
|
bool has_mode, enum NewImageMode mode,
|
||||||
bool has_speed, int64_t speed,
|
bool has_speed, int64_t speed,
|
||||||
bool has_on_source_error, BlockdevOnError on_source_error,
|
bool has_on_source_error, BlockdevOnError on_source_error,
|
||||||
|
@ -1435,6 +1437,10 @@ void qmp_drive_backup(const char *device, const char *target,
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (sync != MIRROR_SYNC_MODE_FULL) {
|
||||||
|
error_setg(errp, "only sync mode 'full' is currently supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!has_speed) {
|
if (!has_speed) {
|
||||||
speed = 0;
|
speed = 0;
|
||||||
}
|
}
|
||||||
|
|
20
cpus.c
20
cpus.c
|
@ -434,17 +434,21 @@ bool cpu_is_stopped(CPUState *cpu)
|
||||||
return !runstate_is_running() || cpu->stopped;
|
return !runstate_is_running() || cpu->stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_vm_stop(RunState state)
|
static int do_vm_stop(RunState state)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (runstate_is_running()) {
|
if (runstate_is_running()) {
|
||||||
cpu_disable_ticks();
|
cpu_disable_ticks();
|
||||||
pause_all_vcpus();
|
pause_all_vcpus();
|
||||||
runstate_set(state);
|
runstate_set(state);
|
||||||
vm_state_notify(0, state);
|
vm_state_notify(0, state);
|
||||||
bdrv_drain_all();
|
bdrv_drain_all();
|
||||||
bdrv_flush_all();
|
ret = bdrv_flush_all();
|
||||||
monitor_protocol_event(QEVENT_STOP, NULL);
|
monitor_protocol_event(QEVENT_STOP, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cpu_can_run(CPUState *cpu)
|
static bool cpu_can_run(CPUState *cpu)
|
||||||
|
@ -1070,7 +1074,7 @@ void cpu_stop_current(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_stop(RunState state)
|
int vm_stop(RunState state)
|
||||||
{
|
{
|
||||||
if (qemu_in_vcpu_thread()) {
|
if (qemu_in_vcpu_thread()) {
|
||||||
qemu_system_vmstop_request(state);
|
qemu_system_vmstop_request(state);
|
||||||
|
@ -1079,19 +1083,21 @@ void vm_stop(RunState state)
|
||||||
* vm_stop() has been requested.
|
* vm_stop() has been requested.
|
||||||
*/
|
*/
|
||||||
cpu_stop_current();
|
cpu_stop_current();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
do_vm_stop(state);
|
|
||||||
|
return do_vm_stop(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* does a state transition even if the VM is already stopped,
|
/* does a state transition even if the VM is already stopped,
|
||||||
current state is forgotten forever */
|
current state is forgotten forever */
|
||||||
void vm_stop_force_state(RunState state)
|
int vm_stop_force_state(RunState state)
|
||||||
{
|
{
|
||||||
if (runstate_is_running()) {
|
if (runstate_is_running()) {
|
||||||
vm_stop(state);
|
return vm_stop(state);
|
||||||
} else {
|
} else {
|
||||||
runstate_set(state);
|
runstate_set(state);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1056,6 +1056,26 @@ STEXI
|
||||||
@findex drive_mirror
|
@findex drive_mirror
|
||||||
Start mirroring a block device's writes to a new destination,
|
Start mirroring a block device's writes to a new destination,
|
||||||
using the specified target.
|
using the specified target.
|
||||||
|
ETEXI
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "drive_backup",
|
||||||
|
.args_type = "reuse:-n,full:-f,device:B,target:s,format:s?",
|
||||||
|
.params = "[-n] [-f] device target [format]",
|
||||||
|
.help = "initiates a point-in-time\n\t\t\t"
|
||||||
|
"copy for a device. The device's contents are\n\t\t\t"
|
||||||
|
"copied to the new image file, excluding data that\n\t\t\t"
|
||||||
|
"is written after the command is started.\n\t\t\t"
|
||||||
|
"The -n flag requests QEMU to reuse the image found\n\t\t\t"
|
||||||
|
"in new-image-file, instead of recreating it from scratch.\n\t\t\t"
|
||||||
|
"The -f flag requests QEMU to copy the whole disk,\n\t\t\t"
|
||||||
|
"so that the result does not need a backing file.\n\t\t\t",
|
||||||
|
.mhandler.cmd = hmp_drive_backup,
|
||||||
|
},
|
||||||
|
STEXI
|
||||||
|
@item drive_backup
|
||||||
|
@findex drive_backup
|
||||||
|
Start a point-in-time copy of a block device to a specificed target.
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
28
hmp.c
28
hmp.c
|
@ -907,6 +907,34 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
||||||
|
{
|
||||||
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
|
const char *filename = qdict_get_str(qdict, "target");
|
||||||
|
const char *format = qdict_get_try_str(qdict, "format");
|
||||||
|
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
||||||
|
int full = qdict_get_try_bool(qdict, "full", 0);
|
||||||
|
enum NewImageMode mode;
|
||||||
|
Error *errp = NULL;
|
||||||
|
|
||||||
|
if (!filename) {
|
||||||
|
error_set(&errp, QERR_MISSING_PARAMETER, "target");
|
||||||
|
hmp_handle_error(mon, &errp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reuse) {
|
||||||
|
mode = NEW_IMAGE_MODE_EXISTING;
|
||||||
|
} else {
|
||||||
|
mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmp_drive_backup(device, filename, !!format, format,
|
||||||
|
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||||
|
true, mode, false, 0, false, 0, false, 0, &errp);
|
||||||
|
hmp_handle_error(mon, &errp);
|
||||||
|
}
|
||||||
|
|
||||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
|
|
1
hmp.h
1
hmp.h
|
@ -55,6 +55,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_block_resize(Monitor *mon, const QDict *qdict);
|
void hmp_block_resize(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
|
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
|
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
|
||||||
|
void hmp_drive_backup(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
|
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
|
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
|
void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
|
||||||
|
|
|
@ -1106,10 +1106,15 @@ static int ahci_dma_add_status(IDEDMA *dma, int status)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ahci_dma_set_inactive(IDEDMA *dma)
|
static int ahci_dma_set_inactive(IDEDMA *dma)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ahci_async_cmd_done(IDEDMA *dma)
|
||||||
{
|
{
|
||||||
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
|
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
|
||||||
|
|
||||||
DPRINTF(ad->port_no, "dma done\n");
|
DPRINTF(ad->port_no, "async cmd done\n");
|
||||||
|
|
||||||
/* update d2h status */
|
/* update d2h status */
|
||||||
ahci_write_fis_d2h(ad, NULL);
|
ahci_write_fis_d2h(ad, NULL);
|
||||||
|
@ -1144,6 +1149,7 @@ static const IDEDMAOps ahci_dma_ops = {
|
||||||
.set_unit = ahci_dma_set_unit,
|
.set_unit = ahci_dma_set_unit,
|
||||||
.add_status = ahci_dma_add_status,
|
.add_status = ahci_dma_add_status,
|
||||||
.set_inactive = ahci_dma_set_inactive,
|
.set_inactive = ahci_dma_set_inactive,
|
||||||
|
.async_cmd_done = ahci_async_cmd_done,
|
||||||
.restart_cb = ahci_dma_restart_cb,
|
.restart_cb = ahci_dma_restart_cb,
|
||||||
.reset = ahci_dma_reset,
|
.reset = ahci_dma_reset,
|
||||||
};
|
};
|
||||||
|
|
|
@ -568,10 +568,18 @@ static void dma_buf_commit(IDEState *s)
|
||||||
qemu_sglist_destroy(&s->sg);
|
qemu_sglist_destroy(&s->sg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ide_async_cmd_done(IDEState *s)
|
||||||
|
{
|
||||||
|
if (s->bus->dma->ops->async_cmd_done) {
|
||||||
|
s->bus->dma->ops->async_cmd_done(s->bus->dma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ide_set_inactive(IDEState *s)
|
void ide_set_inactive(IDEState *s)
|
||||||
{
|
{
|
||||||
s->bus->dma->aiocb = NULL;
|
s->bus->dma->aiocb = NULL;
|
||||||
s->bus->dma->ops->set_inactive(s->bus->dma);
|
s->bus->dma->ops->set_inactive(s->bus->dma);
|
||||||
|
ide_async_cmd_done(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ide_dma_error(IDEState *s)
|
void ide_dma_error(IDEState *s)
|
||||||
|
@ -804,6 +812,7 @@ static void ide_flush_cb(void *opaque, int ret)
|
||||||
|
|
||||||
bdrv_acct_done(s->bs, &s->acct);
|
bdrv_acct_done(s->bs, &s->acct);
|
||||||
s->status = READY_STAT | SEEK_STAT;
|
s->status = READY_STAT | SEEK_STAT;
|
||||||
|
ide_async_cmd_done(s);
|
||||||
ide_set_irq(s->bus);
|
ide_set_irq(s->bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -433,6 +433,7 @@ struct IDEDMAOps {
|
||||||
DMAIntFunc *set_unit;
|
DMAIntFunc *set_unit;
|
||||||
DMAIntFunc *add_status;
|
DMAIntFunc *add_status;
|
||||||
DMAFunc *set_inactive;
|
DMAFunc *set_inactive;
|
||||||
|
DMAFunc *async_cmd_done;
|
||||||
DMARestartFunc *restart_cb;
|
DMARestartFunc *restart_cb;
|
||||||
DMAFunc *reset;
|
DMAFunc *reset;
|
||||||
};
|
};
|
||||||
|
|
|
@ -111,7 +111,8 @@ bool bdrv_io_limits_enabled(BlockDriverState *bs);
|
||||||
|
|
||||||
void bdrv_init(void);
|
void bdrv_init(void);
|
||||||
void bdrv_init_with_whitelist(void);
|
void bdrv_init_with_whitelist(void);
|
||||||
BlockDriver *bdrv_find_protocol(const char *filename);
|
BlockDriver *bdrv_find_protocol(const char *filename,
|
||||||
|
bool allow_protocol_prefix);
|
||||||
BlockDriver *bdrv_find_format(const char *format_name);
|
BlockDriver *bdrv_find_format(const char *format_name);
|
||||||
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
|
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
|
||||||
bool readonly);
|
bool readonly);
|
||||||
|
@ -266,7 +267,7 @@ void bdrv_clear_incoming_migration_all(void);
|
||||||
/* Ensure contents are flushed to disk. */
|
/* Ensure contents are flushed to disk. */
|
||||||
int bdrv_flush(BlockDriverState *bs);
|
int bdrv_flush(BlockDriverState *bs);
|
||||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
||||||
void bdrv_flush_all(void);
|
int bdrv_flush_all(void);
|
||||||
void bdrv_close_all(void);
|
void bdrv_close_all(void);
|
||||||
void bdrv_drain_all(void);
|
void bdrv_drain_all(void);
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ void vm_state_notify(int running, RunState state);
|
||||||
#define VMRESET_REPORT true
|
#define VMRESET_REPORT true
|
||||||
|
|
||||||
void vm_start(void);
|
void vm_start(void);
|
||||||
void vm_stop(RunState state);
|
int vm_stop(RunState state);
|
||||||
void vm_stop_force_state(RunState state);
|
int vm_stop_force_state(RunState state);
|
||||||
|
|
||||||
typedef enum WakeupReason {
|
typedef enum WakeupReason {
|
||||||
QEMU_WAKEUP_REASON_OTHER = 0,
|
QEMU_WAKEUP_REASON_OTHER = 0,
|
||||||
|
|
17
migration.c
17
migration.c
|
@ -527,15 +527,26 @@ static void *migration_thread(void *opaque)
|
||||||
if (pending_size && pending_size >= max_size) {
|
if (pending_size && pending_size >= max_size) {
|
||||||
qemu_savevm_state_iterate(s->file);
|
qemu_savevm_state_iterate(s->file);
|
||||||
} else {
|
} else {
|
||||||
|
int ret;
|
||||||
|
|
||||||
DPRINTF("done iterating\n");
|
DPRINTF("done iterating\n");
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
start_time = qemu_get_clock_ms(rt_clock);
|
start_time = qemu_get_clock_ms(rt_clock);
|
||||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
|
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
|
||||||
old_vm_running = runstate_is_running();
|
old_vm_running = runstate_is_running();
|
||||||
vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
|
|
||||||
qemu_file_set_rate_limit(s->file, INT_MAX);
|
ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
|
||||||
qemu_savevm_state_complete(s->file);
|
if (ret >= 0) {
|
||||||
|
qemu_file_set_rate_limit(s->file, INT_MAX);
|
||||||
|
qemu_savevm_state_complete(s->file);
|
||||||
|
}
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
migrate_finish_set_state(s, MIG_STATE_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!qemu_file_get_error(s->file)) {
|
if (!qemu_file_get_error(s->file)) {
|
||||||
migrate_finish_set_state(s, MIG_STATE_COMPLETED);
|
migrate_finish_set_state(s, MIG_STATE_COMPLETED);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1634,6 +1634,10 @@
|
||||||
# @format: #optional the format of the new destination, default is to
|
# @format: #optional the format of the new destination, default is to
|
||||||
# probe if @mode is 'existing', else the format of the source
|
# probe if @mode is 'existing', else the format of the source
|
||||||
#
|
#
|
||||||
|
# @sync: what parts of the disk image should be copied to the destination
|
||||||
|
# (all the disk, only the sectors allocated in the topmost image, or
|
||||||
|
# only new I/O).
|
||||||
|
#
|
||||||
# @mode: #optional whether and how QEMU should create a new image, default is
|
# @mode: #optional whether and how QEMU should create a new image, default is
|
||||||
# 'absolute-paths'.
|
# 'absolute-paths'.
|
||||||
#
|
#
|
||||||
|
@ -1655,7 +1659,8 @@
|
||||||
##
|
##
|
||||||
{ 'type': 'DriveBackup',
|
{ 'type': 'DriveBackup',
|
||||||
'data': { 'device': 'str', 'target': 'str', '*format': 'str',
|
'data': { 'device': 'str', 'target': 'str', '*format': 'str',
|
||||||
'*mode': 'NewImageMode', '*speed': 'int',
|
'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',
|
||||||
|
'*speed': 'int',
|
||||||
'*on-source-error': 'BlockdevOnError',
|
'*on-source-error': 'BlockdevOnError',
|
||||||
'*on-target-error': 'BlockdevOnError' } }
|
'*on-target-error': 'BlockdevOnError' } }
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ static int print_block_option_help(const char *filename, const char *fmt)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_drv = bdrv_find_protocol(filename);
|
proto_drv = bdrv_find_protocol(filename, true);
|
||||||
if (!proto_drv) {
|
if (!proto_drv) {
|
||||||
error_report("Unknown protocol '%s'", filename);
|
error_report("Unknown protocol '%s'", filename);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1261,7 +1261,7 @@ static int img_convert(int argc, char **argv)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_drv = bdrv_find_protocol(out_filename);
|
proto_drv = bdrv_find_protocol(out_filename, true);
|
||||||
if (!proto_drv) {
|
if (!proto_drv) {
|
||||||
error_report("Unknown protocol '%s'", out_filename);
|
error_report("Unknown protocol '%s'", out_filename);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
|
@ -913,7 +913,7 @@ EQMP
|
||||||
|
|
||||||
{
|
{
|
||||||
.name = "drive-backup",
|
.name = "drive-backup",
|
||||||
.args_type = "device:B,target:s,speed:i?,mode:s?,format:s?,"
|
.args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
|
||||||
"on-source-error:s?,on-target-error:s?",
|
"on-source-error:s?,on-target-error:s?",
|
||||||
.mhandler.cmd_new = qmp_marshal_input_drive_backup,
|
.mhandler.cmd_new = qmp_marshal_input_drive_backup,
|
||||||
},
|
},
|
||||||
|
@ -939,6 +939,10 @@ Arguments:
|
||||||
- "format": the format of the new destination, default is to probe if 'mode' is
|
- "format": the format of the new destination, default is to probe if 'mode' is
|
||||||
'existing', else the format of the source
|
'existing', else the format of the source
|
||||||
(json-string, optional)
|
(json-string, optional)
|
||||||
|
- "sync": what parts of the disk image should be copied to the destination;
|
||||||
|
possibilities include "full" for all the disk, "top" for only the sectors
|
||||||
|
allocated in the topmost image, or "none" to only replicate new I/O
|
||||||
|
(MirrorSyncMode).
|
||||||
- "mode": whether and how QEMU should create a new image
|
- "mode": whether and how QEMU should create a new image
|
||||||
(NewImageMode, optional, default 'absolute-paths')
|
(NewImageMode, optional, default 'absolute-paths')
|
||||||
- "speed": the maximum speed, in bytes per second (json-int, optional)
|
- "speed": the maximum speed, in bytes per second (json-int, optional)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
void vm_stop(RunState state)
|
int vm_stop(RunState state)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,18 @@ echo
|
||||||
run_qemu -drive file=$TEST_IMG,file.driver=file
|
run_qemu -drive file=$TEST_IMG,file.driver=file
|
||||||
run_qemu -drive file=$TEST_IMG,file.driver=qcow2
|
run_qemu -drive file=$TEST_IMG,file.driver=qcow2
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Parsing protocol from file name ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Protocol strings are supposed to be parsed from traditional option strings,
|
||||||
|
# but not when using driver-specific options. We can distinguish them by the
|
||||||
|
# error message for non-existing files.
|
||||||
|
|
||||||
|
run_qemu -hda foo:bar
|
||||||
|
run_qemu -drive file=foo:bar
|
||||||
|
run_qemu -drive file.filename=foo:bar
|
||||||
|
|
||||||
# success, all done
|
# success, all done
|
||||||
echo "*** done"
|
echo "*** done"
|
||||||
rm -f $seq.full
|
rm -f $seq.full
|
||||||
|
|
|
@ -23,10 +23,12 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not
|
||||||
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
|
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on
|
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=
|
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=: Parameter 'lazy_refcounts' expects 'on' or 'off'
|
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=: Parameter 'lazy_refcounts' expects 'on' or 'off'
|
||||||
|
@ -49,112 +51,152 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: Lazy ref
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy_refcounts=off
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
|
|
||||||
=== No medium ===
|
=== No medium ===
|
||||||
|
|
||||||
Testing: -drive if=floppy
|
Testing: -drive if=floppy
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive if=ide,media=cdrom
|
Testing: -drive if=ide,media=cdrom
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive if=scsi,media=cdrom
|
Testing: -drive if=scsi,media=cdrom
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive if=ide
|
Testing: -drive if=ide
|
||||||
QEMU_PROG: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: Device initialization failed.
|
||||||
QEMU_PROG: Initialization of device ide-hd failed
|
QEMU_PROG: Initialization of device ide-hd failed
|
||||||
|
|
||||||
Testing: -drive if=virtio
|
Testing: -drive if=virtio
|
||||||
QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -drive if=virtio: Device initialization failed.
|
||||||
|
QEMU_PROG: -drive if=virtio: Device initialization failed.
|
||||||
QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
|
QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
|
||||||
|
|
||||||
Testing: -drive if=scsi
|
Testing: -drive if=scsi
|
||||||
QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -drive if=scsi: Device initialization failed.
|
||||||
|
QEMU_PROG: Device initialization failed.
|
||||||
QEMU_PROG: Initialization of device lsi53c895a failed
|
QEMU_PROG: Initialization of device lsi53c895a failed
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
|
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
|
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
|
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
|
||||||
QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
|
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
|
||||||
QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
|
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
|
||||||
QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
|
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
|
||||||
|
|
||||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
|
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
|
||||||
QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
|
||||||
|
QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
|
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
|
||||||
|
|
||||||
|
|
||||||
=== Read-only ===
|
=== Read-only ===
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: readonly not supported by this bus type
|
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: readonly not supported by this bus type
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
|
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
|
||||||
QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
|
||||||
|
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
|
||||||
QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
|
||||||
|
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
|
||||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
|
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
|
|
||||||
=== Cache modes ===
|
=== Cache modes ===
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=none
|
Testing: -drive media=cdrom,cache=none
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=directsync
|
Testing: -drive media=cdrom,cache=directsync
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=writeback
|
Testing: -drive media=cdrom,cache=writeback
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=writethrough
|
Testing: -drive media=cdrom,cache=writethrough
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=unsafe
|
Testing: -drive media=cdrom,cache=unsafe
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive media=cdrom,cache=invalid_value
|
Testing: -drive media=cdrom,cache=invalid_value
|
||||||
QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
|
QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
|
||||||
|
@ -163,10 +205,25 @@ QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
|
||||||
=== Specifying the protocol layer ===
|
=== Specifying the protocol layer ===
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
|
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
|
||||||
q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
QEMU 1.5.50 monitor - type 'help' for more information
|
||||||
|
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||||
|
|
||||||
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
|
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level
|
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level
|
||||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||||
|
|
||||||
|
|
||||||
|
=== Parsing protocol from file name ===
|
||||||
|
|
||||||
|
Testing: -hda foo:bar
|
||||||
|
QEMU_PROG: -hda foo:bar: Unknown protocol
|
||||||
|
QEMU_PROG: -hda foo:bar: could not open disk image foo:bar: No such file or directory
|
||||||
|
|
||||||
|
Testing: -drive file=foo:bar
|
||||||
|
QEMU_PROG: -drive file=foo:bar: Unknown protocol
|
||||||
|
QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: No such file or directory
|
||||||
|
|
||||||
|
Testing: -drive file.filename=foo:bar
|
||||||
|
QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: No such file or directory
|
||||||
|
|
||||||
*** done
|
*** done
|
||||||
|
|
|
@ -54,7 +54,7 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||||
self.assert_no_active_block_jobs()
|
self.assert_no_active_block_jobs()
|
||||||
|
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
||||||
event = self.cancel_and_wait()
|
event = self.cancel_and_wait()
|
||||||
|
@ -64,7 +64,7 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||||
self.assert_no_active_block_jobs()
|
self.assert_no_active_block_jobs()
|
||||||
|
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
||||||
result = self.vm.qmp('block-job-pause', device='drive0')
|
result = self.vm.qmp('block-job-pause', device='drive0')
|
||||||
|
@ -89,17 +89,17 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||||
|
|
||||||
def test_medium_not_found(self):
|
def test_medium_not_found(self):
|
||||||
result = self.vm.qmp('drive-backup', device='ide1-cd0',
|
result = self.vm.qmp('drive-backup', device='ide1-cd0',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
|
||||||
def test_image_not_found(self):
|
def test_image_not_found(self):
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
mode='existing', target=target_img)
|
target=target_img, sync='full', mode='existing')
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
|
||||||
def test_device_not_found(self):
|
def test_device_not_found(self):
|
||||||
result = self.vm.qmp('drive-backup', device='nonexistent',
|
result = self.vm.qmp('drive-backup', device='nonexistent',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
|
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
|
||||||
|
|
||||||
class TestSetSpeed(iotests.QMPTestCase):
|
class TestSetSpeed(iotests.QMPTestCase):
|
||||||
|
@ -119,7 +119,7 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||||
self.assert_no_active_block_jobs()
|
self.assert_no_active_block_jobs()
|
||||||
|
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
||||||
# Default speed is 0
|
# Default speed is 0
|
||||||
|
@ -140,7 +140,7 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||||
|
|
||||||
# Check setting speed in drive-backup works
|
# Check setting speed in drive-backup works
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img, speed=4*1024*1024)
|
target=target_img, sync='full', speed=4*1024*1024)
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
||||||
result = self.vm.qmp('query-block-jobs')
|
result = self.vm.qmp('query-block-jobs')
|
||||||
|
@ -154,13 +154,13 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||||
self.assert_no_active_block_jobs()
|
self.assert_no_active_block_jobs()
|
||||||
|
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img, speed=-1)
|
target=target_img, sync='full', speed=-1)
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
|
||||||
self.assert_no_active_block_jobs()
|
self.assert_no_active_block_jobs()
|
||||||
|
|
||||||
result = self.vm.qmp('drive-backup', device='drive0',
|
result = self.vm.qmp('drive-backup', device='drive0',
|
||||||
target=target_img)
|
target=target_img, sync='full')
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
|
||||||
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
|
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
|
||||||
|
@ -196,7 +196,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
result = self.vm.qmp('transaction', actions=[{
|
result = self.vm.qmp('transaction', actions=[{
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'drive0',
|
'data': { 'device': 'drive0',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
@ -210,7 +211,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
result = self.vm.qmp('transaction', actions=[{
|
result = self.vm.qmp('transaction', actions=[{
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'drive0',
|
'data': { 'device': 'drive0',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assert_qmp(result, 'return', {})
|
self.assert_qmp(result, 'return', {})
|
||||||
|
@ -239,7 +241,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
result = self.vm.qmp('transaction', actions=[{
|
result = self.vm.qmp('transaction', actions=[{
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'ide1-cd0',
|
'data': { 'device': 'ide1-cd0',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
@ -249,7 +252,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'drive0',
|
'data': { 'device': 'drive0',
|
||||||
'mode': 'existing',
|
'mode': 'existing',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
@ -259,7 +263,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'nonexistent',
|
'data': { 'device': 'nonexistent',
|
||||||
'mode': 'existing',
|
'mode': 'existing',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
|
self.assert_qmp(result, 'error/class', 'DeviceNotFound')
|
||||||
|
@ -269,7 +274,8 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||||
'type': 'drive-backup',
|
'type': 'drive-backup',
|
||||||
'data': { 'device': 'nonexistent',
|
'data': { 'device': 'nonexistent',
|
||||||
'mode': 'existing',
|
'mode': 'existing',
|
||||||
'target': target_img },
|
'target': target_img,
|
||||||
|
'sync': 'full' },
|
||||||
}, {
|
}, {
|
||||||
'type': 'Abort',
|
'type': 'Abort',
|
||||||
'data': {},
|
'data': {},
|
||||||
|
|
|
@ -155,7 +155,7 @@ _filter_qemu_io()
|
||||||
# replace occurrences of QEMU_PROG with "qemu"
|
# replace occurrences of QEMU_PROG with "qemu"
|
||||||
_filter_qemu()
|
_filter_qemu()
|
||||||
{
|
{
|
||||||
sed -e "s#^$(basename $QEMU_PROG):#QEMU_PROG:#"
|
sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#"
|
||||||
}
|
}
|
||||||
|
|
||||||
# make sure this script returns success
|
# make sure this script returns success
|
||||||
|
|
Loading…
Reference in New Issue