diff options
Diffstat (limited to '')
109 files changed, 1265 insertions, 810 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 27efc48619..90645fede6 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -22,7 +22,9 @@ macos_task: install_script: - brew install pkg-config python gnu-sed glib pixman make sdl2 script: - - ./configure --python=/usr/local/bin/python3 || { cat config.log; exit 1; } + - mkdir build + - cd build + - ../configure --python=/usr/local/bin/python3 || { cat config.log; exit 1; } - gmake -j$(sysctl -n hw.ncpu) - gmake check -j$(sysctl -n hw.ncpu) @@ -33,6 +35,8 @@ macos_xcode_task: install_script: - brew install pkg-config gnu-sed glib pixman make sdl2 script: - - ./configure --cc=clang || { cat config.log; exit 1; } + - mkdir build + - cd build + - ../configure --cc=clang || { cat config.log; exit 1; } - gmake -j$(sysctl -n hw.ncpu) - gmake check -j$(sysctl -n hw.ncpu) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3db1b847c..ebcef0ebe9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,9 @@ build-system1: script: - apt-get install -y -qq libgtk-3-dev libvte-dev nettle-dev libcacard-dev libusb-dev libvde-dev libspice-protocol-dev libgl1-mesa-dev libvdeplug-dev - - ./configure --enable-werror --target-list="aarch64-softmmu alpha-softmmu + - mkdir build + - cd build + - ../configure --enable-werror --target-list="aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu lm32-softmmu moxie-softmmu microblazeel-softmmu mips64el-softmmu m68k-softmmu ppc-softmmu riscv64-softmmu sparc-softmmu" - make -j2 @@ -16,7 +18,9 @@ build-system2: script: - apt-get install -y -qq libsdl2-dev libgcrypt-dev libbrlapi-dev libaio-dev libfdt-dev liblzo2-dev librdmacm-dev libibverbs-dev libibumad-dev - - ./configure --enable-werror --target-list="tricore-softmmu unicore32-softmmu + - mkdir build + - cd build + - ../configure --enable-werror --target-list="tricore-softmmu unicore32-softmmu microblaze-softmmu mips-softmmu riscv32-softmmu s390x-softmmu sh4-softmmu sparc64-softmmu x86_64-softmmu xtensa-softmmu nios2-softmmu or1k-softmmu" - make -j2 @@ -24,7 +28,9 @@ build-system2: build-disabled: script: - - ./configure --enable-werror --disable-rdma --disable-slirp --disable-curl + - mkdir build + - cd build + - ../configure --enable-werror --disable-rdma --disable-slirp --disable-curl --disable-capstone --disable-live-block-migration --disable-glusterfs --disable-replication --disable-coroutine-pool --disable-smartcard --disable-guest-agent --disable-curses --disable-libxml2 --disable-tpm @@ -37,7 +43,9 @@ build-disabled: build-tcg-disabled: script: - apt-get install -y -qq clang libgtk-3-dev libusb-dev - - ./configure --cc=clang --enable-werror --disable-tcg --audio-drv-list="" + - mkdir build + - cd build + - ../configure --cc=clang --enable-werror --disable-tcg --audio-drv-list="" - make -j2 - make check-unit - make check-qapi-schema @@ -52,7 +60,9 @@ build-tcg-disabled: build-user: script: - - ./configure --enable-werror --disable-system --disable-guest-agent + - mkdir build + - cd build + - ../configure --enable-werror --disable-system --disable-guest-agent --disable-capstone --disable-slirp --disable-fdt - make -j2 - make run-tcg-tests-i386-linux-user run-tcg-tests-x86_64-linux-user @@ -61,7 +71,9 @@ build-clang: script: - apt-get install -y -qq clang libsdl2-dev libattr1-dev libcap-ng-dev xfslibs-dev libiscsi-dev libnfs-dev libseccomp-dev gnutls-dev librbd-dev - - ./configure --cc=clang --cxx=clang++ --enable-werror + - mkdir build + - cd build + - ../configure --cc=clang --cxx=clang++ --enable-werror --target-list="alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu ppc-softmmu s390x-softmmu x86_64-softmmu arm-linux-user" - make -j2 @@ -70,7 +82,9 @@ build-clang: build-tci: script: - TARGETS="aarch64 alpha arm hppa m68k microblaze moxie ppc64 s390x x86_64" - - ./configure --enable-tcg-interpreter + - mkdir build + - cd build + - ../configure --enable-tcg-interpreter --target-list="$(for tg in $TARGETS; do echo -n ${tg}'-softmmu '; done)" - make -j2 - make tests/boot-serial-test tests/cdrom-test tests/pxe-test diff --git a/.shippable.yml b/.shippable.yml index f74a3de3ff..83aae08bb4 100644 --- a/.shippable.yml +++ b/.shippable.yml @@ -35,5 +35,7 @@ build: options: "-e HOME=/root" ci: - unset CC - - ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST} + - mkdir build + - cd build + - ../configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST} - make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) diff --git a/.travis.yml b/.travis.yml index 6cb8af6fa5..376b7d6dfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,8 +73,8 @@ notifications: env: global: - - SRC_DIR="." - - BUILD_DIR="." + - SRC_DIR=".." + - BUILD_DIR="build" - BASE_CONFIG="--disable-docs --disable-tools" - TEST_CMD="make check V=1" # This is broadly a list of "mainline" softmmu targets which have support across the major distros @@ -181,17 +181,12 @@ matrix: - env: - - CONFIG="--disable-user --target-list=${MAIN_SOFTMMU_TARGETS}" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-default" - compiler: clang - - - - env: - CONFIG="--target-list=${MAIN_SOFTMMU_TARGETS} " - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-sanitize" compiler: clang before_script: - - ./configure ${CONFIG} --extra-cflags="-fsanitize=undefined -Werror" || { cat config.log && exit 1; } + - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} + - ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-fsanitize=undefined -Werror" || { cat config.log && exit 1; } - env: @@ -214,10 +209,11 @@ matrix: - TEST_CMD="" - # We manually include builds which we disable "make check" for + # Check the TCG interpreter (TCI) - env: - - CONFIG="--enable-debug --enable-tcg-interpreter" - - TEST_CMD="" + - CONFIG="--enable-debug-tcg --enable-tcg-interpreter --disable-kvm --disable-containers + --target-list=alpha-softmmu,arm-softmmu,hppa-softmmu,m68k-softmmu,microblaze-softmmu,moxie-softmmu,ppc-softmmu,s390x-softmmu,x86_64-softmmu" + - TEST_CMD="make check-qtest check-tcg V=1" # We don't need to exercise every backend with every front-end @@ -322,7 +318,8 @@ matrix: - CONFIG="--cc=gcc-9 --cxx=g++-9 --disable-pie --disable-linux-user" - TEST_CMD="" before_script: - - ./configure ${CONFIG} --extra-cflags="-g3 -O0 -Wno-error=stringop-truncation -fsanitize=thread -fuse-ld=gold" || { cat config.log && exit 1; } + - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} + - ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-g3 -O0 -Wno-error=stringop-truncation -fsanitize=thread -fuse-ld=gold" || { cat config.log && exit 1; } # Run check-tcg against linux-user @@ -353,6 +350,92 @@ matrix: - TEST_CMD="make -j3 check-tcg V=1" - CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg" + - arch: arm64 + dist: xenial + addons: + apt_packages: + - libaio-dev + - libattr1-dev + - libbrlapi-dev + - libcap-ng-dev + - libgcrypt20-dev + - libgnutls28-dev + - libgtk-3-dev + - libiscsi-dev + - liblttng-ust-dev + - libncurses5-dev + - libnfs-dev + - libnss3-dev + - libpixman-1-dev + - libpng-dev + - librados-dev + - libsdl2-dev + - libseccomp-dev + - liburcu-dev + - libusb-1.0-0-dev + - libvdeplug-dev + - libvte-2.91-dev + env: + - TEST_CMD="make check check-tcg V=1" + - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS}" + + - arch: ppc64le + dist: xenial + addons: + apt_packages: + - libaio-dev + - libattr1-dev + - libbrlapi-dev + - libcap-ng-dev + - libgcrypt20-dev + - libgnutls28-dev + - libgtk-3-dev + - libiscsi-dev + - liblttng-ust-dev + - libncurses5-dev + - libnfs-dev + - libnss3-dev + - libpixman-1-dev + - libpng-dev + - librados-dev + - libsdl2-dev + - libseccomp-dev + - liburcu-dev + - libusb-1.0-0-dev + - libvdeplug-dev + - libvte-2.91-dev + env: + - TEST_CMD="make check check-tcg V=1" + - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS},ppc64le-linux-user" + + - arch: s390x + dist: bionic + addons: + apt_packages: + - libaio-dev + - libattr1-dev + - libbrlapi-dev + - libcap-ng-dev + - libgcrypt20-dev + - libgnutls28-dev + - libgtk-3-dev + - libiscsi-dev + - liblttng-ust-dev + - libncurses5-dev + - libnfs-dev + - libnss3-dev + - libpixman-1-dev + - libpng-dev + - librados-dev + - libsdl2-dev + - libseccomp-dev + - liburcu-dev + - libusb-1.0-0-dev + - libvdeplug-dev + - libvte-2.91-dev + env: + - TEST_CMD="make check check-tcg V=1" + - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS},s390x-linux-user" # Release builds # The make-release script expect a QEMU version, so our tag must start with a 'v'. @@ -373,5 +456,6 @@ matrix: - make -C ${SRC_DIR} qemu-${QEMU_VERSION}.tar.bz2 - ls -l ${SRC_DIR}/qemu-${QEMU_VERSION}.tar.bz2 - tar -xf ${SRC_DIR}/qemu-${QEMU_VERSION}.tar.bz2 && cd qemu-${QEMU_VERSION} - - ./configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; } + - mkdir -p release-build && cd release-build + - ../configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; } - make install diff --git a/MAINTAINERS b/MAINTAINERS index 387879aebc..8571327881 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1872,12 +1872,12 @@ M: John Snow <jsnow@redhat.com> R: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> L: qemu-block@nongnu.org S: Supported -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: block/dirty-bitmap.c +F: block/qcow2-bitmap.c F: migration/block-dirty-bitmap.c +F: util/hbitmap.c F: tests/test-hbitmap.c F: docs/interop/bitmaps.rst T: git https://github.com/jnsnow/qemu.git bitmaps diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index c01f59c743..62068d10c3 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -156,7 +156,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) #if defined(DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_CPU) && qemu_log_in_addr_range(itb->pc)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); int flags = 0; if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) { flags |= CPU_DUMP_FPU; @@ -165,7 +165,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) flags |= CPU_DUMP_CCOP; #endif log_cpu_state(cpu, flags); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif /* DEBUG_DISAS */ diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 9f48da9472..bb325a2bc4 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1804,7 +1804,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && qemu_log_in_addr_range(tb->pc)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("OUT: [size=%d]\n", gen_code_size); if (tcg_ctx->data_gen_ptr) { size_t code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr; @@ -1829,7 +1829,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, } qemu_log("\n"); qemu_log_flush(); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index f977682be7..603d17ff83 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -138,11 +138,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(db->pc_first)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("----------------\n"); ops->disas_log(db, cpu); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif } diff --git a/block.c b/block.c index 473eb6eeaa..1b6f7c86e8 100644 --- a/block.c +++ b/block.c @@ -5335,10 +5335,6 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, return; } - if (!(bs->open_flags & BDRV_O_INACTIVE)) { - return; - } - QLIST_FOREACH(child, &bs->children, next) { bdrv_co_invalidate_cache(child->bs, &local_err); if (local_err) { @@ -5360,34 +5356,36 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, * just keep the extended permissions for the next time that an activation * of the image is tried. */ - bs->open_flags &= ~BDRV_O_INACTIVE; - bdrv_get_cumulative_perm(bs, &perm, &shared_perm); - ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err); - if (ret < 0) { - bs->open_flags |= BDRV_O_INACTIVE; - error_propagate(errp, local_err); - return; - } - bdrv_set_perm(bs, perm, shared_perm); - - if (bs->drv->bdrv_co_invalidate_cache) { - bs->drv->bdrv_co_invalidate_cache(bs, &local_err); - if (local_err) { + if (bs->open_flags & BDRV_O_INACTIVE) { + bs->open_flags &= ~BDRV_O_INACTIVE; + bdrv_get_cumulative_perm(bs, &perm, &shared_perm); + ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err); + if (ret < 0) { bs->open_flags |= BDRV_O_INACTIVE; error_propagate(errp, local_err); return; } - } + bdrv_set_perm(bs, perm, shared_perm); - FOR_EACH_DIRTY_BITMAP(bs, bm) { - bdrv_dirty_bitmap_skip_store(bm, false); - } + if (bs->drv->bdrv_co_invalidate_cache) { + bs->drv->bdrv_co_invalidate_cache(bs, &local_err); + if (local_err) { + bs->open_flags |= BDRV_O_INACTIVE; + error_propagate(errp, local_err); + return; + } + } - ret = refresh_total_sectors(bs, bs->total_sectors); - if (ret < 0) { - bs->open_flags |= BDRV_O_INACTIVE; - error_setg_errno(errp, -ret, "Could not refresh total sector count"); - return; + FOR_EACH_DIRTY_BITMAP(bs, bm) { + bdrv_dirty_bitmap_skip_store(bm, false); + } + + ret = refresh_total_sectors(bs, bs->total_sectors); + if (ret < 0) { + bs->open_flags |= BDRV_O_INACTIVE; + error_setg_errno(errp, -ret, "Could not refresh total sector count"); + return; + } } QLIST_FOREACH(parent, &bs->parents, next_parent) { @@ -5751,12 +5749,11 @@ void bdrv_img_create(const char *filename, const char *fmt, return; } + /* Create parameter list */ create_opts = qemu_opts_append(create_opts, drv->create_opts); create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); - /* Create parameter list with default values */ opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort); /* Parse -o options */ if (options) { @@ -5766,6 +5763,13 @@ void bdrv_img_create(const char *filename, const char *fmt, } } + if (!qemu_opt_get(opts, BLOCK_OPT_SIZE)) { + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort); + } else if (img_size != UINT64_C(-1)) { + error_setg(errp, "The image size must be specified only once"); + goto out; + } + if (base_filename) { qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename, &local_err); if (local_err) { diff --git a/block/qcow2.c b/block/qcow2.c index 7c18721741..7fbaac8457 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -367,7 +367,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, return -EINVAL; } - if (bitmaps_ext.bitmap_directory_offset & (s->cluster_size - 1)) { + if (offset_into_cluster(s, bitmaps_ext.bitmap_directory_offset)) { error_setg(errp, "bitmaps_ext: " "invalid bitmap directory offset"); return -EINVAL; @@ -1705,14 +1705,14 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, if (!(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) { /* It's case 1, 2 or 3.2. Or 3.1 which is BUG in management layer. */ bool header_updated = qcow2_load_dirty_bitmaps(bs, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto fail; + } update_header = update_header && !header_updated; } - if (local_err != NULL) { - error_propagate(errp, local_err); - ret = -EINVAL; - goto fail; - } if (update_header) { ret = qcow2_update_header(bs); @@ -1722,7 +1722,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, } } - bs->supported_zero_flags = header.version >= 3 ? BDRV_REQ_MAY_UNMAP : 0; + bs->supported_zero_flags = header.version >= 3 ? + BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0; /* Repair image if dirty */ if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only && @@ -1958,9 +1959,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, { BDRVQcow2State *s = bs->opaque; uint64_t cluster_offset; - int index_in_cluster, ret; unsigned int bytes; - int status = 0; + int ret, status = 0; qemu_co_mutex_lock(&s->lock); @@ -1981,8 +1981,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, if ((ret == QCOW2_CLUSTER_NORMAL || ret == QCOW2_CLUSTER_ZERO_ALLOC) && !s->crypto) { - index_in_cluster = offset & (s->cluster_size - 1); - *map = cluster_offset | index_in_cluster; + *map = cluster_offset | offset_into_cluster(s, offset); *file = s->data_file->bs; status |= BDRV_BLOCK_OFFSET_VALID; } diff --git a/blockjob.c b/blockjob.c index c6e20e2fcd..5d63b1e89d 100644 --- a/blockjob.c +++ b/blockjob.c @@ -261,7 +261,8 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) return; } if (speed < 0) { - error_setg(errp, QERR_INVALID_PARAMETER, "speed"); + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed", + "a non-negative value"); return; } diff --git a/bsd-user/main.c b/bsd-user/main.c index 470a8bf79e..7f4e3cd627 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -963,7 +963,7 @@ int main(int argc, char **argv) if (qemu_loglevel_mask(CPU_LOG_PAGE)) { qemu_log("guest_base 0x%lx\n", guest_base); - log_page_dump(); + log_page_dump("binary load"); qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); diff --git a/configure b/configure index 5723a29070..940bf9e87a 100755 --- a/configure +++ b/configure @@ -302,6 +302,7 @@ audio_win_int="" libs_qga="" debug_info="yes" stack_protector="" +use_containers="yes" if test -e "$source_path/.git" then @@ -1535,6 +1536,10 @@ for opt do ;; --disable-plugins) plugins="no" ;; + --enable-containers) use_containers="yes" + ;; + --disable-containers) use_containers="no" + ;; *) echo "ERROR: unknown option $opt" echo "Try '$0 --help' for more information" @@ -1718,6 +1723,7 @@ Advanced options (experts only): track the maximum stack usage of stacks created by qemu_alloc_stack --enable-plugins enable plugins via shared library loading + --disable-containers don't use containers for cross-building Optional features, enabled with --enable-FEATURE and disabled with --disable-FEATURE, default is enabled if available: @@ -6399,6 +6405,7 @@ else echo "local state directory queried at runtime" echo "Windows SDK $win_sdk" fi +echo "Build directory $(pwd)" echo "Source path $source_path" echo "GIT binary $git" echo "GIT submodules $git_submodules" @@ -7996,7 +8003,7 @@ done (for i in $cross_cc_vars; do export $i done -export target_list source_path +export target_list source_path use_containers $source_path/tests/tcg/configure.sh) # temporary config to build submodules diff --git a/contrib/vhost-user-gpu/50-qemu-gpu.json.in b/contrib/vhost-user-gpu/50-qemu-gpu.json.in index 658b545864..f5edd097f8 100644 --- a/contrib/vhost-user-gpu/50-qemu-gpu.json.in +++ b/contrib/vhost-user-gpu/50-qemu-gpu.json.in @@ -1,5 +1,5 @@ { "description": "QEMU vhost-user-gpu", "type": "gpu", - "binary": "@libexecdir@/vhost-user-gpu", + "binary": "@libexecdir@/vhost-user-gpu" } diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst index 1b367e22e1..9b537a75e6 100644 --- a/docs/arm-cpu-features.rst +++ b/docs/arm-cpu-features.rst @@ -41,9 +41,9 @@ CPU type is possible with the `query-cpu-model-expansion` QMP command. Below are some examples where `scripts/qmp/qmp-shell` (see the top comment block in the script for usage) is used to issue the QMP commands. -(1) Determine which CPU features are available for the `max` CPU type - (Note, we started QEMU with qemu-system-aarch64, so `max` is - implementing the ARMv8-A reference manual in this case):: +1. Determine which CPU features are available for the `max` CPU type + (Note, we started QEMU with qemu-system-aarch64, so `max` is + implementing the ARMv8-A reference manual in this case):: (QEMU) query-cpu-model-expansion type=full model={"name":"max"} { "return": { diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 27f286858a..ab5be0c729 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -418,13 +418,15 @@ access, so they SHOULD NOT be exposed to external interfaces if you are concerned about attackers taking control of the guest and potentially exploiting a QEMU security bug to compromise the host. -QEMU binary ------------ +QEMU binaries +------------- By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there isn't one, or if it is older than 2.10, the test won't work. In this case, provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``. +Likewise the path to qemu-img can be set in QEMU_IMG environment variable. + Make jobs --------- diff --git a/docs/virtio-net-failover.rst b/docs/virtio-net-failover.rst index 22f64c7bc8..6002dc5d96 100644 --- a/docs/virtio-net-failover.rst +++ b/docs/virtio-net-failover.rst @@ -1,6 +1,6 @@ -======================== +====================================== QEMU virtio-net standby (net_failover) -======================== +====================================== This document explains the setup and usage of virtio-net standby feature which is used to create a net_failover pair of devices. diff --git a/docs/virtio-pmem.rst b/docs/virtio-pmem.rst index e77881b26f..4bf5d00443 100644 --- a/docs/virtio-pmem.rst +++ b/docs/virtio-pmem.rst @@ -27,17 +27,18 @@ virtio pmem usage ----------------- A virtio pmem device backed by a memory-backend-file can be created on - the QEMU command line as in the following example: + the QEMU command line as in the following example:: - -object memory-backend-file,id=mem1,share,mem-path=./virtio_pmem.img,size=4G - -device virtio-pmem-pci,memdev=mem1,id=nv1 + -object memory-backend-file,id=mem1,share,mem-path=./virtio_pmem.img,size=4G + -device virtio-pmem-pci,memdev=mem1,id=nv1 - where: - - "object memory-backend-file,id=mem1,share,mem-path=<image>, size=<image size>" - creates a backend file with the specified size. + where: - - "device virtio-pmem-pci,id=nvdimm1,memdev=mem1" creates a virtio pmem - pci device whose storage is provided by above memory backend device. + - "object memory-backend-file,id=mem1,share,mem-path=<image>, size=<image size>" + creates a backend file with the specified size. + + - "device virtio-pmem-pci,id=nvdimm1,memdev=mem1" creates a virtio pmem + pci device whose storage is provided by above memory backend device. Multiple virtio pmem devices can be created if multiple pairs of "-object" and "-device" are provided. @@ -50,7 +51,7 @@ memory backing has to be added via 'object_add'; afterwards, the virtio pmem device can be added via 'device_add'. For example, the following commands add another 4GB virtio pmem device to -the guest: +the guest:: (qemu) object_add memory-backend-file,id=mem2,share=on,mem-path=virtio_pmem2.img,size=4G (qemu) device_add virtio-pmem-pci,id=virtio_pmem2,memdev=mem2 diff --git a/exec.c b/exec.c index efdc0aee98..d4b769d0d4 100644 --- a/exec.c +++ b/exec.c @@ -1225,13 +1225,13 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...) fprintf(stderr, "\n"); cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP); if (qemu_log_separate()) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("qemu: fatal: "); qemu_log_vprintf(fmt, ap2); qemu_log("\n"); log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP); qemu_log_flush(); - qemu_log_unlock(); + qemu_log_unlock(logfile); qemu_log_close(); } va_end(ap2); diff --git a/hmp-commands.hx b/hmp-commands.hx index cfcc044ce4..dc23185de4 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1875,9 +1875,11 @@ ETEXI { .name = "qemu-io", - .args_type = "device:B,command:s", - .params = "[device] \"[command]\"", - .help = "run a qemu-io command on a block device", + .args_type = "qdev:-d,device:B,command:s", + .params = "[-d] [device] \"[command]\"", + .help = "run a qemu-io command on a block device\n\t\t\t" + "-d: [device] is a device ID rather than a " + "drive ID or node name", .cmd = hmp_qemu_io, }, diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 119906a5fe..1b52e8159c 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -67,7 +67,7 @@ static void notify_guest_bh(void *opaque) memset(s->batch_notify_vqs, 0, sizeof(bitmap)); for (j = 0; j < nvqs; j += BITS_PER_LONG) { - unsigned long bits = bitmap[j]; + unsigned long bits = bitmap[j / BITS_PER_LONG]; while (bits != 0) { unsigned i = j + ctzl(bits); diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index dc1bd1641d..215db9a231 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -252,6 +252,8 @@ static void bochs_display_update(void *opaque) dpy_gfx_update(s->con, 0, ys, mode.width, y - ys); } + + g_free(snap); } } diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c index 1f81341554..39c78faf9b 100644 --- a/hw/net/can/can_sja1000.c +++ b/hw/net/can/can_sja1000.c @@ -247,8 +247,8 @@ int can_sja_accept_filter(CanSJA1000State *s, static void can_display_msg(const char *prefix, const qemu_can_frame *msg) { int i; + FILE *logfile = qemu_log_lock(); - qemu_log_lock(); qemu_log("%s%03X [%01d] %s %s", prefix, msg->can_id & QEMU_CAN_EFF_MASK, @@ -261,7 +261,7 @@ static void can_display_msg(const char *prefix, const qemu_can_frame *msg) } qemu_log("\n"); qemu_log_flush(); - qemu_log_unlock(); + qemu_log_unlock(logfile); } static void buff2frame_pel(const uint8_t *buff, qemu_can_frame *frame) diff --git a/include/exec/log.h b/include/exec/log.h index e2cfd436e6..fcc7b9e00b 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -15,8 +15,15 @@ */ static inline void log_cpu_state(CPUState *cpu, int flags) { + QemuLogFile *logfile; + if (qemu_log_enabled()) { - cpu_dump_state(cpu, qemu_logfile, flags); + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + cpu_dump_state(cpu, logfile->fd, flags); + } + rcu_read_unlock(); } } @@ -40,19 +47,36 @@ static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags) static inline void log_target_disas(CPUState *cpu, target_ulong start, target_ulong len) { - target_disas(qemu_logfile, cpu, start, len); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + target_disas(logfile->fd, cpu, start, len); + } + rcu_read_unlock(); } static inline void log_disas(void *code, unsigned long size) { - disas(qemu_logfile, code, size); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + disas(logfile->fd, code, size); + } + rcu_read_unlock(); } #if defined(CONFIG_USER_ONLY) /* page_dump() output to the log file: */ -static inline void log_page_dump(void) +static inline void log_page_dump(const char *operation) { - page_dump(qemu_logfile); + FILE *logfile = qemu_log_lock(); + if (logfile) { + qemu_log("page layout changed following %s\n", operation); + page_dump(logfile); + } + qemu_log_unlock(logfile); } #endif #endif diff --git a/include/qemu/log.h b/include/qemu/log.h index a91105b2ad..e0f4e40628 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -3,9 +3,16 @@ /* A small part of this API is split into its own header */ #include "qemu/log-for-trace.h" +#include "qemu/rcu.h" + +typedef struct QemuLogFile { + struct rcu_head rcu; + FILE *fd; +} QemuLogFile; /* Private global variable, don't use */ -extern FILE *qemu_logfile; +extern QemuLogFile *qemu_logfile; + /* * The new API: @@ -25,7 +32,16 @@ static inline bool qemu_log_enabled(void) */ static inline bool qemu_log_separate(void) { - return qemu_logfile != NULL && qemu_logfile != stderr; + QemuLogFile *logfile; + bool res = false; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile && logfile->fd != stderr) { + res = true; + } + rcu_read_unlock(); + return res; } #define CPU_LOG_TB_OUT_ASM (1 << 0) @@ -53,14 +69,25 @@ static inline bool qemu_log_separate(void) * qemu_loglevel is never set when qemu_logfile is unset. */ -static inline void qemu_log_lock(void) +static inline FILE *qemu_log_lock(void) { - qemu_flockfile(qemu_logfile); + QemuLogFile *logfile; + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + qemu_flockfile(logfile->fd); + return logfile->fd; + } else { + return NULL; + } } -static inline void qemu_log_unlock(void) +static inline void qemu_log_unlock(FILE *fd) { - qemu_funlockfile(qemu_logfile); + if (fd) { + qemu_funlockfile(fd); + } + rcu_read_unlock(); } /* Logging functions: */ @@ -70,9 +97,14 @@ static inline void qemu_log_unlock(void) static inline void GCC_FMT_ATTR(1, 0) qemu_log_vprintf(const char *fmt, va_list va) { - if (qemu_logfile) { - vfprintf(qemu_logfile, fmt, va); + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + vfprintf(logfile->fd, fmt, va); } + rcu_read_unlock(); } /* log only if a bit is set on the current loglevel mask: diff --git a/linux-user/main.c b/linux-user/main.c index 6ff7851e86..8718d03ee2 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -826,7 +826,7 @@ int main(int argc, char **argv, char **envp) if (qemu_loglevel_mask(CPU_LOG_PAGE)) { qemu_log("guest_base 0x%lx\n", guest_base); - log_page_dump(); + log_page_dump("binary load"); qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code); diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 46a6e3a761..8685f02e7e 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -17,11 +17,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" - +#include "trace.h" +#include "exec/log.h" #include "qemu.h" -//#define DEBUG_MMAP - static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER; static __thread int mmap_lock_count; @@ -66,13 +65,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) abi_ulong end, host_start, host_end, addr; int prot1, ret; -#ifdef DEBUG_MMAP - printf("mprotect: start=0x" TARGET_ABI_FMT_lx - "len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c\n", start, len, - prot & PROT_READ ? 'r' : '-', - prot & PROT_WRITE ? 'w' : '-', - prot & PROT_EXEC ? 'x' : '-'); -#endif + trace_target_mprotect(start, len, prot); if ((start & ~TARGET_PAGE_MASK) != 0) return -TARGET_EINVAL; @@ -369,32 +362,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; mmap_lock(); -#ifdef DEBUG_MMAP - { - printf("mmap: start=0x" TARGET_ABI_FMT_lx - " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=", - start, len, - prot & PROT_READ ? 'r' : '-', - prot & PROT_WRITE ? 'w' : '-', - prot & PROT_EXEC ? 'x' : '-'); - if (flags & MAP_FIXED) - printf("MAP_FIXED "); - if (flags & MAP_ANONYMOUS) - printf("MAP_ANON "); - switch(flags & MAP_TYPE) { - case MAP_PRIVATE: - printf("MAP_PRIVATE "); - break; - case MAP_SHARED: - printf("MAP_SHARED "); - break; - default: - printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE); - break; - } - printf("fd=%d offset=" TARGET_ABI_FMT_lx "\n", fd, offset); - } -#endif + trace_target_mmap(start, len, prot, flags, fd, offset); if (!len) { errno = EINVAL; @@ -569,11 +537,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, the_end1: page_set_flags(start, start + len, prot | PAGE_VALID); the_end: -#ifdef DEBUG_MMAP - printf("ret=0x" TARGET_ABI_FMT_lx "\n", start); - page_dump(stdout); - printf("\n"); -#endif + trace_target_mmap_complete(start); + if (qemu_loglevel_mask(CPU_LOG_PAGE)) { + log_page_dump(__func__); + } tb_invalidate_phys_range(start, start + len); mmap_unlock(); return start; @@ -628,11 +595,8 @@ int target_munmap(abi_ulong start, abi_ulong len) abi_ulong end, real_start, real_end, addr; int prot, ret; -#ifdef DEBUG_MMAP - printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x" - TARGET_ABI_FMT_lx "\n", - start, len); -#endif + trace_target_munmap(start, len); + if (start & ~TARGET_PAGE_MASK) return -TARGET_EINVAL; len = TARGET_PAGE_ALIGN(len); diff --git a/linux-user/trace-events b/linux-user/trace-events index 6df234bbb6..f6de1b8bef 100644 --- a/linux-user/trace-events +++ b/linux-user/trace-events @@ -11,3 +11,9 @@ user_handle_signal(void *env, int target_sig) "env=%p signal %d" user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d(" user_queue_signal(void *env, int target_sig) "env=%p signal %d" user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr 0x%"PRIx64 " current psw.addr 0x%"PRIx64 + +# mmap.c +target_mprotect(uint64_t start, uint64_t len, int flags) "start=0x%"PRIx64 " len=0x%"PRIx64 " prot=0x%x" +target_mmap(uint64_t start, uint64_t len, int pflags, int mflags, int fd, uint64_t offset) "start=0x%"PRIx64 " len=0x%"PRIx64 " prot=0x%x flags=0x%x fd=%d offset=0x%"PRIx64 +target_mmap_complete(uint64_t retaddr) "retaddr=0x%"PRIx64 +target_munmap(uint64_t start, uint64_t len) "start=0x%"PRIx64" len=0x%"PRIx64 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index c5dea307b6..d0e0af893a 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -2467,23 +2467,31 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict) { BlockBackend *blk; BlockBackend *local_blk = NULL; + bool qdev = qdict_get_try_bool(qdict, "qdev", false); const char* device = qdict_get_str(qdict, "device"); const char* command = qdict_get_str(qdict, "command"); Error *err = NULL; int ret; - blk = blk_by_name(device); - if (!blk) { - BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err); - if (bs) { - blk = local_blk = blk_new(bdrv_get_aio_context(bs), - 0, BLK_PERM_ALL); - ret = blk_insert_bs(blk, bs, &err); - if (ret < 0) { + if (qdev) { + blk = blk_by_qdev_id(device, &err); + if (!blk) { + goto fail; + } + } else { + blk = blk_by_name(device); + if (!blk) { + BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err); + if (bs) { + blk = local_blk = blk_new(bdrv_get_aio_context(bs), + 0, BLK_PERM_ALL); + ret = blk_insert_bs(blk, bs, &err); + if (ret < 0) { + goto fail; + } + } else { goto fail; } - } else { - goto fail; } } diff --git a/net/can/can_socketcan.c b/net/can/can_socketcan.c index 8a6ffad40c..29bfacd4f8 100644 --- a/net/can/can_socketcan.c +++ b/net/can/can_socketcan.c @@ -76,8 +76,7 @@ QEMU_BUILD_BUG_ON(offsetof(qemu_can_frame, data) static void can_host_socketcan_display_msg(struct qemu_can_frame *msg) { int i; - - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("[cansocketcan]: %03X [%01d] %s %s", msg->can_id & QEMU_CAN_EFF_MASK, msg->can_dlc, @@ -89,7 +88,7 @@ static void can_host_socketcan_display_msg(struct qemu_can_frame *msg) } qemu_log("\n"); qemu_log_flush(); - qemu_log_unlock(); + qemu_log_unlock(logfile); } static void can_host_socketcan_read(void *opaque) diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin index 40e7e67a9b..4af7f7d5a9 100644 --- a/pc-bios/bios-256k.bin +++ b/pc-bios/bios-256k.bin Binary files differdiff --git a/pc-bios/bios.bin b/pc-bios/bios.bin index 97b1e239aa..67874c31b8 100644 --- a/pc-bios/bios.bin +++ b/pc-bios/bios.bin Binary files differdiff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img index c84ae93561..91cdee4436 100644 --- a/pc-bios/s390-ccw.img +++ b/pc-bios/s390-ccw.img Binary files differdiff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c index 266f1502b9..da13c43cc0 100644 --- a/pc-bios/s390-ccw/jump2ipl.c +++ b/pc-bios/s390-ccw/jump2ipl.c @@ -12,11 +12,11 @@ #define KERN_IMAGE_START 0x010000UL #define PSW_MASK_64 0x0000000100000000ULL #define PSW_MASK_32 0x0000000080000000ULL -#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) +#define PSW_MASK_SHORTPSW 0x0008000000000000ULL +#define RESET_PSW_MASK (PSW_MASK_SHORTPSW | PSW_MASK_32 | PSW_MASK_64) typedef struct ResetInfo { - uint32_t ipl_mask; - uint32_t ipl_addr; + uint64_t ipl_psw; uint32_t ipl_continue; } ResetInfo; @@ -50,7 +50,9 @@ void jump_to_IPL_code(uint64_t address) ResetInfo *current = 0; save = *current; - current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2; + + current->ipl_psw = (uint64_t) &jump_to_IPL_2; + current->ipl_psw |= RESET_PSW_MASK; current->ipl_continue = address & 0x7fffffff; debug_print_int("set IPL addr to", current->ipl_continue); @@ -82,7 +84,7 @@ void jump_to_low_kernel(void) } /* Trying to get PSW at zero address */ - if (*((uint64_t *)0) & IPL_PSW_MASK) { + if (*((uint64_t *)0) & RESET_PSW_MASK) { jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff); } diff --git a/pc-bios/s390-netboot.img b/pc-bios/s390-netboot.img index f9ef28ef1a..6bb5c86eb0 100644 --- a/pc-bios/s390-netboot.img +++ b/pc-bios/s390-netboot.img Binary files differdiff --git a/pc-bios/vgabios-ati.bin b/pc-bios/vgabios-ati.bin index b5314fb66c..6202cf73e2 100644 --- a/pc-bios/vgabios-ati.bin +++ b/pc-bios/vgabios-ati.bin Binary files differdiff --git a/pc-bios/vgabios-bochs-display.bin b/pc-bios/vgabios-bochs-display.bin index 5033cc8433..b675f86bc6 100644 --- a/pc-bios/vgabios-bochs-display.bin +++ b/pc-bios/vgabios-bochs-display.bin Binary files differdiff --git a/pc-bios/vgabios-cirrus.bin b/pc-bios/vgabios-cirrus.bin index 4a3643903f..63fde14fea 100644 --- a/pc-bios/vgabios-cirrus.bin +++ b/pc-bios/vgabios-cirrus.bin Binary files differdiff --git a/pc-bios/vgabios-qxl.bin b/pc-bios/vgabios-qxl.bin index f6811bcc8b..80168826e2 100644 --- a/pc-bios/vgabios-qxl.bin +++ b/pc-bios/vgabios-qxl.bin Binary files differdiff --git a/pc-bios/vgabios-ramfb.bin b/pc-bios/vgabios-ramfb.bin index 79986b26cf..1dc413dcd2 100644 --- a/pc-bios/vgabios-ramfb.bin +++ b/pc-bios/vgabios-ramfb.bin Binary files differdiff --git a/pc-bios/vgabios-stdvga.bin b/pc-bios/vgabios-stdvga.bin index d709ec60a0..f92b9a664d 100644 --- a/pc-bios/vgabios-stdvga.bin +++ b/pc-bios/vgabios-stdvga.bin Binary files differdiff --git a/pc-bios/vgabios-virtio.bin b/pc-bios/vgabios-virtio.bin index b99faf4ccc..b0d2f70670 100644 --- a/pc-bios/vgabios-virtio.bin +++ b/pc-bios/vgabios-virtio.bin Binary files differdiff --git a/pc-bios/vgabios-vmware.bin b/pc-bios/vgabios-vmware.bin index 8c92ab76f7..1c2776e8cf 100644 --- a/pc-bios/vgabios-vmware.bin +++ b/pc-bios/vgabios-vmware.bin Binary files differdiff --git a/pc-bios/vgabios.bin b/pc-bios/vgabios.bin index aeae0364ad..c5aad8f3a9 100644 --- a/pc-bios/vgabios.bin +++ b/pc-bios/vgabios.bin Binary files differdiff --git a/qapi/block-core.json b/qapi/block-core.json index 0cf68fea14..fcb52ec24f 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2963,9 +2963,13 @@ # # Driver specific block device options for the NVMe backend. # -# @device: controller address of the NVMe device. +# @device: PCI controller address of the NVMe device in +# format hhhh:bb:ss.f (host:bus:slot.function) # @namespace: namespace number of the device, starting from 1. # +# Note that the PCI @device must have been unbound from any host +# kernel driver before instructing QEMU to add the blockdev. +# # Since: 2.12 ## { 'struct': 'BlockdevOptionsNVMe', diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 97ba3cb88c..09d0ca069e 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -284,6 +284,17 @@ spec you can use the ``-cpu rv64gcsu,priv_spec=v1.9.1`` command line argument. @section Device options +@subsection Emulated device options + +@subsubsection -device virtio-blk,scsi=on|off (since 5.0.0) + +The virtio-blk SCSI passthrough feature is a legacy VIRTIO feature. VIRTIO 1.0 +and later do not support it because the virtio-scsi device was introduced for +full SCSI support. Use virtio-scsi instead when SCSI passthrough is required. + +Note this also applies to ``-device virtio-blk-pci,scsi=on|off'', which is an +alias. + @subsection Block device options @subsubsection "backing": "" (since 2.12.0) diff --git a/qemu-img.c b/qemu-img.c index 95a24b9762..6233b8ca56 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2680,7 +2680,10 @@ static ImageInfoList *collect_image_info_list(bool image_opts, blk_unref(blk); + /* Clear parameters that only apply to the topmost image */ filename = fmt = NULL; + image_opts = false; + if (chain) { if (info->has_full_backing_filename) { filename = info->full_backing_filename; diff --git a/roms/config.seabios-128k b/roms/config.seabios-128k index a17502ca0f..c43912bf9d 100644 --- a/roms/config.seabios-128k +++ b/roms/config.seabios-128k @@ -15,3 +15,4 @@ CONFIG_PVSCSI=n CONFIG_NVME=n CONFIG_USE_SMM=n CONFIG_VGAHOOKS=n +CONFIG_HOST_BIOS_GEOMETRY=n diff --git a/roms/seabios b/roms/seabios -Subproject c9ba5276e3217ac6a1ec772dbebf568ba3a8a55 +Subproject f21b5a4aeb020f2a5e2c6503f906a9349dd2f06 diff --git a/target/cris/translate.c b/target/cris/translate.c index e752bd0609..cb57516a44 100644 --- a/target/cris/translate.c +++ b/target/cris/translate.c @@ -3273,11 +3273,11 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) #if !DISAS_CRIS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("--------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif #endif diff --git a/target/i386/translate.c b/target/i386/translate.c index 77e932d827..7c99ef1385 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -2502,14 +2502,15 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) gen_illegal_opcode(s); if (qemu_loglevel_mask(LOG_UNIMP)) { + FILE *logfile = qemu_log_lock(); target_ulong pc = s->pc_start, end = s->pc; - qemu_log_lock(); + qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc); for (; pc < end; ++pc) { qemu_log(" %02x", cpu_ldub_code(env, pc)); } qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } } diff --git a/target/lm32/translate.c b/target/lm32/translate.c index 778cae1e81..73db9654d6 100644 --- a/target/lm32/translate.c +++ b/target/lm32/translate.c @@ -1137,10 +1137,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif } diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index bdc7d5326a..525115b041 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -1765,10 +1765,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) #if !SIM_COMPAT if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("--------------\n"); log_target_disas(cs, pc_start, dc->pc - pc_start); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif #endif diff --git a/target/nios2/translate.c b/target/nios2/translate.c index e17656e66f..82107bf270 100644 --- a/target/nios2/translate.c +++ b/target/nios2/translate.c @@ -892,11 +892,11 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(tb->pc)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(tb->pc)); log_target_disas(cs, tb->pc, dc->pc - tb->pc); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif } diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 99ea09085a..625daeedd1 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -76,8 +76,16 @@ static bool s390_cpu_has_work(CPUState *cs) static void s390_cpu_load_normal(CPUState *s) { S390CPU *cpu = S390_CPU(s); - cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; - cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64; + uint64_t spsw = ldq_phys(s->as, 0); + + cpu->env.psw.mask = spsw & 0xffffffff80000000ULL; + /* + * Invert short psw indication, so SIE will report a specification + * exception if it was not set. + */ + cpu->env.psw.mask ^= PSW_MASK_SHORTPSW; + cpu->env.psw.addr = spsw & 0x7fffffffULL; + s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); } #endif diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index aa829e954c..e195e5c7c8 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -269,6 +269,7 @@ extern const VMStateDescription vmstate_s390_cpu; #define PSW_MASK_EXT 0x0100000000000000ULL #define PSW_MASK_KEY 0x00F0000000000000ULL #define PSW_SHIFT_KEY 52 +#define PSW_MASK_SHORTPSW 0x0008000000000000ULL #define PSW_MASK_MCHECK 0x0004000000000000ULL #define PSW_MASK_WAIT 0x0002000000000000ULL #define PSW_MASK_PSTATE 0x0001000000000000ULL diff --git a/target/s390x/helper.h b/target/s390x/helper.h index 56e8149866..b5813c2ac2 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -324,13 +324,10 @@ DEF_HELPER_FLAGS_4(ipte, TCG_CALL_NO_RWG, void, env, i64, i64, i32) DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_1(purge, TCG_CALL_NO_RWG, void, env) DEF_HELPER_2(lra, i64, env, i64) -DEF_HELPER_FLAGS_2(lura, TCG_CALL_NO_WG, i64, env, i64) -DEF_HELPER_FLAGS_2(lurag, TCG_CALL_NO_WG, i64, env, i64) -DEF_HELPER_FLAGS_3(stura, TCG_CALL_NO_WG, void, env, i64, i64) -DEF_HELPER_FLAGS_3(sturg, TCG_CALL_NO_WG, void, env, i64, i64) DEF_HELPER_1(per_check_exception, void, env) DEF_HELPER_FLAGS_3(per_branch, TCG_CALL_NO_RWG, void, env, i64, i64) DEF_HELPER_FLAGS_2(per_ifetch, TCG_CALL_NO_RWG, void, env, i64) +DEF_HELPER_FLAGS_1(per_store_real, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_1(stfl, TCG_CALL_NO_RWG, void, env) DEF_HELPER_2(xsch, void, env, i64) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index 449eee1662..2bc77f0871 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -1275,8 +1275,8 @@ F(0xe313, LRAY, RXY_a, LD, 0, a2, r1, 0, lra, 0, IF_PRIV) F(0xe303, LRAG, RXY_a, Z, 0, a2, r1, 0, lra, 0, IF_PRIV) /* LOAD USING REAL ADDRESS */ - F(0xb24b, LURA, RRE, Z, 0, r2, new, r1_32, lura, 0, IF_PRIV) - F(0xb905, LURAG, RRE, Z, 0, r2, r1, 0, lurag, 0, IF_PRIV) + E(0xb24b, LURA, RRE, Z, 0, 0, new, r1_32, lura, 0, MO_TEUL, IF_PRIV) + E(0xb905, LURAG, RRE, Z, 0, 0, r1, 0, lura, 0, MO_TEQ, IF_PRIV) /* MOVE TO PRIMARY */ F(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0, IF_PRIV) /* MOVE TO SECONDARY */ @@ -1329,8 +1329,8 @@ /* STORE THEN OR SYSTEM MASK */ F(0xad00, STOSM, SI, Z, la1, 0, 0, 0, stnosm, 0, IF_PRIV) /* STORE USING REAL ADDRESS */ - F(0xb246, STURA, RRE, Z, r1_o, r2_o, 0, 0, stura, 0, IF_PRIV) - F(0xb925, STURG, RRE, Z, r1_o, r2_o, 0, 0, sturg, 0, IF_PRIV) + E(0xb246, STURA, RRE, Z, r1_o, 0, 0, 0, stura, 0, MO_TEUL, IF_PRIV) + E(0xb925, STURG, RRE, Z, r1_o, 0, 0, 0, stura, 0, MO_TEQ, IF_PRIV) /* TEST BLOCK */ F(0xb22c, TB, RRE, Z, 0, r2_o, 0, 0, testblock, 0, IF_PRIV) /* TEST PROTECTION */ diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c index 2325767f17..2921419c27 100644 --- a/target/s390x/mem_helper.c +++ b/target/s390x/mem_helper.c @@ -2329,44 +2329,6 @@ void HELPER(purge)(CPUS390XState *env) tlb_flush_all_cpus_synced(env_cpu(env)); } -/* load using real address */ -uint64_t HELPER(lura)(CPUS390XState *env, uint64_t addr) -{ - return cpu_ldl_real_ra(env, wrap_address(env, addr), GETPC()); -} - -uint64_t HELPER(lurag)(CPUS390XState *env, uint64_t addr) -{ - return cpu_ldq_real_ra(env, wrap_address(env, addr), GETPC()); -} - -/* store using real address */ -void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint64_t v1) -{ - cpu_stl_real_ra(env, wrap_address(env, addr), (uint32_t)v1, GETPC()); - - if ((env->psw.mask & PSW_MASK_PER) && - (env->cregs[9] & PER_CR9_EVENT_STORE) && - (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) { - /* PSW is saved just before calling the helper. */ - env->per_address = env->psw.addr; - env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env); - } -} - -void HELPER(sturg)(CPUS390XState *env, uint64_t addr, uint64_t v1) -{ - cpu_stq_real_ra(env, wrap_address(env, addr), v1, GETPC()); - - if ((env->psw.mask & PSW_MASK_PER) && - (env->cregs[9] & PER_CR9_EVENT_STORE) && - (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) { - /* PSW is saved just before calling the helper. */ - env->per_address = env->psw.addr; - env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env); - } -} - /* load real address */ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr) { diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index bfb457fb63..58dbc023eb 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -620,6 +620,16 @@ void HELPER(per_ifetch)(CPUS390XState *env, uint64_t addr) } } } + +void HELPER(per_store_real)(CPUS390XState *env) +{ + if ((env->cregs[9] & PER_CR9_EVENT_STORE) && + (env->cregs[9] & PER_CR9_EVENT_STORE_REAL)) { + /* PSW is saved just before calling the helper. */ + env->per_address = env->psw.addr; + env->per_perc_atmid = PER_CODE_EVENT_STORE_REAL | get_per_atmid(env); + } +} #endif static uint8_t stfl_bytes[2048]; diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 151dfa91fb..4292bb0dd0 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3272,13 +3272,8 @@ static DisasJumpType op_lpq(DisasContext *s, DisasOps *o) #ifndef CONFIG_USER_ONLY static DisasJumpType op_lura(DisasContext *s, DisasOps *o) { - gen_helper_lura(o->out, cpu_env, o->in2); - return DISAS_NEXT; -} - -static DisasJumpType op_lurag(DisasContext *s, DisasOps *o) -{ - gen_helper_lurag(o->out, cpu_env, o->in2); + o->addr1 = get_address(s, 0, get_field(s->fields, r2), 0); + tcg_gen_qemu_ld_tl(o->out, o->addr1, MMU_REAL_IDX, s->insn->data); return DISAS_NEXT; } #endif @@ -4506,13 +4501,13 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o) static DisasJumpType op_stura(DisasContext *s, DisasOps *o) { - gen_helper_stura(cpu_env, o->in2, o->in1); - return DISAS_NEXT; -} + o->addr1 = get_address(s, 0, get_field(s->fields, r2), 0); + tcg_gen_qemu_st_tl(o->in1, o->addr1, MMU_REAL_IDX, s->insn->data); -static DisasJumpType op_sturg(DisasContext *s, DisasOps *o) -{ - gen_helper_sturg(cpu_env, o->in2, o->in1); + if (s->base.tb->flags & FLAG_MASK_PER) { + update_psw_addr(s); + gen_helper_per_store_real(cpu_env); + } return DISAS_NEXT; } #endif diff --git a/target/tilegx/translate.c b/target/tilegx/translate.c index 68dd4aa2d8..abce7e1c75 100644 --- a/target/tilegx/translate.c +++ b/target/tilegx/translate.c @@ -2388,7 +2388,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) dc->zero = NULL; if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { - qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); } gen_tb_start(tb); @@ -2417,11 +2416,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) gen_tb_end(tb, num_insns); tb->size = dc->pc - pc_start; tb->icount = num_insns; - - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { - qemu_log("\n"); - qemu_log_unlock(); - } } void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb, diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c index 0e01f35856..0f6891b8aa 100644 --- a/target/unicore32/translate.c +++ b/target/unicore32/translate.c @@ -1994,12 +1994,12 @@ done_generating: #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif tb->size = dc->pc - pc_start; diff --git a/tcg/tcg.c b/tcg/tcg.c index 5475d49ed1..4f616ba38b 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1085,7 +1085,7 @@ void tcg_prologue_init(TCGContext *s) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("PROLOGUE: [size=%zu]\n", prologue_size); if (s->data_gen_ptr) { size_t code_size = s->data_gen_ptr - buf0; @@ -1110,7 +1110,7 @@ void tcg_prologue_init(TCGContext *s) } qemu_log("\n"); qemu_log_flush(); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif @@ -2114,9 +2114,17 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs) } if (have_prefs || op->life) { - for (; col < 40; ++col) { - putc(' ', qemu_logfile); + + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + for (; col < 40; ++col) { + putc(' ', logfile->fd); + } } + rcu_read_unlock(); } if (op->life) { @@ -4041,11 +4049,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) && qemu_log_in_addr_range(tb->pc))) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("OP:\n"); tcg_dump_ops(s, false); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif @@ -4086,11 +4094,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND) && qemu_log_in_addr_range(tb->pc))) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("OP before indirect lowering:\n"); tcg_dump_ops(s, false); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif /* Replace indirect temps with direct temps. */ @@ -4107,11 +4115,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) && qemu_log_in_addr_range(tb->pc))) { - qemu_log_lock(); + FILE *logfile = qemu_log_lock(); qemu_log("OP after optimization and liveness analysis:\n"); tcg_dump_ops(s, true); qemu_log("\n"); - qemu_log_unlock(); + qemu_log_unlock(logfile); } #endif diff --git a/tests/boot-sector.c b/tests/boot-sector.c index 7824286b9a..9e66c6d013 100644 --- a/tests/boot-sector.c +++ b/tests/boot-sector.c @@ -75,11 +75,11 @@ static const uint8_t s390x_psw_and_magic[] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* in the s390-ccw bios */ }; static const uint8_t s390x_code[] = { - 0xa7, 0xf4, 0x00, 0x0a, /* j 0x10010 */ + 0xa7, 0xf4, 0x00, 0x08, /* j 0x10010 */ 0x00, 0x00, 0x00, 0x00, 'S', '3', '9', '0', 'E', 'P', 0x00, 0x01, - 0xa7, 0x38, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lhi r3,0x7c10 */ + 0xa7, 0x39, HIGH(SIGNATURE_ADDR), LOW(SIGNATURE_ADDR), /* lghi r3,0x7c10 */ 0xa7, 0x48, LOW(SIGNATURE), HIGH(SIGNATURE), /* lhi r4,0xadde */ 0x40, 0x40, 0x30, 0x00, /* sth r4,0(r3) */ 0xa7, 0xf4, 0xff, 0xfa /* j 0x10010 */ diff --git a/tests/docker/common.rc b/tests/docker/common.rc index 512202b0a1..02cd67a8c5 100755 --- a/tests/docker/common.rc +++ b/tests/docker/common.rc @@ -53,12 +53,7 @@ check_qemu() INVOCATION="$@" fi - if command -v gtester > /dev/null 2>&1 && \ - gtester --version > /dev/null 2>&1; then - make $MAKEFLAGS $INVOCATION - else - echo "No working gtester, skipping make $INVOCATION" - fi + make $MAKEFLAGS $INVOCATION } test_fail() diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c index 7e86c5416c..a249800544 100644 --- a/tests/hd-geo-test.c +++ b/tests/hd-geo-test.c @@ -34,8 +34,13 @@ static char *create_test_img(int secs) fd = mkstemp(template); g_assert(fd >= 0); ret = ftruncate(fd, (off_t)secs * 512); - g_assert(ret == 0); close(fd); + + if (ret) { + free(template); + template = NULL; + } + return template; } @@ -934,6 +939,10 @@ int main(int argc, char **argv) for (i = 0; i < backend_last; i++) { if (img_secs[i] >= 0) { img_file_name[i] = create_test_img(img_secs[i]); + if (!img_file_name[i]) { + g_test_message("Could not create test images."); + goto test_add_done; + } } else { img_file_name[i] = NULL; } @@ -965,6 +974,7 @@ int main(int argc, char **argv) "skipping hd-geo/override/* tests"); } +test_add_done: ret = g_test_run(); for (i = 0; i < backend_last; i++) { diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005 index 58442762fe..b6d03ac37d 100755 --- a/tests/qemu-iotests/005 +++ b/tests/qemu-iotests/005 @@ -59,10 +59,7 @@ fi # Sanity check: For raw, we require a file system that permits the creation # of a HUGE (but very sparse) file. Check we can create it before continuing. if [ "$IMGFMT" = "raw" ]; then - if ! truncate --size=5T "$TEST_IMG"; then - _notrun "file system on $TEST_DIR does not support large enough files" - fi - rm "$TEST_IMG" + _require_large_file 5T fi echo diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index f3766f2a81..be35bde06f 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -943,7 +943,7 @@ class TestSetSpeed(iotests.QMPTestCase): self.assert_no_active_block_jobs() result = self.vm.qmp('block-stream', device='drive0', speed=-1) - self.assert_qmp(result, 'error/desc', "Invalid parameter 'speed'") + self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value") self.assert_no_active_block_jobs() @@ -952,7 +952,7 @@ class TestSetSpeed(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) - self.assert_qmp(result, 'error/desc', "Invalid parameter 'speed'") + self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value") self.cancel_and_wait(resume=True) diff --git a/tests/qemu-iotests/049 b/tests/qemu-iotests/049 index c100d30ed0..051a1c79e0 100755 --- a/tests/qemu-iotests/049 +++ b/tests/qemu-iotests/049 @@ -78,6 +78,11 @@ for s in $sizes; do test_qemu_img create -f $IMGFMT -o size=$s "$TEST_IMG" done +echo "== 4. Specify size twice (-o and traditional parameter) ==" +echo + +test_qemu_img create -f $IMGFMT -o size=10M "$TEST_IMG" 20M + echo "== Check correct interpretation of suffixes for cluster size ==" echo sizes="1024 1024b 1k 1K 1M " diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index 6b505408dd..affa55b341 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -121,6 +121,11 @@ qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta- and exabytes, respectively. +== 4. Specify size twice (-o and traditional parameter) == + +qemu-img create -f qcow2 -o size=10M TEST_DIR/t.qcow2 20M +qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once + == Check correct interpretation of suffixes for cluster size == qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 53bcdbc911..a13bce2fd0 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -41,6 +41,7 @@ _supported_proto file # A compat=0.10 image is created in this test which does not support anything # other than refcount_bits=16 _unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' +_require_drivers nbd do_run_qemu() { diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index b91d8321bb..d96f17a484 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -49,6 +49,9 @@ _supported_fmt qcow2 _supported_proto file _supported_os Linux +# The repair process will create a large file - so check for availability first +_require_large_file 64G + rt_offset=65536 # 0x10000 (XXX: just an assumption) rb_offset=131072 # 0x20000 (XXX: just an assumption) l1_offset=196608 # 0x30000 (XXX: just an assumption) diff --git a/tests/qemu-iotests/079 b/tests/qemu-iotests/079 index 81f0c21f53..78536d3bbf 100755 --- a/tests/qemu-iotests/079 +++ b/tests/qemu-iotests/079 @@ -39,6 +39,9 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file nfs +# Some containers (e.g. non-x86 on Travis) do not allow large files +_require_large_file 4G + echo "=== Check option preallocation and cluster_size ===" echo cluster_sizes="16384 32768 65536 131072 262144 524288 1048576 2097152 4194304" diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206 index 5bb738bf23..9f16a7df8d 100755 --- a/tests/qemu-iotests/206 +++ b/tests/qemu-iotests/206 @@ -25,16 +25,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['qcow2']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', - filters=[iotests.filter_qmp_testfiles], - job_id='job0', options=options) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - with iotests.FilePath('t.qcow2') as disk_path, \ iotests.FilePath('t.qcow2.base') as backing_path, \ iotests.VM() as vm: @@ -50,18 +40,18 @@ with iotests.FilePath('t.qcow2') as disk_path, \ size = 128 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) vm.qmp_log('blockdev-add', filters=[iotests.filter_qmp_testfiles], driver='file', filename=disk_path, node_name='imgfile') - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'imgfile', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) vm.shutdown() iotests.img_info_log(disk_path) @@ -76,23 +66,23 @@ with iotests.FilePath('t.qcow2') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0, - 'preallocation': 'off', - 'nocow': False }) - - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'version': 'v3', - 'cluster-size': 65536, - 'preallocation': 'off', - 'lazy-refcounts': False, - 'refcount-bits': 16 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0, + 'preallocation': 'off', + 'nocow': False }) + + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'version': 'v3', + 'cluster-size': 65536, + 'preallocation': 'off', + 'lazy-refcounts': False, + 'refcount-bits': 16 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -107,23 +97,23 @@ with iotests.FilePath('t.qcow2') as disk_path, \ size = 32 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0, - 'preallocation': 'falloc', - 'nocow': True }) - - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'version': 'v3', - 'cluster-size': 2097152, - 'preallocation': 'metadata', - 'lazy-refcounts': True, - 'refcount-bits': 1 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0, + 'preallocation': 'falloc', + 'nocow': True }) + + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'version': 'v3', + 'cluster-size': 2097152, + 'preallocation': 'metadata', + 'lazy-refcounts': True, + 'refcount-bits': 1 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -135,20 +125,20 @@ with iotests.FilePath('t.qcow2') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'backing-file': backing_path, - 'backing-fmt': 'qcow2', - 'version': 'v2', - 'cluster-size': 512 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'backing-file': backing_path, + 'backing-fmt': 'qcow2', + 'version': 'v2', + 'cluster-size': 512 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -160,22 +150,22 @@ with iotests.FilePath('t.qcow2') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'encrypt': { - 'format': 'luks', - 'key-secret': 'keysec0', - 'cipher-alg': 'twofish-128', - 'cipher-mode': 'ctr', - 'ivgen-alg': 'plain64', - 'ivgen-hash-alg': 'md5', - 'hash-alg': 'sha1', - 'iter-time': 10, - }}) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'encrypt': { + 'format': 'luks', + 'key-secret': 'keysec0', + 'cipher-alg': 'twofish-128', + 'cipher-mode': 'ctr', + 'ivgen-alg': 'plain64', + 'ivgen-hash-alg': 'md5', + 'hash-alg': 'sha1', + 'iter-time': 10, + }}) vm.shutdown() iotests.img_info_log(disk_path) @@ -187,9 +177,9 @@ with iotests.FilePath('t.qcow2') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': "this doesn't exist", - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) vm.shutdown() # @@ -211,9 +201,9 @@ with iotests.FilePath('t.qcow2') as disk_path, \ vm.launch() for size in [ 1234, 18446744073709551104, 9223372036854775808, 9223372036854775296 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size }) vm.shutdown() # @@ -222,20 +212,20 @@ with iotests.FilePath('t.qcow2') as disk_path, \ iotests.log("=== Invalid version ===") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'version': 'v1' }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'version': 'v2', - 'lazy-refcounts': True }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'version': 'v2', - 'refcount-bits': 8 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v1' }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v2', + 'lazy-refcounts': True }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'version': 'v2', + 'refcount-bits': 8 }) vm.shutdown() # @@ -244,15 +234,15 @@ with iotests.FilePath('t.qcow2') as disk_path, \ iotests.log("=== Invalid backing file options ===") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'backing-file': '/dev/null', - 'preallocation': 'full' }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'backing-fmt': imgfmt }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'backing-file': '/dev/null', + 'preallocation': 'full' }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'backing-fmt': imgfmt }) vm.shutdown() # @@ -262,14 +252,14 @@ with iotests.FilePath('t.qcow2') as disk_path, \ vm.launch() for csize in [ 1234, 128, 4194304, 0 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'cluster-size': csize }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 281474976710656, - 'cluster-size': 512 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'cluster-size': csize }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 281474976710656, + 'cluster-size': 512 }) vm.shutdown() # @@ -279,8 +269,8 @@ with iotests.FilePath('t.qcow2') as disk_path, \ vm.launch() for refcount_bits in [ 128, 0, 7 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'refcount-bits': refcount_bits }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'refcount-bits': refcount_bits }) vm.shutdown() diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207 index ec8c1d06f0..812ab34e47 100755 --- a/tests/qemu-iotests/207 +++ b/tests/qemu-iotests/207 @@ -35,13 +35,7 @@ def filter_hash(qmsg): return iotests.filter_qmp(qmsg, _filter) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles, filter_hash]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") + vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash]) with iotests.FilePath('t.img') as disk_path, \ iotests.VM() as vm: diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210 index 565e3b7b9b..4ca0fe26ef 100755 --- a/tests/qemu-iotests/210 +++ b/tests/qemu-iotests/210 @@ -26,15 +26,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['luks']) iotests.verify_protocol(supported=['file']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - with iotests.FilePath('t.luks') as disk_path, \ iotests.VM() as vm: @@ -49,18 +40,18 @@ with iotests.FilePath('t.luks') as disk_path, \ size = 128 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'imgfile', - 'key-secret': 'keysec0', - 'size': size, - 'iter-time': 10 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'imgfile', + 'key-secret': 'keysec0', + 'size': size, + 'iter-time': 10 }) vm.shutdown() # TODO Proper support for images to be used with imgopts and/or protocols @@ -79,22 +70,22 @@ with iotests.FilePath('t.luks') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'key-secret': 'keysec0', - 'cipher-alg': 'twofish-128', - 'cipher-mode': 'ctr', - 'ivgen-alg': 'plain64', - 'ivgen-hash-alg': 'md5', - 'hash-alg': 'sha1', - 'iter-time': 10 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'key-secret': 'keysec0', + 'cipher-alg': 'twofish-128', + 'cipher-mode': 'ctr', + 'ivgen-alg': 'plain64', + 'ivgen-hash-alg': 'md5', + 'hash-alg': 'sha1', + 'iter-time': 10 }) vm.shutdown() # TODO Proper support for images to be used with imgopts and/or protocols @@ -113,9 +104,9 @@ with iotests.FilePath('t.luks') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': "this doesn't exist", - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) vm.shutdown() # @@ -126,11 +117,11 @@ with iotests.FilePath('t.luks') as disk_path, \ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'key-secret': 'keysec0', - 'size': 0, - 'iter-time': 10 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'key-secret': 'keysec0', + 'size': 0, + 'iter-time': 10 }) vm.shutdown() # TODO Proper support for images to be used with imgopts and/or protocols @@ -157,10 +148,10 @@ with iotests.FilePath('t.luks') as disk_path, \ vm.launch() for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'key-secret': 'keysec0', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'key-secret': 'keysec0', + 'size': size }) vm.shutdown() # diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211 index 6afc894f76..8834ebfe85 100755 --- a/tests/qemu-iotests/211 +++ b/tests/qemu-iotests/211 @@ -27,15 +27,9 @@ iotests.verify_image_format(supported_fmts=['vdi']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - error = vm.run_job('job0') - if error and 'Could not allocate bmap' in error: - iotests.notrun('Insufficient memory') - iotests.log("") + error = vm.blockdev_create(options) + if error and 'Could not allocate bmap' in error: + iotests.notrun('Insufficient memory') with iotests.FilePath('t.vdi') as disk_path, \ iotests.VM() as vm: diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212 index 42b74f208b..8f3ccc7b15 100755 --- a/tests/qemu-iotests/212 +++ b/tests/qemu-iotests/212 @@ -26,15 +26,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['parallels']) iotests.verify_protocol(supported=['file']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - with iotests.FilePath('t.parallels') as disk_path, \ iotests.VM() as vm: @@ -47,16 +38,16 @@ with iotests.FilePath('t.parallels') as disk_path, \ size = 128 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'imgfile', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) vm.shutdown() iotests.img_info_log(disk_path) @@ -71,16 +62,16 @@ with iotests.FilePath('t.parallels') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'cluster-size': 1048576 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'cluster-size': 1048576 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -95,16 +86,16 @@ with iotests.FilePath('t.parallels') as disk_path, \ size = 32 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'cluster-size': 65536 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'cluster-size': 65536 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -116,9 +107,9 @@ with iotests.FilePath('t.parallels') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': "this doesn't exist", - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) vm.shutdown() # @@ -129,9 +120,9 @@ with iotests.FilePath('t.parallels') as disk_path, \ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 0 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -143,9 +134,9 @@ with iotests.FilePath('t.parallels') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 4503599627369984}) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 4503599627369984}) vm.shutdown() iotests.img_info_log(disk_path) @@ -171,9 +162,9 @@ with iotests.FilePath('t.parallels') as disk_path, \ vm.launch() for size in [ 1234, 18446744073709551104, 9223372036854775808, 9223372036854775296, 4503599627370497 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size }) vm.shutdown() # @@ -185,12 +176,12 @@ with iotests.FilePath('t.parallels') as disk_path, \ vm.launch() for csize in [ 1234, 128, 4294967296, 9223372036854775808, 18446744073709551104, 0 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'cluster-size': csize }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 281474976710656, - 'cluster-size': 512 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'cluster-size': csize }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 281474976710656, + 'cluster-size': 512 }) vm.shutdown() diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213 index 5604f3cebb..3fc8dc6eaa 100755 --- a/tests/qemu-iotests/213 +++ b/tests/qemu-iotests/213 @@ -26,15 +26,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['vhdx']) iotests.verify_protocol(supported=['file']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - with iotests.FilePath('t.vhdx') as disk_path, \ iotests.VM() as vm: @@ -47,16 +38,16 @@ with iotests.FilePath('t.vhdx') as disk_path, \ size = 128 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'imgfile', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) vm.shutdown() iotests.img_info_log(disk_path) @@ -71,19 +62,19 @@ with iotests.FilePath('t.vhdx') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'log-size': 1048576, - 'block-size': 8388608, - 'subformat': 'dynamic', - 'block-state-zero': True }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'log-size': 1048576, + 'block-size': 8388608, + 'subformat': 'dynamic', + 'block-state-zero': True }) vm.shutdown() iotests.img_info_log(disk_path) @@ -98,19 +89,19 @@ with iotests.FilePath('t.vhdx') as disk_path, \ size = 32 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'log-size': 8388608, - 'block-size': 268435456, - 'subformat': 'fixed', - 'block-state-zero': False }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'log-size': 8388608, + 'block-size': 268435456, + 'subformat': 'fixed', + 'block-state-zero': False }) vm.shutdown() iotests.img_info_log(disk_path) @@ -122,9 +113,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': "this doesn't exist", - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) vm.shutdown() # @@ -135,9 +126,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \ vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 0 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -149,9 +140,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 70368744177664 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 70368744177664 }) vm.shutdown() iotests.img_info_log(disk_path) @@ -176,9 +167,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \ vm.launch() for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296, 70368744177665 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size }) vm.shutdown() # @@ -189,10 +180,10 @@ with iotests.FilePath('t.vhdx') as disk_path, \ vm.launch() for bsize in [ 1234567, 128, 3145728, 536870912, 0 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'block-size': bsize }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'block-size': bsize }) vm.shutdown() # @@ -203,8 +194,8 @@ with iotests.FilePath('t.vhdx') as disk_path, \ vm.launch() for lsize in [ 1234567, 128, 4294967296, 0 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 67108864, - 'log-size': lsize }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 67108864, + 'log-size': lsize }) vm.shutdown() diff --git a/tests/qemu-iotests/220 b/tests/qemu-iotests/220 index 2d62c5dcac..15159270d3 100755 --- a/tests/qemu-iotests/220 +++ b/tests/qemu-iotests/220 @@ -42,10 +42,8 @@ echo "== Creating huge file ==" # Sanity check: We require a file system that permits the creation # of a HUGE (but very sparse) file. tmpfs works, ext4 does not. -if ! truncate --size=513T "$TEST_IMG"; then - _notrun "file system on $TEST_DIR does not support large enough files" -fi -rm "$TEST_IMG" +_require_large_file 513T + IMGOPTS='cluster_size=2M,refcount_bits=1' _make_test_img 513T echo "== Populating refcounts ==" diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237 index 06897f8c87..a2242a4736 100755 --- a/tests/qemu-iotests/237 +++ b/tests/qemu-iotests/237 @@ -26,15 +26,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['vmdk']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - with iotests.FilePath('t.vmdk') as disk_path, \ iotests.FilePath('t.vmdk.1') as extent1_path, \ iotests.FilePath('t.vmdk.2') as extent2_path, \ @@ -50,16 +41,16 @@ with iotests.FilePath('t.vmdk') as disk_path, \ size = 5 * 1024 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'imgfile', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'imgfile', + 'size': size }) vm.shutdown() iotests.img_info_log(disk_path) @@ -74,21 +65,21 @@ with iotests.FilePath('t.vmdk') as disk_path, \ size = 64 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'extents': [], - 'subformat': 'monolithicSparse', - 'adapter-type': 'ide', - 'hwversion': '4', - 'zeroed-grain': False }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'extents': [], + 'subformat': 'monolithicSparse', + 'adapter-type': 'ide', + 'hwversion': '4', + 'zeroed-grain': False }) vm.shutdown() iotests.img_info_log(disk_path) @@ -103,20 +94,20 @@ with iotests.FilePath('t.vmdk') as disk_path, \ size = 32 * 1024 * 1024 vm.launch() - blockdev_create(vm, { 'driver': 'file', - 'filename': disk_path, - 'size': 0 }) - - blockdev_create(vm, { 'driver': imgfmt, - 'file': { - 'driver': 'file', - 'filename': disk_path, - }, - 'size': size, - 'extents': [], - 'subformat': 'monolithicSparse', - 'adapter-type': 'buslogic', - 'zeroed-grain': True }) + vm.blockdev_create({ 'driver': 'file', + 'filename': disk_path, + 'size': 0 }) + + vm.blockdev_create({ 'driver': imgfmt, + 'file': { + 'driver': 'file', + 'filename': disk_path, + }, + 'size': size, + 'extents': [], + 'subformat': 'monolithicSparse', + 'adapter-type': 'buslogic', + 'zeroed-grain': True }) vm.shutdown() iotests.img_info_log(disk_path) @@ -128,9 +119,9 @@ with iotests.FilePath('t.vmdk') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': "this doesn't exist", - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': "this doesn't exist", + 'size': size }) vm.shutdown() # @@ -148,10 +139,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \ vm.launch() for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size, - 'adapter-type': adapter_type }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size, + 'adapter-type': adapter_type }) vm.shutdown() # Invalid @@ -160,10 +151,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \ vm.launch() for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]: - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size, - 'adapter-type': adapter_type }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size, + 'adapter-type': adapter_type }) vm.shutdown() # @@ -185,10 +176,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size, - 'subformat': 'monolithicFlat' }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size, + 'subformat': 'monolithicFlat' }) vm.shutdown() # Correct extent @@ -196,11 +187,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size, - 'subformat': 'monolithicFlat', - 'extents': ['ext1'] }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size, + 'subformat': 'monolithicFlat', + 'extents': ['ext1'] }) vm.shutdown() # Extra extent @@ -208,11 +199,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \ iotests.log("") vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': 512, - 'subformat': 'monolithicFlat', - 'extents': ['ext1', 'ext2', 'ext3'] }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': 512, + 'subformat': 'monolithicFlat', + 'extents': ['ext1', 'ext2', 'ext3'] }) vm.shutdown() # Split formats @@ -228,11 +219,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \ extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ] vm.launch() - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'node0', - 'size': size, - 'subformat': subfmt, - 'extents': extents }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'node0', + 'size': size, + 'subformat': subfmt, + 'extents': extents }) vm.shutdown() iotests.img_info_log(disk_path) diff --git a/tests/qemu-iotests/255 b/tests/qemu-iotests/255 index 3632d507d0..0ba03d9e61 100755 --- a/tests/qemu-iotests/255 +++ b/tests/qemu-iotests/255 @@ -25,16 +25,6 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['qcow2']) -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', - filters=[iotests.filter_qmp_testfiles], - job_id='job0', options=options) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - iotests.log("") - iotests.log('Finishing a commit job with background reads') iotests.log('============================================') iotests.log('') diff --git a/tests/qemu-iotests/266 b/tests/qemu-iotests/266 index 5b35cd67e4..c353cf88ee 100755 --- a/tests/qemu-iotests/266 +++ b/tests/qemu-iotests/266 @@ -22,15 +22,6 @@ import iotests from iotests import imgfmt -def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_qmp_testfiles]) - - if 'return' in result: - assert result['return'] == {} - vm.run_job('job0') - - # Successful image creation (defaults) def implicit_defaults(vm, file_path): iotests.log("=== Successful image creation (defaults) ===") @@ -40,9 +31,9 @@ def implicit_defaults(vm, file_path): # (Close to 64 MB) size = 8 * 964 * 17 * 512 - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': size }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': size }) # Successful image creation (explicit defaults) @@ -54,11 +45,11 @@ def explicit_defaults(vm, file_path): # (Close to 128 MB) size = 16 * 964 * 17 * 512 - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': size, - 'subformat': 'dynamic', - 'force-size': False }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': size, + 'subformat': 'dynamic', + 'force-size': False }) # Successful image creation (non-default options) @@ -69,11 +60,11 @@ def non_defaults(vm, file_path): # Not representable in CHS (fine with force-size=True) size = 1048576 - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': size, - 'subformat': 'fixed', - 'force-size': True }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': size, + 'subformat': 'fixed', + 'force-size': True }) # Size not representable in CHS with force-size=False @@ -84,10 +75,10 @@ def non_chs_size_without_force(vm, file_path): # Not representable in CHS (will not work with force-size=False) size = 1048576 - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': size, - 'force-size': False }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': size, + 'force-size': False }) # Zero size @@ -95,9 +86,9 @@ def zero_size(vm, file_path): iotests.log("=== Zero size===") iotests.log("") - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': 0 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': 0 }) # Maximum CHS size @@ -105,9 +96,9 @@ def maximum_chs_size(vm, file_path): iotests.log("=== Maximum CHS size===") iotests.log("") - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': 16 * 65535 * 255 * 512 }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': 16 * 65535 * 255 * 512 }) # Actual maximum size @@ -115,10 +106,10 @@ def maximum_size(vm, file_path): iotests.log("=== Actual maximum size===") iotests.log("") - blockdev_create(vm, { 'driver': imgfmt, - 'file': 'protocol-node', - 'size': 0xff000000 * 512, - 'force-size': True }) + vm.blockdev_create({ 'driver': imgfmt, + 'file': 'protocol-node', + 'size': 0xff000000 * 512, + 'force-size': True }) def main(): @@ -132,9 +123,9 @@ def main(): vm.launch() iotests.log('--- Creating empty file ---') - blockdev_create(vm, { 'driver': 'file', - 'filename': file_path, - 'size': 0 }) + vm.blockdev_create({ 'driver': 'file', + 'filename': file_path, + 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=file_path, node_name='protocol-node', diff --git a/tests/qemu-iotests/266.out b/tests/qemu-iotests/266.out index b11953e81f..5a7d7d01aa 100644 --- a/tests/qemu-iotests/266.out +++ b/tests/qemu-iotests/266.out @@ -3,6 +3,7 @@ {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -13,6 +14,7 @@ {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 64 MiB (67125248 bytes) @@ -23,6 +25,7 @@ cluster_size: 2097152 {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -33,6 +36,7 @@ cluster_size: 2097152 {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 128 MiB (134250496 bytes) @@ -43,6 +47,7 @@ cluster_size: 2097152 {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -53,6 +58,7 @@ cluster_size: 2097152 {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 1 MiB (1048576 bytes) @@ -62,6 +68,7 @@ virtual size: 1 MiB (1048576 bytes) {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -73,6 +80,7 @@ Job failed: The requested image size cannot be represented in CHS geometry {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + qemu-img: Could not open 'TEST_IMG': File too small for a VHD header --- Creating empty file --- @@ -80,6 +88,7 @@ qemu-img: Could not open 'TEST_IMG': File too small for a VHD header {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -90,6 +99,7 @@ qemu-img: Could not open 'TEST_IMG': File too small for a VHD header {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 0 B (0 bytes) @@ -100,6 +110,7 @@ cluster_size: 2097152 {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -110,6 +121,7 @@ cluster_size: 2097152 {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 127 GiB (136899993600 bytes) @@ -120,6 +132,7 @@ cluster_size: 2097152 {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + {"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}} {"return": {}} @@ -130,6 +143,7 @@ cluster_size: 2097152 {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} + image: TEST_IMG file format: IMGFMT virtual size: 1.99 TiB (2190433320960 bytes) diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267 index 170e173c0a..b823668e29 100755 --- a/tests/qemu-iotests/267 +++ b/tests/qemu-iotests/267 @@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto file _supported_os Linux +_require_drivers copy-on-read # Internal snapshots are (currently) impossible with refcount_bits=1 _unsupported_imgopts 'refcount_bits=1[^0-9]' diff --git a/tests/qemu-iotests/273 b/tests/qemu-iotests/273 index 98a672516d..d598c47d9b 100755 --- a/tests/qemu-iotests/273 +++ b/tests/qemu-iotests/273 @@ -48,7 +48,8 @@ do_run_qemu() run_qemu() { do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp | - _filter_generated_node_ids | _filter_imgfmt | _filter_actual_image_size + _filter_generated_node_ids | _filter_imgfmt | + _filter_actual_image_size | _filter_img_info } TEST_IMG="$TEST_IMG.base" _make_test_img 64M diff --git a/tests/qemu-iotests/273.out b/tests/qemu-iotests/273.out index c410fee5c4..684b8d6f77 100644 --- a/tests/qemu-iotests/273.out +++ b/tests/qemu-iotests/273.out @@ -38,15 +38,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev "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 @@ -57,15 +48,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev "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 @@ -136,15 +118,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev "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 diff --git a/tests/qemu-iotests/279 b/tests/qemu-iotests/279 new file mode 100755 index 0000000000..6682376808 --- /dev/null +++ b/tests/qemu-iotests/279 @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# Test qemu-img --backing-chain --image-opts +# +# 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 + rm -f "$TEST_IMG.mid" +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# Backing files are required... +_supported_fmt qcow qcow2 vmdk qed +_supported_proto file +_supported_os Linux + +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" + +echo +echo '== qemu-img info --backing-chain ==' +_img_info --backing-chain | _filter_img_info + +echo +echo '== qemu-img info --backing-chain --image-opts ==' +TEST_IMG="driver=qcow2,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts | _filter_img_info + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/279.out b/tests/qemu-iotests/279.out new file mode 100644 index 0000000000..f4dc6c69cb --- /dev/null +++ b/tests/qemu-iotests/279.out @@ -0,0 +1,35 @@ +QA output created by 279 +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 + +== qemu-img info --backing-chain == +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +backing file: TEST_DIR/t.IMGFMT.mid + +image: TEST_DIR/t.IMGFMT.mid +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +backing file: TEST_DIR/t.IMGFMT.base + +image: TEST_DIR/t.IMGFMT.base +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) + +== qemu-img info --backing-chain --image-opts == +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +backing file: TEST_DIR/t.IMGFMT.mid + +image: TEST_DIR/t.IMGFMT.mid +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +backing file: TEST_DIR/t.IMGFMT.base + +image: TEST_DIR/t.IMGFMT.base +file format: IMGFMT +virtual size: 64 MiB (67108864 bytes) +*** done diff --git a/tests/qemu-iotests/280 b/tests/qemu-iotests/280 new file mode 100755 index 0000000000..0b1fa8e1d8 --- /dev/null +++ b/tests/qemu-iotests/280 @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# +# 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/>. +# +# Creator/Owner: Kevin Wolf <kwolf@redhat.com> +# +# Test migration to file for taking an external snapshot with VM state. + +import iotests +import os + +iotests.verify_image_format(supported_fmts=['qcow2']) +iotests.verify_protocol(supported=['file']) +iotests.verify_platform(['linux']) + +with iotests.FilePath('base') as base_path , \ + iotests.FilePath('top') as top_path, \ + iotests.VM() as vm: + + iotests.qemu_img_log('create', '-f', iotests.imgfmt, base_path, '64M') + + iotests.log('=== Launch VM ===') + vm.add_object('iothread,id=iothread0') + vm.add_blockdev('file,filename=%s,node-name=base-file' % (base_path)) + vm.add_blockdev('%s,file=base-file,node-name=base-fmt' % (iotests.imgfmt)) + vm.add_device('virtio-blk,drive=base-fmt,iothread=iothread0,id=vda') + vm.launch() + + vm.enable_migration_events('VM') + + iotests.log('\n=== Migrate to file ===') + vm.qmp_log('migrate', uri='exec:cat > /dev/null') + + with iotests.Timeout(3, 'Migration does not complete'): + vm.wait_migration() + + iotests.log('\nVM is now stopped:') + iotests.log(vm.qmp('query-migrate')['return']['status']) + vm.qmp_log('query-status') + + iotests.log('\n=== Create a snapshot of the disk image ===') + vm.blockdev_create({ + 'driver': 'file', + 'filename': top_path, + 'size': 0, + }) + vm.qmp_log('blockdev-add', node_name='top-file', + driver='file', filename=top_path, + filters=[iotests.filter_qmp_testfiles]) + + vm.blockdev_create({ + 'driver': iotests.imgfmt, + 'file': 'top-file', + 'size': 1024 * 1024, + }) + vm.qmp_log('blockdev-add', node_name='top-fmt', + driver=iotests.imgfmt, file='top-file') + + vm.qmp_log('blockdev-snapshot', node='base-fmt', overlay='top-fmt') + + iotests.log('\n=== Resume the VM and simulate a write request ===') + vm.qmp_log('cont') + iotests.log(vm.hmp_qemu_io('-d vda/virtio-backend', 'write 4k 4k')) + + iotests.log('\n=== Commit it to the backing file ===') + result = vm.qmp_log('block-commit', job_id='job0', auto_dismiss=False, + device='top-fmt', top_node='top-fmt', + filters=[iotests.filter_qmp_testfiles]) + if 'return' in result: + vm.run_job('job0') diff --git a/tests/qemu-iotests/280.out b/tests/qemu-iotests/280.out new file mode 100644 index 0000000000..5d382faaa8 --- /dev/null +++ b/tests/qemu-iotests/280.out @@ -0,0 +1,50 @@ +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 + +=== Launch VM === +Enabling migration QMP events on VM... +{"return": {}} + +=== Migrate to file === +{"execute": "migrate", "arguments": {"uri": "exec:cat > /dev/null"}} +{"return": {}} +{"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} +{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} +{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} + +VM is now stopped: +completed +{"execute": "query-status", "arguments": {}} +{"return": {"running": false, "singlestep": false, "status": "postmigrate"}} + +=== Create a snapshot of the disk image === +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-top", "size": 0}}} +{"return": {}} +{"execute": "job-dismiss", "arguments": {"id": "job0"}} +{"return": {}} + +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-top", "node-name": "top-file"}} +{"return": {}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "top-file", "size": 1048576}}} +{"return": {}} +{"execute": "job-dismiss", "arguments": {"id": "job0"}} +{"return": {}} + +{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": "top-file", "node-name": "top-fmt"}} +{"return": {}} +{"execute": "blockdev-snapshot", "arguments": {"node": "base-fmt", "overlay": "top-fmt"}} +{"return": {}} + +=== Resume the VM and simulate a write request === +{"execute": "cont", "arguments": {}} +{"return": {}} +{"return": ""} + +=== Commit it to the backing file === +{"execute": "block-commit", "arguments": {"auto-dismiss": false, "device": "top-fmt", "job-id": "job0", "top-node": "top-fmt"}} +{"return": {}} +{"execute": "job-complete", "arguments": {"id": "job0"}} +{"return": {}} +{"data": {"device": "job0", "len": 65536, "offset": 65536, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} +{"data": {"device": "job0", "len": 65536, "offset": 65536, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}} +{"execute": "job-dismiss", "arguments": {"id": "job0"}} +{"return": {}} diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 0cc8acc9ed..555c453911 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -217,7 +217,8 @@ 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.type=unix,file.path=$SOCKDIR/nbd" + TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix" + TEST_IMG="$TEST_IMG,file.path=$SOCK_DIR/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" @@ -643,5 +644,15 @@ _require_drivers() done } +# Check that we have a file system that allows huge (but very sparse) files +# +_require_large_file() +{ + if ! truncate --size="$1" "$TEST_IMG"; then + _notrun "file system on $TEST_DIR does not support large enough files" + fi + rm "$TEST_IMG" +} + # make sure this script returns success true diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 6b10a6a762..cb2b789e44 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -286,3 +286,5 @@ 272 rw 273 backing quick 277 rw quick +279 rw backing quick +280 rw migration quick diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index df0708923d..8739ec6613 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -162,6 +162,11 @@ def qemu_io(*args): sys.stderr.write('qemu-io received signal %i: %s\n' % (-exitcode, ' '.join(args))) return subp.communicate()[0] +def qemu_io_log(*args): + result = qemu_io(*args) + log(result, filters=[filter_testfiles, filter_qemu_io]) + return result + def qemu_io_silent(*args): '''Run qemu-io and return the exit code, suppressing stdout''' args = qemu_io_args + list(args) @@ -604,7 +609,7 @@ class VM(qtest.QEMUQtestMachine): ] error = None while True: - ev = filter_qmp_event(self.events_wait(events)) + ev = filter_qmp_event(self.events_wait(events, timeout=wait)) if ev['event'] != 'JOB_STATUS_CHANGE': if use_log: log(ev) @@ -617,6 +622,8 @@ class VM(qtest.QEMUQtestMachine): error = j['error'] if use_log: log('Job failed: %s' % (j['error'])) + elif status == 'ready': + self.qmp_log('job-complete', id=job) elif status == 'pending' and not auto_finalize: if pre_finalize: pre_finalize() @@ -636,6 +643,22 @@ class VM(qtest.QEMUQtestMachine): elif status == 'null': return error + # Returns None on success, and an error string on failure + def blockdev_create(self, options, job_id='job0', filters=None): + if filters is None: + filters = [filter_qmp_testfiles] + result = self.qmp_log('blockdev-create', filters=filters, + job_id=job_id, options=options) + + if 'return' in result: + assert result['return'] == {} + job_result = self.run_job(job_id) + else: + job_result = result['error'] + + log("") + return job_result + def enable_migration_events(self, name): log('Enabling migration QMP events on %s...' % name) log(self.qmp('migrate-set-capabilities', capabilities=[ diff --git a/tests/tcg/Makefile.prereqs b/tests/tcg/Makefile.prereqs index 7494b31b95..9a29604a83 100644 --- a/tests/tcg/Makefile.prereqs +++ b/tests/tcg/Makefile.prereqs @@ -13,6 +13,6 @@ DOCKER_IMAGE:= ifneq ($(DOCKER_IMAGE),) build-tcg-tests-$(PROBE_TARGET): docker-image-$(DOCKER_IMAGE) +endif $(BUILD_DIR)/tests/tcg/config_$(PROBE_TARGET).mak: config-host.mak config-host.mak: $(SRC_PATH)/tests/tcg/configure.sh -endif diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index 6c4a471aea..210e68396f 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -36,8 +36,10 @@ TMPC="${TMPDIR1}/qemu-conf.c" TMPE="${TMPDIR1}/qemu-conf.exe" container="no" -if has "docker" || has "podman"; then - container=$($python $source_path/tests/docker/docker.py probe) +if test $use_containers = "yes"; then + if has "docker" || has "podman"; then + container=$($python $source_path/tests/docker/docker.py probe) + fi fi # cross compilers defaults, can be overridden with --cross-cc-ARCH diff --git a/tests/test-logging.c b/tests/test-logging.c index a12585f70a..1e646f045d 100644 --- a/tests/test-logging.c +++ b/tests/test-logging.c @@ -108,6 +108,82 @@ static void test_parse_path(gconstpointer data) error_free_or_abort(&err); } +static void test_logfile_write(gconstpointer data) +{ + QemuLogFile *logfile; + QemuLogFile *logfile2; + gchar const *dir = data; + Error *err = NULL; + g_autofree gchar *file_path; + g_autofree gchar *file_path1; + FILE *orig_fd; + + /* + * Before starting test, set log flags, to ensure the file gets + * opened below with the call to qemu_set_log_filename(). + * In cases where a logging backend other than log is used, + * this is needed. + */ + qemu_set_log(CPU_LOG_TB_OUT_ASM); + file_path = g_build_filename(dir, "qemu_test_log_write0.log", NULL); + file_path1 = g_build_filename(dir, "qemu_test_log_write1.log", NULL); + + /* + * Test that even if an open file handle is changed, + * our handle remains valid due to RCU. + */ + qemu_set_log_filename(file_path, &err); + g_assert(!err); + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + orig_fd = logfile->fd; + g_assert(logfile && logfile->fd); + fprintf(logfile->fd, "%s 1st write to file\n", __func__); + fflush(logfile->fd); + + /* Change the logfile and ensure that the handle is still valid. */ + qemu_set_log_filename(file_path1, &err); + g_assert(!err); + logfile2 = atomic_rcu_read(&qemu_logfile); + g_assert(logfile->fd == orig_fd); + g_assert(logfile2->fd != logfile->fd); + fprintf(logfile->fd, "%s 2nd write to file\n", __func__); + fflush(logfile->fd); + rcu_read_unlock(); +} + +static void test_logfile_lock(gconstpointer data) +{ + FILE *logfile; + gchar const *dir = data; + Error *err = NULL; + g_autofree gchar *file_path; + + file_path = g_build_filename(dir, "qemu_test_logfile_lock0.log", NULL); + + /* + * Test the use of the logfile lock, such + * that even if an open file handle is closed, + * our handle remains valid for use due to RCU. + */ + qemu_set_log_filename(file_path, &err); + logfile = qemu_log_lock(); + g_assert(logfile); + fprintf(logfile, "%s 1st write to file\n", __func__); + fflush(logfile); + + /* + * Initiate a close file and make sure our handle remains + * valid since we still have the logfile lock. + */ + qemu_log_close(); + fprintf(logfile, "%s 2nd write to file\n", __func__); + fflush(logfile); + qemu_log_unlock(logfile); + + g_assert(!err); +} + /* Remove a directory and all its entries (non-recursive). */ static void rmdir_full(gchar const *root) { @@ -134,6 +210,10 @@ int main(int argc, char **argv) g_test_add_func("/logging/parse_range", test_parse_range); g_test_add_data_func("/logging/parse_path", tmp_path, test_parse_path); + g_test_add_data_func("/logging/logfile_write_path", + tmp_path, test_logfile_write); + g_test_add_data_func("/logging/logfile_lock_path", + tmp_path, test_logfile_lock); rc = g_test_run(); diff --git a/tests/test-util-filemonitor.c b/tests/test-util-filemonitor.c index 301cd2db61..45009c69f4 100644 --- a/tests/test-util-filemonitor.c +++ b/tests/test-util-filemonitor.c @@ -406,11 +406,22 @@ test_file_monitor_events(void) char *pathdst = NULL; QFileMonitorTestData data; GHashTable *ids = g_hash_table_new(g_int64_hash, g_int64_equal); + char *travis_arch; qemu_mutex_init(&data.lock); data.records = NULL; /* + * This test does not work on Travis LXD containers since some + * syscalls are blocked in that environment. + */ + travis_arch = getenv("TRAVIS_ARCH"); + if (travis_arch && !g_str_equal(travis_arch, "x86_64")) { + g_test_skip("Test does not work on non-x86 Travis containers."); + return; + } + + /* * The file monitor needs the main loop running in * order to receive events from inotify. We must * thus spawn a background thread to run an event diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include index fea348e845..9e7c46a473 100644 --- a/tests/vm/Makefile.include +++ b/tests/vm/Makefile.include @@ -34,6 +34,7 @@ vm-help vm-test: @echo " DEBUG=1 - Enable verbose output on host and interactive debugging" @echo " V=1 - Enable verbose ouput on host and guest commands" @echo " QEMU=/path/to/qemu - Change path to QEMU binary" + @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool" vm-build-all: $(addprefix vm-build-, $(IMAGES)) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 53b9515ee2..ed5dd4f3d0 100755 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -152,6 +152,11 @@ class BaseVM(object): def build_image(self, img): raise NotImplementedError + def exec_qemu_img(self, *args): + cmd = [os.environ.get("QEMU_IMG", "qemu-img")] + cmd.extend(list(args)) + subprocess.check_call(cmd) + def add_source_dir(self, src_dir): name = "data-" + hashlib.sha1(src_dir.encode("utf-8")).hexdigest()[:5] tarfile = os.path.join(self._tmpdir, name + ".tar") diff --git a/tests/vm/centos b/tests/vm/centos index b9e851f2d3..f2f0befd84 100755 --- a/tests/vm/centos +++ b/tests/vm/centos @@ -68,7 +68,7 @@ class CentosVM(basevm.BaseVM): sys.stderr.write("Extracting the image...\n") subprocess.check_call(["ln", "-f", cimg, img_tmp + ".xz"]) subprocess.check_call(["xz", "--keep", "-dvf", img_tmp + ".xz"]) - subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"]) + self.exec_qemu_img("resize", img_tmp, "50G") self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()]) self.wait_ssh() self.ssh_root_check("touch /etc/cloud/cloud-init.disabled") diff --git a/tests/vm/fedora b/tests/vm/fedora index 7fec1479fb..8e270fc0f0 100755 --- a/tests/vm/fedora +++ b/tests/vm/fedora @@ -74,9 +74,7 @@ class FedoraVM(basevm.BaseVM): self.print_step("Preparing iso and disk image") subprocess.check_call(["cp", "-f", cimg, iso]) - subprocess.check_call(["qemu-img", "create", "-f", "qcow2", - img_tmp, self.size]) - + self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) self.print_step("Booting installer") self.boot(img_tmp, extra_args = [ "-bios", "pc-bios/bios-256k.bin", diff --git a/tests/vm/freebsd b/tests/vm/freebsd index 2a19461a90..1825cc5821 100755 --- a/tests/vm/freebsd +++ b/tests/vm/freebsd @@ -82,8 +82,7 @@ class FreeBSDVM(basevm.BaseVM): self.print_step("Preparing iso and disk image") subprocess.check_call(["cp", "-f", cimg, iso_xz]) subprocess.check_call(["xz", "-dvf", iso_xz]) - subprocess.check_call(["qemu-img", "create", "-f", "qcow2", - img_tmp, self.size]) + self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) self.print_step("Booting installer") self.boot(img_tmp, extra_args = [ diff --git a/tests/vm/netbsd b/tests/vm/netbsd index 611e6cc5b5..ec6f3563b2 100755 --- a/tests/vm/netbsd +++ b/tests/vm/netbsd @@ -77,8 +77,7 @@ class NetBSDVM(basevm.BaseVM): self.print_step("Preparing iso and disk image") subprocess.check_call(["ln", "-f", cimg, iso]) - subprocess.check_call(["qemu-img", "create", "-f", "qcow2", - img_tmp, self.size]) + self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) self.print_step("Booting installer") self.boot(img_tmp, extra_args = [ diff --git a/tests/vm/openbsd b/tests/vm/openbsd index b92c39f89a..6df5162dbf 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -73,8 +73,7 @@ class OpenBSDVM(basevm.BaseVM): self.print_step("Preparing iso and disk image") subprocess.check_call(["cp", "-f", cimg, iso]) - subprocess.check_call(["qemu-img", "create", "-f", "qcow2", - img_tmp, self.size]) + self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) self.print_step("Booting installer") self.boot(img_tmp, extra_args = [ diff --git a/tests/vm/ubuntu.i386 b/tests/vm/ubuntu.i386 index f611bebdc9..3834cd7a8d 100755 --- a/tests/vm/ubuntu.i386 +++ b/tests/vm/ubuntu.i386 @@ -70,7 +70,7 @@ class UbuntuX86VM(basevm.BaseVM): sha256sum="28969840626d1ea80bb249c08eef1a4533e8904aa51a327b40f37ac4b4ff04ef") img_tmp = img + ".tmp" subprocess.check_call(["cp", "-f", cimg, img_tmp]) - subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"]) + self.exec_qemu_img("resize", img_tmp, "50G") self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()]) self.wait_ssh() self.ssh_root_check("touch /etc/cloud/cloud-init.disabled") diff --git a/trace/control.c b/trace/control.c index d9cafc161b..0fb8124160 100644 --- a/trace/control.c +++ b/trace/control.c @@ -98,38 +98,6 @@ TraceEvent *trace_event_name(const char *name) return NULL; } -static bool pattern_glob(const char *pat, const char *ev) -{ - while (*pat != '\0' && *ev != '\0') { - if (*pat == *ev) { - pat++; - ev++; - } - else if (*pat == '*') { - if (pattern_glob(pat, ev+1)) { - return true; - } else if (pattern_glob(pat+1, ev)) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - while (*pat == '*') { - pat++; - } - - if (*pat == '\0' && *ev == '\0') { - return true; - } else { - return false; - } -} - - void trace_event_iter_init(TraceEventIter *iter, const char *pattern) { iter->event = 0; @@ -148,8 +116,7 @@ TraceEvent *trace_event_iter_next(TraceEventIter *iter) iter->group++; } if (!iter->pattern || - pattern_glob(iter->pattern, - trace_event_get_name(ev))) { + g_pattern_match_simple(iter->pattern, trace_event_get_name(ev))) { return ev; } } diff --git a/util/log.c b/util/log.c index 1ca13059ee..867264da8d 100644 --- a/util/log.c +++ b/util/log.c @@ -24,9 +24,11 @@ #include "qapi/error.h" #include "qemu/cutils.h" #include "trace/control.h" +#include "qemu/thread.h" static char *logfilename; -FILE *qemu_logfile; +static QemuMutex qemu_logfile_mutex; +QemuLogFile *qemu_logfile; int qemu_loglevel; static int log_append = 0; static GArray *debug_regions; @@ -35,10 +37,14 @@ static GArray *debug_regions; int qemu_log(const char *fmt, ...) { int ret = 0; - if (qemu_logfile) { + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { va_list ap; va_start(ap, fmt); - ret = vfprintf(qemu_logfile, fmt, ap); + ret = vfprintf(logfile->fd, fmt, ap); va_end(ap); /* Don't pass back error results. */ @@ -46,57 +52,91 @@ int qemu_log(const char *fmt, ...) ret = 0; } } + rcu_read_unlock(); return ret; } +static void __attribute__((__constructor__)) qemu_logfile_init(void) +{ + qemu_mutex_init(&qemu_logfile_mutex); +} + +static void qemu_logfile_free(QemuLogFile *logfile) +{ + g_assert(logfile); + + if (logfile->fd != stderr) { + fclose(logfile->fd); + } + g_free(logfile); +} + static bool log_uses_own_buffers; /* enable or disable low levels log */ void qemu_set_log(int log_flags) { + bool need_to_open_file = false; + QemuLogFile *logfile; + qemu_loglevel = log_flags; #ifdef CONFIG_TRACE_LOG qemu_loglevel |= LOG_TRACE; #endif - if (!qemu_logfile && - (is_daemonized() ? logfilename != NULL : qemu_loglevel)) { + /* + * In all cases we only log if qemu_loglevel is set. + * Also: + * If not daemonized we will always log either to stderr + * or to a file (if there is a logfilename). + * If we are daemonized, + * we will only log if there is a logfilename. + */ + if (qemu_loglevel && (!is_daemonized() || logfilename)) { + need_to_open_file = true; + } + qemu_mutex_lock(&qemu_logfile_mutex); + if (qemu_logfile && !need_to_open_file) { + logfile = qemu_logfile; + atomic_rcu_set(&qemu_logfile, NULL); + call_rcu(logfile, qemu_logfile_free, rcu); + } else if (!qemu_logfile && need_to_open_file) { + logfile = g_new0(QemuLogFile, 1); if (logfilename) { - qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); - if (!qemu_logfile) { + logfile->fd = fopen(logfilename, log_append ? "a" : "w"); + if (!logfile->fd) { + g_free(logfile); perror(logfilename); _exit(1); } /* In case we are a daemon redirect stderr to logfile */ if (is_daemonized()) { - dup2(fileno(qemu_logfile), STDERR_FILENO); - fclose(qemu_logfile); + dup2(fileno(logfile->fd), STDERR_FILENO); + fclose(logfile->fd); /* This will skip closing logfile in qemu_log_close() */ - qemu_logfile = stderr; + logfile->fd = stderr; } } else { /* Default to stderr if no log file specified */ assert(!is_daemonized()); - qemu_logfile = stderr; + logfile->fd = stderr; } /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ if (log_uses_own_buffers) { static char logfile_buf[4096]; - setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); + setvbuf(logfile->fd, logfile_buf, _IOLBF, sizeof(logfile_buf)); } else { #if defined(_WIN32) /* Win32 doesn't support line-buffering, so use unbuffered output. */ - setvbuf(qemu_logfile, NULL, _IONBF, 0); + setvbuf(logfile->fd, NULL, _IONBF, 0); #else - setvbuf(qemu_logfile, NULL, _IOLBF, 0); + setvbuf(logfile->fd, NULL, _IOLBF, 0); #endif log_append = 1; } + atomic_rcu_set(&qemu_logfile, logfile); } - if (qemu_logfile && - (is_daemonized() ? logfilename == NULL : !qemu_loglevel)) { - qemu_log_close(); - } + qemu_mutex_unlock(&qemu_logfile_mutex); } void qemu_log_needs_buffers(void) @@ -113,6 +153,7 @@ void qemu_set_log_filename(const char *filename, Error **errp) { char *pidstr; g_free(logfilename); + logfilename = NULL; pidstr = strstr(filename, "%"); if (pidstr) { @@ -224,18 +265,29 @@ out: /* fflush() the log file */ void qemu_log_flush(void) { - fflush(qemu_logfile); + QemuLogFile *logfile; + + rcu_read_lock(); + logfile = atomic_rcu_read(&qemu_logfile); + if (logfile) { + fflush(logfile->fd); + } + rcu_read_unlock(); } /* Close the log file */ void qemu_log_close(void) { - if (qemu_logfile) { - if (qemu_logfile != stderr) { - fclose(qemu_logfile); - } - qemu_logfile = NULL; + QemuLogFile *logfile; + + qemu_mutex_lock(&qemu_logfile_mutex); + logfile = qemu_logfile; + + if (logfile) { + atomic_rcu_set(&qemu_logfile, NULL); + call_rcu(logfile, qemu_logfile_free, rcu); } + qemu_mutex_unlock(&qemu_logfile_mutex); } const QEMULogItem qemu_log_items[] = { |