diff options
31 files changed, 292 insertions, 438 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 28a83afb91..7adb9a4cef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -222,6 +222,7 @@ build-system-centos: variables: IMAGE: centos8 CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-fdt=system + --enable-modules TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu MAKE_CHECK_ARGS: check-build @@ -402,7 +403,7 @@ build-some-softmmu: <<: *native_build_job_definition variables: IMAGE: debian-all-test-cross - CONFIGURE_ARGS: --disable-tools --enable-debug-tcg + CONFIGURE_ARGS: --disable-tools --enable-debug TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu MAKE_CHECK_ARGS: check-tcg @@ -432,14 +433,33 @@ build-some-softmmu-plugins: TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu MAKE_CHECK_ARGS: check-tcg -build-clang: +clang-system: <<: *native_build_job_definition variables: IMAGE: fedora CONFIGURE_ARGS: --cc=clang --cxx=clang++ + --extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu - ppc-softmmu s390x-softmmu arm-linux-user - MAKE_CHECK_ARGS: check + ppc-softmmu s390x-softmmu + MAKE_CHECK_ARGS: check-qtest check-tcg + +clang-user: + <<: *native_build_job_definition + variables: + IMAGE: debian-all-test-cross + CONFIGURE_ARGS: --cc=clang --cxx=clang++ --disable-system + --target-list-exclude=microblazeel-linux-user,aarch64_be-linux-user,i386-linux-user,m68k-linux-user,mipsn32el-linux-user,xtensaeb-linux-user + --extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined + MAKE_CHECK_ARGS: check-unit check-tcg + +tsan-build: + <<: *native_build_job_definition + variables: + IMAGE: ubuntu2004 + CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10 --disable-docs + --enable-fdt=system --enable-slirp=system + TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user + MAKE_CHECK_ARGS: bench V=1 # These targets are on the way out build-deprecated: @@ -467,6 +487,18 @@ check-deprecated: MAKE_CHECK_ARGS: check-tcg allow_failure: true +# gprof/gcov are GCC features +gprof-gcov: + <<: *native_build_job_definition + variables: + IMAGE: ubuntu2004 + CONFIGURE_ARGS: --enable-gprof --enable-gcov + MAKE_CHECK_ARGS: check + TARGETS: aarch64-softmmu ppc64-softmmu s390x-softmmu x86_64-softmmu + timeout: 70m + after_script: + - ${CI_PROJECT_DIR}/scripts/ci/coverage-summary.sh + build-oss-fuzz: <<: *native_build_job_definition variables: diff --git a/.shippable.yml b/.shippable.yml deleted file mode 100644 index 97bfa2a0f3..0000000000 --- a/.shippable.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: c -git: - submodules: false -env: - global: - - LC_ALL=C - matrix: - - IMAGE=debian-amd64 - TARGET_LIST=x86_64-softmmu,x86_64-linux-user - - IMAGE=debian-mips-cross - TARGET_LIST=mips-softmmu -build: - pre_ci_boot: - image_name: registry.gitlab.com/qemu-project/qemu/qemu/${IMAGE} - image_tag: latest - pull: true - options: "-e HOME=/root" - ci: - - unset CC - - mkdir build - - cd build - - ../configure --disable-docs ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST} - - make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) diff --git a/.travis.yml b/.travis.yml index 5f1dea873e..fc27fd6330 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,6 @@ addons: - ninja-build - sparse - uuid-dev - - gcovr # Tests dependencies - genisoimage @@ -119,116 +118,6 @@ after_script: jobs: include: - # --enable-debug implies --enable-debug-tcg, also runs quite a bit slower - - name: "GCC debug (main-softmmu)" - env: - - CONFIG="--enable-debug --target-list=${MAIN_SOFTMMU_TARGETS}" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug" - - - # TCG debug can be run just on its own and is mostly agnostic to user/softmmu distinctions - - name: "GCC debug (user)" - env: - - CONFIG="--enable-debug-tcg --disable-system" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg" - - # Module builds are mostly of interest to major distros - - name: "GCC modules (main-softmmu)" - env: - - CONFIG="--enable-modules --target-list=${MAIN_SOFTMMU_TARGETS}" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-default" - - - # Test with Clang for compile portability (Travis uses clang-5.0) - - name: "Clang (user)" - env: - - CONFIG="--disable-system --host-cc=clang --cxx=clang++" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-default" - compiler: clang - - - - name: "Clang (main-softmmu)" - env: - - CONFIG="--target-list=${MAIN_SOFTMMU_TARGETS} - --host-cc=clang --cxx=clang++" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-sanitize" - compiler: clang - before_script: - - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} - - ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-fsanitize=undefined -Werror" || { cat config.log meson-logs/meson-log.txt && exit 1; } - - - - name: "Clang (other-softmmu)" - env: - - CONFIG="--disable-user --target-list-exclude=${MAIN_SOFTMMU_TARGETS} - --host-cc=clang --cxx=clang++" - - CACHE_NAME="${TRAVIS_BRANCH}-linux-clang-default" - compiler: clang - - - # gprof/gcov are GCC features - - name: "GCC gprof/gcov" - dist: bionic - addons: - apt: - packages: - - ninja-build - env: - - CONFIG="--enable-gprof --enable-gcov --disable-libssh - --target-list=${MAIN_SOFTMMU_TARGETS}" - after_success: - - ${SRC_DIR}/scripts/travis/coverage-summary.sh - - - # Using newer GCC with sanitizers - - name: "GCC9 with sanitizers (softmmu)" - dist: bionic - addons: - apt: - update: true - sources: - # PPAs for newer toolchains - - ubuntu-toolchain-r-test - packages: - # Extra toolchains - - gcc-9 - - g++-9 - # Build dependencies - - libaio-dev - - libattr1-dev - - libbrlapi-dev - - libcap-ng-dev - - libgnutls28-dev - - libgtk-3-dev - - libiscsi-dev - - liblttng-ust-dev - - libnfs-dev - - libncurses5-dev - - libnss3-dev - - libpixman-1-dev - - libpng-dev - - librados-dev - - libsdl2-dev - - libsdl2-image-dev - - libseccomp-dev - - libspice-protocol-dev - - libspice-server-dev - - liburcu-dev - - libusb-1.0-0-dev - - libvte-2.91-dev - - ninja-build - - sparse - - uuid-dev - language: generic - compiler: none - env: - - COMPILER_NAME=gcc CXX=g++-9 CC=gcc-9 - - CONFIG="--cc=gcc-9 --cxx=g++-9 --disable-linux-user" - - TEST_CMD="" - before_script: - - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR} - - ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread" || { cat config.log meson-logs/meson-log.txt && exit 1; } - - name: "[aarch64] GCC check-tcg" arch: arm64 @@ -261,7 +150,7 @@ jobs: - genisoimage env: - TEST_CMD="make check check-tcg V=1" - - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS}" + - CONFIG="--disable-containers --target-list=${MAIN_SOFTMMU_TARGETS} --cxx=/bin/false" - UNRELIABLE=true - name: "[ppc64] GCC check-tcg" diff --git a/MAINTAINERS b/MAINTAINERS index de5fe1c65f..8201f12271 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2340,6 +2340,7 @@ M: Alex Bennée <alex.bennee@linaro.org> R: Philippe Mathieu-Daudé <philmd@redhat.com> S: Maintained F: gdbstub* +F: include/exec/gdbstub.h F: gdb-xml/ F: tests/tcg/multiarch/gdbstub/ @@ -3235,13 +3236,11 @@ R: Philippe Mathieu-Daudé <philmd@redhat.com> S: Maintained F: .github/lockdown.yml F: .travis.yml -F: scripts/travis/ -F: .shippable.yml +F: scripts/ci/ F: tests/docker/ F: tests/vm/ F: scripts/archive-source.sh W: https://travis-ci.org/qemu/qemu -W: https://app.shippable.com/github/qemu/qemu W: http://patchew.org/QEMU/ FreeBSD Hosted Continuous Integration @@ -2827,14 +2827,15 @@ static BdrvChildRole bdrv_backing_role(BlockDriverState *bs) * Sets the bs->backing link of a BDS. A new reference is created; callers * which don't need their own reference any more must call bdrv_unref(). */ -void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, - Error **errp) +int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, + Error **errp) { + int ret = 0; bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) && bdrv_inherits_from_recursive(backing_hd, bs); if (bdrv_is_backing_chain_frozen(bs, child_bs(bs->backing), errp)) { - return; + return -EPERM; } if (backing_hd) { @@ -2853,15 +2854,22 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds, bdrv_backing_role(bs), errp); + if (!bs->backing) { + ret = -EPERM; + goto out; + } + /* If backing_hd was already part of bs's backing chain, and * inherits_from pointed recursively to bs then let's update it to * point directly to bs (else it will become NULL). */ - if (bs->backing && update_inherits_from) { + if (update_inherits_from) { backing_hd->inherits_from = bs; } out: bdrv_refresh_limits(bs, NULL); + + return ret; } /* @@ -3110,7 +3118,6 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, int64_t total_size; QemuOpts *opts = NULL; BlockDriverState *bs_snapshot = NULL; - Error *local_err = NULL; int ret; /* if snapshot, we create a temporary backing file and open it @@ -3157,9 +3164,8 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, * order to be able to return one, we have to increase * bs_snapshot's refcount here */ bdrv_ref(bs_snapshot); - bdrv_append(bs_snapshot, bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); + ret = bdrv_append(bs_snapshot, bs, errp); + if (ret < 0) { bs_snapshot = NULL; goto out; } @@ -4532,9 +4538,9 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) * With auto_skip=false the error is returned if from has a parent which should * not be updated. */ -static void bdrv_replace_node_common(BlockDriverState *from, - BlockDriverState *to, - bool auto_skip, Error **errp) +static int bdrv_replace_node_common(BlockDriverState *from, + BlockDriverState *to, + bool auto_skip, Error **errp) { BdrvChild *c, *next; GSList *list = NULL, *p; @@ -4556,11 +4562,13 @@ static void bdrv_replace_node_common(BlockDriverState *from, if (auto_skip) { continue; } + ret = -EINVAL; error_setg(errp, "Should not change '%s' link to '%s'", c->name, from->node_name); goto out; } if (c->frozen) { + ret = -EPERM; error_setg(errp, "Cannot change '%s' link to '%s'", c->name, from->node_name); goto out; @@ -4591,14 +4599,18 @@ static void bdrv_replace_node_common(BlockDriverState *from, bdrv_set_perm(to); + ret = 0; + out: g_slist_free(list); bdrv_drained_end(from); bdrv_unref(from); + + return ret; } -void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, - Error **errp) +int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, + Error **errp) { return bdrv_replace_node_common(from, to, true, errp); } @@ -4619,28 +4631,30 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, * parents of bs_top after bdrv_append() returns. If the caller needs to keep a * reference of its own, it must call bdrv_ref(). */ -void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - Error **errp) +int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, + Error **errp) { - Error *local_err = NULL; - - bdrv_set_backing_hd(bs_new, bs_top, &local_err); - if (local_err) { - error_propagate(errp, local_err); + int ret = bdrv_set_backing_hd(bs_new, bs_top, errp); + if (ret < 0) { goto out; } - bdrv_replace_node(bs_top, bs_new, &local_err); - if (local_err) { - error_propagate(errp, local_err); + ret = bdrv_replace_node(bs_top, bs_new, errp); + if (ret < 0) { bdrv_set_backing_hd(bs_new, NULL, &error_abort); goto out; } - /* bs_new is now referenced by its new parents, we don't need the - * additional reference any more. */ + ret = 0; + out: + /* + * bs_new is now referenced by its new parents, we don't need the + * additional reference any more. + */ bdrv_unref(bs_new); + + return ret; } static void bdrv_delete(BlockDriverState *bs) diff --git a/block/backup-top.c b/block/backup-top.c index 6e7e7bf340..d1253e1aa6 100644 --- a/block/backup-top.c +++ b/block/backup-top.c @@ -191,7 +191,8 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, BlockCopyState **bcs, Error **errp) { - Error *local_err = NULL; + ERRP_GUARD(); + int ret; BDRVBackupTopState *state; BlockDriverState *top; bool appended = false; @@ -224,9 +225,9 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, bdrv_drained_begin(source); bdrv_ref(top); - bdrv_append(top, source, &local_err); - if (local_err) { - error_prepend(&local_err, "Cannot append backup-top filter: "); + ret = bdrv_append(top, source, errp); + if (ret < 0) { + error_prepend(errp, "Cannot append backup-top filter: "); goto fail; } appended = true; @@ -236,19 +237,18 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source, * we want. */ state->active = true; - bdrv_child_refresh_perms(top, top->backing, &local_err); - if (local_err) { - error_prepend(&local_err, - "Cannot set permissions for backup-top filter: "); + ret = bdrv_child_refresh_perms(top, top->backing, errp); + if (ret < 0) { + error_prepend(errp, "Cannot set permissions for backup-top filter: "); goto fail; } state->cluster_size = cluster_size; state->bcs = block_copy_state_new(top->backing, state->target, cluster_size, perf->use_copy_range, - write_flags, &local_err); - if (local_err) { - error_prepend(&local_err, "Cannot create block-copy-state: "); + write_flags, errp); + if (!state->bcs) { + error_prepend(errp, "Cannot create block-copy-state: "); goto fail; } *bcs = state->bcs; @@ -266,7 +266,6 @@ fail: } bdrv_drained_end(source); - error_propagate(errp, local_err); return NULL; } diff --git a/block/commit.c b/block/commit.c index 71db7ba747..dd9ba87349 100644 --- a/block/commit.c +++ b/block/commit.c @@ -254,7 +254,6 @@ void commit_start(const char *job_id, BlockDriverState *bs, BlockDriverState *iter; BlockDriverState *commit_top_bs = NULL; BlockDriverState *filtered_base; - Error *local_err = NULL; int64_t base_size, top_size; uint64_t base_perms, iter_shared_perms; int ret; @@ -312,10 +311,9 @@ void commit_start(const char *job_id, BlockDriverState *bs, commit_top_bs->total_sectors = top->total_sectors; - bdrv_append(commit_top_bs, top, &local_err); - if (local_err) { + ret = bdrv_append(commit_top_bs, top, errp); + if (ret < 0) { commit_top_bs = NULL; - error_propagate(errp, local_err); goto fail; } diff --git a/block/mirror.c b/block/mirror.c index 9faffe4707..1803c6988b 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1569,7 +1569,6 @@ static BlockJob *mirror_start_job( BlockDriverState *mirror_top_bs; bool target_is_backing; uint64_t target_perms, target_shared_perms; - Error *local_err = NULL; int ret; if (granularity == 0) { @@ -1618,12 +1617,11 @@ static BlockJob *mirror_start_job( * it alive until block_job_create() succeeds even if bs has no parent. */ bdrv_ref(mirror_top_bs); bdrv_drained_begin(bs); - bdrv_append(mirror_top_bs, bs, &local_err); + ret = bdrv_append(mirror_top_bs, bs, errp); bdrv_drained_end(bs); - if (local_err) { + if (ret < 0) { bdrv_unref(mirror_top_bs); - error_propagate(errp, local_err); return NULL; } diff --git a/blockdev.c b/blockdev.c index b250b9b959..cd438e60e3 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1432,6 +1432,7 @@ typedef struct ExternalSnapshotState { static void external_snapshot_prepare(BlkActionState *common, Error **errp) { + int ret; int flags = 0; QDict *options = NULL; Error *local_err = NULL; @@ -1591,9 +1592,8 @@ static void external_snapshot_prepare(BlkActionState *common, * can fail, so we need to do it in .prepare; undoing it for abort is * always possible. */ bdrv_ref(state->new_bs); - bdrv_append(state->new_bs, state->old_bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); + ret = bdrv_append(state->new_bs, state->old_bs, errp); + if (ret < 0) { goto out; } state->overlay_appended = true; diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst index ee43f5dfee..568274baec 100644 --- a/docs/devel/loads-stores.rst +++ b/docs/devel/loads-stores.rst @@ -24,16 +24,12 @@ potentially unaligned pointer values. Function names follow the pattern: -load: ``ld{type}{sign}{size}_{endian}_p(ptr)`` +load: ``ld{sign}{size}_{endian}_p(ptr)`` -store: ``st{type}{size}_{endian}_p(ptr, val)`` - -``type`` - - (empty) : integer access - - ``f`` : float access +store: ``st{size}_{endian}_p(ptr, val)`` ``sign`` - - (empty) : for 32 or 64 bit sizes (including floats and doubles) + - (empty) : for 32 or 64 bit sizes - ``u`` : unsigned - ``s`` : signed @@ -67,8 +63,8 @@ of size ``sz`` bytes. Regexes for git grep - - ``\<ldf\?[us]\?[bwlq]\(_[hbl]e\)\?_p\>`` - - ``\<stf\?[bwlq]\(_[hbl]e\)\?_p\>`` + - ``\<ld[us]\?[bwlq]\(_[hbl]e\)\?_p\>`` + - ``\<st[bwlq]\(_[hbl]e\)\?_p\>`` - ``\<ldn_\([hbl]e\)?_p\>`` - ``\<stn_\([hbl]e\)?_p\>`` diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index 209f9d8172..00ce16de48 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -357,20 +357,6 @@ source and build it. The full list of tests is printed in the ``make docker`` help. -Tools ------ - -There are executables that are created to run in a specific Docker environment. -This makes it easy to write scripts that have heavy or special dependencies, -but are still very easy to use. - -Currently the only tool is ``travis``, which mimics the Travis-CI tests in a -container. It runs in the ``travis`` image: - -.. code:: - - make docker-travis@travis - Debugging a Docker test failure ------------------------------- diff --git a/include/block/block.h b/include/block/block.h index 2f2698074e..a9b7f03f11 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -356,10 +356,10 @@ int bdrv_create(BlockDriver *drv, const char* filename, int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp); BlockDriverState *bdrv_new(void); -void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, - Error **errp); -void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, - Error **errp); +int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, + Error **errp); +int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, + Error **errp); BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options, int flags, Error **errp); @@ -373,8 +373,8 @@ BdrvChild *bdrv_open_child(const char *filename, BdrvChildRole child_role, bool allow_none, Error **errp); BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp); -void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, - Error **errp); +int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, + Error **errp); int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, const char *bdref_key, Error **errp); BlockDriverState *bdrv_open(const char *filename, const char *reference, diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index cfb1d79331..babf0a8959 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -125,13 +125,9 @@ static inline void tswap64s(uint64_t *s) #define ldsw_p(p) ldsw_be_p(p) #define ldl_p(p) ldl_be_p(p) #define ldq_p(p) ldq_be_p(p) -#define ldfl_p(p) ldfl_be_p(p) -#define ldfq_p(p) ldfq_be_p(p) #define stw_p(p, v) stw_be_p(p, v) #define stl_p(p, v) stl_be_p(p, v) #define stq_p(p, v) stq_be_p(p, v) -#define stfl_p(p, v) stfl_be_p(p, v) -#define stfq_p(p, v) stfq_be_p(p, v) #define ldn_p(p, sz) ldn_be_p(p, sz) #define stn_p(p, sz, v) stn_be_p(p, sz, v) #else @@ -139,13 +135,9 @@ static inline void tswap64s(uint64_t *s) #define ldsw_p(p) ldsw_le_p(p) #define ldl_p(p) ldl_le_p(p) #define ldq_p(p) ldq_le_p(p) -#define ldfl_p(p) ldfl_le_p(p) -#define ldfq_p(p) ldfq_le_p(p) #define stw_p(p, v) stw_le_p(p, v) #define stl_p(p, v) stl_le_p(p, v) #define stq_p(p, v) stq_le_p(p, v) -#define stfl_p(p, v) stfl_le_p(p, v) -#define stfq_p(p, v) stfq_le_p(p, v) #define ldn_p(p, sz) ldn_le_p(p, sz) #define stn_p(p, sz, v) stn_le_p(p, sz, v) #endif diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ff0b7bc45e..a024a0350d 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -135,26 +135,6 @@ static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi, return 16; } -static inline int gdb_get_float32(GByteArray *array, float32 val) -{ - uint8_t buf[sizeof(CPU_FloatU)]; - - stfl_p(buf, val); - g_byte_array_append(array, buf, sizeof(buf)); - - return sizeof(buf); -} - -static inline int gdb_get_float64(GByteArray *array, float64 val) -{ - uint8_t buf[sizeof(CPU_DoubleU)]; - - stfq_p(buf, val); - g_byte_array_append(array, buf, sizeof(buf)); - - return sizeof(buf); -} - static inline int gdb_get_zeroes(GByteArray *array, size_t len) { guint oldlen = array->len; diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h index 8b01c38040..4aaf992b5d 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -400,36 +400,6 @@ static inline void stq_le_p(void *ptr, uint64_t v) stq_he_p(ptr, le_bswap(v, 64)); } -/* float access */ - -static inline float32 ldfl_le_p(const void *ptr) -{ - CPU_FloatU u; - u.l = ldl_le_p(ptr); - return u.f; -} - -static inline void stfl_le_p(void *ptr, float32 v) -{ - CPU_FloatU u; - u.f = v; - stl_le_p(ptr, u.l); -} - -static inline float64 ldfq_le_p(const void *ptr) -{ - CPU_DoubleU u; - u.ll = ldq_le_p(ptr); - return u.d; -} - -static inline void stfq_le_p(void *ptr, float64 v) -{ - CPU_DoubleU u; - u.d = v; - stq_le_p(ptr, u.ll); -} - static inline int lduw_be_p(const void *ptr) { return (uint16_t)be_bswap(lduw_he_p(ptr), 16); @@ -465,36 +435,6 @@ static inline void stq_be_p(void *ptr, uint64_t v) stq_he_p(ptr, be_bswap(v, 64)); } -/* float access */ - -static inline float32 ldfl_be_p(const void *ptr) -{ - CPU_FloatU u; - u.l = ldl_be_p(ptr); - return u.f; -} - -static inline void stfl_be_p(void *ptr, float32 v) -{ - CPU_FloatU u; - u.f = v; - stl_be_p(ptr, u.l); -} - -static inline float64 ldfq_be_p(const void *ptr) -{ - CPU_DoubleU u; - u.ll = ldq_be_p(ptr); - return u.d; -} - -static inline void stfq_be_p(void *ptr, float64 v) -{ - CPU_DoubleU u; - u.d = v; - stq_be_p(ptr, u.ll); -} - static inline unsigned long leul_to_cpu(unsigned long v) { #if HOST_LONG_BITS == 32 diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index c61d382be8..975093610a 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -75,6 +75,8 @@ #include "qemu/id.h" #include "qapi/error.h" #include "qapi/qapi-commands-migration.h" +#include "qapi/qapi-visit-migration.h" +#include "qapi/clone-visitor.h" #include "trace.h" #define CHUNK_SIZE (1 << 10) @@ -148,6 +150,7 @@ typedef struct DBMLoadState { BdrvDirtyBitmap *bitmap; bool before_vm_start_handled; /* set in dirty_bitmap_mig_before_vm_start */ + BitmapMigrationBitmapAlias *bmap_inner; /* * cancelled @@ -224,6 +227,7 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, AliasMapInnerNode *amin; GHashTable *bitmaps_map; const char *node_map_from, *node_map_to; + GDestroyNotify gdn; if (!id_wellformed(bmna->alias)) { error_setg(errp, "The node alias '%s' is not well-formed", @@ -263,8 +267,9 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, node_map_to = bmna->node_name; } - bitmaps_map = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); + gdn = (GDestroyNotify) qapi_free_BitmapMigrationBitmapAlias; + bitmaps_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + gdn); amin = g_new(AliasMapInnerNode, 1); *amin = (AliasMapInnerNode){ @@ -276,7 +281,7 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) { const BitmapMigrationBitmapAlias *bmba = bmbal->value; - const char *bmap_map_from, *bmap_map_to; + const char *bmap_map_from; if (strlen(bmba->alias) > UINT8_MAX) { error_setg(errp, @@ -293,7 +298,6 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, if (name_to_alias) { bmap_map_from = bmba->name; - bmap_map_to = bmba->alias; if (g_hash_table_contains(bitmaps_map, bmba->name)) { error_setg(errp, "The bitmap '%s'/'%s' is mapped twice", @@ -302,7 +306,6 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, } } else { bmap_map_from = bmba->alias; - bmap_map_to = bmba->name; if (g_hash_table_contains(bitmaps_map, bmba->alias)) { error_setg(errp, "The bitmap alias '%s'/'%s' is used twice", @@ -311,8 +314,8 @@ static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, } } - g_hash_table_insert(bitmaps_map, - g_strdup(bmap_map_from), g_strdup(bmap_map_to)); + g_hash_table_insert(bitmaps_map, g_strdup(bmap_map_from), + QAPI_CLONE(BitmapMigrationBitmapAlias, bmba)); } } @@ -527,6 +530,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, } FOR_EACH_DIRTY_BITMAP(bs, bitmap) { + BitmapMigrationBitmapAliasTransform *bitmap_transform = NULL; bitmap_name = bdrv_dirty_bitmap_name(bitmap); if (!bitmap_name) { continue; @@ -538,11 +542,18 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, } if (bitmap_aliases) { - bitmap_alias = g_hash_table_lookup(bitmap_aliases, bitmap_name); - if (!bitmap_alias) { + BitmapMigrationBitmapAlias *bmap_inner; + + bmap_inner = g_hash_table_lookup(bitmap_aliases, bitmap_name); + if (!bmap_inner) { /* Skip bitmaps with no alias */ continue; } + + bitmap_alias = bmap_inner->alias; + if (bmap_inner->has_transform) { + bitmap_transform = bmap_inner->transform; + } } else { if (strlen(bitmap_name) > UINT8_MAX) { error_report("Cannot migrate bitmap '%s' on node '%s': " @@ -568,8 +579,15 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, if (bdrv_dirty_bitmap_enabled(bitmap)) { dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED; } - if (bdrv_dirty_bitmap_get_persistence(bitmap)) { - dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + if (bitmap_transform && + bitmap_transform->has_persistent) { + if (bitmap_transform->persistent) { + dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } + } else { + if (bdrv_dirty_bitmap_get_persistence(bitmap)) { + dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } } QSIMPLEQ_INSERT_TAIL(&s->dbms_list, dbms, entry); @@ -777,6 +795,7 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) uint32_t granularity = qemu_get_be32(f); uint8_t flags = qemu_get_byte(f); LoadBitmapState *b; + bool persistent; if (s->cancelled) { return 0; @@ -801,7 +820,15 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) return -EINVAL; } - if (flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT) { + if (s->bmap_inner && + s->bmap_inner->has_transform && + s->bmap_inner->transform->has_persistent) { + persistent = s->bmap_inner->transform->persistent; + } else { + persistent = flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } + + if (persistent) { bdrv_dirty_bitmap_set_persistence(s->bitmap, true); } @@ -1074,14 +1101,19 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, bitmap_name = s->bitmap_alias; if (!s->cancelled && bitmap_alias_map) { - bitmap_name = g_hash_table_lookup(bitmap_alias_map, - s->bitmap_alias); - if (!bitmap_name) { + BitmapMigrationBitmapAlias *bmap_inner; + + bmap_inner = g_hash_table_lookup(bitmap_alias_map, s->bitmap_alias); + if (!bmap_inner) { error_report("Error: Unknown bitmap alias '%s' on node " "'%s' (alias '%s')", s->bitmap_alias, s->bs->node_name, s->node_alias); cancel_incoming_locked(s); + } else { + bitmap_name = bmap_inner->name; } + + s->bmap_inner = bmap_inner; } if (!s->cancelled) { diff --git a/qapi/migration.json b/qapi/migration.json index ce14d78071..6e5943fbb4 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -537,6 +537,19 @@ { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] } ## +# @BitmapMigrationBitmapAliasTransform: +# +# @persistent: If present, the bitmap will be made persistent +# or transient depending on this parameter. +# +# Since: 6.0 +## +{ 'struct': 'BitmapMigrationBitmapAliasTransform', + 'data': { + '*persistent': 'bool' + } } + +## # @BitmapMigrationBitmapAlias: # # @name: The name of the bitmap. @@ -544,12 +557,16 @@ # @alias: An alias name for migration (for example the bitmap name on # the opposite site). # +# @transform: Allows the modification of the migrated bitmap. +# (since 6.0) +# # Since: 5.2 ## { 'struct': 'BitmapMigrationBitmapAlias', 'data': { 'name': 'str', - 'alias': 'str' + 'alias': 'str', + '*transform': 'BitmapMigrationBitmapAliasTransform' } } ## diff --git a/scripts/travis/coverage-summary.sh b/scripts/ci/coverage-summary.sh index d7086cf9ca..8d9fb4de40 100755 --- a/scripts/travis/coverage-summary.sh +++ b/scripts/ci/coverage-summary.sh @@ -3,7 +3,7 @@ # Author: Alex Bennée <alex.bennee@linaro.org> # # Summerise the state of code coverage with gcovr and tweak the output -# to be more sane on Travis hosts. As we expect to be executed on a +# to be more sane on CI runner. As we expect to be executed on a # throw away CI instance we do spam temp files all over the shop. You # most likely don't want to execute this script but just call gcovr # directly. See also "make coverage-report" diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 4185ca94ce..137a3e1a3d 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -72,8 +72,7 @@ static int cf_fpu_gdb_get_reg(CPUM68KState *env, GByteArray *mem_buf, int n) { if (n < 8) { float_status s; - return gdb_get_float64(mem_buf, - floatx80_to_float64(env->fregs[n].d, &s)); + return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); } switch (n) { case 8: /* fpcontrol */ @@ -90,7 +89,7 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) { if (n < 8) { float_status s; - env->fregs[n].d = float64_to_floatx80(ldfq_p(mem_buf), &s); + env->fregs[n].d = float64_to_floatx80(ldq_p(mem_buf), &s); return 8; } switch (n) { diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 01459dd31d..c28319fb97 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -130,7 +130,7 @@ int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n) gdb_get_regl(buf, env->gpr[n]); } else if (n < 64) { /* fprs */ - gdb_get_float64(buf, *cpu_fpr_ptr(env, n - 32)); + gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); } else { switch (n) { case 64: @@ -184,7 +184,7 @@ int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n) gdb_get_reg64(buf, env->gpr[n]); } else if (n < 64) { /* fprs */ - gdb_get_float64(buf, *cpu_fpr_ptr(env, n - 32)); + gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32)); } else if (n < 96) { /* Altivec */ gdb_get_reg64(buf, n - 64); @@ -241,7 +241,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) env->gpr[n] = ldtul_p(mem_buf); } else if (n < 64) { /* fprs */ - *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf); + *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf); } else { switch (n) { case 64: @@ -291,7 +291,7 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) env->gpr[n] = ldq_p(mem_buf); } else if (n < 64) { /* fprs */ - *cpu_fpr_ptr(env, n - 32) = ldfq_p(mem_buf); + *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf); } else { switch (n) { case 64 + 32: diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 3ec45cbc19..e7324e85cd 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -9923,7 +9923,7 @@ static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) { uint8_t *mem_buf; if (n < 32) { - gdb_get_float64(buf, *cpu_fpr_ptr(env, n)); + gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); mem_buf = gdb_get_reg_ptr(buf, 8); ppc_maybe_bswap_register(env, mem_buf, 8); return 8; @@ -9941,7 +9941,7 @@ static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { ppc_maybe_bswap_register(env, mem_buf, 8); - *cpu_fpr_ptr(env, n) = ldfq_p(mem_buf); + *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); return 8; } if (n == 32) { diff --git a/target/sh4/gdbstub.c b/target/sh4/gdbstub.c index 34ad3ca050..3488f68e32 100644 --- a/target/sh4/gdbstub.c +++ b/target/sh4/gdbstub.c @@ -58,9 +58,9 @@ int superh_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) return gdb_get_regl(mem_buf, env->fpscr); case 25 ... 40: if (env->fpscr & FPSCR_FR) { - return gdb_get_float32(mem_buf, env->fregs[n - 9]); + return gdb_get_reg32(mem_buf, env->fregs[n - 9]); } - return gdb_get_float32(mem_buf, env->fregs[n - 25]); + return gdb_get_reg32(mem_buf, env->fregs[n - 25]); case 41: return gdb_get_regl(mem_buf, env->ssr); case 42: @@ -119,9 +119,9 @@ int superh_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; case 25 ... 40: if (env->fpscr & FPSCR_FR) { - env->fregs[n - 9] = ldfl_p(mem_buf); + env->fregs[n - 9] = ldl_p(mem_buf); } else { - env->fregs[n - 25] = ldfl_p(mem_buf); + env->fregs[n - 25] = ldl_p(mem_buf); } break; case 41: diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 93b29ad823..7cab761bf5 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -21,8 +21,6 @@ DOCKER_REGISTRY := $(if $(REGISTRY),$(REGISTRY),registry.gitlab.com/qemu-project DOCKER_TESTS := $(notdir $(shell \ find $(SRC_PATH)/tests/docker/ -name 'test-*' -type f)) -DOCKER_TOOLS := travis - ENGINE := auto DOCKER_SCRIPT=$(SRC_PATH)/tests/docker/docker.py --engine $(ENGINE) @@ -126,7 +124,7 @@ ifneq ($(HOST_ARCH),x86_64) DOCKER_PARTIAL_IMAGES += debian-mips-cross debian-mipsel-cross debian-mips64el-cross DOCKER_PARTIAL_IMAGES += debian-ppc64el-cross DOCKER_PARTIAL_IMAGES += debian-s390x-cross -DOCKER_PARTIAL_IMAGES += fedora travis +DOCKER_PARTIAL_IMAGES += fedora endif docker-image-debian-alpha-cross: docker-image-debian10 @@ -147,8 +145,6 @@ docker-image-debian-s390x-cross: docker-image-debian10 docker-image-debian-sh4-cross: docker-image-debian10 docker-image-debian-sparc64-cross: docker-image-debian10 -docker-image-travis: NOUSER=1 - # Specialist build images, sometimes very limited tools docker-image-debian-tricore-cross: docker-image-debian10 docker-image-debian-all-test-cross: docker-image-debian10 @@ -174,7 +170,7 @@ DOCKER_PARTIAL_IMAGES += fedora-i386-cross fedora-cris-cross # Expand all the pre-requistes for each docker image and test combination $(foreach i,$(filter-out $(DOCKER_PARTIAL_IMAGES),$(DOCKER_IMAGES)), \ - $(foreach t,$(DOCKER_TESTS) $(DOCKER_TOOLS), \ + $(foreach t,$(DOCKER_TESTS), \ $(eval .PHONY: docker-$t@$i) \ $(eval docker-$t@$i: docker-image-$i docker-run-$t@$i) \ ) \ @@ -212,9 +208,6 @@ endif @echo 'Available tests:' @echo ' $(DOCKER_TESTS)' @echo - @echo 'Available tools:' - @echo ' $(DOCKER_TOOLS)' - @echo @echo 'Special variables:' @echo ' TARGET_LIST=a,b,c Override target list in builds.' @echo ' EXTRA_CONFIGURE_OPTS="..."' diff --git a/tests/docker/dockerfiles/travis.docker b/tests/docker/dockerfiles/travis.docker deleted file mode 100644 index cd1435a7e9..0000000000 --- a/tests/docker/dockerfiles/travis.docker +++ /dev/null @@ -1,17 +0,0 @@ -# -# Travis Image - this is broadly the same image that we run our CI -# tests on. -# -FROM travisci/ci-sardonyx:packer-1552557266-f909ac5 -ENV DEBIAN_FRONTEND noninteractive -ENV LANG en_US.UTF-8 -ENV LC_ALL en_US.UTF-8 -RUN sed -i "s/# deb-src/deb-src/" /etc/apt/sources.list -RUN apt-get update -RUN apt-get -y build-dep qemu -RUN apt-get -y install device-tree-compiler python3 python3-yaml dh-autoreconf gdb strace lsof net-tools gcovr ninja-build -# Travis tools require PhantomJS / Neo4j / Maven accessible -# in their PATH (QEMU build won't access them). -ENV PATH /usr/local/phantomjs/bin:/usr/local/phantomjs:/usr/local/neo4j-3.2.7/bin:/usr/local/maven-3.5.2/bin:/usr/local/cmake-3.9.2/bin:/usr/local/clang-5.0.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -ENV FEATURES clang pyyaml docs -USER travis diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index 8519584d2b..9750016e51 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -1,8 +1,10 @@ FROM ubuntu:20.04 ENV PACKAGES flex bison \ + bsdmainutils \ ccache \ clang-10\ gcc \ + gcovr \ genisoimage \ gettext \ git \ diff --git a/tests/docker/travis b/tests/docker/travis deleted file mode 100755 index 47c03677d6..0000000000 --- a/tests/docker/travis +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -e -# -# Mimic a travis testing matrix -# -# Copyright (c) 2016 Red Hat Inc. -# -# Authors: -# Fam Zheng <famz@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 -# or (at your option) any later version. See the COPYING file in -# the top-level directory. - -. common.rc - -requires pyyaml -cmdfile=/tmp/travis_cmd_list.sh -$QEMU_SRC/tests/docker/travis.py $QEMU_SRC/.travis.yml > $cmdfile -chmod +x $cmdfile -cd "$QEMU_SRC" -unset BUILD_DIR SRC_DIR -$cmdfile diff --git a/tests/docker/travis.py b/tests/docker/travis.py deleted file mode 100755 index 37307ac366..0000000000 --- a/tests/docker/travis.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 -# -# Travis YAML config parser -# -# Copyright (c) 2016 Red Hat Inc. -# -# Authors: -# Fam Zheng <famz@redhat.com> -# -# This work is licensed under the terms of the GNU GPL, version 2 -# or (at your option) any later version. See the COPYING file in -# the top-level directory. - -import sys -import yaml -import itertools - -def load_yaml(fname): - return yaml.safe_load(open(fname, "r").read()) - -def conf_iter(conf): - # If "compiler" is omitted from the included env then Travis picks the - # first entry of the global compiler list. - default_compiler = conf["compiler"][0] - def env_to_list(env): - return env if isinstance(env, list) else [env] - for entry in conf["matrix"]["include"]: - yield {"env": env_to_list(entry["env"]), - "compiler": entry.get("compiler", default_compiler)} - -def main(): - if len(sys.argv) < 2: - sys.stderr.write("Usage: %s <travis-file>\n" % sys.argv[0]) - return 1 - conf = load_yaml(sys.argv[1]) - print("\n".join((": ${%s}" % var for var in conf["env"]["global"]))) - for config in conf_iter(conf): - print("(") - print("\n".join(config["env"])) - print("alias cc=" + config["compiler"]) - print("\n".join(conf["before_script"])) - print("\n".join(conf["script"])) - print(")") - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300 index 43264d883d..63036f6a6e 100755 --- a/tests/qemu-iotests/300 +++ b/tests/qemu-iotests/300 @@ -600,6 +600,99 @@ class TestCrossAliasMigration(TestDirtyBitmapMigration): self.verify_dest_has_all_bitmaps() self.verify_dest_error(None) +class TestAliasTransformMigration(TestDirtyBitmapMigration): + """ + Tests the 'transform' option which modifies bitmap persistence on migration. + """ + + src_node_name = 'node-a' + dst_node_name = 'node-b' + src_bmap_name = 'bmap-a' + dst_bmap_name = 'bmap-b' + + def setUp(self) -> None: + TestDirtyBitmapMigration.setUp(self) + + # Now create another block device and let both have two bitmaps each + result = self.vm_a.qmp('blockdev-add', + node_name='node-b', driver='null-co', + read_zeroes=False) + self.assert_qmp(result, 'return', {}) + + result = self.vm_b.qmp('blockdev-add', + node_name='node-a', driver='null-co', + read_zeroes=False) + self.assert_qmp(result, 'return', {}) + + bmaps_to_add = (('node-a', 'bmap-b'), + ('node-b', 'bmap-a'), + ('node-b', 'bmap-b')) + + for (node, bmap) in bmaps_to_add: + result = self.vm_a.qmp('block-dirty-bitmap-add', + node=node, name=bmap) + self.assert_qmp(result, 'return', {}) + + @staticmethod + def transform_mapping() -> BlockBitmapMapping: + return [ + { + 'node-name': 'node-a', + 'alias': 'node-a', + 'bitmaps': [ + { + 'name': 'bmap-a', + 'alias': 'bmap-a', + 'transform': + { + 'persistent': True + } + }, + { + 'name': 'bmap-b', + 'alias': 'bmap-b' + } + ] + }, + { + 'node-name': 'node-b', + 'alias': 'node-b', + 'bitmaps': [ + { + 'name': 'bmap-a', + 'alias': 'bmap-a' + }, + { + 'name': 'bmap-b', + 'alias': 'bmap-b' + } + ] + } + ] + + def verify_dest_bitmap_state(self) -> None: + bitmaps = self.vm_b.query_bitmaps() + + for node in bitmaps: + bitmaps[node] = sorted(((bmap['name'], bmap['persistent']) for bmap in bitmaps[node])) + + self.assertEqual(bitmaps, + {'node-a': [('bmap-a', True), ('bmap-b', False)], + 'node-b': [('bmap-a', False), ('bmap-b', False)]}) + + def test_transform_on_src(self) -> None: + self.set_mapping(self.vm_a, self.transform_mapping()) + + self.migrate() + self.verify_dest_bitmap_state() + self.verify_dest_error(None) + + def test_transform_on_dst(self) -> None: + self.set_mapping(self.vm_b, self.transform_mapping()) + + self.migrate() + self.verify_dest_bitmap_state() + self.verify_dest_error(None) if __name__ == '__main__': iotests.main(supported_protocols=['file']) diff --git a/tests/qemu-iotests/300.out b/tests/qemu-iotests/300.out index cafb8161f7..12e9ab7d57 100644 --- a/tests/qemu-iotests/300.out +++ b/tests/qemu-iotests/300.out @@ -1,5 +1,5 @@ -..................................... +....................................... ---------------------------------------------------------------------- -Ran 37 tests +Ran 39 tests OK diff --git a/tests/tcg/multiarch/system/Makefile.softmmu-target b/tests/tcg/multiarch/system/Makefile.softmmu-target index 4657f6e4cf..625ed792c6 100644 --- a/tests/tcg/multiarch/system/Makefile.softmmu-target +++ b/tests/tcg/multiarch/system/Makefile.softmmu-target @@ -27,5 +27,9 @@ run-gdbstub-memory: memory --bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \ "softmmu gdbstub support") -MULTIARCH_RUNS += run-gdbstub-memory +else +run-gdbstub-%: + $(call skip-test, "gdbstub test $*", "need working gdb") endif + +MULTIARCH_RUNS += run-gdbstub-memory diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c index 8cff13830e..c4f7d16039 100644 --- a/tests/test-bdrv-graph-mod.c +++ b/tests/test-bdrv-graph-mod.c @@ -101,7 +101,7 @@ static BlockDriverState *pass_through_node(const char *name) */ static void test_update_perm_tree(void) { - Error *local_err = NULL; + int ret; BlockBackend *root = blk_new(qemu_get_aio_context(), BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ, @@ -114,8 +114,8 @@ static void test_update_perm_tree(void) bdrv_attach_child(filter, bs, "child", &child_of_bds, BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_append(filter, bs, &local_err); - error_free_or_abort(&local_err); + ret = bdrv_append(filter, bs, NULL); + g_assert_cmpint(ret, <, 0); blk_unref(root); } |