diff options
-rw-r--r-- | block.c | 33 | ||||
-rw-r--r-- | block/iscsi.c | 3 | ||||
-rw-r--r-- | block/qcow2.c | 25 | ||||
-rw-r--r-- | block/qed.c | 4 | ||||
-rw-r--r-- | block/raw-posix.c | 39 | ||||
-rw-r--r-- | block/raw_bsd.c | 3 | ||||
-rw-r--r-- | block/stream.c | 2 | ||||
-rw-r--r-- | block/vmdk.c | 4 | ||||
-rw-r--r-- | hw/i386/kvm/clock.c | 52 | ||||
-rw-r--r-- | include/block/block.h | 2 | ||||
-rw-r--r-- | include/block/block_int.h | 2 | ||||
-rw-r--r-- | target-i386/helper.c | 3 | ||||
-rw-r--r-- | tests/Makefile | 3 | ||||
-rwxr-xr-x | tests/qemu-iotests/028 | 4 | ||||
-rw-r--r-- | tests/qemu-iotests/028.out | 2 | ||||
-rwxr-xr-x | tests/qemu-iotests/036 | 52 | ||||
-rw-r--r-- | tests/qemu-iotests/036.out | 35 | ||||
-rwxr-xr-x | tests/qemu-iotests/qcow2.py | 15 | ||||
-rw-r--r-- | tests/wdt_ib700-test.c | 134 | ||||
-rw-r--r-- | util/module.c | 9 |
20 files changed, 315 insertions, 111 deletions
@@ -508,19 +508,24 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) return ret; } -int bdrv_refresh_limits(BlockDriverState *bs) +void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; + Error *local_err = NULL; memset(&bs->bl, 0, sizeof(bs->bl)); if (!drv) { - return 0; + return; } /* Take some limits from the children as a default */ if (bs->file) { - bdrv_refresh_limits(bs->file); + bdrv_refresh_limits(bs->file, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length; bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment; } else { @@ -528,7 +533,11 @@ int bdrv_refresh_limits(BlockDriverState *bs) } if (bs->backing_hd) { - bdrv_refresh_limits(bs->backing_hd); + bdrv_refresh_limits(bs->backing_hd, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } bs->bl.opt_transfer_length = MAX(bs->bl.opt_transfer_length, bs->backing_hd->bl.opt_transfer_length); @@ -539,10 +548,8 @@ int bdrv_refresh_limits(BlockDriverState *bs) /* Then let the driver override it */ if (drv->bdrv_refresh_limits) { - return drv->bdrv_refresh_limits(bs); + drv->bdrv_refresh_limits(bs, errp); } - - return 0; } /* @@ -993,7 +1000,13 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, goto free_and_fail; } - bdrv_refresh_limits(bs); + bdrv_refresh_limits(bs, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto free_and_fail; + } + assert(bdrv_opt_mem_align(bs) != 0); assert((bs->request_alignment != 0) || bs->sg); return 0; @@ -1154,7 +1167,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT, bs->backing_blocker); out: - bdrv_refresh_limits(bs); + bdrv_refresh_limits(bs, NULL); } /* @@ -1778,7 +1791,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) BDRV_O_CACHE_WB); reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR); - bdrv_refresh_limits(reopen_state->bs); + bdrv_refresh_limits(reopen_state->bs, NULL); } /* diff --git a/block/iscsi.c b/block/iscsi.c index f3e83e2332..a7bb6970ac 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1450,7 +1450,7 @@ static void iscsi_close(BlockDriverState *bs) memset(iscsilun, 0, sizeof(IscsiLun)); } -static int iscsi_refresh_limits(BlockDriverState *bs) +static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp) { IscsiLun *iscsilun = bs->opaque; @@ -1475,7 +1475,6 @@ static int iscsi_refresh_limits(BlockDriverState *bs) } bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun); - return 0; } /* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in diff --git a/block/qcow2.c b/block/qcow2.c index b0faa6917b..1e3ab6bd02 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -210,20 +210,31 @@ static void GCC_FMT_ATTR(3, 4) report_unsupported(BlockDriverState *bs, static void report_unsupported_feature(BlockDriverState *bs, Error **errp, Qcow2Feature *table, uint64_t mask) { + char *features = g_strdup(""); + char *old; + while (table && table->name[0] != '\0') { if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) { - if (mask & (1 << table->bit)) { - report_unsupported(bs, errp, "%.46s", table->name); - mask &= ~(1 << table->bit); + if (mask & (1ULL << table->bit)) { + old = features; + features = g_strdup_printf("%s%s%.46s", old, *old ? ", " : "", + table->name); + g_free(old); + mask &= ~(1ULL << table->bit); } } table++; } if (mask) { - report_unsupported(bs, errp, "Unknown incompatible feature: %" PRIx64, - mask); + old = features; + features = g_strdup_printf("%s%sUnknown incompatible feature: %" PRIx64, + old, *old ? ", " : "", mask); + g_free(old); } + + report_unsupported(bs, errp, "%s", features); + g_free(features); } /* @@ -855,13 +866,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, return ret; } -static int qcow2_refresh_limits(BlockDriverState *bs) +static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQcowState *s = bs->opaque; bs->bl.write_zeroes_alignment = s->cluster_sectors; - - return 0; } static int qcow2_set_key(BlockDriverState *bs, const char *key) diff --git a/block/qed.c b/block/qed.c index cd4872b529..7944832181 100644 --- a/block/qed.c +++ b/block/qed.c @@ -528,13 +528,11 @@ out: return ret; } -static int bdrv_qed_refresh_limits(BlockDriverState *bs) +static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQEDState *s = bs->opaque; bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS; - - return 0; } /* We have nothing to do for QED reopen, stubs just return diff --git a/block/raw-posix.c b/block/raw-posix.c index 2bcc73dc37..8e9758e920 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -221,7 +221,7 @@ static int raw_normalize_devicepath(const char **filename) } #endif -static void raw_probe_alignment(BlockDriverState *bs) +static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) { BDRVRawState *s = bs->opaque; char *buf; @@ -240,24 +240,24 @@ static void raw_probe_alignment(BlockDriverState *bs) s->buf_align = 0; #ifdef BLKSSZGET - if (ioctl(s->fd, BLKSSZGET, §or_size) >= 0) { + if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef DKIOCGETBLOCKSIZE - if (ioctl(s->fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { + if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef DIOCGSECTORSIZE - if (ioctl(s->fd, DIOCGSECTORSIZE, §or_size) >= 0) { + if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef CONFIG_XFS if (s->is_xfs) { struct dioattr da; - if (xfsctl(NULL, s->fd, XFS_IOC_DIOINFO, &da) >= 0) { + if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) { bs->request_alignment = da.d_miniosz; /* The kernel returns wrong information for d_mem */ /* s->buf_align = da.d_mem; */ @@ -270,7 +270,7 @@ static void raw_probe_alignment(BlockDriverState *bs) size_t align; buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE); for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) { - if (pread(s->fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) { + if (pread(fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) { s->buf_align = align; break; } @@ -282,13 +282,18 @@ static void raw_probe_alignment(BlockDriverState *bs) size_t align; buf = qemu_memalign(s->buf_align, MAX_BLOCKSIZE); for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) { - if (pread(s->fd, buf, align, 0) >= 0) { + if (pread(fd, buf, align, 0) >= 0) { bs->request_alignment = align; break; } } qemu_vfree(buf); } + + if (!s->buf_align || !bs->request_alignment) { + error_setg(errp, "Could not find working O_DIRECT alignment. " + "Try cache.direct=off."); + } } static void raw_parse_flags(int bdrv_flags, int *open_flags) @@ -505,6 +510,7 @@ static int raw_reopen_prepare(BDRVReopenState *state, BDRVRawState *s; BDRVRawReopenState *raw_s; int ret = 0; + Error *local_err = NULL; assert(state != NULL); assert(state->bs != NULL); @@ -577,6 +583,19 @@ static int raw_reopen_prepare(BDRVReopenState *state, ret = -1; } } + + /* Fail already reopen_prepare() if we can't get a working O_DIRECT + * alignment with the new fd. */ + if (raw_s->fd != -1) { + raw_probe_alignment(state->bs, raw_s->fd, &local_err); + if (local_err) { + qemu_close(raw_s->fd); + raw_s->fd = -1; + error_propagate(errp, local_err); + ret = -EINVAL; + } + } + return ret; } @@ -615,14 +634,12 @@ static void raw_reopen_abort(BDRVReopenState *state) state->opaque = NULL; } -static int raw_refresh_limits(BlockDriverState *bs) +static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; - raw_probe_alignment(bs); + raw_probe_alignment(bs, s->fd, errp); bs->bl.opt_mem_alignment = s->buf_align; - - return 0; } static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 492f58de69..f82f4c25df 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -94,10 +94,9 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return bdrv_get_info(bs->file, bdi); } -static int raw_refresh_limits(BlockDriverState *bs) +static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { bs->bl = bs->file->bl; - return 0; } static int raw_truncate(BlockDriverState *bs, int64_t offset) diff --git a/block/stream.c b/block/stream.c index 34de8ba0d9..cdea3e8d0c 100644 --- a/block/stream.c +++ b/block/stream.c @@ -76,7 +76,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, bdrv_unref(unused); } - bdrv_refresh_limits(top); + bdrv_refresh_limits(top, NULL); } static void coroutine_fn stream_run(void *opaque) diff --git a/block/vmdk.c b/block/vmdk.c index 27a78daa02..0517bbaf91 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -938,7 +938,7 @@ fail: } -static int vmdk_refresh_limits(BlockDriverState *bs) +static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVVmdkState *s = bs->opaque; int i; @@ -950,8 +950,6 @@ static int vmdk_refresh_limits(BlockDriverState *bs) s->extents[i].cluster_sectors); } } - - return 0; } static int get_whole_cluster(BlockDriverState *bs, diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 272a88acb5..07b9c0e581 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -14,10 +14,8 @@ */ #include "qemu-common.h" -#include "qemu/host-utils.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" -#include "sysemu/cpus.h" #include "hw/sysbus.h" #include "hw/kvm/clock.h" @@ -36,48 +34,6 @@ typedef struct KVMClockState { bool clock_valid; } KVMClockState; -struct pvclock_vcpu_time_info { - uint32_t version; - uint32_t pad0; - uint64_t tsc_timestamp; - uint64_t system_time; - uint32_t tsc_to_system_mul; - int8_t tsc_shift; - uint8_t flags; - uint8_t pad[2]; -} __attribute__((__packed__)); /* 32 bytes */ - -static uint64_t kvmclock_current_nsec(KVMClockState *s) -{ - CPUState *cpu = first_cpu; - CPUX86State *env = cpu->env_ptr; - hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL; - uint64_t migration_tsc = env->tsc; - struct pvclock_vcpu_time_info time; - uint64_t delta; - uint64_t nsec_lo; - uint64_t nsec_hi; - uint64_t nsec; - - if (!(env->system_time_msr & 1ULL)) { - /* KVM clock not active */ - return 0; - } - - cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time)); - - assert(time.tsc_timestamp <= migration_tsc); - delta = migration_tsc - time.tsc_timestamp; - if (time.tsc_shift < 0) { - delta >>= -time.tsc_shift; - } else { - delta <<= time.tsc_shift; - } - - mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul); - nsec = (nsec_lo >> 32) | (nsec_hi << 32); - return nsec + time.system_time; -} static void kvmclock_vm_state_change(void *opaque, int running, RunState state) @@ -89,15 +45,9 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (running) { struct kvm_clock_data data; - uint64_t time_at_migration = kvmclock_current_nsec(s); s->clock_valid = false; - /* We can't rely on the migrated clock value, just discard it */ - if (time_at_migration) { - s->clock = time_at_migration; - } - data.clock = s->clock; data.flags = 0; ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); @@ -125,8 +75,6 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (s->clock_valid) { return; } - - cpu_synchronize_all_states(); ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); if (ret < 0) { fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); diff --git a/include/block/block.h b/include/block/block.h index 32d36760fd..f08471d7e1 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -278,7 +278,7 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset); int64_t bdrv_getlength(BlockDriverState *bs); int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); -int bdrv_refresh_limits(BlockDriverState *bs); +void bdrv_refresh_limits(BlockDriverState *bs, Error **errp); int bdrv_commit(BlockDriverState *bs); int bdrv_commit_all(void); int bdrv_change_backing_file(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index f6c3befed8..7b541a0691 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -240,7 +240,7 @@ struct BlockDriver { int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag); bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag); - int (*bdrv_refresh_limits)(BlockDriverState *bs); + void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp); /* * Returns 1 if newly created images are guaranteed to contain only diff --git a/target-i386/helper.c b/target-i386/helper.c index 11ca8649b5..47b982b437 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -750,7 +750,8 @@ do_check_protect_pse36: /* the page can be put in the TLB */ prot = PAGE_READ; if (!(ptep & PG_NX_MASK) && - !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK))) { + (mmu_idx == MMU_USER_IDX || + !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { prot |= PAGE_EXEC; } if (pte & PG_DIRTY_MASK) { diff --git a/tests/Makefile b/tests/Makefile index fa25c70712..4b2e1bbea9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -141,6 +141,8 @@ check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-i386-y += tests/blockdev-test$(EXESUF) check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF) +check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF) +gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c check-qtest-i386-y += $(check-qtest-pci-y) gcov-files-i386-y += $(gcov-files-pci-y) check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) @@ -311,6 +313,7 @@ tests/pcnet-test$(EXESUF): tests/pcnet-test.o tests/eepro100-test$(EXESUF): tests/eepro100-test.o tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o tests/ne2000-test$(EXESUF): tests/ne2000-test.o +tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028 index d5718c5594..9e701e1c2b 100755 --- a/tests/qemu-iotests/028 +++ b/tests/qemu-iotests/028 @@ -110,7 +110,9 @@ _launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk h=$QEMU_HANDLE QEMU_COMM_TIMEOUT=1 -_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)" +# Silence output since it contains the disk image path and QEMU's readline +# character echoing makes it very hard to filter the output +_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)" >/dev/null qemu_cmd_repeat=20 _send_qemu_cmd $h "info block-jobs" "No active jobs" _send_qemu_cmd $h 'quit' "" diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out index 38099e44c9..0e1a5ae65d 100644 --- a/tests/qemu-iotests/028.out +++ b/tests/qemu-iotests/028.out @@ -468,8 +468,6 @@ No errors were found on the image. block-backup -QEMU X.Y.Z monitor - type 'help' for more information -(qemu) d[K[Ddr[K[D[Ddri[K[D[D[Ddriv[K[D[D[D[Ddrive[K[D[D[D[D[Ddrive_[K[D[D[D[D[D[Ddrive_b[K[D[D[D[D[D[D[Ddrive_ba[K[D[D[D[D[D[D[D[Ddrive_bac[K[D[D[D[D[D[D[D[D[Ddrive_back[K[D[D[D[D[D[D[D[D[D[Ddrive_backu[K[D[D[D[D[D[D[D[D[D[D[Ddrive_backup[K[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup [K[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup d[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup di[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup dis[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk [K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /h[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /ho[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /hom[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/k[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kw[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwo[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwol[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/s[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/so[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sou[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sour[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/sourc[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/q[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qe[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qem[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/t[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/te[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tes[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/test[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/q[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qe[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qem[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-i[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-io[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iot[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iote[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotes[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotest[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/s[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/sc[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/scr[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/scra[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/scrat[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk /home/kwolf/source/qemu/tests/qemu-iotests/scratc[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.q[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qc[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qco[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2.[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2.c[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2.co[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2.cop[K[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[Ddrive_backup disk TEST_DIR/t.qcow2.copy[K Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=4294968832 backing_file='TEST_DIR/t.qcow2.base' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off (qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K[D[D[D[D[D[D[D[D[D[Dinfo block-[K[D[D[D[D[D[D[D[D[D[D[Dinfo block-j[K[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jo[K[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-job[K[D[D[D[D[D[D[D[D[D[D[D[D[D[Dinfo block-jobs[K Type backup, device disk: Completed 0 of 4294968832 bytes, speed limit 0 bytes/s diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036 index a77365347d..392f1ef3e6 100755 --- a/tests/qemu-iotests/036 +++ b/tests/qemu-iotests/036 @@ -1,6 +1,6 @@ #!/bin/bash # -# Test that qcow2 unknown autoclear feature bits are cleared +# Test qcow2 feature bits # # Copyright (C) 2011 Red Hat, Inc. # Copyright IBM, Corp. 2010 @@ -50,6 +50,56 @@ _supported_os Linux # Only qcow2v3 and later supports feature bits IMGOPTS="compat=1.1" +echo +echo === Image with unknown incompatible feature bit === +echo +_make_test_img 64M +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63 + +# Without feature table +$PYTHON qcow2.py "$TEST_IMG" dump-header +_img_info + +# With feature table containing bit 63 +printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + +echo +echo === Image with multiple incompatible feature bits === +echo +_make_test_img 64M +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 61 +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 62 +$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63 + +# Without feature table +_img_info + +# With feature table containing bit 63 +printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + +# With feature table containing bit 61 +$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857 +printf "\x00\x3d%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + +# With feature table containing bits 61 and 62 +$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857 +printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s" "test1" "" "test2" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + +# With feature table containing all bits +$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857 +printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s\x00\x3f%s\x00%40s" "test1" "" "test2" "" "test3" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + +# With feature table containing unrelated bits, including compatible/autoclear +$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857 +printf "\x01\x3d%s\x00%40s\x00\x3e%s\x00%40s\x02\x3f%s\x00%40s\x00\x3c%s\x00%40s" "test1" "" "test2" "" "test3" "" "test4" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857 +_img_info + + echo === Create image with unknown autoclear feature bit === echo _make_test_img 64M diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out index 55a3e6e441..720bd89161 100644 --- a/tests/qemu-iotests/036.out +++ b/tests/qemu-iotests/036.out @@ -1,4 +1,39 @@ QA output created by 036 + +=== Image with unknown incompatible feature bit === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +magic 0x514649fb +version 3 +backing_file_offset 0x0 +backing_file_size 0x0 +cluster_bits 16 +size 67108864 +crypt_method 0 +l1_size 1 +l1_table_offset 0x30000 +refcount_table_offset 0x10000 +refcount_table_clusters 1 +nb_snapshots 0 +snapshot_offset 0x0 +incompatible_features 0x8000000000000000 +compatible_features 0x0 +autoclear_features 0x0 +refcount_order 4 +header_length 104 + +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Unknown incompatible feature: 8000000000000000 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature + +=== Image with multiple incompatible feature bits === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Unknown incompatible feature: e000000000000000 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: 6000000000000000 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: Test feature, Unknown incompatible feature: c000000000000000 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test1, test2, Unknown incompatible feature: 8000000000000000 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test1, test2, test3 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'image' uses a IMGFMT feature which is not supported by this qemu version: test2, Unknown incompatible feature: a000000000000000 === Create image with unknown autoclear feature bit === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py index 44a2b45641..2058596964 100755 --- a/tests/qemu-iotests/qcow2.py +++ b/tests/qemu-iotests/qcow2.py @@ -176,6 +176,10 @@ def cmd_add_header_ext(fd, magic, data): h.extensions.append(QcowHeaderExtension.create(magic, data)) h.update(fd) +def cmd_add_header_ext_stdio(fd, magic): + data = sys.stdin.read() + cmd_add_header_ext(fd, magic, data) + def cmd_del_header_ext(fd, magic): try: magic = int(magic, 0) @@ -220,11 +224,12 @@ def cmd_set_feature_bit(fd, group, bit): h.update(fd) cmds = [ - [ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ], - [ 'set-header', cmd_set_header, 2, 'Set a field in the header'], - [ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ], - [ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ], - [ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'], + [ 'dump-header', cmd_dump_header, 0, 'Dump image header and header extensions' ], + [ 'set-header', cmd_set_header, 2, 'Set a field in the header'], + [ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ], + [ 'add-header-ext-stdio', cmd_add_header_ext_stdio, 1, 'Add a header extension, data from stdin' ], + [ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ], + [ 'set-feature-bit', cmd_set_feature_bit, 2, 'Set a feature bit'], ] def main(filename, cmd, args): diff --git a/tests/wdt_ib700-test.c b/tests/wdt_ib700-test.c new file mode 100644 index 0000000000..513a533852 --- /dev/null +++ b/tests/wdt_ib700-test.c @@ -0,0 +1,134 @@ +/* + * QTest testcase for the IB700 watchdog + * + * Copyright (c) 2014 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include <glib.h> +#include <string.h> +#include "libqtest.h" +#include "qemu/osdep.h" + +#define NS_PER_SEC 1000000000ULL + +static void qmp_check_no_event(void) +{ + QDict *resp = qmp("{'execute':'query-status'}"); + g_assert(qdict_haskey(resp, "return")); + QDECREF(resp); +} + +static QDict *qmp_get_event(const char *name) +{ + QDict *event = qmp(""); + QDict *data; + g_assert(qdict_haskey(event, "event")); + g_assert(!strcmp(qdict_get_str(event, "event"), name)); + + if (qdict_haskey(event, "data")) { + data = qdict_get_qdict(event, "data"); + QINCREF(data); + } else { + data = NULL; + } + + QDECREF(event); + return data; +} + +static QDict *ib700_program_and_wait(QTestState *s) +{ + clock_step(NS_PER_SEC * 40); + qmp_check_no_event(); + + /* 2 second limit */ + outb(0x443, 14); + + /* Ping */ + clock_step(NS_PER_SEC); + qmp_check_no_event(); + outb(0x443, 14); + + /* Disable */ + clock_step(NS_PER_SEC); + qmp_check_no_event(); + outb(0x441, 1); + clock_step(3 * NS_PER_SEC); + qmp_check_no_event(); + + /* Enable and let it fire */ + outb(0x443, 13); + clock_step(3 * NS_PER_SEC); + qmp_check_no_event(); + clock_step(2 * NS_PER_SEC); + return qmp_get_event("WATCHDOG"); +} + + +static void ib700_pause(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action pause -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "pause")); + QDECREF(d); + d = qmp_get_event("STOP"); + QDECREF(d); + qtest_end(); +} + +static void ib700_reset(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action reset -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); + QDECREF(d); + d = qmp_get_event("RESET"); + QDECREF(d); + qtest_end(); +} + +static void ib700_shutdown(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action reset -no-reboot -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); + QDECREF(d); + d = qmp_get_event("SHUTDOWN"); + QDECREF(d); + qtest_end(); +} + +static void ib700_none(void) +{ + QDict *d; + QTestState *s = qtest_start("-watchdog-action none -device ib700"); + qtest_irq_intercept_in(s, "ioapic"); + d = ib700_program_and_wait(s); + g_assert(!strcmp(qdict_get_str(d, "action"), "none")); + QDECREF(d); + qtest_end(); +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + qtest_add_func("/wdt_ib700/pause", ib700_pause); + qtest_add_func("/wdt_ib700/reset", ib700_reset); + qtest_add_func("/wdt_ib700/shutdown", ib700_shutdown); + qtest_add_func("/wdt_ib700/none", ib700_none); + + ret = g_test_run(); + + return ret; +} diff --git a/util/module.c b/util/module.c index 214effb39f..4bd4a94d87 100644 --- a/util/module.c +++ b/util/module.c @@ -202,18 +202,13 @@ static void module_load(module_init_type type) for (i = 0; i < ARRAY_SIZE(dirs); i++) { fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF); ret = module_load_file(fname); + g_free(fname); + fname = NULL; /* Try loading until loaded a module file */ if (!ret) { break; } - g_free(fname); - fname = NULL; - } - if (ret == -ENOENT) { - fprintf(stderr, "Can't find module: %s\n", *mp); } - - g_free(fname); } for (i = 0; i < ARRAY_SIZE(dirs); i++) { |