diff options
90 files changed, 1379 insertions, 196 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ff8d0d29f4..dfb7932608 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1869,6 +1869,8 @@ F: util/hbitmap.c F: block/dirty-bitmap.c F: include/qemu/hbitmap.h F: include/block/dirty-bitmap.h +F: qcow2-bitmap.c +F: migration/block-dirty-bitmap.c F: tests/test-hbitmap.c F: docs/interop/bitmaps.rst T: git https://github.com/jnsnow/qemu.git bitmaps @@ -3019,6 +3019,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, "use \"backing\": null instead"); } flags |= BDRV_O_NO_BACKING; + qdict_del(bs->explicit_options, "backing"); + qdict_del(bs->options, "backing"); qdict_del(options, "backing"); } diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 4bbb251b2c..7039e82520 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -104,9 +104,15 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE); - if (name && bdrv_find_dirty_bitmap(bs, name)) { - error_setg(errp, "Bitmap already exists: %s", name); - return NULL; + if (name) { + if (bdrv_find_dirty_bitmap(bs, name)) { + error_setg(errp, "Bitmap already exists: %s", name); + return NULL; + } + if (strlen(name) > BDRV_BITMAP_MAX_NAME_SIZE) { + error_setg(errp, "Bitmap name too long: %s", name); + return NULL; + } } bitmap_size = bdrv_getlength(bs); if (bitmap_size < 0) { diff --git a/block/nbd.c b/block/nbd.c index 123976171c..5f18f78a94 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -1832,6 +1832,10 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, } s->export = g_strdup(qemu_opt_get(opts, "export")); + if (s->export && strlen(s->export) > NBD_MAX_STRING_SIZE) { + error_setg(errp, "export name too long to send to server"); + goto error; + } s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds")); if (s->tlscredsid) { @@ -1849,6 +1853,11 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, } s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap")); + if (s->x_dirty_bitmap && strlen(s->x_dirty_bitmap) > NBD_MAX_STRING_SIZE) { + error_setg(errp, "x-dirty-bitmap query too long to send to server"); + goto error; + } + s->reconnect_delay = qemu_opt_get_number(opts, "reconnect-delay", 0); ret = 0; @@ -1859,6 +1868,7 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, qapi_free_SocketAddress(s->saddr); g_free(s->export); g_free(s->tlscredsid); + g_free(s->x_dirty_bitmap); } qemu_opts_del(opts); return ret; diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index ef9ef628a0..809bbc5d20 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -42,6 +42,8 @@ #define BME_MIN_GRANULARITY_BITS 9 #define BME_MAX_NAME_SIZE 1023 +QEMU_BUILD_BUG_ON(BME_MAX_NAME_SIZE != BDRV_BITMAP_MAX_NAME_SIZE); + #if BME_MAX_TABLE_SIZE * 8ULL > INT_MAX #error In the code bitmap table physical size assumed to fit into int #endif diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 6a8b206e1d..8c20baa4a4 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -162,6 +162,11 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name, name = device; } + if (strlen(name) > NBD_MAX_STRING_SIZE) { + error_setg(errp, "export name '%s' too long", name); + return; + } + if (nbd_export_find(name)) { error_setg(errp, "NBD server already has export named '%s'", name); return; diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 566c0acb77..54e6ebd385 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -276,7 +276,7 @@ static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset, DPRINTF("BUG in %s\n", __func__); abort(); } - trace_pflash_data_read(offset, width << 1, ret); + trace_pflash_data_read(offset, width, ret); return ret; } @@ -389,7 +389,7 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset, break; } - trace_pflash_io_read(offset, width, width << 1, ret, pfl->cmd, pfl->wcycle); + trace_pflash_io_read(offset, width, ret, pfl->cmd, pfl->wcycle); return ret; } @@ -414,7 +414,7 @@ static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset, { uint8_t *p = pfl->storage; - trace_pflash_data_write(offset, width << 1, value, pfl->counter); + trace_pflash_data_write(offset, width, value, pfl->counter); switch (width) { case 1: p[offset] = value; @@ -453,7 +453,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset, cmd = value; - trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle); + trace_pflash_io_write(offset, width, value, pfl->wcycle); if (!pfl->wcycle) { /* Set the device in I/O access mode */ memory_region_rom_device_set_romd(&pfl->mem, false); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 4baca701b7..c7d92c3e79 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -260,7 +260,7 @@ static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr offset, { uint8_t *p = (uint8_t *)pfl->storage + offset; uint64_t ret = pfl->be ? ldn_be_p(p, width) : ldn_le_p(p, width); - trace_pflash_data_read(offset, width << 1, ret); + trace_pflash_data_read(offset, width, ret); return ret; } @@ -385,7 +385,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width) } break; } - trace_pflash_io_read(offset, width, width << 1, ret, pfl->cmd, pfl->wcycle); + trace_pflash_io_read(offset, width, ret, pfl->cmd, pfl->wcycle); return ret; } @@ -432,7 +432,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value, uint8_t *p; uint8_t cmd; - trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle); + trace_pflash_io_write(offset, width, value, pfl->wcycle); cmd = value; if (pfl->cmd != 0xA0) { /* Reset does nothing during chip erase and sector erase. */ @@ -542,7 +542,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value, } goto reset_flash; } - trace_pflash_data_write(offset, width << 1, value, 0); + trace_pflash_data_write(offset, width, value, 0); if (!pfl->ro) { p = (uint8_t *)pfl->storage + offset; if (pfl->be) { diff --git a/hw/block/trace-events b/hw/block/trace-events index 13d1b21dd4..c03e80c2c9 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -8,10 +8,10 @@ fdc_ioport_write(uint8_t reg, uint8_t value) "write reg 0x%02x val 0x%02x" # pflash_cfi01.c pflash_reset(void) "reset" pflash_timer_expired(uint8_t cmd) "command 0x%02x done" -pflash_io_read(uint64_t offset, int width, int fmt_width, uint32_t value, uint8_t cmd, uint8_t wcycle) "offset:0x%04"PRIx64" width:%d value:0x%0*x cmd:0x%02x wcycle:%u" -pflash_io_write(uint64_t offset, int width, int fmt_width, uint32_t value, uint8_t wcycle) "offset:0x%04"PRIx64" width:%d value:0x%0*x wcycle:%u" -pflash_data_read(uint64_t offset, int width, uint32_t value) "data offset:0x%04"PRIx64" value:0x%0*x" -pflash_data_write(uint64_t offset, int width, uint32_t value, uint64_t counter) "data offset:0x%04"PRIx64" value:0x%0*x counter:0x%016"PRIx64 +pflash_io_read(uint64_t offset, unsigned size, uint32_t value, uint8_t cmd, uint8_t wcycle) "offset:0x%04"PRIx64" size:%u value:0x%04x cmd:0x%02x wcycle:%u" +pflash_io_write(uint64_t offset, unsigned size, uint32_t value, uint8_t wcycle) "offset:0x%04"PRIx64" size:%u value:0x%04x wcycle:%u" +pflash_data_read(uint64_t offset, unsigned size, uint32_t value) "data offset:0x%04"PRIx64" size:%u value:0x%04x" +pflash_data_write(uint64_t offset, unsigned size, uint32_t value, uint64_t counter) "data offset:0x%04"PRIx64" size:%u value:0x%04x counter:0x%016"PRIx64 pflash_manufacturer_id(uint16_t id) "Read Manufacturer ID: 0x%04x" pflash_device_id(uint16_t id) "Read Device ID: 0x%04x" pflash_device_info(uint64_t offset) "Read Device Information offset:0x%04"PRIx64 diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index d8e1291905..9cb8d38a3b 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -555,6 +555,15 @@ static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc, xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx)); } +static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc, + PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + xive_tctx_destroy(spapr_cpu->tctx); + spapr_cpu->tctx = NULL; +} + static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val) { SpaprXive *xive = SPAPR_XIVE(intc); @@ -692,6 +701,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) sicc->deactivate = spapr_xive_deactivate; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset; + sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy; sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; sicc->set_irq = spapr_xive_set_irq; diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 6da05763f9..e7ac9ba618 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -44,7 +44,16 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon) { - int cpu_index = icp->cs ? icp->cs->cpu_index : -1; + int cpu_index; + + /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs + * are hot plugged or unplugged. + */ + if (!icp) { + return; + } + + cpu_index = icp->cs ? icp->cs->cpu_index : -1; if (!icp->output) { return; @@ -388,8 +397,10 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp) obj = object_new(type); object_property_add_child(cpu, type, obj, &error_abort); object_unref(obj); + object_ref(OBJECT(xi)); object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi), &error_abort); + object_ref(cpu); object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort); object_property_set_bool(obj, true, "realized", &local_err); if (local_err) { @@ -401,6 +412,15 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp) return obj; } +void icp_destroy(ICPState *icp) +{ + Object *obj = OBJECT(icp); + + object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort)); + object_unref(object_property_get_link(obj, ICP_PROP_XICS, &error_abort)); + object_unparent(obj); +} + /* * ICS: Source layer */ diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 7418fb9f37..b3705dab0e 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -352,6 +352,15 @@ static void xics_spapr_cpu_intc_reset(SpaprInterruptController *intc, icp_reset(spapr_cpu_state(cpu)->icp); } +static void xics_spapr_cpu_intc_destroy(SpaprInterruptController *intc, + PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + icp_destroy(spapr_cpu->icp); + spapr_cpu->icp = NULL; +} + static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq, bool lsi, Error **errp) { @@ -440,6 +449,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) sicc->deactivate = xics_spapr_deactivate; sicc->cpu_intc_create = xics_spapr_cpu_intc_create; sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset; + sicc->cpu_intc_destroy = xics_spapr_cpu_intc_destroy; sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; sicc->set_irq = xics_spapr_set_irq; diff --git a/hw/intc/xive.c b/hw/intc/xive.c index f066be5eb5..75dce82fb2 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -523,9 +523,18 @@ static const char * const xive_tctx_ring_names[] = { void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon) { - int cpu_index = tctx->cs ? tctx->cs->cpu_index : -1; + int cpu_index; int i; + /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs + * are hot plugged or unplugged. + */ + if (!tctx) { + return; + } + + cpu_index = tctx->cs ? tctx->cs->cpu_index : -1; + if (kvm_irqchip_in_kernel()) { Error *local_err = NULL; @@ -682,6 +691,7 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp) obj = object_new(TYPE_XIVE_TCTX); object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort); object_unref(obj); + object_ref(cpu); object_property_add_const_link(obj, "cpu", cpu, &error_abort); object_property_set_bool(obj, true, "realized", &local_err); if (local_err) { @@ -696,6 +706,14 @@ error: return NULL; } +void xive_tctx_destroy(XiveTCTX *tctx) +{ + Object *obj = OBJECT(tctx); + + object_unref(object_property_get_link(obj, "cpu", &error_abort)); + object_unparent(obj); +} + /* * XIVE ESB helpers */ diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 5cab9c1ee1..f1af840d8e 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -642,19 +642,19 @@ static void gt64120_writel(void *opaque, hwaddr addr, /* not really implemented */ s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe)); s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe); - trace_gt64120_write("INTRCAUSE", size << 1, val); + trace_gt64120_write("INTRCAUSE", size, val); break; case GT_INTRMASK: s->regs[saddr] = val & 0x3c3ffffe; - trace_gt64120_write("INTRMASK", size << 1, val); + trace_gt64120_write("INTRMASK", size, val); break; case GT_PCI0_ICMASK: s->regs[saddr] = val & 0x03fffffe; - trace_gt64120_write("ICMASK", size << 1, val); + trace_gt64120_write("ICMASK", size, val); break; case GT_PCI0_SERR0MASK: s->regs[saddr] = val & 0x0000003f; - trace_gt64120_write("SERR0MASK", size << 1, val); + trace_gt64120_write("SERR0MASK", size, val); break; /* Reserved when only PCI_0 is configured. */ @@ -930,19 +930,19 @@ static uint64_t gt64120_readl(void *opaque, /* Interrupts */ case GT_INTRCAUSE: val = s->regs[saddr]; - trace_gt64120_read("INTRCAUSE", size << 1, val); + trace_gt64120_read("INTRCAUSE", size, val); break; case GT_INTRMASK: val = s->regs[saddr]; - trace_gt64120_read("INTRMASK", size << 1, val); + trace_gt64120_read("INTRMASK", size, val); break; case GT_PCI0_ICMASK: val = s->regs[saddr]; - trace_gt64120_read("ICMASK", size << 1, val); + trace_gt64120_read("ICMASK", size, val); break; case GT_PCI0_SERR0MASK: val = s->regs[saddr]; - trace_gt64120_read("SERR0MASK", size << 1, val); + trace_gt64120_read("SERR0MASK", size, val); break; /* Reserved when only PCI_0 is configured. */ diff --git a/hw/mips/trace-events b/hw/mips/trace-events index 75d4c73f2e..321933283f 100644 --- a/hw/mips/trace-events +++ b/hw/mips/trace-events @@ -1,4 +1,4 @@ # gt64xxx.c -gt64120_read(const char *regname, int width, uint64_t value) "gt64120 read %s value:0x%0*" PRIx64 -gt64120_write(const char *regname, int width, uint64_t value) "gt64120 write %s value:0x%0*" PRIx64 +gt64120_read(const char *regname, unsigned size, uint64_t value) "gt64120 read %s size:%u value:0x%08" PRIx64 +gt64120_write(const char *regname, unsigned size, uint64_t value) "gt64120 write %s size:%u value:0x%08" PRIx64 gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64 diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 57f13db266..aa3bfe1afd 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -38,8 +38,10 @@ /* XXX: implement all timer modes */ -static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti, - int64_t current_time); +static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti, + int64_t current_time); +static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti, + int64_t current_time); static void mos6522_update_irq(MOS6522State *s) { @@ -98,7 +100,11 @@ static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val) trace_mos6522_set_counter(1 + ti->index, val); ti->load_time = get_load_time(s, ti); ti->counter_value = val; - mos6522_timer_update(s, ti, ti->load_time); + if (ti->index == 0) { + mos6522_timer1_update(s, ti, ti->load_time); + } else { + mos6522_timer2_update(s, ti, ti->load_time); + } } static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti, @@ -130,19 +136,34 @@ static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti, trace_mos6522_get_next_irq_time(ti->latch, d, next_time - d); next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, ti->frequency) + ti->load_time; + if (next_time <= current_time) { next_time = current_time + 1; } return next_time; } -static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti, +static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti, + int64_t current_time) +{ + if (!ti->timer) { + return; + } + if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) { + timer_del(ti->timer); + } else { + ti->next_irq_time = get_next_irq_time(s, ti, current_time); + timer_mod(ti->timer, ti->next_irq_time); + } +} + +static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti, int64_t current_time) { if (!ti->timer) { return; } - if (ti->index == 0 && (s->acr & T1MODE) != T1MODE_CONT) { + if ((s->ier & T2_INT) == 0) { timer_del(ti->timer); } else { ti->next_irq_time = get_next_irq_time(s, ti, current_time); @@ -155,7 +176,7 @@ static void mos6522_timer1(void *opaque) MOS6522State *s = opaque; MOS6522Timer *ti = &s->timers[0]; - mos6522_timer_update(s, ti, ti->next_irq_time); + mos6522_timer1_update(s, ti, ti->next_irq_time); s->ifr |= T1_INT; mos6522_update_irq(s); } @@ -165,7 +186,7 @@ static void mos6522_timer2(void *opaque) MOS6522State *s = opaque; MOS6522Timer *ti = &s->timers[1]; - mos6522_timer_update(s, ti, ti->next_irq_time); + mos6522_timer2_update(s, ti, ti->next_irq_time); s->ifr |= T2_INT; mos6522_update_irq(s); } @@ -204,7 +225,16 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size) { MOS6522State *s = opaque; uint32_t val; + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + if (now >= s->timers[0].next_irq_time) { + mos6522_timer1_update(s, &s->timers[0], now); + s->ifr |= T1_INT; + } + if (now >= s->timers[1].next_irq_time) { + mos6522_timer2_update(s, &s->timers[1], now); + s->ifr |= T2_INT; + } switch (addr) { case VIA_REG_B: val = s->b; @@ -299,8 +329,8 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) break; case VIA_REG_T1CL: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; - mos6522_timer_update(s, &s->timers[0], - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + mos6522_timer1_update(s, &s->timers[0], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); break; case VIA_REG_T1CH: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); @@ -309,14 +339,14 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) break; case VIA_REG_T1LL: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; - mos6522_timer_update(s, &s->timers[0], - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + mos6522_timer1_update(s, &s->timers[0], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); break; case VIA_REG_T1LH: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); s->ifr &= ~T1_INT; - mos6522_timer_update(s, &s->timers[0], - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + mos6522_timer1_update(s, &s->timers[0], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); break; case VIA_REG_T2CL: s->timers[1].latch = (s->timers[1].latch & 0xff00) | val; @@ -334,8 +364,8 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) break; case VIA_REG_ACR: s->acr = val; - mos6522_timer_update(s, &s->timers[0], - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + mos6522_timer1_update(s, &s->timers[0], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); break; case VIA_REG_PCR: s->pcr = val; @@ -354,6 +384,11 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) s->ier &= ~val; } mos6522_update_irq(s); + /* if IER is modified starts needed timers */ + mos6522_timer1_update(s, &s->timers[0], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); + mos6522_timer2_update(s, &s->timers[1], + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); break; default: case VIA_REG_ANH: @@ -426,9 +461,11 @@ static void mos6522_reset(DeviceState *dev) s->timers[0].frequency = s->frequency; s->timers[0].latch = 0xffff; set_counter(s, &s->timers[0], 0xffff); + timer_del(s->timers[0].timer); s->timers[1].frequency = s->frequency; s->timers[1].latch = 0xffff; + timer_del(s->timers[1].timer); } static void mos6522_init(Object *obj) diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 7f9cb5ab95..b8be73dc55 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -271,9 +271,10 @@ #define PHY_REG_EXT_PHYSPCFC_ST 27 #define PHY_REG_CABLE_DIAG 28 -#define PHY_REG_CONTROL_RST 0x8000 -#define PHY_REG_CONTROL_LOOP 0x4000 -#define PHY_REG_CONTROL_ANEG 0x1000 +#define PHY_REG_CONTROL_RST 0x8000 +#define PHY_REG_CONTROL_LOOP 0x4000 +#define PHY_REG_CONTROL_ANEG 0x1000 +#define PHY_REG_CONTROL_ANRESTART 0x0200 #define PHY_REG_STATUS_LINK 0x0004 #define PHY_REG_STATUS_ANEGCMPL 0x0020 @@ -1345,7 +1346,7 @@ static void gem_phy_write(CadenceGEMState *s, unsigned reg_num, uint16_t val) } if (val & PHY_REG_CONTROL_ANEG) { /* Complete autonegotiation immediately */ - val &= ~PHY_REG_CONTROL_ANEG; + val &= ~(PHY_REG_CONTROL_ANEG | PHY_REG_CONTROL_ANRESTART); s->phy_regs[PHY_REG_STATUS] |= PHY_REG_STATUS_ANEGCMPL; } if (val & PHY_REG_CONTROL_LOOP) { diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 60632720ef..627c08e5b9 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -778,6 +778,7 @@ static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu, pnv_cpu->intc = obj; } + static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); @@ -785,6 +786,14 @@ static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu) icp_reset(ICP(pnv_cpu->intc)); } +static void pnv_chip_power8_intc_destroy(PnvChip *chip, PowerPCCPU *cpu) +{ + PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); + + icp_destroy(ICP(pnv_cpu->intc)); + pnv_cpu->intc = NULL; +} + /* * 0:48 Reserved - Read as zeroes * 49:52 Node ID @@ -829,6 +838,14 @@ static void pnv_chip_power9_intc_reset(PnvChip *chip, PowerPCCPU *cpu) xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc)); } +static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu) +{ + PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); + + xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc)); + pnv_cpu->intc = NULL; +} + /* * Allowed core identifiers on a POWER8 Processor Chip : * @@ -999,6 +1016,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; k->intc_reset = pnv_chip_power8_intc_reset; + k->intc_destroy = pnv_chip_power8_intc_destroy; k->isa_create = pnv_chip_power8_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1019,6 +1037,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; k->intc_reset = pnv_chip_power8_intc_reset; + k->intc_destroy = pnv_chip_power8_intc_destroy; k->isa_create = pnv_chip_power8_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1039,6 +1058,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; k->intc_reset = pnv_chip_power8_intc_reset; + k->intc_destroy = pnv_chip_power8_intc_destroy; k->isa_create = pnv_chip_power8nvl_isa_create; k->dt_populate = pnv_chip_power8_dt_populate; k->pic_print_info = pnv_chip_power8_pic_print_info; @@ -1209,6 +1229,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->core_pir = pnv_chip_core_pir_p9; k->intc_create = pnv_chip_power9_intc_create; k->intc_reset = pnv_chip_power9_intc_reset; + k->intc_destroy = pnv_chip_power9_intc_destroy; k->isa_create = pnv_chip_power9_isa_create; k->dt_populate = pnv_chip_power9_dt_populate; k->pic_print_info = pnv_chip_power9_pic_print_info; diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index e81cd3a3e0..61b3d3ce22 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -269,11 +269,12 @@ err: error_propagate(errp, local_err); } -static void pnv_core_cpu_unrealize(PowerPCCPU *cpu) +static void pnv_core_cpu_unrealize(PowerPCCPU *cpu, PnvChip *chip) { PnvCPUState *pnv_cpu = pnv_cpu_state(cpu); + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); - object_unparent(OBJECT(pnv_cpu_state(cpu)->intc)); + pcc->intc_destroy(chip, cpu); cpu_remove_sync(CPU(cpu)); cpu->machine_data = NULL; g_free(pnv_cpu); @@ -289,7 +290,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp) qemu_unregister_reset(pnv_core_reset, pc); for (i = 0; i < cc->nr_threads; i++) { - pnv_core_cpu_unrealize(pc->threads[i]); + pnv_core_cpu_unrealize(pc->threads[i], pc->chip); } g_free(pc->threads); } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 94f9d27096..e076f6023c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -917,7 +917,7 @@ static bool spapr_hotplugged_dev_before_cas(void) return false; } -static void *spapr_build_fdt(SpaprMachineState *spapr); +static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset); int spapr_h_cas_compose_response(SpaprMachineState *spapr, target_ulong addr, target_ulong size, @@ -939,7 +939,7 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr, size -= sizeof(hdr); - fdt = spapr_build_fdt(spapr); + fdt = spapr_build_fdt(spapr, false); _FDT((fdt_pack(fdt))); if (fdt_totalsize(fdt) + sizeof(hdr) > size) { @@ -1197,7 +1197,7 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt) } } -static void *spapr_build_fdt(SpaprMachineState *spapr) +static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset) { MachineState *machine = MACHINE(spapr); MachineClass *mc = MACHINE_GET_CLASS(machine); @@ -1297,7 +1297,9 @@ static void *spapr_build_fdt(SpaprMachineState *spapr) spapr_dt_rtas(spapr, fdt); /* /chosen */ - spapr_dt_chosen(spapr, fdt); + if (reset) { + spapr_dt_chosen(spapr, fdt); + } /* /hypervisor */ if (kvm_enabled()) { @@ -1305,11 +1307,14 @@ static void *spapr_build_fdt(SpaprMachineState *spapr) } /* Build memory reserve map */ - if (spapr->kernel_size) { - _FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size))); - } - if (spapr->initrd_size) { - _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, spapr->initrd_size))); + if (reset) { + if (spapr->kernel_size) { + _FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size))); + } + if (spapr->initrd_size) { + _FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, + spapr->initrd_size))); + } } /* ibm,client-architecture-support updates */ @@ -1718,7 +1723,7 @@ static void spapr_machine_reset(MachineState *machine) */ fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE; - fdt = spapr_build_fdt(spapr); + fdt = spapr_build_fdt(spapr, true); rc = fdt_pack(fdt); diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ef7b27a66d..8339c4c0f8 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -195,12 +195,7 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) if (!sc->pre_3_0_migration) { vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data); } - if (spapr_cpu_state(cpu)->icp) { - object_unparent(OBJECT(spapr_cpu_state(cpu)->icp)); - } - if (spapr_cpu_state(cpu)->tctx) { - object_unparent(OBJECT(spapr_cpu_state(cpu)->tctx)); - } + spapr_irq_cpu_intc_destroy(SPAPR_MACHINE(qdev_get_machine()), cpu); cpu_remove_sync(CPU(cpu)); object_unparent(OBJECT(cpu)); } diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index b941608b69..168044be85 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -234,6 +234,20 @@ void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu) } } +void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu) +{ + SpaprInterruptController *intcs[] = ALL_INTCS(spapr); + int i; + + for (i = 0; i < ARRAY_SIZE(intcs); i++) { + SpaprInterruptController *intc = intcs[i]; + if (intc) { + SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); + sicc->cpu_intc_destroy(intc, cpu); + } + } +} + static void spapr_set_irq(void *opaque, int irq, int level) { SpaprMachineState *spapr = SPAPR_MACHINE(opaque); diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c index 3a982752a2..c57cf83165 100644 --- a/hw/rtc/pl031.c +++ b/hw/rtc/pl031.c @@ -149,11 +149,7 @@ static void pl031_write(void * opaque, hwaddr offset, pl031_update(s); break; case RTC_ICR: - /* The PL031 documentation (DDI0224B) states that the interrupt is - cleared when bit 0 of the written value is set. However the - arm926e documentation (DDI0287B) states that the interrupt is - cleared when any value is written. */ - s->is = 0; + s->is &= ~value; pl031_update(s); break; case RTC_CR: diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index a309c712ca..0d6c2e1a61 100644 --- a/hw/ssi/xilinx_spips.c +++ b/hw/ssi/xilinx_spips.c @@ -109,6 +109,7 @@ #define R_GPIO (0x30 / 4) #define R_LPBK_DLY_ADJ (0x38 / 4) #define R_LPBK_DLY_ADJ_RESET (0x33) +#define R_IOU_TAPDLY_BYPASS (0x3C / 4) #define R_TXD1 (0x80 / 4) #define R_TXD2 (0x84 / 4) #define R_TXD3 (0x88 / 4) @@ -139,6 +140,8 @@ #define R_LQSPI_STS (0xA4 / 4) #define LQSPI_STS_WR_RECVD (1 << 1) +#define R_DUMMY_CYCLE_EN (0xC8 / 4) +#define R_ECO (0xF8 / 4) #define R_MOD_ID (0xFC / 4) #define R_GQSPI_SELECT (0x144 / 4) @@ -970,6 +973,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr, { int mask = ~0; XilinxSPIPS *s = opaque; + bool try_flush = true; DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value); addr >>= 2; @@ -1019,13 +1023,23 @@ static void xilinx_spips_write(void *opaque, hwaddr addr, tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3, s->regs[R_CONFIG] & R_CONFIG_ENDIAN); goto no_reg_update; + /* Skip SPI bus update for below registers writes */ + case R_GPIO: + case R_LPBK_DLY_ADJ: + case R_IOU_TAPDLY_BYPASS: + case R_DUMMY_CYCLE_EN: + case R_ECO: + try_flush = false; + break; } s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); no_reg_update: - xilinx_spips_update_cs_lines(s); - xilinx_spips_check_flush(s); - xilinx_spips_update_cs_lines(s); - xilinx_spips_update_ixr(s); + if (try_flush) { + xilinx_spips_update_cs_lines(s); + xilinx_spips_check_flush(s); + xilinx_spips_update_cs_lines(s); + xilinx_spips_update_ixr(s); + } } static const MemoryRegionOps spips_ops = { diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index e6569a7968..0c55883bba 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -2737,9 +2737,10 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) error_setg(&vdev->migration_blocker, "VFIO device doesn't support migration"); ret = migrate_add_blocker(vdev->migration_blocker, &err); - if (err) { + if (ret) { error_propagate(errp, err); error_free(vdev->migration_blocker); + vdev->migration_blocker = NULL; return; } } @@ -3023,6 +3024,7 @@ error: if (vdev->migration_blocker) { migrate_del_blocker(vdev->migration_blocker); error_free(vdev->migration_blocker); + vdev->migration_blocker = NULL; } } diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index 958e7474fb..e2b20ecab9 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -14,6 +14,8 @@ typedef enum BitmapCheckFlags { BDRV_BITMAP_INCONSISTENT) #define BDRV_BITMAP_ALLOW_RO (BDRV_BITMAP_BUSY | BDRV_BITMAP_INCONSISTENT) +#define BDRV_BITMAP_MAX_NAME_SIZE 1023 + BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, uint32_t granularity, const char *name, diff --git a/include/block/nbd.h b/include/block/nbd.h index 316fd705a9..7f46932d80 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -226,12 +226,12 @@ enum { /* Maximum size of a single READ/WRITE data buffer */ #define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024) -/* Maximum size of an export name. The NBD spec requires 256 and - * suggests that servers support up to 4096, but we stick to only the - * required size so that we can stack-allocate the names, and because - * going larger would require an audit of more code to make sure we - * aren't overflowing some other buffer. */ -#define NBD_MAX_NAME_SIZE 256 +/* + * Maximum size of a protocol string (export name, meta context name, + * etc.). Use malloc rather than stack allocation for storage of a + * string. + */ +#define NBD_MAX_STRING_SIZE 4096 /* Two types of reply structures */ #define NBD_SIMPLE_REPLY_MAGIC 0x67446698 diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 2a780e633f..0b4c722e6b 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -112,6 +112,7 @@ typedef struct PnvChipClass { uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp); void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu); + void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu); ISABus *(*isa_create)(PnvChip *chip, Error **errp); void (*dt_populate)(PnvChip *chip, void *fdt); void (*pic_print_info)(PnvChip *chip, Monitor *mon); diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 09232999b0..ff814d13de 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -53,6 +53,7 @@ typedef struct SpaprInterruptControllerClass { int (*cpu_intc_create)(SpaprInterruptController *intc, PowerPCCPU *cpu, Error **errp); void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu); + void (*cpu_intc_destroy)(SpaprInterruptController *intc, PowerPCCPU *cpu); int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi, Error **errp); void (*free_irq)(SpaprInterruptController *intc, int irq); @@ -70,6 +71,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr); int spapr_irq_cpu_intc_create(SpaprMachineState *spapr, PowerPCCPU *cpu, Error **errp); void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu); +void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu); void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon); void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt, uint32_t phandle); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 602173c122..48a75aa4ab 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -181,6 +181,7 @@ void icp_resend(ICPState *ss); Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp); +void icp_destroy(ICPState *icp); /* KVM */ void icp_get_kvm_state(ICPState *icp); diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 99381639f5..8fd439ec9b 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -416,6 +416,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size); void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon); Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp); void xive_tctx_reset(XiveTCTX *tctx); +void xive_tctx_destroy(XiveTCTX *tctx); static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx) { diff --git a/monitor/qmp.c b/monitor/qmp.c index 9d9e5d8b27..b67a8e7d1f 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -75,10 +75,35 @@ static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon) } } -static void monitor_qmp_cleanup_queues(MonitorQMP *mon) +static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon) { qemu_mutex_lock(&mon->qmp_queue_lock); + + /* + * Same condition as in monitor_qmp_bh_dispatcher(), but before + * removing an element from the queue (hence no `- 1`). + * Also, the queue should not be empty either, otherwise the + * monitor hasn't been suspended yet (or was already resumed). + */ + bool need_resume = (!qmp_oob_enabled(mon) || + mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX) + && !g_queue_is_empty(mon->qmp_requests); + monitor_qmp_cleanup_req_queue_locked(mon); + + if (need_resume) { + /* + * handle_qmp_command() suspended the monitor because the + * request queue filled up, to be resumed when the queue has + * space again. We just emptied it; resume the monitor. + * + * Without this, the monitor would remain suspended forever + * when we get here while the monitor is suspended. An + * unfortunately timed CHR_EVENT_CLOSED can do the trick. + */ + monitor_resume(&mon->common); + } + qemu_mutex_unlock(&mon->qmp_queue_lock); } @@ -263,9 +288,10 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) /* * Suspend the monitor when we can't queue more requests after - * this one. Dequeuing in monitor_qmp_bh_dispatcher() will resume - * it. Note that when OOB is disabled, we queue at most one - * command, for backward compatibility. + * this one. Dequeuing in monitor_qmp_bh_dispatcher() or + * monitor_qmp_cleanup_queue_and_resume() will resume it. + * Note that when OOB is disabled, we queue at most one command, + * for backward compatibility. */ if (!qmp_oob_enabled(mon) || mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) { @@ -332,7 +358,7 @@ static void monitor_qmp_event(void *opaque, int event) * stdio, it's possible that stdout is still open when stdin * is closed. */ - monitor_qmp_cleanup_queues(mon); + monitor_qmp_cleanup_queue_and_resume(mon); json_message_parser_destroy(&mon->parser); json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL); diff --git a/nbd/client.c b/nbd/client.c index f6733962b4..ba173108ba 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -289,8 +289,8 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, char **description, return -1; } len -= sizeof(namelen); - if (len < namelen) { - error_setg(errp, "incorrect option name length"); + if (len < namelen || namelen > NBD_MAX_STRING_SIZE) { + error_setg(errp, "incorrect name length in server's list response"); nbd_send_opt_abort(ioc); return -1; } @@ -303,6 +303,12 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, char **description, local_name[namelen] = '\0'; len -= namelen; if (len) { + if (len > NBD_MAX_STRING_SIZE) { + error_setg(errp, "incorrect description length in server's " + "list response"); + nbd_send_opt_abort(ioc); + return -1; + } local_desc = g_malloc(len + 1); if (nbd_read(ioc, local_desc, len, "export description", errp) < 0) { nbd_send_opt_abort(ioc); @@ -479,6 +485,10 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt, break; default: + /* + * Not worth the bother to check if NBD_INFO_NAME or + * NBD_INFO_DESCRIPTION exceed NBD_MAX_STRING_SIZE. + */ trace_nbd_opt_info_unknown(type, nbd_info_lookup(type)); if (nbd_drop(ioc, len, errp) < 0) { error_prepend(errp, "Failed to read info payload: "); @@ -645,9 +655,11 @@ static int nbd_send_meta_query(QIOChannel *ioc, uint32_t opt, char *p; data_len = sizeof(export_len) + export_len + sizeof(queries); + assert(export_len <= NBD_MAX_STRING_SIZE); if (query) { query_len = strlen(query); data_len += sizeof(query_len) + query_len; + assert(query_len <= NBD_MAX_STRING_SIZE); } else { assert(opt == NBD_OPT_LIST_META_CONTEXT); } @@ -1009,7 +1021,7 @@ int nbd_receive_negotiate(AioContext *aio_context, QIOChannel *ioc, bool zeroes; bool base_allocation = info->base_allocation; - assert(info->name); + assert(info->name && strlen(info->name) <= NBD_MAX_STRING_SIZE); trace_nbd_receive_negotiate_name(info->name); result = nbd_start_negotiate(aio_context, ioc, tlscreds, hostname, outioc, diff --git a/nbd/server.c b/nbd/server.c index d8d1e62455..24ebc1a805 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -321,41 +321,45 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp) /* nbd_opt_read_name * * Read a string with the format: - * uint32_t len (<= NBD_MAX_NAME_SIZE) + * uint32_t len (<= NBD_MAX_STRING_SIZE) * len bytes string (not 0-terminated) * - * @name should be enough to store NBD_MAX_NAME_SIZE+1. + * On success, @name will be allocated. * If @length is non-null, it will be set to the actual string length. * * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_opt_read_name(NBDClient *client, char *name, uint32_t *length, +static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, Error **errp) { int ret; uint32_t len; + g_autofree char *local_name = NULL; + *name = NULL; ret = nbd_opt_read(client, &len, sizeof(len), errp); if (ret <= 0) { return ret; } len = cpu_to_be32(len); - if (len > NBD_MAX_NAME_SIZE) { + if (len > NBD_MAX_STRING_SIZE) { return nbd_opt_invalid(client, errp, "Invalid name length: %" PRIu32, len); } - ret = nbd_opt_read(client, name, len, errp); + local_name = g_malloc(len + 1); + ret = nbd_opt_read(client, local_name, len, errp); if (ret <= 0) { return ret; } - name[len] = '\0'; + local_name[len] = '\0'; if (length) { *length = len; } + *name = g_steal_pointer(&local_name); return 1; } @@ -375,6 +379,7 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, trace_nbd_negotiate_send_rep_list(name, desc); name_len = strlen(name); desc_len = strlen(desc); + assert(name_len <= NBD_MAX_STRING_SIZE && desc_len <= NBD_MAX_STRING_SIZE); len = name_len + desc_len + sizeof(len); ret = nbd_negotiate_send_rep_len(client, NBD_REP_SERVER, len, errp); if (ret < 0) { @@ -427,7 +432,7 @@ static void nbd_check_meta_export(NBDClient *client) static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, Error **errp) { - char name[NBD_MAX_NAME_SIZE + 1]; + g_autofree char *name = NULL; char buf[NBD_REPLY_EXPORT_NAME_SIZE] = ""; size_t len; int ret; @@ -441,10 +446,11 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes, [10 .. 133] reserved (0) [unless no_zeroes] */ trace_nbd_negotiate_handle_export_name(); - if (client->optlen >= sizeof(name)) { + if (client->optlen > NBD_MAX_STRING_SIZE) { error_setg(errp, "Bad length received"); return -EINVAL; } + name = g_malloc(client->optlen + 1); if (nbd_read(client->ioc, name, client->optlen, "export name", errp) < 0) { return -EIO; } @@ -533,7 +539,7 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp) static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) { int rc; - char name[NBD_MAX_NAME_SIZE + 1]; + g_autofree char *name = NULL; NBDExport *exp; uint16_t requests; uint16_t request; @@ -551,7 +557,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) 2 bytes: N, number of requests (can be 0) N * 2 bytes: N requests */ - rc = nbd_opt_read_name(client, name, &namelen, errp); + rc = nbd_opt_read_name(client, &name, &namelen, errp); if (rc <= 0) { return rc; } @@ -608,6 +614,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) if (exp->description) { size_t len = strlen(exp->description); + assert(len <= NBD_MAX_STRING_SIZE); rc = nbd_negotiate_send_info(client, NBD_INFO_DESCRIPTION, len, exp->description, errp); if (rc < 0) { @@ -752,6 +759,7 @@ static int nbd_negotiate_send_meta_context(NBDClient *client, {.iov_base = (void *)context, .iov_len = strlen(context)} }; + assert(iov[1].iov_len <= NBD_MAX_STRING_SIZE); if (client->opt == NBD_OPT_LIST_META_CONTEXT) { context_id = 0; } @@ -900,7 +908,7 @@ static int nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta, * Parse namespace name and call corresponding function to parse body of the * query. * - * The only supported namespace now is 'base'. + * The only supported namespaces are 'base' and 'qemu'. * * The function aims not wasting time and memory to read long unknown namespace * names. @@ -926,6 +934,10 @@ static int nbd_negotiate_meta_query(NBDClient *client, } len = cpu_to_be32(len); + if (len > NBD_MAX_STRING_SIZE) { + trace_nbd_negotiate_meta_query_skip("length too long"); + return nbd_opt_skip(client, len, errp); + } if (len < ns_len) { trace_nbd_negotiate_meta_query_skip("length too short"); return nbd_opt_skip(client, len, errp); @@ -957,7 +969,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, NBDExportMetaContexts *meta, Error **errp) { int ret; - char export_name[NBD_MAX_NAME_SIZE + 1]; + g_autofree char *export_name = NULL; NBDExportMetaContexts local_meta; uint32_t nb_queries; int i; @@ -976,7 +988,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, memset(meta, 0, sizeof(*meta)); - ret = nbd_opt_read_name(client, export_name, NULL, errp); + ret = nbd_opt_read_name(client, &export_name, NULL, errp); if (ret <= 0) { return ret; } @@ -1487,7 +1499,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, * access since the export could be available before migration handover. * ctx was acquired in the caller. */ - assert(name); + assert(name && strlen(name) <= NBD_MAX_STRING_SIZE); ctx = bdrv_get_aio_context(bs); bdrv_invalidate_cache(bs, NULL); @@ -1513,6 +1525,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, assert(dev_offset <= INT64_MAX); exp->dev_offset = dev_offset; exp->name = g_strdup(name); + assert(!desc || strlen(desc) <= NBD_MAX_STRING_SIZE); exp->description = g_strdup(desc); exp->nbdflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA | NBD_FLAG_SEND_CACHE); @@ -1559,8 +1572,10 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, bdrv_dirty_bitmap_set_busy(bm, true); exp->export_bitmap = bm; + assert(strlen(bitmap) <= BDRV_BITMAP_MAX_NAME_SIZE); exp->export_bitmap_context = g_strdup_printf("qemu:dirty-bitmap:%s", bitmap); + assert(strlen(exp->export_bitmap_context) < NBD_MAX_STRING_SIZE); } exp->close = close; diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin Binary files differindex c77468d5e6..40e7e67a9b 100644 --- a/pc-bios/bios-256k.bin +++ b/pc-bios/bios-256k.bin diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin Binary files differindex a84adde296..97b1e239aa 100644 --- a/pc-bios/bios.bin +++ b/pc-bios/bios.bin diff --git a/pc-bios/vgabios-ati.bin b/pc-bios/vgabios-ati.bin Binary files differindex df9da73099..b5314fb66c 100644 --- a/pc-bios/vgabios-ati.bin +++ b/pc-bios/vgabios-ati.bin diff --git a/pc-bios/vgabios-bochs-display.bin b/pc-bios/vgabios-bochs-display.bin Binary files differindex 8ab76bd755..5033cc8433 100644 --- a/pc-bios/vgabios-bochs-display.bin +++ b/pc-bios/vgabios-bochs-display.bin diff --git a/pc-bios/vgabios-cirrus.bin b/pc-bios/vgabios-cirrus.bin Binary files differindex 0a3ae298ac..4a3643903f 100644 --- a/pc-bios/vgabios-cirrus.bin +++ b/pc-bios/vgabios-cirrus.bin diff --git a/pc-bios/vgabios-qxl.bin b/pc-bios/vgabios-qxl.bin Binary files differindex 6d56fdf64f..f6811bcc8b 100644 --- a/pc-bios/vgabios-qxl.bin +++ b/pc-bios/vgabios-qxl.bin diff --git a/pc-bios/vgabios-ramfb.bin b/pc-bios/vgabios-ramfb.bin Binary files differindex 1214549b38..79986b26cf 100644 --- a/pc-bios/vgabios-ramfb.bin +++ b/pc-bios/vgabios-ramfb.bin diff --git a/pc-bios/vgabios-stdvga.bin b/pc-bios/vgabios-stdvga.bin Binary files differindex d7274d8b4f..d709ec60a0 100644 --- a/pc-bios/vgabios-stdvga.bin +++ b/pc-bios/vgabios-stdvga.bin diff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin Binary files differindex 2420a9462c..b99faf4ccc 100644 --- a/pc-bios/vgabios-virtio.bin +++ b/pc-bios/vgabios-virtio.bin diff --git a/pc-bios/vgabios-vmware.bin b/pc-bios/vgabios-vmware.bin Binary files differindex a89b9df1a6..8c92ab76f7 100644 --- a/pc-bios/vgabios-vmware.bin +++ b/pc-bios/vgabios-vmware.bin diff --git a/pc-bios/vgabios.bin b/pc-bios/vgabios.bin Binary files differindex a43eae8c61..aeae0364ad 100644 --- a/pc-bios/vgabios.bin +++ b/pc-bios/vgabios.bin diff --git a/qapi/block-core.json b/qapi/block-core.json index aa97ee2641..0cf68fea14 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2042,7 +2042,7 @@ # # @node: name of device/node which the bitmap is tracking # -# @name: name of the dirty bitmap +# @name: name of the dirty bitmap (must be less than 1024 bytes) # # @granularity: the bitmap granularity, default is 64k for # block-dirty-bitmap-add diff --git a/qemu-nbd.c b/qemu-nbd.c index caacf0ed73..108a51f7eb 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -833,9 +833,18 @@ int main(int argc, char **argv) break; case 'x': export_name = optarg; + if (strlen(export_name) > NBD_MAX_STRING_SIZE) { + error_report("export name '%s' too long", export_name); + exit(EXIT_FAILURE); + } break; case 'D': export_description = optarg; + if (strlen(export_description) > NBD_MAX_STRING_SIZE) { + error_report("export description '%s' too long", + export_description); + exit(EXIT_FAILURE); + } break; case 'v': verbose = 1; diff --git a/roms/seabios b/roms/seabios -Subproject 3bdd2b77656124e3fa7693fbfd7a06f74c38eb8 +Subproject c9ba5276e3217ac6a1ec772dbebf568ba3a8a55 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index e1a66a2d1c..83a809d4ba 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -185,12 +185,9 @@ typedef struct { #ifdef TARGET_AARCH64 # define ARM_MAX_VQ 16 void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp); -uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq); #else # define ARM_MAX_VQ 1 static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { } -static inline uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq) -{ return 0; } #endif typedef struct ARMVectorReg { @@ -1317,6 +1314,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) if (mask & XPSR_GE) { env->GE = (val & XPSR_GE) >> 16; } +#ifndef CONFIG_USER_ONLY if (mask & XPSR_T) { env->thumb = ((val & XPSR_T) != 0); } @@ -1332,6 +1330,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) /* Note that this only happens on exception exit */ write_v7m_exception(env, val & XPSR_EXCP); } +#endif } #define HCR_VM (1ULL << 0) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 68baf0482f..a39d6fcea3 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -458,21 +458,6 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) cpu->sve_max_vq = max_vq; } -uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq) -{ - uint32_t bitnum; - - /* - * We allow vq == ARM_MAX_VQ + 1 to be input because the caller may want - * to find the maximum vq enabled, which may be ARM_MAX_VQ, but this - * function always returns the next smaller than the input. - */ - assert(vq && vq <= ARM_MAX_VQ + 1); - - bitnum = find_last_bit(cpu->sve_vq_map, vq - 1); - return bitnum == vq - 1 ? 0 : bitnum + 1; -} - static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { diff --git a/target/arm/helper.c b/target/arm/helper.c index be67e2c66d..a089fb5a69 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -5363,9 +5363,14 @@ int sve_exception_el(CPUARMState *env, int el) static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len) { - uint32_t start_vq = (start_len & 0xf) + 1; + uint32_t end_len; - return arm_cpu_vq_map_next_smaller(cpu, start_vq + 1) - 1; + end_len = start_len &= 0xf; + if (!test_bit(start_len, cpu->sve_vq_map)) { + end_len = find_last_bit(cpu->sve_vq_map, start_len); + assert(end_len < start_len); + } + return end_len; } /* diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index f2512e448e..4a48b79252 100644 --- a/target/arm/m_helper.c +++ b/target/arm/m_helper.c @@ -33,22 +33,82 @@ #include "exec/cpu_ldst.h" #endif +static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask, + uint32_t reg, uint32_t val) +{ + /* Only APSR is actually writable */ + if (!(reg & 4)) { + uint32_t apsrmask = 0; + + if (mask & 8) { + apsrmask |= XPSR_NZCV | XPSR_Q; + } + if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) { + apsrmask |= XPSR_GE; + } + xpsr_write(env, val, apsrmask); + } +} + +static uint32_t v7m_mrs_xpsr(CPUARMState *env, uint32_t reg, unsigned el) +{ + uint32_t mask = 0; + + if ((reg & 1) && el) { + mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */ + } + if (!(reg & 4)) { + mask |= XPSR_NZCV | XPSR_Q; /* APSR */ + if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) { + mask |= XPSR_GE; + } + } + /* EPSR reads as zero */ + return xpsr_read(env) & mask; +} + +static uint32_t v7m_mrs_control(CPUARMState *env, uint32_t secure) +{ + uint32_t value = env->v7m.control[secure]; + + if (!secure) { + /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */ + value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK; + } + return value; +} + #ifdef CONFIG_USER_ONLY -/* These should probably raise undefined insn exceptions. */ -void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) +void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) { - ARMCPU *cpu = env_archcpu(env); + uint32_t mask = extract32(maskreg, 8, 4); + uint32_t reg = extract32(maskreg, 0, 8); - cpu_abort(CPU(cpu), "v7m_msr %d\n", reg); + switch (reg) { + case 0 ... 7: /* xPSR sub-fields */ + v7m_msr_xpsr(env, mask, reg, val); + break; + case 20: /* CONTROL */ + /* There are no sub-fields that are actually writable from EL0. */ + break; + default: + /* Unprivileged writes to other registers are ignored */ + break; + } } uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) { - ARMCPU *cpu = env_archcpu(env); - - cpu_abort(CPU(cpu), "v7m_mrs %d\n", reg); - return 0; + switch (reg) { + case 0 ... 7: /* xPSR sub-fields */ + return v7m_mrs_xpsr(env, reg, 0); + case 20: /* CONTROL */ + return v7m_mrs_control(env, 0); + default: + /* Unprivileged reads others as zero. */ + return 0; + } } void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest) @@ -2196,35 +2256,14 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) { - uint32_t mask; unsigned el = arm_current_el(env); /* First handle registers which unprivileged can read */ - switch (reg) { case 0 ... 7: /* xPSR sub-fields */ - mask = 0; - if ((reg & 1) && el) { - mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */ - } - if (!(reg & 4)) { - mask |= XPSR_NZCV | XPSR_Q; /* APSR */ - if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) { - mask |= XPSR_GE; - } - } - /* EPSR reads as zero */ - return xpsr_read(env) & mask; - break; + return v7m_mrs_xpsr(env, reg, el); case 20: /* CONTROL */ - { - uint32_t value = env->v7m.control[env->v7m.secure]; - if (!env->v7m.secure) { - /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */ - value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK; - } - return value; - } + return v7m_mrs_control(env, env->v7m.secure); case 0x94: /* CONTROL_NS */ /* * We have to handle this here because unprivileged Secure code @@ -2454,18 +2493,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) switch (reg) { case 0 ... 7: /* xPSR sub-fields */ - /* only APSR is actually writable */ - if (!(reg & 4)) { - uint32_t apsrmask = 0; - - if (mask & 8) { - apsrmask |= XPSR_NZCV | XPSR_Q; - } - if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) { - apsrmask |= XPSR_GE; - } - xpsr_write(env, val, apsrmask); - } + v7m_msr_xpsr(env, mask, reg, val); break; case 8: /* MSP */ if (v7m_using_psp(env)) { diff --git a/target/arm/translate.c b/target/arm/translate.c index 2ea9da7637..4d5d4bd888 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -8927,15 +8927,17 @@ static bool trans_SWPB(DisasContext *s, arg_SWP *a) static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel) { TCGv_i32 addr; + /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */ + bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M); /* We UNDEF for these UNPREDICTABLE cases. */ if (a->rd == 15 || a->rn == 15 || a->rt == 15 || a->rd == a->rn || a->rd == a->rt - || (s->thumb && (a->rd == 13 || a->rt == 13)) + || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13)) || (mop == MO_64 && (a->rt2 == 15 - || a->rd == a->rt2 || a->rt == a->rt2 - || (s->thumb && a->rt2 == 13)))) { + || a->rd == a->rt2 + || (!v8a && s->thumb && a->rt2 == 13)))) { unallocated_encoding(s); return true; } @@ -9084,13 +9086,15 @@ static bool trans_STLH(DisasContext *s, arg_STL *a) static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq) { TCGv_i32 addr; + /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */ + bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M); /* We UNDEF for these UNPREDICTABLE cases. */ if (a->rn == 15 || a->rt == 15 - || (s->thumb && a->rt == 13) + || (!v8a && s->thumb && a->rt == 13) || (mop == MO_64 && (a->rt2 == 15 || a->rt == a->rt2 - || (s->thumb && a->rt2 == 13)))) { + || (!v8a && s->thumb && a->rt2 == 13)))) { unallocated_encoding(s); return true; } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 7d2e8969ac..c77f9848ec 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -100,7 +100,7 @@ static bool kvmppc_is_pr(KVMState *ks) return kvm_vm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0; } -static int kvm_ppc_register_host_cpu_type(MachineState *ms); +static int kvm_ppc_register_host_cpu_type(void); static void kvmppc_get_cpu_characteristics(KVMState *s); static int kvmppc_get_dec_bits(void); @@ -147,7 +147,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) exit(1); } - kvm_ppc_register_host_cpu_type(ms); + kvm_ppc_register_host_cpu_type(); return 0; } @@ -2534,13 +2534,19 @@ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void) return pvr_pcc; } -static int kvm_ppc_register_host_cpu_type(MachineState *ms) +static void pseries_machine_class_fixup(ObjectClass *oc, void *opaque) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->default_cpu_type = TYPE_HOST_POWERPC_CPU; +} + +static int kvm_ppc_register_host_cpu_type(void) { TypeInfo type_info = { .name = TYPE_HOST_POWERPC_CPU, .class_init = kvmppc_host_cpu_class_init, }; - MachineClass *mc = MACHINE_GET_CLASS(ms); PowerPCCPUClass *pvr_pcc; ObjectClass *oc; DeviceClass *dc; @@ -2552,10 +2558,9 @@ static int kvm_ppc_register_host_cpu_type(MachineState *ms) } type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc)); type_register(&type_info); - if (object_dynamic_cast(OBJECT(ms), TYPE_SPAPR_MACHINE)) { - /* override TCG default cpu type with 'host' cpu model */ - mc->default_cpu_type = TYPE_HOST_POWERPC_CPU; - } + /* override TCG default cpu type with 'host' cpu model */ + object_class_foreach(pseries_machine_class_fixup, TYPE_SPAPR_MACHINE, + false, NULL); oc = object_class_by_name(type_info.name); g_assert(oc); diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out index 2a5f256cd3..bb50227b82 100644 --- a/tests/qemu-iotests/085.out +++ b/tests/qemu-iotests/085.out @@ -7,48 +7,61 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 === Sending capabilities === +{ 'execute': 'qmp_capabilities' } {"return": {}} === Create a single snapshot on virtio0 === +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } } Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} === Invalid command - missing device and nodename === +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } } {"error": {"class": "GenericError", "desc": "Cannot find device= nor node_name="}} === Invalid command - missing snapshot-file === +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'format': 'IMGFMT' } } {"error": {"class": "GenericError", "desc": "Parameter 'snapshot-file' is missing"}} === Create several transactional group snapshots === +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } } Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} @@ -56,35 +69,48 @@ Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_fil === Create a couple of snapshots using blockdev-snapshot === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/10-snapshot-v0.IMGFMT +{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_11', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/11-snapshot-v0.IMGFMT', 'node-name': 'file_11' } } } {"return": {}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } } {"return": {}} Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/11-snapshot-v0.IMGFMT +{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_12', 'backing': null, 'file': { 'driver': 'file', 'filename': 'TEST_DIR/12-snapshot-v0.IMGFMT', 'node-name': 'file_12' } } } {"return": {}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_12' } } {"return": {}} === Invalid command - cannot create a snapshot using a file BDS === +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'file_12' } } {"error": {"class": "GenericError", "desc": "The overlay does not support backing images"}} === Invalid command - snapshot node used as active layer === +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_12' } } {"error": {"class": "GenericError", "desc": "The overlay is already in use"}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'virtio0' } } {"error": {"class": "GenericError", "desc": "The overlay is already in use"}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'virtio1' } } {"error": {"class": "GenericError", "desc": "The overlay is already in use"}} === Invalid command - snapshot node used as backing hd === +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } } {"error": {"class": "GenericError", "desc": "Node 'snap_11' is busy: node is used as backing hd of 'snap_12'"}} === Invalid command - snapshot node has a backing image === Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base +{ 'execute': 'blockdev-add', 'arguments': { 'driver': 'IMGFMT', 'node-name': 'snap_13', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'node-name': 'file_13' } } } {"return": {}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_13' } } {"error": {"class": "GenericError", "desc": "The overlay already has a backing image"}} === Invalid command - The node does not exist === +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_14' } } {"error": {"class": "GenericError", "desc": "Cannot find device=snap_14 nor node_name=snap_14"}} +{ 'execute': 'blockdev-snapshot', 'arguments': { 'node':'nodevice', 'overlay':'snap_13' } } {"error": {"class": "GenericError", "desc": "Cannot find device=nodevice nor node_name=nodevice"}} *** done diff --git a/tests/qemu-iotests/094.out b/tests/qemu-iotests/094.out index f3b9ecf22b..9b6c57b3e2 100644 --- a/tests/qemu-iotests/094.out +++ b/tests/qemu-iotests/094.out @@ -1,16 +1,20 @@ QA output created by 094 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/source.IMGFMT', fmt=IMGFMT size=67108864 +{'execute': 'qmp_capabilities'} {"return": {}} +{'execute': 'drive-mirror', 'arguments': {'device': 'src', 'target': 'nbd+unix:///?socket=SOCK_DIR/nbd', 'format': 'nbd', 'sync':'full', 'mode':'existing'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}} +{'execute': 'block-job-complete', 'arguments': {'device': 'src'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 67108864, "offset": 67108864, "speed": 0, "type": "mirror"}} +{'execute': 'quit'} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} {"return": {}} diff --git a/tests/qemu-iotests/095.out b/tests/qemu-iotests/095.out index d2e393fef8..614e5ccbbb 100644 --- a/tests/qemu-iotests/095.out +++ b/tests/qemu-iotests/095.out @@ -10,7 +10,9 @@ virtual size: 5 MiB (5242880 bytes) === Running QEMU Live Commit Test === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'block-commit', 'arguments': { 'device': 'test', 'top': 'TEST_DIR/t.IMGFMT.snp1' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "test"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "test"}} {"return": {}} diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out index 9c1159bf08..884f65f18d 100644 --- a/tests/qemu-iotests/109.out +++ b/tests/qemu-iotests/109.out @@ -4,7 +4,9 @@ QA output created by 109 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -16,18 +18,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -42,7 +50,9 @@ Images are identical. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -54,18 +64,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 197120, "offset": 197120, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -80,7 +96,9 @@ Images are identical. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -92,18 +110,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -118,7 +142,9 @@ Images are identical. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -130,18 +156,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 1024, "offset": 1024, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -156,7 +188,9 @@ Images are identical. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -168,18 +202,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 65536, "offset": 65536, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -194,7 +234,9 @@ Images are identical. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -206,18 +248,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -231,7 +279,9 @@ Images are identical. === Copying sample image empty.bochs into raw === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -243,18 +293,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2560, "offset": 2560, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -268,7 +324,9 @@ Images are identical. === Copying sample image iotest-dirtylog-10G-4M.vhdx into raw === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -280,18 +338,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 31457280, "offset": 31457280, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -305,7 +369,9 @@ Images are identical. === Copying sample image parallels-v1 into raw === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -317,18 +383,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 327680, "offset": 327680, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -342,7 +414,9 @@ Images are identical. === Copying sample image simple-pattern.cloop into raw === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -354,18 +428,24 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} +{"execute":"query-block-jobs"} {"return": []} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 2048, "offset": 2048, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -379,7 +459,9 @@ Images are identical. === Write legitimate MBR into raw === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}} WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw. Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted. Specify the 'raw' format explicitly to remove the restrictions. @@ -388,7 +470,9 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} @@ -398,13 +482,17 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}} Warning: Image size mismatch! Images are identical. +{ 'execute': 'qmp_capabilities' } {"return": {}} +{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "src"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "src"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} +{"execute":"query-block-jobs"} {"return": [{"auto-finalize": true, "io-status": "ok", "device": "src", "auto-dismiss": true, "busy": false, "len": 512, "offset": 512, "status": "ready", "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "src"}} diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out index 57079af167..bb623dcc0a 100644 --- a/tests/qemu-iotests/117.out +++ b/tests/qemu-iotests/117.out @@ -1,11 +1,16 @@ QA output created by 117 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'blockdev-add', 'arguments': { 'node-name': 'protocol', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' } } {"return": {}} +{ 'execute': 'blockdev-add', 'arguments': { 'node-name': 'format', 'driver': 'IMGFMT', 'file': 'protocol' } } {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io format "write -P 42 0 64k"' } } wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} No errors were found on the image. diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out index 6c98b1824e..623d52bbd1 100644 --- a/tests/qemu-iotests/127.out +++ b/tests/qemu-iotests/127.out @@ -4,16 +4,20 @@ Formatting 'TEST_DIR/t.IMGFMT.overlay0', fmt=IMGFMT size=65536 backing_file=TEST Formatting 'TEST_DIR/t.IMGFMT.overlay1', fmt=IMGFMT size=65536 backing_file=TEST_DIR/t.IMGFMT wrote 42/42 bytes at offset 0 42 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'drive-mirror', 'arguments': { 'job-id': 'mirror', 'device': 'source', 'target': 'TEST_DIR/t.IMGFMT.overlay1', 'mode': 'existing', 'sync': 'top' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} +{ 'execute': 'block-job-complete', 'arguments': { 'device': 'mirror' } } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} +{ 'execute': 'quit' } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}} {"return": {}} diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out index 2511eb7369..86b985da75 100644 --- a/tests/qemu-iotests/140.out +++ b/tests/qemu-iotests/140.out @@ -2,14 +2,19 @@ QA output created by 140 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd' }}}} {"return": {}} +{ 'execute': 'nbd-server-add', 'arguments': { 'device': 'drv' }} {"return": {}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'eject', 'arguments': { 'device': 'drv' }} {"return": {}} qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available server reported: export 'drv' not present +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} *** done diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out index e3b578282d..3645675ce8 100644 --- a/tests/qemu-iotests/141.out +++ b/tests/qemu-iotests/141.out @@ -2,82 +2,108 @@ QA output created by 141 Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=1048576 Formatting 'TEST_DIR/m.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/b.IMGFMT Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.IMGFMT +{'execute': 'qmp_capabilities'} {"return": {}} === Testing drive-backup === +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}} {"return": {}} +{'execute': 'drive-backup', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'target': 'TEST_DIR/o.IMGFMT', 'format': 'IMGFMT', 'sync': 'none'}} Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}} +{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"return": {}} === Testing drive-mirror === +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}} {"return": {}} +{'execute': 'drive-mirror', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'target': 'TEST_DIR/o.IMGFMT', 'format': 'IMGFMT', 'sync': 'none'}} Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}} +{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"return": {}} === Testing active block-commit === +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}} {"return": {}} +{'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'drv0'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}} +{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"return": {}} === Testing non-active block-commit === wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}} {"return": {}} +{'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'top': 'TEST_DIR/m.IMGFMT', 'speed': 1}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"error": {"class": "GenericError", "desc": "Node drv0 is in use"}} +{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"return": {}} === Testing block-stream === wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'drv0', 'driver': 'IMGFMT', 'file': { 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT' }}} {"return": {}} +{'execute': 'block-stream', 'arguments': {'job-id': 'job0', 'device': 'drv0', 'speed': 1}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"error": {"class": "GenericError", "desc": "Node drv0 is in use"}} +{'execute': 'block-job-cancel', 'arguments': {'device': 'job0'}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} +{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}} {"return": {}} *** done diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out index 037d34a409..1f4001c601 100644 --- a/tests/qemu-iotests/143.out +++ b/tests/qemu-iotests/143.out @@ -1,8 +1,11 @@ QA output created by 143 +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd' }}}} {"return": {}} qemu-io: can't open device nbd+unix:///no_such_export?socket=SOCK_DIR/nbd: Requested export not available server reported: export 'no_such_export' not present +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} *** done diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out index a9a8216bea..c7aa2e4820 100644 --- a/tests/qemu-iotests/144.out +++ b/tests/qemu-iotests/144.out @@ -6,17 +6,21 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912 === Performing Live Snapshot 1 === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } } Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} === Performing block-commit on active layer === +{ 'execute': 'block-commit', 'arguments': { 'device': 'virtio0' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} +{ 'execute': 'block-job-complete', 'arguments': { 'device': 'virtio0' } } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "virtio0"}} @@ -26,6 +30,7 @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/ === Performing Live Snapshot 2 === +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } } Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} *** done diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out index e969420006..f7464dd8d3 100644 --- a/tests/qemu-iotests/153.out +++ b/tests/qemu-iotests/153.out @@ -144,6 +144,7 @@ _qemu_img_wrapper bench -U -c 1 TEST_DIR/t.qcow2 _qemu_img_wrapper bench -U -w -c 1 TEST_DIR/t.qcow2 qemu-img: Could not open 'TEST_DIR/t.qcow2': force-share=on can only be used with read-only images +{ 'execute': 'quit' } Round done @@ -266,6 +267,7 @@ _qemu_img_wrapper bench -U -c 1 TEST_DIR/t.qcow2 _qemu_img_wrapper bench -U -w -c 1 TEST_DIR/t.qcow2 qemu-img: Could not open 'TEST_DIR/t.qcow2': force-share=on can only be used with read-only images +{ 'execute': 'quit' } Round done @@ -367,6 +369,7 @@ _qemu_img_wrapper bench -U -c 1 TEST_DIR/t.qcow2 _qemu_img_wrapper bench -U -w -c 1 TEST_DIR/t.qcow2 qemu-img: Could not open 'TEST_DIR/t.qcow2': force-share=on can only be used with read-only images +{ 'execute': 'quit' } Round done @@ -412,11 +415,14 @@ QEMU_PROG: -drive if=none,file=TEST_DIR/t.qcow2: Failed to get "write" lock Is another process using the image [TEST_DIR/t.qcow2]? == Active commit to intermediate layer should work when base in use == +{ 'execute': 'qmp_capabilities' } {"return": {}} _qemu_img_wrapper commit -b TEST_DIR/t.qcow2.b TEST_DIR/t.qcow2.c +{ 'execute': 'qmp_capabilities' } {"return": {}} Adding drive +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT' } } {"return": "OKrn"} _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 @@ -426,20 +432,25 @@ Creating overlay with qemu-img when the guest is running should be allowed _qemu_img_wrapper create -f qcow2 -b TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.overlay == Closing an image should unlock it == +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d0' } } {"return": ""} _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 Adding two and closing one +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d0,file=TEST_DIR/t.IMGFMT,readonly=on' } } {"return": "OKrn"} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_add 0 if=none,id=d1,file=TEST_DIR/t.IMGFMT,readonly=on' } } {"return": "OKrn"} _qemu_img_wrapper info TEST_DIR/t.qcow2 +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d0' } } {"return": ""} _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock Is another process using the image [TEST_DIR/t.qcow2]? Closing the other +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'drive_del d1' } } {"return": ""} _qemu_io_wrapper TEST_DIR/t.qcow2 -c write 0 512 diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out index 4c391a7603..084be5ad71 100644 --- a/tests/qemu-iotests/156.out +++ b/tests/qemu-iotests/156.out @@ -5,21 +5,27 @@ wrote 262144/262144 bytes at offset 0 256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) wrote 196608/196608 bytes at offset 65536 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } {"return": {}} Formatting 'TEST_DIR/t.IMGFMT.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'source', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'format': 'IMGFMT', 'mode': 'existing' } } {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "write -P 3 128k 128k"' } } wrote 131072/131072 bytes at offset 131072 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.target +{ 'execute': 'drive-mirror', 'arguments': { 'device': 'source', 'target': 'TEST_DIR/t.IMGFMT.target.overlay', 'mode': 'existing', 'sync': 'top' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "write -P 4 192k 64k"' } } wrote 65536/65536 bytes at offset 196608 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'block-job-complete', 'arguments': { 'device': 'source' } } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}} @@ -27,19 +33,24 @@ wrote 65536/65536 bytes at offset 196608 {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 1 0k 64k"' } } read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 2 64k 64k"' } } read 65536/65536 bytes at offset 65536 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 3 128k 64k"' } } read 65536/65536 bytes at offset 131072 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io source "read -P 4 192k 64k"' } } read 65536/65536 bytes at offset 196608 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out index 39951993ee..aef9741ed3 100644 --- a/tests/qemu-iotests/161.out +++ b/tests/qemu-iotests/161.out @@ -5,15 +5,20 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t. *** Change an option on the backing file +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } } {"return": ""} *** Stream and then change an option on the backing file +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'block-stream', 'arguments': { 'device': 'none0', 'base': 'TEST_DIR/t.IMGFMT.base' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}} {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}} @@ -26,10 +31,13 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t. Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576 Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'block-commit', 'arguments': { 'device': 'none0', 'top': 'TEST_DIR/t.IMGFMT.int' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}} {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}} diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173 index 9e2fa2e73c..29dcaa1960 100755 --- a/tests/qemu-iotests/173 +++ b/tests/qemu-iotests/173 @@ -47,9 +47,9 @@ size=100M BASE_IMG="${TEST_DIR}/image.base" TOP_IMG="${TEST_DIR}/image.snp1" -TEST_IMG="${BASE_IMG}" _make_test_img $size +TEST_IMG_FILE="${BASE_IMG}" _make_test_img $size -TEST_IMG="${TOP_IMG}" _make_test_img $size +TEST_IMG_FILE="${TOP_IMG}" _make_test_img $size echo echo === Running QEMU, using block-stream to find backing image === diff --git a/tests/qemu-iotests/173.out b/tests/qemu-iotests/173.out index f477a0099a..b5114b5c79 100644 --- a/tests/qemu-iotests/173.out +++ b/tests/qemu-iotests/173.out @@ -4,9 +4,17 @@ Formatting 'TEST_DIR/image.snp1', fmt=IMGFMT size=104857600 === Running QEMU, using block-stream to find backing image === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'arguments': { 'device': 'disk2', 'format': 'IMGFMT', 'mode': 'existing', 'snapshot-file': 'TEST_DIR/image.snp1', 'snapshot-node-name': 'snp1' }, 'execute': 'blockdev-snapshot-sync' } {"return": {}} +{ 'arguments': { 'backing-file': 'image.base', 'device': 'disk2', 'image-node-name': 'snp1' }, 'execute': 'change-backing-file' } {"return": {}} +{ 'arguments': { 'base': 'TEST_DIR/image.base', 'device': 'disk2' }, 'execute': 'block-stream' } +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk2"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk2"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "disk2", "len": 104857600, "offset": 104857600, "speed": 0, "type": "stream"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "disk2"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "disk2"}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "disk2", "len": 0, "offset": 0, "speed": 0, "type": "stream"}} *** done diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out index ffef23e32b..a8eea166c3 100644 --- a/tests/qemu-iotests/182.out +++ b/tests/qemu-iotests/182.out @@ -8,17 +8,25 @@ Is another process using the image [TEST_DIR/t.qcow2]? === Testing reopen === +{'execute': 'qmp_capabilities'} {"return": {}} +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } } {"return": {}} +{'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } } Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } } {"return": {}} +{'execute': 'nbd-server-start', 'arguments': { 'addr': { 'type': 'unix', 'data': { 'path': 'SOCK_DIR/nbd.socket' } } } } {"return": {}} +{'execute': 'nbd-server-add', 'arguments': { 'device': 'node1' } } {"return": {}} === Testing failure to loosen restrictions === +{'execute': 'qmp_capabilities'} {"return": {}} +{'execute': 'quit'} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} *** done diff --git a/tests/qemu-iotests/183.out b/tests/qemu-iotests/183.out index 112cf31f8b..d4be2cb2de 100644 --- a/tests/qemu-iotests/183.out +++ b/tests/qemu-iotests/183.out @@ -4,37 +4,48 @@ Formatting 'TEST_DIR/t.IMGFMT.dest', fmt=IMGFMT size=67108864 === Starting VMs === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'qmp_capabilities' } {"return": {}} === Write something on the source === +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write -P 0x55 0 64k"' } } wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "read -P 0x55 0 64k"' } } read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} === Do block migration to destination === +{ 'execute': 'migrate', 'arguments': { 'uri': 'unix:SOCK_DIR/migrate', 'blk': true } } {"return": {}} +{ 'execute': 'query-status' } {"return": {"status": "postmigrate", "singlestep": false, "running": false}} === Do some I/O on the destination === +{ 'execute': 'query-status' } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESUME"} {"return": {"status": "running", "singlestep": false, "running": true}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "read -P 0x55 0 64k"' } } read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write -P 0x66 1M 64k"' } } wrote 65536/65536 bytes at offset 1048576 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} === Shut down and check image === +{"execute":"quit"} {"return": {}} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out index ddfbf3c765..8379ac5854 100644 --- a/tests/qemu-iotests/185.out +++ b/tests/qemu-iotests/185.out @@ -3,65 +3,83 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 === Starting VM === +{ 'execute': 'qmp_capabilities' } {"return": {}} === Creating backing chain === +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } } Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} +{ 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } } wrote 4194304/4194304 bytes at offset 0 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} +{ 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } } Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"return": {}} === Start commit job and exit qemu === +{ 'execute': 'block-commit', 'arguments': { 'device': 'disk', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid', 'speed': 65536 } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "commit"}} === Start active commit job and exit qemu === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'block-commit', 'arguments': { 'device': 'disk', 'base':'TEST_DIR/t.IMGFMT.base', 'speed': 65536 } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "commit"}} === Start mirror job and exit qemu === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } } Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 4194304, "offset": 4194304, "speed": 65536, "type": "mirror"}} === Start backup job and exit qemu === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } } Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 65536, "speed": 65536, "type": "backup"}} === Start streaming job and exit qemu === +{ 'execute': 'qmp_capabilities' } {"return": {}} +{ 'execute': 'block-stream', 'arguments': { 'device': 'disk', 'speed': 65536 } } {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} +{ 'execute': 'quit' } {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "stream"}} diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out index 3fc92bb56e..34cec7b9ec 100644 --- a/tests/qemu-iotests/191.out +++ b/tests/qemu-iotests/191.out @@ -8,6 +8,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid wrote 65536/65536 bytes at offset 1048576 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } { "return": { } @@ -15,6 +16,7 @@ wrote 65536/65536 bytes at offset 1048576 === Perform commit job === +{ 'execute': 'block-commit', 'arguments': { 'job-id': 'commit0', 'device': 'top', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid' } } { "timestamp": { "seconds": TIMESTAMP, @@ -102,6 +104,7 @@ wrote 65536/65536 bytes at offset 1048576 === Check that both top and top2 point to base now === +{ 'execute': 'query-named-block-nodes' } { "return": [ { @@ -378,6 +381,7 @@ wrote 65536/65536 bytes at offset 1048576 } ] } +{ 'execute': 'quit' } { "return": { } @@ -415,6 +419,7 @@ Formatting 'TEST_DIR/t.IMGFMT.ovl2', fmt=IMGFMT size=67108864 backing_file=TEST_ Formatting 'TEST_DIR/t.IMGFMT.ovl3', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.ovl2 wrote 65536/65536 bytes at offset 1048576 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{ 'execute': 'qmp_capabilities' } { "return": { } @@ -422,6 +427,7 @@ wrote 65536/65536 bytes at offset 1048576 === Perform commit job === +{ 'execute': 'block-commit', 'arguments': { 'job-id': 'commit0', 'device': 'top', 'base':'TEST_DIR/t.IMGFMT.base', 'top': 'TEST_DIR/t.IMGFMT.mid' } } { "timestamp": { "seconds": TIMESTAMP, @@ -509,6 +515,7 @@ wrote 65536/65536 bytes at offset 1048576 === Check that both top and top2 point to base now === +{ 'execute': 'query-named-block-nodes' } { "return": [ { @@ -796,6 +803,7 @@ wrote 65536/65536 bytes at offset 1048576 } ] } +{ 'execute': 'quit' } { "return": { } diff --git a/tests/qemu-iotests/200.out b/tests/qemu-iotests/200.out index af6a809e30..a6776070e4 100644 --- a/tests/qemu-iotests/200.out +++ b/tests/qemu-iotests/200.out @@ -6,6 +6,7 @@ wrote 314572800/314572800 bytes at offset 512 === Starting QEMU VM === +{ 'execute': 'qmp_capabilities' } {"return": {}} === Sending stream/cancel, checking for SIGSEGV only === diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index b5a80e50bb..ea69cd4b8b 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -117,10 +117,19 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"qmp_capabilities"}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"blockdev-add", "arguments":{"driver":"qcow2", "node-name":"n", "file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' "return" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-blockdev-set-iothread", - "arguments":{"node-name":"n", "iothread":"io0"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"block-dirty-bitmap-disable", "arguments":{"node":"n", "name":"b"}}' "return" + +for attempt in normal iothread; do + +echo +echo "=== Set up NBD with $attempt access ===" +echo +if [ $attempt = iothread ]; then +_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-blockdev-set-iothread", + "arguments":{"node-name":"n", "iothread":"io0"}}' "return" +fi + _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", "arguments":{"device":"n"}}' "error" # Attempt add without server _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start", @@ -180,6 +189,9 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove", "arguments":{"name":"n2"}}' "error" # Attempt duplicate clean _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "error" # Again + +done + _send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return" wait=yes _cleanup_qemu diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 23b34fcd20..f175598802 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -24,19 +24,113 @@ wrote 2097152/2097152 bytes at offset 2097152 === End dirty bitmaps, and start serving image over NBD === +{"execute":"qmp_capabilities"} {"return": {}} +{"execute":"blockdev-add", "arguments":{"driver":"IMGFMT", "node-name":"n", "file":{"driver":"file", "filename":"TEST_DIR/t.IMGFMT"}}} {"return": {}} +{"execute":"block-dirty-bitmap-disable", "arguments":{"node":"n", "name":"b"}} {"return": {}} + +=== Set up NBD with normal access === + +{"execute":"nbd-server-add", "arguments":{"device":"n"}} +{"error": {"class": "GenericError", "desc": "NBD server not running"}} +{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd"}}}} +{"return": {}} +{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd1"}}}} +{"error": {"class": "GenericError", "desc": "NBD server already running"}} +exports available: 0 +{"execute":"nbd-server-add", "arguments":{"device":"n", "bitmap":"b"}} +{"return": {}} +{"execute":"nbd-server-add", "arguments":{"device":"nosuch"}} +{"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}} +{"execute":"nbd-server-add", "arguments":{"device":"n"}} +{"error": {"class": "GenericError", "desc": "NBD server already has export named 'n'"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b2"}} +{"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b3"}} +{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "writable":true, "bitmap":"b2"}} +{"return": {}} +exports available: 2 + export: 'n' + size: 4194304 + flags: 0x58f ( readonly flush fua df multi cache ) + min block: 1 + opt block: 4096 + max block: 33554432 + available meta contexts: 2 + base:allocation + qemu:dirty-bitmap:b + export: 'n2' + size: 4194304 + flags: 0xced ( flush fua trim zeroes df cache fast-zero ) + min block: 1 + opt block: 4096 + max block: 33554432 + available meta contexts: 2 + base:allocation + qemu:dirty-bitmap:b2 + +=== Contrast normal status to large granularity dirty-bitmap === + +read 512/512 bytes at offset 512 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 524288/524288 bytes at offset 524288 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 1048576/1048576 bytes at offset 1048576 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 2097152/2097152 bytes at offset 2097152 +2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false, "offset": OFFSET}, +{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true, "offset": OFFSET}] +[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, +{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] + +=== Contrast to small granularity dirty-bitmap === + +[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, +{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true, "offset": OFFSET}, +{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] + +=== End qemu NBD server === + +{"execute":"nbd-server-remove", "arguments":{"name":"n"}} +{"return": {}} +{"execute":"nbd-server-remove", "arguments":{"name":"n2"}} +{"return": {}} +{"execute":"nbd-server-remove", "arguments":{"name":"n2"}} +{"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}} +{"execute":"nbd-server-stop"} +{"return": {}} +{"execute":"nbd-server-stop"} +{"error": {"class": "GenericError", "desc": "NBD server not running"}} + +=== Set up NBD with iothread access === + +{"execute":"x-blockdev-set-iothread", "arguments":{"node-name":"n", "iothread":"io0"}} {"return": {}} +{"execute":"nbd-server-add", "arguments":{"device":"n"}} {"error": {"class": "GenericError", "desc": "NBD server not running"}} +{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd"}}}} {"return": {}} +{"execute":"nbd-server-start", "arguments":{"addr":{"type":"unix", "data":{"path":"SOCK_DIR/nbd1"}}}} {"error": {"class": "GenericError", "desc": "NBD server already running"}} exports available: 0 +{"execute":"nbd-server-add", "arguments":{"device":"n", "bitmap":"b"}} {"return": {}} +{"execute":"nbd-server-add", "arguments":{"device":"nosuch"}} {"error": {"class": "GenericError", "desc": "Cannot find device=nosuch nor node_name=nosuch"}} +{"execute":"nbd-server-add", "arguments":{"device":"n"}} {"error": {"class": "GenericError", "desc": "NBD server already has export named 'n'"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b2"}} {"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompatible with readonly export"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "bitmap":"b3"}} {"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}} +{"execute":"nbd-server-add", "arguments":{"device":"n", "name":"n2", "writable":true, "bitmap":"b2"}} {"return": {}} exports available: 2 export: 'n' @@ -84,11 +178,17 @@ read 2097152/2097152 bytes at offset 2097152 === End qemu NBD server === +{"execute":"nbd-server-remove", "arguments":{"name":"n"}} {"return": {}} +{"execute":"nbd-server-remove", "arguments":{"name":"n2"}} {"return": {}} +{"execute":"nbd-server-remove", "arguments":{"name":"n2"}} {"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}} +{"execute":"nbd-server-stop"} {"return": {}} +{"execute":"nbd-server-stop"} {"error": {"class": "GenericError", "desc": "NBD server not running"}} +{"execute":"quit"} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}} diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out index a3eb33788a..22350d75d7 100644 --- a/tests/qemu-iotests/229.out +++ b/tests/qemu-iotests/229.out @@ -3,10 +3,12 @@ Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152 Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=1048576 wrote 2097152/2097152 bytes at offset 0 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{'execute': 'qmp_capabilities'} {"return": {}} === Starting drive-mirror, causing error & stop === +{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}} {"return": {}} @@ -15,6 +17,7 @@ wrote 2097152/2097152 bytes at offset 0 === Force cancel job paused in error state === +{'execute': 'block-job-cancel', 'arguments': { 'device': 'testdisk', 'force': true}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}} {"return": {}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}} diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out index 1c93164e84..51307ed0f7 100644 --- a/tests/qemu-iotests/249.out +++ b/tests/qemu-iotests/249.out @@ -2,24 +2,29 @@ QA output created by 249 Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576 Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int +{ 'execute': 'qmp_capabilities' } {"return": {}} === Send a write command to a drive opened in read-only mode (1) +{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}} {"return": "Block node is read-onlyrn"} === Run block-commit on base using an invalid filter node name +{ 'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int', 'filter-node-name': '1234'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} {"error": {"class": "GenericError", "desc": "Invalid node name"}} === Send a write command to a drive opened in read-only mode (2) +{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}} {"return": "Block node is read-onlyrn"} === Run block-commit on base using the default filter node name +{ 'execute': 'block-commit', 'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} {"return": {}} @@ -31,5 +36,6 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t. === Send a write command to a drive opened in read-only mode (3) +{ 'execute': 'human-monitor-command', 'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}} {"return": "Block node is read-onlyrn"} *** done diff --git a/tests/qemu-iotests/273 b/tests/qemu-iotests/273 new file mode 100755 index 0000000000..98a672516d --- /dev/null +++ b/tests/qemu-iotests/273 @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +# +# Test multiple blockdev-snapshot calls with 'backing': null +# +# Copyright (C) 2019 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +seq=$(basename "$0") +echo "QA output created by $seq" + +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# This is a qcow2 regression test +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +do_run_qemu() +{ + echo Testing: "$@" + $QEMU -nographic -qmp-pretty stdio -nodefaults "$@" + echo +} + +run_qemu() +{ + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp | + _filter_generated_node_ids | _filter_imgfmt | _filter_actual_image_size +} + +TEST_IMG="$TEST_IMG.base" _make_test_img 64M +TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base" +_make_test_img -b "$TEST_IMG.mid" + +run_qemu \ + -blockdev file,node-name=base,filename="$TEST_IMG.base" \ + -blockdev file,node-name=midf,filename="$TEST_IMG.mid" \ + -blockdev '{"driver":"qcow2","node-name":"mid","file":"midf","backing":null}' \ + -blockdev file,node-name=topf,filename="$TEST_IMG" \ + -blockdev '{"driver":"qcow2","file":"topf","node-name":"top","backing":null}' \ +<<EOF +{"execute":"qmp_capabilities"} +{"execute":"blockdev-snapshot","arguments":{"node":"base","overlay":"mid"}} +{"execute":"blockdev-snapshot","arguments":{"node":"mid","overlay":"top"}} +{"execute":"query-named-block-nodes"} +{"execute":"x-debug-query-block-graph"} +{"execute":"quit"} +EOF + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out new file mode 100644 index 0000000000..c410fee5c4 --- /dev/null +++ b/tests/qemu-iotests/273.out @@ -0,0 +1,337 @@ +QA output created by 273 +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 +Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid +Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev file,node-name=midf,filename=TEST_DIR/t.IMGFMT.mid -blockdev {"driver":"IMGFMT","node-name":"mid","file":"midf","backing":null} -blockdev file,node-name=topf,filename=TEST_DIR/t.IMGFMT -blockdev {"driver":"IMGFMT","file":"topf","node-name":"top","backing":null} +{ + QMP_VERSION +} +{ + "return": { + } +} +{ + "return": { + } +} +{ + "return": { + } +} +{ + "return": [ + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-image": { + "backing-image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.base", + "format": "file", + "actual-size": SIZE, + "dirty-flag": false + }, + "backing-filename-format": "file", + "virtual-size": 67108864, + "filename": "TEST_DIR/t.IMGFMT.mid", + "cluster-size": 65536, + "format": "IMGFMT", + "actual-size": SIZE, + "format-specific": { + "type": "IMGFMT", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "TEST_DIR/t.IMGFMT.base", + "backing-filename": "TEST_DIR/t.IMGFMT.base", + "dirty-flag": false + }, + "backing-filename-format": "IMGFMT", + "virtual-size": 67108864, + "filename": "TEST_DIR/t.IMGFMT", + "cluster-size": 65536, + "format": "IMGFMT", + "actual-size": SIZE, + "format-specific": { + "type": "IMGFMT", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "TEST_DIR/t.IMGFMT.mid", + "backing-filename": "TEST_DIR/t.IMGFMT.mid", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "top", + "backing_file_depth": 2, + "drv": "IMGFMT", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "TEST_DIR/t.IMGFMT.mid", + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.IMGFMT", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT", + "format": "file", + "actual-size": SIZE, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "topf", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.IMGFMT", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "backing-image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.base", + "format": "file", + "actual-size": SIZE, + "dirty-flag": false + }, + "backing-filename-format": "file", + "virtual-size": 67108864, + "filename": "TEST_DIR/t.IMGFMT.mid", + "cluster-size": 65536, + "format": "IMGFMT", + "actual-size": SIZE, + "format-specific": { + "type": "IMGFMT", + "data": { + "compat": "1.1", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false + } + }, + "full-backing-filename": "TEST_DIR/t.IMGFMT.base", + "backing-filename": "TEST_DIR/t.IMGFMT.base", + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "mid", + "backing_file_depth": 1, + "drv": "IMGFMT", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "backing_file": "TEST_DIR/t.IMGFMT.base", + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.IMGFMT.mid", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.mid", + "format": "file", + "actual-size": SIZE, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "midf", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.IMGFMT.mid", + "encryption_key_missing": false + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 197120, + "filename": "TEST_DIR/t.IMGFMT.base", + "format": "file", + "actual-size": SIZE, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "base", + "backing_file_depth": 0, + "drv": "file", + "iops": 0, + "bps_wr": 0, + "write_threshold": 0, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "TEST_DIR/t.IMGFMT.base", + "encryption_key_missing": false + } + ] +} +{ + "return": { + "edges": [ + { + "name": "file", + "parent": 5, + "shared-perm": [ + "graph-mod", + "write-unchanged", + "consistent-read" + ], + "perm": [ + "resize", + "write", + "consistent-read" + ], + "child": 4 + }, + { + "name": "backing", + "parent": 5, + "shared-perm": [ + "graph-mod", + "resize", + "write-unchanged", + "write", + "consistent-read" + ], + "perm": [ + ], + "child": 3 + }, + { + "name": "file", + "parent": 3, + "shared-perm": [ + "graph-mod", + "write-unchanged", + "consistent-read" + ], + "perm": [ + "consistent-read" + ], + "child": 2 + }, + { + "name": "backing", + "parent": 3, + "shared-perm": [ + "graph-mod", + "resize", + "write-unchanged", + "write", + "consistent-read" + ], + "perm": [ + ], + "child": 1 + } + ], + "nodes": [ + { + "name": "top", + "type": "block-driver", + "id": 5 + }, + { + "name": "topf", + "type": "block-driver", + "id": 4 + }, + { + "name": "mid", + "type": "block-driver", + "id": 3 + }, + { + "name": "midf", + "type": "block-driver", + "id": 2 + }, + { + "name": "base", + "type": "block-driver", + "id": 1 + } + ] + } +} +{ + "return": { + } +} +{ + "timestamp": { + "seconds": TIMESTAMP, + "microseconds": TIMESTAMP + }, + "event": "SHUTDOWN", + "data": { + "guest": false, + "reason": "host-qmp-quit" + } +} + +*** done diff --git a/tests/qemu-iotests/277 b/tests/qemu-iotests/277 new file mode 100755 index 0000000000..1f72dca2d4 --- /dev/null +++ b/tests/qemu-iotests/277 @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# Test NBD client reconnection +# +# Copyright (c) 2019 Virtuozzo International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import os +import subprocess +import iotests +from iotests import file_path, log + + +nbd_sock, conf_file = file_path('nbd-sock', 'nbd-fault-injector.conf') + + +def make_conf_file(event): + """ + Create configuration file for the nbd-fault-injector.py + + :param event: which event the server should close a connection on + """ + with open(conf_file, 'w') as conff: + conff.write('[inject-error]\nevent={}\nwhen=after'.format(event)) + + +def start_server_NBD(event): + make_conf_file(event) + + srv = subprocess.Popen(['nbd-fault-injector.py', '--classic-negotiation', + nbd_sock, conf_file], stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, universal_newlines=True) + line = srv.stdout.readline() + if 'Listening on ' in line: + log('NBD server: started') + else: + log('NBD server: ' + line.rstrip()) + + return srv + + +def start_client_NBD(): + log('NBD client: QEMU-IO write') + args = iotests.qemu_io_args_no_fmt + \ + ['-c', 'write -P 0x7 0 3M', '--image-opts', + 'driver=nbd,server.type=unix,server.path={},' + 'reconnect-delay=7'.format(nbd_sock)] + clt = subprocess.Popen(args, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) + return clt + + +def check_proc_NBD(proc, connector): + try: + outs, errs = proc.communicate(timeout=10) + + if proc.returncode < 0: + log('NBD {}: EXIT SIGNAL {}\n'.format(connector, proc.returncode)) + log(outs) + else: + msg = outs.split('\n', 1) + log('NBD {}: {}'.format(connector, msg[0])) + + except subprocess.TimeoutExpired: + proc.kill() + log('NBD {}: ERROR timeout expired'.format(connector)) + finally: + if connector == 'server': + os.remove(nbd_sock) + os.remove(conf_file) + + +srv = start_server_NBD('data') +clt = start_client_NBD() +# The server should close the connection after a client write request +check_proc_NBD(srv, 'server') +# Start the NBD server again +srv = start_server_NBD('reply') +# The client should reconnect and complete the write operation +check_proc_NBD(clt, 'client') +# Make it sure that server terminated +check_proc_NBD(srv, 'server') diff --git a/tests/qemu-iotests/277.out b/tests/qemu-iotests/277.out new file mode 100644 index 0000000000..45404b34eb --- /dev/null +++ b/tests/qemu-iotests/277.out @@ -0,0 +1,6 @@ +NBD server: started +NBD client: QEMU-IO write +NBD server: Closing connection on rule match inject-error +NBD server: started +NBD client: wrote 3145728/3145728 bytes at offset 0 +NBD server: Closing connection on rule match inject-error diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index 71fe38834e..90970b0549 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -887,7 +887,7 @@ do if [ ! -f "$reference" ] then status="fail" - reason="no qualified output" + results="no qualified output" err=true else if diff -w "$reference" $tmp.out >/dev/null 2>&1 diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index f870e00e44..5367deea39 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -127,7 +127,8 @@ _filter_img_create() -e "s#$TEST_DIR#TEST_DIR#g" \ -e "s#$SOCK_DIR#SOCK_DIR#g" \ -e "s#$IMGFMT#IMGFMT#g" \ - -e 's#nbd:127.0.0.1:10810#TEST_DIR/t.IMGFMT#g' \ + -e 's#nbd:127.0.0.1:[0-9]\\+#TEST_DIR/t.IMGFMT#g' \ + -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \ -e "s# encryption=off##g" \ -e "s# cluster_size=[0-9]\\+##g" \ -e "s# table_size=[0-9]\\+##g" \ @@ -164,7 +165,8 @@ _filter_img_info() -e "s#$TEST_DIR#TEST_DIR#g" \ -e "s#$SOCK_DIR#SOCK_DIR#g" \ -e "s#$IMGFMT#IMGFMT#g" \ - -e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \ + -e 's#nbd://127.0.0.1:[0-9]\\+$#TEST_DIR/t.IMGFMT#g' \ + -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \ -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \ -e "/encrypted: yes/d" \ -e "/cluster_size: [0-9]\\+/d" \ diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu index 8d2021a7eb..de680cf1c7 100644 --- a/tests/qemu-iotests/common.qemu +++ b/tests/qemu-iotests/common.qemu @@ -123,6 +123,9 @@ _timed_wait_for() # until either timeout, or a response. If it is not set, or <=0, # then the command is only sent once. # +# If neither $silent nor $mismatch_only is set, and $cmd begins with '{', +# echo the command before sending it the first time. +# # If $qemu_error_no_exit is set, then even if the expected response # is not seen, we will not exit. $QEMU_STATUS[$1] will be set it -1 in # that case. @@ -152,6 +155,12 @@ _send_qemu_cmd() shift $(($# - 2)) fi + # Display QMP being sent, but not HMP (since HMP already echoes its + # input back to output); decide based on leading '{' + if [ -z "$silent" ] && [ -z "$mismatch_only" ] && + [ "$cmd" != "${cmd#\{}" ]; then + echo "${cmd}" | _filter_testdir | _filter_imgfmt + fi while [ ${count} -gt 0 ] do echo "${cmd}" >&${QEMU_IN[${h}]} diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index fa7bae2422..0cc8acc9ed 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -217,7 +217,7 @@ if [ "$IMGOPTSSYNTAX" = "true" ]; then TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT" elif [ "$IMGPROTO" = "nbd" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - TEST_IMG="$DRIVER,file.driver=nbd,file.host=127.0.0.1,file.port=10810" + TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix,file.path=$SOCKDIR/nbd" elif [ "$IMGPROTO" = "ssh" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE" @@ -233,7 +233,7 @@ else TEST_IMG=$TEST_DIR/t.$IMGFMT elif [ "$IMGPROTO" = "nbd" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - TEST_IMG="nbd:127.0.0.1:10810" + TEST_IMG="nbd+unix:///?socket=$SOCK_DIR/nbd" elif [ "$IMGPROTO" = "ssh" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR" @@ -293,7 +293,7 @@ _stop_nbd_server() local QEMU_NBD_PID read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid" kill ${QEMU_NBD_PID} - rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid" + rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid" "$SOCK_DIR/nbd" fi } @@ -349,11 +349,14 @@ _make_test_img() fi ) | _filter_img_create - # Start an NBD server on the image file, which is what we'll be talking to + # Start an NBD server on the image file, which is what we'll be talking to. + # Once NBD gains resize support, we may also want to use -f raw at the + # server and interpret format over NBD, but for now, the format is + # interpreted at the server and raw data sent over NBD. if [ $IMGPROTO = "nbd" ]; then # Pass a sufficiently high number to -e that should be enough for all # tests - eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &" + eval "$QEMU_NBD -v -t -k '$SOCK_DIR/nbd' -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &" sleep 1 # FIXME: qemu-nbd needs to be listening before we continue fi diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 065040398d..6b10a6a762 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -284,3 +284,5 @@ 268 rw auto quick 270 rw backing quick 272 rw +273 backing quick +277 rw quick diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 075f4739da..df0708923d 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -47,6 +47,11 @@ qemu_io_args = [os.environ.get('QEMU_IO_PROG', 'qemu-io')] if os.environ.get('QEMU_IO_OPTIONS'): qemu_io_args += os.environ['QEMU_IO_OPTIONS'].strip().split(' ') +qemu_io_args_no_fmt = [os.environ.get('QEMU_IO_PROG', 'qemu-io')] +if os.environ.get('QEMU_IO_OPTIONS_NO_FMT'): + qemu_io_args_no_fmt += \ + os.environ['QEMU_IO_OPTIONS_NO_FMT'].strip().split(' ') + qemu_nbd_args = [os.environ.get('QEMU_NBD_PROG', 'qemu-nbd')] if os.environ.get('QEMU_NBD_OPTIONS'): qemu_nbd_args += os.environ['QEMU_NBD_OPTIONS'].strip().split(' ') @@ -731,8 +736,8 @@ class QMPTestCase(unittest.TestCase): self.fail('no match for "%s" in %s' % (str(result), str(value))) else: self.assertEqual(result, value, - 'values not equal "%s" and "%s"' - % (str(result), str(value))) + '"%s" is "%s", expected "%s"' + % (path, str(result), str(value))) def assert_no_active_block_jobs(self): result = self.vm.qmp('query-block-jobs') diff --git a/tests/qemu-iotests/nbd-fault-injector.py b/tests/qemu-iotests/nbd-fault-injector.py index 6b2d659dee..7e2dab6ea4 100755 --- a/tests/qemu-iotests/nbd-fault-injector.py +++ b/tests/qemu-iotests/nbd-fault-injector.py @@ -115,7 +115,8 @@ class FaultInjectionSocket(object): if rule.match(event, io): if rule.when == 0 or bufsize is None: print('Closing connection on rule match %s' % rule.name) - self.sock.flush() + self.sock.close() + sys.stdout.flush() sys.exit(0) if rule.when != -1: return rule.when diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c index ae91b92b6e..769a76e57d 100644 --- a/util/qemu-coroutine-sleep.c +++ b/util/qemu-coroutine-sleep.c @@ -68,5 +68,12 @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QEMUClockType type, int64_t ns, } timer_mod(state.ts, qemu_clock_get_ns(type) + ns); qemu_coroutine_yield(); + if (sleep_state) { + /* + * Note that *sleep_state is cleared during qemu_co_sleep_wake + * before resuming this coroutine. + */ + assert(*sleep_state == NULL); + } timer_free(state.ts); } |