diff options
50 files changed, 457 insertions, 347 deletions
@@ -1743,11 +1743,10 @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs, uint64_t parent_perm, uint64_t parent_shared, uint64_t *nperm, uint64_t *nshared) { - if (bs->drv && bs->drv->bdrv_child_perm) { - bs->drv->bdrv_child_perm(bs, c, role, reopen_queue, - parent_perm, parent_shared, - nperm, nshared); - } + assert(bs->drv && bs->drv->bdrv_child_perm); + bs->drv->bdrv_child_perm(bs, c, role, reopen_queue, + parent_perm, parent_shared, + nperm, nshared); /* TODO Take force_share from reopen_queue */ if (child_bs && child_bs->force_share) { *nshared = BLK_PERM_ALL; diff --git a/block/commit.c b/block/commit.c index 27537d995b..14e5bb394c 100644 --- a/block/commit.c +++ b/block/commit.c @@ -303,23 +303,14 @@ void commit_start(const char *job_id, BlockDriverState *bs, commit_top_bs->total_sectors = top->total_sectors; bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top)); - bdrv_set_backing_hd(commit_top_bs, top, &local_err); + bdrv_append(commit_top_bs, top, &local_err); if (local_err) { - bdrv_unref(commit_top_bs); - commit_top_bs = NULL; - error_propagate(errp, local_err); - goto fail; - } - bdrv_replace_node(top, commit_top_bs, &local_err); - if (local_err) { - bdrv_unref(commit_top_bs); commit_top_bs = NULL; error_propagate(errp, local_err); goto fail; } s->commit_top_bs = commit_top_bs; - bdrv_unref(commit_top_bs); /* Block all nodes between top and base, because they will * disappear from the chain after this operation. */ diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index e53a1609d7..8a75366c92 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -202,7 +202,7 @@ static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table, continue; } - qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_OTHER); + qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_ALWAYS); bitmap_table[i] = 0; } } diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index e0fe322500..fa7ac1f7cb 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1520,12 +1520,31 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, { BDRVQcow2State *s = bs->opaque; uint64_t start, last, cluster_offset, k, refcount; + int64_t file_len; int ret; if (size <= 0) { return 0; } + file_len = bdrv_getlength(bs->file->bs); + if (file_len < 0) { + return file_len; + } + + /* + * Last cluster of qcow2 image may be semi-allocated, so it may be OK to + * reference some space after file end but it should be less than one + * cluster. + */ + if (offset + size - file_len >= s->cluster_size) { + fprintf(stderr, "ERROR: counting reference for region exceeding the " + "end of the file by one cluster or more: offset 0x%" PRIx64 + " size 0x%" PRIx64 "\n", offset, size); + res->corruptions++; + return 0; + } + start = start_of_cluster(s, offset); last = start_of_cluster(s, offset + size - 1); for(cluster_offset = start; cluster_offset <= last; @@ -1572,7 +1591,7 @@ enum { static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size, int64_t l2_offset, - int flags, BdrvCheckMode fix) + int flags, BdrvCheckMode fix, bool active) { BDRVQcow2State *s = bs->opaque; uint64_t *l2_table, l2_entry; @@ -1641,17 +1660,10 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, { uint64_t offset = l2_entry & L2E_OFFSET_MASK; - if (flags & CHECK_FRAG_INFO) { - res->bfi.allocated_clusters++; - if (next_contiguous_offset && - offset != next_contiguous_offset) { - res->bfi.fragmented_clusters++; - } - next_contiguous_offset = offset + s->cluster_size; - } - /* Correct offsets are cluster aligned */ if (offset_into_cluster(s, offset)) { + res->corruptions++; + if (qcow2_get_cluster_type(bs, l2_entry) == QCOW2_CLUSTER_ZERO_ALLOC) { @@ -1663,11 +1675,12 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, if (fix & BDRV_FIX_ERRORS) { uint64_t l2e_offset = l2_offset + (uint64_t)i * sizeof(uint64_t); + int ign = active ? QCOW2_OL_ACTIVE_L2 : + QCOW2_OL_INACTIVE_L2; l2_entry = QCOW_OFLAG_ZERO; l2_table[i] = cpu_to_be64(l2_entry); - ret = qcow2_pre_write_overlap_check(bs, - QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2, + ret = qcow2_pre_write_overlap_check(bs, ign, l2e_offset, sizeof(uint64_t), false); if (ret < 0) { fprintf(stderr, "ERROR: Overlap check failed\n"); @@ -1686,21 +1699,28 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, /* Do not abort, continue checking the rest of this * L2 table's entries */ } else { + res->corruptions--; res->corruptions_fixed++; /* Skip marking the cluster as used * (it is unused now) */ continue; } - } else { - res->corruptions++; } } else { fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is " "not properly aligned; L2 entry corrupted.\n", offset); - res->corruptions++; } } + if (flags & CHECK_FRAG_INFO) { + res->bfi.allocated_clusters++; + if (next_contiguous_offset && + offset != next_contiguous_offset) { + res->bfi.fragmented_clusters++; + } + next_contiguous_offset = offset + s->cluster_size; + } + /* Mark cluster as used */ if (!has_data_file(bs)) { ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, @@ -1743,7 +1763,7 @@ static int check_refcounts_l1(BlockDriverState *bs, void **refcount_table, int64_t *refcount_table_size, int64_t l1_table_offset, int l1_size, - int flags, BdrvCheckMode fix) + int flags, BdrvCheckMode fix, bool active) { BDRVQcow2State *s = bs->opaque; uint64_t *l1_table = NULL, l2_offset, l1_size2; @@ -1799,7 +1819,7 @@ static int check_refcounts_l1(BlockDriverState *bs, /* Process and check L2 entries */ ret = check_refcounts_l2(bs, res, refcount_table, refcount_table_size, l2_offset, flags, - fix); + fix, active); if (ret < 0) { goto fail; } @@ -1846,7 +1866,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, for (i = 0; i < s->l1_size; i++) { uint64_t l1_entry = s->l1_table[i]; uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK; - bool l2_dirty = false; + int l2_dirty = 0; if (!l2_offset) { continue; @@ -1859,6 +1879,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, continue; } if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) { + res->corruptions++; fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d " "l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n", repair ? "Repairing" : "ERROR", i, l1_entry, refcount); @@ -1871,9 +1892,8 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, res->check_errors++; goto fail; } + res->corruptions--; res->corruptions_fixed++; - } else { - res->corruptions++; } } @@ -1905,6 +1925,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, } } if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) { + res->corruptions++; fprintf(stderr, "%s OFLAG_COPIED data cluster: " "l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n", repair ? "Repairing" : "ERROR", l2_entry, refcount); @@ -1912,16 +1933,13 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, l2_table[j] = cpu_to_be64(refcount == 1 ? l2_entry | QCOW_OFLAG_COPIED : l2_entry & ~QCOW_OFLAG_COPIED); - l2_dirty = true; - res->corruptions_fixed++; - } else { - res->corruptions++; + l2_dirty++; } } } } - if (l2_dirty) { + if (l2_dirty > 0) { ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2, l2_offset, s->cluster_size, false); @@ -1940,6 +1958,8 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res, res->check_errors++; goto fail; } + res->corruptions -= l2_dirty; + res->corruptions_fixed += l2_dirty; } } @@ -1977,6 +1997,7 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, } if (cluster >= *nb_clusters) { + res->corruptions++; fprintf(stderr, "%s refcount block %" PRId64 " is outside image\n", fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); @@ -2016,6 +2037,7 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, goto resize_fail; } + res->corruptions--; res->corruptions_fixed++; ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters, @@ -2029,12 +2051,9 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res, continue; resize_fail: - res->corruptions++; *rebuild = true; fprintf(stderr, "ERROR could not resize image: %s\n", strerror(-ret)); - } else { - res->corruptions++; } continue; } @@ -2090,7 +2109,7 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, /* current L1 table */ ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO, - fix); + fix, true); if (ret < 0) { return ret; } @@ -2119,7 +2138,8 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, continue; } ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, - sn->l1_table_offset, sn->l1_size, 0, fix); + sn->l1_table_offset, sn->l1_size, 0, fix, + false); if (ret < 0) { return ret; } diff --git a/block/ssh.c b/block/ssh.c index 859249113d..12fd4f39e8 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -75,6 +75,14 @@ typedef struct BDRVSSHState { /* Used to warn if 'flush' is not supported. */ bool unsafe_flush_warning; + + /* + * Store the user name for ssh_refresh_filename() because the + * default depends on the system you are on -- therefore, when we + * generate a filename, it should always contain the user name we + * are actually using. + */ + char *user; } BDRVSSHState; static void ssh_state_init(BDRVSSHState *s) @@ -87,6 +95,8 @@ static void ssh_state_init(BDRVSSHState *s) static void ssh_state_free(BDRVSSHState *s) { + g_free(s->user); + if (s->sftp_handle) { libssh2_sftp_close(s->sftp_handle); } @@ -628,14 +638,13 @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts, int ssh_flags, int creat_mode, Error **errp) { int r, ret; - const char *user; long port = 0; if (opts->has_user) { - user = opts->user; + s->user = g_strdup(opts->user); } else { - user = g_get_user_name(); - if (!user) { + s->user = g_strdup(g_get_user_name()); + if (!s->user) { error_setg_errno(errp, errno, "Can't get user name"); ret = -errno; goto err; @@ -685,7 +694,7 @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts, } /* Authenticate. */ - ret = authenticate(s, user, errp); + ret = authenticate(s, s->user, errp); if (ret < 0) { goto err; } @@ -1242,6 +1251,58 @@ static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset, return ssh_grow_file(s, offset, errp); } +static void ssh_refresh_filename(BlockDriverState *bs) +{ + BDRVSSHState *s = bs->opaque; + const char *path, *host_key_check; + int ret; + + /* + * None of these options can be represented in a plain "host:port" + * format, so if any was given, we have to abort. + */ + if (s->inet->has_ipv4 || s->inet->has_ipv6 || s->inet->has_to || + s->inet->has_numeric) + { + return; + } + + path = qdict_get_try_str(bs->full_open_options, "path"); + assert(path); /* mandatory option */ + + host_key_check = qdict_get_try_str(bs->full_open_options, "host_key_check"); + + ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename), + "ssh://%s@%s:%s%s%s%s", + s->user, s->inet->host, s->inet->port, path, + host_key_check ? "?host_key_check=" : "", + host_key_check ?: ""); + if (ret >= sizeof(bs->exact_filename)) { + /* An overflow makes the filename unusable, so do not report any */ + bs->exact_filename[0] = '\0'; + } +} + +static char *ssh_bdrv_dirname(BlockDriverState *bs, Error **errp) +{ + if (qdict_haskey(bs->full_open_options, "host_key_check")) { + /* + * We cannot generate a simple prefix if we would have to + * append a query string. + */ + error_setg(errp, + "Cannot generate a base directory with host_key_check set"); + return NULL; + } + + if (bs->exact_filename[0] == '\0') { + error_setg(errp, "Cannot generate a base directory for this ssh node"); + return NULL; + } + + return path_combine(bs->exact_filename, ""); +} + static const char *const ssh_strong_runtime_opts[] = { "host", "port", @@ -1268,6 +1329,8 @@ static BlockDriver bdrv_ssh = { .bdrv_getlength = ssh_getlength, .bdrv_co_truncate = ssh_co_truncate, .bdrv_co_flush_to_disk = ssh_co_flush, + .bdrv_refresh_filename = ssh_refresh_filename, + .bdrv_dirname = ssh_bdrv_dirname, .create_opts = &ssh_create_opts, .strong_runtime_opts = ssh_strong_runtime_opts, }; diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c index 7b24be8256..251d3d142f 100644 --- a/hw/i2c/smbus_ich9.c +++ b/hw/i2c/smbus_ich9.c @@ -6,23 +6,18 @@ * VA Linux Systems Japan K.K. * Copyright (C) 2012 Jason Baron <jbaron@redhat.com> * - * This is based on acpi.c, but heavily rewritten. + * 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 library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, + * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/> - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. + * 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/> */ #include "qemu/osdep.h" #include "hw/hw.h" diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c index 850f88761c..fe95efc41c 100644 --- a/hw/openrisc/cputimer.c +++ b/hw/openrisc/cputimer.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c index 7d3b734d24..0a906d815e 100644 --- a/hw/openrisc/openrisc_sim.c +++ b/hw/openrisc/openrisc_sim.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c index 569b443f59..2f53cfc82e 100644 --- a/hw/openrisc/pic_cpu.c +++ b/hw/openrisc/pic_cpu.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/include/exec/poison.h b/include/exec/poison.h index 1a7a57baae..b862320fa6 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -44,6 +44,7 @@ #pragma GCC poison TARGET_LONG_BITS #pragma GCC poison TARGET_FMT_lx #pragma GCC poison TARGET_FMT_ld +#pragma GCC poison TARGET_FMT_lu #pragma GCC poison TARGET_PAGE_SIZE #pragma GCC poison TARGET_PAGE_MASK diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h index d1ea4506e2..32ff135089 100644 --- a/linux-user/openrisc/target_cpu.h +++ b/linux-user/openrisc/target_cpu.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/linux-user/openrisc/target_structs.h b/linux-user/openrisc/target_structs.h index afbb7ad108..e98e2bc799 100644 --- a/linux-user/openrisc/target_structs.h +++ b/linux-user/openrisc/target_structs.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h index 1a647ddb98..b0be9a2c1b 100644 --- a/linux-user/sh4/target_cpu.h +++ b/linux-user/sh4/target_cpu.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/linux-user/sh4/target_structs.h b/linux-user/sh4/target_structs.h index 3e832bf69a..00ac39478b 100644 --- a/linux-user/sh4/target_structs.h +++ b/linux-user/sh4/target_structs.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index a50861955a..88a8c70092 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/exception.c b/target/openrisc/exception.c index 49470be051..28c1fce523 100644 --- a/target/openrisc/exception.c +++ b/target/openrisc/exception.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/exception_helper.c b/target/openrisc/exception_helper.c index 6073a5b21c..0797cc9d38 100644 --- a/target/openrisc/exception_helper.c +++ b/target/openrisc/exception_helper.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index 265ce13337..b9d2ebbb8c 100644 --- a/target/openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/insns.decode b/target/openrisc/insns.decode index dad68c8422..7df81c1f22 100644 --- a/target/openrisc/insns.decode +++ b/target/openrisc/insns.decode @@ -6,7 +6,7 @@ # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. +# version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c index bbae956361..ee280df895 100644 --- a/target/openrisc/interrupt.c +++ b/target/openrisc/interrupt.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index 5d822f7ab1..c9e084814c 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c index e7d5219e11..5dec68dcff 100644 --- a/target/openrisc/mmu.c +++ b/target/openrisc/mmu.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 84b08ff640..1be36fe875 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/sh4/gdbstub.c b/target/sh4/gdbstub.c index 13bea00d7d..54568e96f9 100644 --- a/target/sh4/gdbstub.c +++ b/target/sh4/gdbstub.c @@ -7,7 +7,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/sh4/helper.c b/target/sh4/helper.c index 2ff0cf4060..fa51269fb1 100644 --- a/target/sh4/helper.c +++ b/target/sh4/helper.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c index 4f825bae5a..28027f9e0b 100644 --- a/target/sh4/op_helper.c +++ b/target/sh4/op_helper.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/target/sh4/translate.c b/target/sh4/translate.c index cdf0888490..5a7d8c4535 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/tests/Makefile.include b/tests/Makefile.include index 7c8b9c84b2..60de085ee1 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -482,25 +482,6 @@ GENERATED_FILES += tests/test-qapi-types.h \ tests/test-qapi-events-sub-sub-module.h \ tests/test-qapi-introspect.h -test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \ - tests/check-qlist.o tests/check-qnull.o tests/check-qobject.o \ - tests/check-qjson.o tests/check-qlit.o \ - tests/check-block-qtest.o \ - tests/test-coroutine.o tests/test-string-output-visitor.o \ - tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \ - tests/test-clone-visitor.o \ - tests/test-qobject-input-visitor.o \ - tests/test-qmp-cmds.o tests/test-visitor-serialization.o \ - tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \ - tests/test-opts-visitor.o tests/test-qmp-event.o \ - tests/rcutorture.o tests/test-rcu-list.o \ - tests/test-rcu-simpleq.o \ - tests/test-rcu-tailq.o \ - tests/test-qdist.o tests/test-shift128.o \ - tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \ - tests/atomic_add-bench.o tests/atomic64-bench.o - -$(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests @@ -1103,7 +1084,7 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) .PHONY: $(patsubst %, check-%, $(check-qapi-schema-y)) $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json $(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \ - $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \ + PYTHONIOENCODING=utf-8 $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \ $^ >$*.test.out 2>$*.test.err; \ echo $$? >$*.test.exit, \ "TEST","$*.out") diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c index 2f9474e03c..b56b223fc2 100644 --- a/tests/drive_del-test.c +++ b/tests/drive_del-test.c @@ -16,32 +16,32 @@ #include "qapi/qmp/qdict.h" /* TODO actually test the results and get rid of this */ -#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__)) +#define qmp_discard_response(q, ...) qobject_unref(qtest_qmp(q, __VA_ARGS__)) -static void drive_add(void) +static void drive_add(QTestState *qts) { - char *resp = hmp("drive_add 0 if=none,id=drive0"); + char *resp = qtest_hmp(qts, "drive_add 0 if=none,id=drive0"); g_assert_cmpstr(resp, ==, "OK\r\n"); g_free(resp); } -static void drive_del(void) +static void drive_del(QTestState *qts) { - char *resp = hmp("drive_del drive0"); + char *resp = qtest_hmp(qts, "drive_del drive0"); g_assert_cmpstr(resp, ==, ""); g_free(resp); } -static void device_del(void) +static void device_del(QTestState *qts) { QDict *response; /* Complication: ignore DEVICE_DELETED event */ - qmp_discard_response("{'execute': 'device_del'," + qmp_discard_response(qts, "{'execute': 'device_del'," " 'arguments': { 'id': 'dev0' } }"); - response = qmp_receive(); + response = qtest_qmp_receive(qts); g_assert(response); g_assert(qdict_haskey(response, "return")); qobject_unref(response); @@ -49,18 +49,20 @@ static void device_del(void) static void test_drive_without_dev(void) { + QTestState *qts; + /* Start with an empty drive */ - qtest_start("-drive if=none,id=drive0"); + qts = qtest_init("-drive if=none,id=drive0"); /* Delete the drive */ - drive_del(); + drive_del(qts); /* Ensure re-adding the drive works - there should be no duplicate ID error * because the old drive must be gone. */ - drive_add(); + drive_add(qts); - qtest_end(); + qtest_quit(qts); } /* @@ -85,54 +87,53 @@ static void test_after_failed_device_add(void) { char driver[32]; QDict *response; + QTestState *qts; snprintf(driver, sizeof(driver), "virtio-blk-%s", qvirtio_get_dev_type()); - qtest_start("-drive if=none,id=drive0"); + qts = qtest_init("-drive if=none,id=drive0"); /* Make device_add fail. If this leaks the virtio-blk device then a * reference to drive0 will also be held (via qdev properties). */ - response = qmp("{'execute': 'device_add'," - " 'arguments': {" - " 'driver': %s," - " 'drive': 'drive0'" - "}}", driver); + response = qtest_qmp(qts, "{'execute': 'device_add'," + " 'arguments': {" + " 'driver': %s," + " 'drive': 'drive0'" + "}}", driver); g_assert(response); qmp_assert_error_class(response, "GenericError"); /* Delete the drive */ - drive_del(); + drive_del(qts); /* Try to re-add the drive. This fails with duplicate IDs if a leaked * virtio-blk device exists that holds a reference to the old drive0. */ - drive_add(); + drive_add(qts); - qtest_end(); + qtest_quit(qts); } static void test_drive_del_device_del(void) { - char *args; + QTestState *qts; /* Start with a drive used by a device that unplugs instantaneously */ - args = g_strdup_printf("-drive if=none,id=drive0,file=null-co://,format=raw" - " -device virtio-scsi-%s" - " -device scsi-hd,drive=drive0,id=dev0", - qvirtio_get_dev_type()); - qtest_start(args); + qts = qtest_initf("-drive if=none,id=drive0,file=null-co://,format=raw" + " -device virtio-scsi-%s" + " -device scsi-hd,drive=drive0,id=dev0", + qvirtio_get_dev_type()); /* * Delete the drive, and then the device * Doing it in this order takes notoriously tricky special paths */ - drive_del(); - device_del(); + drive_del(qts); + device_del(qts); - qtest_end(); - g_free(args); + qtest_quit(qts); } int main(int argc, char **argv) diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c index 77ba8095bb..6a946c0484 100644 --- a/tests/e1000e-test.c +++ b/tests/e1000e-test.c @@ -231,8 +231,10 @@ static void test_e1000e_multiple_transfers(void *obj, void *data, static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc) { + QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */ + qtest_qmp_device_add("e1000e", "e1000e_net", "{'addr': '0x06'}"); - qpci_unplug_acpi_device_test("e1000e_net", 0x06); + qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06); } static void data_test_clear(void *sockets) diff --git a/tests/ide-test.c b/tests/ide-test.c index d863a99f7f..0277e7d5a9 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -36,7 +36,7 @@ #include "hw/pci/pci_regs.h" /* TODO actually test the results and get rid of this */ -#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__)) +#define qmp_discard_response(q, ...) qobject_unref(qtest_qmp(q, __VA_ARGS__)) #define TEST_IMAGE_SIZE 64 * 1024 * 1024 @@ -125,38 +125,38 @@ static QGuestAllocator guest_malloc; static char tmp_path[] = "/tmp/qtest.XXXXXX"; static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX"; -static void ide_test_start(const char *cmdline_fmt, ...) +static QTestState *ide_test_start(const char *cmdline_fmt, ...) { + QTestState *qts; va_list ap; - char *cmdline; va_start(ap, cmdline_fmt); - cmdline = g_strdup_vprintf(cmdline_fmt, ap); + qts = qtest_vinitf(cmdline_fmt, ap); va_end(ap); - qtest_start(cmdline); - pc_alloc_init(&guest_malloc, global_qtest, 0); + pc_alloc_init(&guest_malloc, qts, 0); - g_free(cmdline); + return qts; } -static void ide_test_quit(void) +static void ide_test_quit(QTestState *qts) { if (pcibus) { qpci_free_pc(pcibus); pcibus = NULL; } alloc_destroy(&guest_malloc); - qtest_end(); + qtest_quit(qts); } -static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar) +static QPCIDevice *get_pci_device(QTestState *qts, QPCIBar *bmdma_bar, + QPCIBar *ide_bar) { QPCIDevice *dev; uint16_t vendor_id, device_id; if (!pcibus) { - pcibus = qpci_new_pc(global_qtest, NULL); + pcibus = qpci_new_pc(qts, NULL); } /* Find PCI device and verify it's the right one */ @@ -198,8 +198,8 @@ static uint64_t trim_range_le(uint64_t sector, uint16_t count) return cpu_to_le64(((uint64_t)count << 48) + sector); } -static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, - PrdtEntry *prdt, int prdt_entries, +static int send_dma_request(QTestState *qts, int cmd, uint64_t sector, + int nb_sectors, PrdtEntry *prdt, int prdt_entries, void(*post_exec)(QPCIDevice *dev, QPCIBar ide_bar, uint64_t sector, int nb_sectors)) { @@ -211,7 +211,7 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, uint8_t status; int flags; - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); flags = cmd & ~0xff; cmd &= 0xff; @@ -246,7 +246,7 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, /* Setup PRDT */ len = sizeof(*prdt) * prdt_entries; guest_prdt = guest_alloc(&guest_malloc, len); - memwrite(guest_prdt, prdt, len); + qtest_memwrite(qts, guest_prdt, prdt, len); qpci_io_writel(dev, bmdma_bar, bmreg_prdt, guest_prdt); /* ATA DMA command */ @@ -283,14 +283,15 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, status = qpci_io_readb(dev, bmdma_bar, bmreg_status); } while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE); - g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR)); + g_assert_cmpint(qtest_get_irq(qts, IDE_PRIMARY_IRQ), ==, + !!(status & BM_STS_INTR)); /* Check IDE status code */ assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), DRDY); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), BSY | DRQ); /* Reading the status register clears the IRQ */ - g_assert(!get_irq(IDE_PRIMARY_IRQ)); + g_assert(!qtest_get_irq(qts, IDE_PRIMARY_IRQ)); /* Stop DMA transfer if still active */ if (status & BM_STS_ACTIVE) { @@ -302,42 +303,61 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, return status; } +static QTestState *test_bmdma_setup(void) +{ + QTestState *qts; + + qts = ide_test_start( + "-drive file=%s,if=ide,cache=writeback,format=raw " + "-global ide-hd.serial=%s -global ide-hd.ver=%s", + tmp_path, "testdisk", "version"); + qtest_irq_intercept_in(qts, "ioapic"); + + return qts; +} + +static void test_bmdma_teardown(QTestState *qts) +{ + ide_test_quit(qts); +} + static void test_bmdma_simple_rw(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; uint8_t *buf; uint8_t *cmpbuf; size_t len = 512; - uintptr_t guest_buf = guest_alloc(&guest_malloc, len); + uintptr_t guest_buf; + PrdtEntry prdt[1]; - PrdtEntry prdt[] = { - { - .addr = cpu_to_le32(guest_buf), - .size = cpu_to_le32(len | PRDT_EOT), - }, - }; + qts = test_bmdma_setup(); + + guest_buf = guest_alloc(&guest_malloc, len); + prdt[0].addr = cpu_to_le32(guest_buf); + prdt[0].size = cpu_to_le32(len | PRDT_EOT); - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); buf = g_malloc(len); cmpbuf = g_malloc(len); /* Write 0x55 pattern to sector 0 */ memset(buf, 0x55, len); - memwrite(guest_buf, buf, len); + qtest_memwrite(qts, guest_buf, buf, len); - status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt, + status = send_dma_request(qts, CMD_WRITE_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); /* Write 0xaa pattern to sector 1 */ memset(buf, 0xaa, len); - memwrite(guest_buf, buf, len); + qtest_memwrite(qts, guest_buf, buf, len); - status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt, + status = send_dma_request(qts, CMD_WRITE_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); @@ -345,31 +365,35 @@ static void test_bmdma_simple_rw(void) /* Read and verify 0x55 pattern in sector 0 */ memset(cmpbuf, 0x55, len); - status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); + status = send_dma_request(qts, CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), + NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); - memread(guest_buf, buf, len); + qtest_memread(qts, guest_buf, buf, len); g_assert(memcmp(buf, cmpbuf, len) == 0); /* Read and verify 0xaa pattern in sector 1 */ memset(cmpbuf, 0xaa, len); - status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL); + status = send_dma_request(qts, CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), + NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); - memread(guest_buf, buf, len); + qtest_memread(qts, guest_buf, buf, len); g_assert(memcmp(buf, cmpbuf, len) == 0); - free_pci_device(dev); g_free(buf); g_free(cmpbuf); + + test_bmdma_teardown(qts); } static void test_bmdma_trim(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; @@ -380,16 +404,16 @@ static void test_bmdma_trim(void) const uint64_t bad_range = trim_range_le(TEST_IMAGE_SIZE / 512 - 1, 2); size_t len = 512; uint8_t *buf; - uintptr_t guest_buf = guest_alloc(&guest_malloc, len); + uintptr_t guest_buf; + PrdtEntry prdt[1]; - PrdtEntry prdt[] = { - { - .addr = cpu_to_le32(guest_buf), - .size = cpu_to_le32(len | PRDT_EOT), - }, - }; + qts = test_bmdma_setup(); + + guest_buf = guest_alloc(&guest_malloc, len); + prdt[0].addr = cpu_to_le32(guest_buf), + prdt[0].size = cpu_to_le32(len | PRDT_EOT), - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); buf = g_malloc(len); @@ -397,9 +421,9 @@ static void test_bmdma_trim(void) *((uint64_t *)buf) = trim_range[0]; *((uint64_t *)buf + 1) = trim_range[1]; - memwrite(guest_buf, buf, 2 * sizeof(uint64_t)); + qtest_memwrite(qts, guest_buf, buf, 2 * sizeof(uint64_t)); - status = send_dma_request(CMD_DSM, 0, 1, prdt, + status = send_dma_request(qts, CMD_DSM, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); @@ -408,9 +432,9 @@ static void test_bmdma_trim(void) *((uint64_t *)buf) = trim_range[2]; *((uint64_t *)buf + 1) = bad_range; - memwrite(guest_buf, buf, 2 * sizeof(uint64_t)); + qtest_memwrite(qts, guest_buf, buf, 2 * sizeof(uint64_t)); - status = send_dma_request(CMD_DSM, 0, 1, prdt, + status = send_dma_request(qts, CMD_DSM, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), ERR); @@ -418,10 +442,12 @@ static void test_bmdma_trim(void) free_pci_device(dev); g_free(buf); + test_bmdma_teardown(qts); } static void test_bmdma_short_prdt(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; @@ -433,24 +459,28 @@ static void test_bmdma_short_prdt(void) }, }; - dev = get_pci_device(&bmdma_bar, &ide_bar); + qts = test_bmdma_setup(); + + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* Normal request */ - status = send_dma_request(CMD_READ_DMA, 0, 1, + status = send_dma_request(qts, CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, 0); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); /* Abort the request before it completes */ - status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1, + status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, 0); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); free_pci_device(dev); + test_bmdma_teardown(qts); } static void test_bmdma_one_sector_short_prdt(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; @@ -463,24 +493,28 @@ static void test_bmdma_one_sector_short_prdt(void) }, }; - dev = get_pci_device(&bmdma_bar, &ide_bar); + qts = test_bmdma_setup(); + + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* Normal request */ - status = send_dma_request(CMD_READ_DMA, 0, 2, + status = send_dma_request(qts, CMD_READ_DMA, 0, 2, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, 0); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); /* Abort the request before it completes */ - status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2, + status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 2, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, 0); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); free_pci_device(dev); + test_bmdma_teardown(qts); } static void test_bmdma_long_prdt(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; @@ -492,29 +526,35 @@ static void test_bmdma_long_prdt(void) }, }; - dev = get_pci_device(&bmdma_bar, &ide_bar); + qts = test_bmdma_setup(); + + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* Normal request */ - status = send_dma_request(CMD_READ_DMA, 0, 1, + status = send_dma_request(qts, CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); /* Abort the request before it completes */ - status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1, + status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); free_pci_device(dev); + test_bmdma_teardown(qts); } static void test_bmdma_no_busmaster(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t status; - dev = get_pci_device(&bmdma_bar, &ide_bar); + qts = test_bmdma_setup(); + + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* No PRDT_EOT, each entry addr 0/size 64k, and in theory qemu shouldn't be * able to access it anyway because the Bus Master bit in the PCI command @@ -522,7 +562,7 @@ static void test_bmdma_no_busmaster(void) * good at confusing and occasionally crashing qemu. */ PrdtEntry prdt[4096] = { }; - status = send_dma_request(CMD_READ_DMA | CMDF_NO_BM, 0, 512, + status = send_dma_request(qts, CMD_READ_DMA | CMDF_NO_BM, 0, 512, prdt, ARRAY_SIZE(prdt), NULL); /* Not entirely clear what the expected result is, but this is what we get @@ -530,20 +570,7 @@ static void test_bmdma_no_busmaster(void) g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); free_pci_device(dev); -} - -static void test_bmdma_setup(void) -{ - ide_test_start( - "-drive file=%s,if=ide,cache=writeback,format=raw " - "-global ide-hd.serial=%s -global ide-hd.ver=%s", - tmp_path, "testdisk", "version"); - qtest_irq_intercept_in(global_qtest, "ioapic"); -} - -static void test_bmdma_teardown(void) -{ - ide_test_quit(); + test_bmdma_teardown(qts); } static void string_cpu_to_be16(uint16_t *s, size_t bytes) @@ -559,6 +586,7 @@ static void string_cpu_to_be16(uint16_t *s, size_t bytes) static void test_identify(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t data; @@ -566,12 +594,12 @@ static void test_identify(void) int i; int ret; - ide_test_start( + qts = ide_test_start( "-drive file=%s,if=ide,cache=writeback,format=raw " "-global ide-hd.serial=%s -global ide-hd.ver=%s", tmp_path, "testdisk", "version"); - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* IDENTIFY command on device 0*/ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -605,7 +633,7 @@ static void test_identify(void) /* Write cache enabled bit */ assert_bit_set(buf[85], 0x20); - ide_test_quit(); + ide_test_quit(qts); free_pci_device(dev); } @@ -613,7 +641,7 @@ static void test_identify(void) * Write sector 1 with random data to make IDE storage dirty * Needed for flush tests so that flushes actually go though the block layer */ -static void make_dirty(uint8_t device) +static void make_dirty(QTestState *qts, uint8_t device) { QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; @@ -622,7 +650,7 @@ static void make_dirty(uint8_t device) uintptr_t guest_buf; void* buf; - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); guest_buf = guest_alloc(&guest_malloc, len); buf = g_malloc(len); @@ -630,7 +658,7 @@ static void make_dirty(uint8_t device) g_assert(guest_buf); g_assert(buf); - memwrite(guest_buf, buf, len); + qtest_memwrite(qts, guest_buf, buf, len); PrdtEntry prdt[] = { { @@ -639,7 +667,7 @@ static void make_dirty(uint8_t device) }, }; - status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt, + status = send_dma_request(qts, CMD_WRITE_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL); g_assert_cmphex(status, ==, BM_STS_INTR); assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR); @@ -650,23 +678,24 @@ static void make_dirty(uint8_t device) static void test_flush(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t data; - ide_test_start( + qts = ide_test_start( "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw", tmp_path); - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); - qtest_irq_intercept_in(global_qtest, "ioapic"); + qtest_irq_intercept_in(qts, "ioapic"); /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */ - make_dirty(0); + make_dirty(qts, 0); /* Delay the completion of the flush request until we explicitly do it */ - g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\"")); + g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"break flush_to_os A\"")); /* FLUSH CACHE command on device 0*/ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -678,7 +707,7 @@ static void test_flush(void) assert_bit_clear(data, DF | ERR | DRQ); /* Complete the command */ - g_free(hmp("qemu-io ide0-hd0 \"resume A\"")); + g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"resume A\"")); /* Check registers */ data = qpci_io_readb(dev, ide_bar, reg_device); @@ -691,29 +720,30 @@ static void test_flush(void) assert_bit_set(data, DRDY); assert_bit_clear(data, BSY | DF | ERR | DRQ); - ide_test_quit(); + ide_test_quit(qts); free_pci_device(dev); } static void test_retry_flush(const char *machine) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t data; prepare_blkdebug_script(debug_path, "flush_to_disk"); - ide_test_start( + qts = ide_test_start( "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw," "rerror=stop,werror=stop", debug_path, tmp_path); - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); - qtest_irq_intercept_in(global_qtest, "ioapic"); + qtest_irq_intercept_in(qts, "ioapic"); /* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */ - make_dirty(0); + make_dirty(qts, 0); /* FLUSH CACHE command on device 0*/ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -724,10 +754,10 @@ static void test_retry_flush(const char *machine) assert_bit_set(data, BSY | DRDY); assert_bit_clear(data, DF | ERR | DRQ); - qmp_eventwait("STOP"); + qtest_qmp_eventwait(qts, "STOP"); /* Complete the command */ - qmp_discard_response("{'execute':'cont' }"); + qmp_discard_response(qts, "{'execute':'cont' }"); /* Check registers */ data = qpci_io_readb(dev, ide_bar, reg_device); @@ -740,18 +770,19 @@ static void test_retry_flush(const char *machine) assert_bit_set(data, DRDY); assert_bit_clear(data, BSY | DF | ERR | DRQ); - ide_test_quit(); + ide_test_quit(qts); free_pci_device(dev); } static void test_flush_nodev(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; - ide_test_start(""); + qts = ide_test_start(""); - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* FLUSH CACHE command on device 0*/ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -760,16 +791,17 @@ static void test_flush_nodev(void) /* Just testing that qemu doesn't crash... */ free_pci_device(dev); - ide_test_quit(); + ide_test_quit(qts); } static void test_flush_empty_drive(void) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; - ide_test_start("-device ide-cd,bus=ide.0"); - dev = get_pci_device(&bmdma_bar, &ide_bar); + qts = ide_test_start("-device ide-cd,bus=ide.0"); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* FLUSH CACHE command on device 0 */ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -778,7 +810,7 @@ static void test_flush_empty_drive(void) /* Just testing that qemu doesn't crash... */ free_pci_device(dev); - ide_test_quit(); + ide_test_quit(qts); } static void test_pci_retry_flush(void) @@ -823,21 +855,21 @@ static void send_scsi_cdb_read10(QPCIDevice *dev, QPCIBar ide_bar, } } -static void nsleep(int64_t nsecs) +static void nsleep(QTestState *qts, int64_t nsecs) { const struct timespec val = { .tv_nsec = nsecs }; nanosleep(&val, NULL); - clock_set(nsecs); + qtest_clock_set(qts, nsecs); } -static uint8_t ide_wait_clear(uint8_t flag) +static uint8_t ide_wait_clear(QTestState *qts, uint8_t flag) { QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; uint8_t data; time_t st; - dev = get_pci_device(&bmdma_bar, &ide_bar); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); /* Wait with a 5 second timeout */ time(&st); @@ -850,26 +882,26 @@ static uint8_t ide_wait_clear(uint8_t flag) if (difftime(time(NULL), st) > 5.0) { break; } - nsleep(400); + nsleep(qts, 400); } g_assert_not_reached(); } -static void ide_wait_intr(int irq) +static void ide_wait_intr(QTestState *qts, int irq) { time_t st; bool intr; time(&st); while (true) { - intr = get_irq(irq); + intr = qtest_get_irq(qts, irq); if (intr) { return; } if (difftime(time(NULL), st) > 5.0) { break; } - nsleep(400); + nsleep(qts, 400); } g_assert_not_reached(); @@ -877,6 +909,7 @@ static void ide_wait_intr(int irq) static void cdrom_pio_impl(int nblocks) { + QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; FILE *fh; @@ -897,10 +930,11 @@ static void cdrom_pio_impl(int nblocks) g_assert_cmpint(ret, ==, patt_blocks); fclose(fh); - ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 " - "-device ide-cd,drive=sr0,bus=ide.0", tmp_path); - dev = get_pci_device(&bmdma_bar, &ide_bar); - qtest_irq_intercept_in(global_qtest, "ioapic"); + qts = ide_test_start( + "-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 " + "-device ide-cd,drive=sr0,bus=ide.0", tmp_path); + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); + qtest_irq_intercept_in(qts, "ioapic"); /* PACKET command on device 0 */ qpci_io_writeb(dev, ide_bar, reg_device, 0); @@ -908,8 +942,8 @@ static void cdrom_pio_impl(int nblocks) qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF)); qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET); /* HP0: Check_Status_A State */ - nsleep(400); - data = ide_wait_clear(BSY); + nsleep(qts, 400); + data = ide_wait_clear(qts, BSY); /* HP1: Send_Packet State */ assert_bit_set(data, DRQ | DRDY); assert_bit_clear(data, ERR | DF | BSY); @@ -930,10 +964,10 @@ static void cdrom_pio_impl(int nblocks) size_t rem = (rxsize / 2) - offset; /* HP3: INTRQ_Wait */ - ide_wait_intr(IDE_PRIMARY_IRQ); + ide_wait_intr(qts, IDE_PRIMARY_IRQ); /* HP2: Check_Status_B (and clear IRQ) */ - data = ide_wait_clear(BSY); + data = ide_wait_clear(qts, BSY); assert_bit_set(data, DRQ | DRDY); assert_bit_clear(data, ERR | DF | BSY); @@ -945,17 +979,17 @@ static void cdrom_pio_impl(int nblocks) } /* Check for final completion IRQ */ - ide_wait_intr(IDE_PRIMARY_IRQ); + ide_wait_intr(qts, IDE_PRIMARY_IRQ); /* Sanity check final state */ - data = ide_wait_clear(DRQ); + data = ide_wait_clear(qts, DRQ); assert_bit_set(data, DRDY); assert_bit_clear(data, DRQ | ERR | DF | BSY); g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0); g_free(pattern); g_free(rx); - test_bmdma_teardown(); + test_bmdma_teardown(qts); free_pci_device(dev); } @@ -973,6 +1007,7 @@ static void test_cdrom_pio_large(void) static void test_cdrom_dma(void) { + QTestState *qts; static const size_t len = ATAPI_BLOCK_SIZE; size_t ret; char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16); @@ -981,9 +1016,10 @@ static void test_cdrom_dma(void) PrdtEntry prdt[1]; FILE *fh; - ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 " - "-device ide-cd,drive=sr0,bus=ide.0", tmp_path); - qtest_irq_intercept_in(global_qtest, "ioapic"); + qts = ide_test_start( + "-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 " + "-device ide-cd,drive=sr0,bus=ide.0", tmp_path); + qtest_irq_intercept_in(qts, "ioapic"); guest_buf = guest_alloc(&guest_malloc, len); prdt[0].addr = cpu_to_le32(guest_buf); @@ -995,15 +1031,15 @@ static void test_cdrom_dma(void) g_assert_cmpint(ret, ==, 16); fclose(fh); - send_dma_request(CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10); + send_dma_request(qts, CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10); /* Read back data from guest memory into local qtest memory */ - memread(guest_buf, rx, len); + qtest_memread(qts, guest_buf, rx, len); g_assert_cmpint(memcmp(pattern, rx, len), ==, 0); g_free(pattern); g_free(rx); - test_bmdma_teardown(); + test_bmdma_teardown(qts); } int main(int argc, char **argv) @@ -1028,7 +1064,6 @@ int main(int argc, char **argv) qtest_add_func("/ide/identify", test_identify); - qtest_add_func("/ide/bmdma/setup", test_bmdma_setup); qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw); qtest_add_func("/ide/bmdma/trim", test_bmdma_trim); qtest_add_func("/ide/bmdma/short_prdt", test_bmdma_short_prdt); @@ -1036,7 +1071,6 @@ int main(int argc, char **argv) test_bmdma_one_sector_short_prdt); qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt); qtest_add_func("/ide/bmdma/no_busmaster", test_bmdma_no_busmaster); - qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown); qtest_add_func("/ide/flush", test_flush); qtest_add_func("/ide/flush/nodev", test_flush_nodev); diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c index 227561fbca..a467b8c03d 100644 --- a/tests/ivshmem-test.c +++ b/tests/ivshmem-test.c @@ -383,18 +383,21 @@ static void test_ivshmem_server(void) static void test_ivshmem_hotplug(void) { + QTestState *qts; const char *arch = qtest_get_arch(); - qtest_start("-object memory-backend-ram,size=1M,id=mb1"); + qts = qtest_init("-object memory-backend-ram,size=1M,id=mb1"); + global_qtest = qts; /* TODO: Get rid of global_qtest here */ qtest_qmp_device_add("ivshmem-plain", "iv1", "{'addr': %s, 'memdev': 'mb1'}", stringify(PCI_SLOT_HP)); if (strcmp(arch, "ppc64") != 0) { - qpci_unplug_acpi_device_test("iv1", PCI_SLOT_HP); + qpci_unplug_acpi_device_test(qts, "iv1", PCI_SLOT_HP); } - qtest_end(); + qtest_quit(qts); + global_qtest = NULL; } static void test_ivshmem_memdev(void) diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c index 407d8aff78..634fedd049 100644 --- a/tests/libqos/pci-pc.c +++ b/tests/libqos/pci-pc.c @@ -176,19 +176,19 @@ void qpci_free_pc(QPCIBus *bus) g_free(s); } -void qpci_unplug_acpi_device_test(const char *id, uint8_t slot) +void qpci_unplug_acpi_device_test(QTestState *qts, const char *id, uint8_t slot) { QDict *response; - response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}", - id); + response = qtest_qmp(qts, "{'execute': 'device_del'," + " 'arguments': {'id': %s}}", id); g_assert(response); g_assert(!qdict_haskey(response, "error")); qobject_unref(response); - outb(ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot); + qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot); - qmp_eventwait("DEVICE_DELETED"); + qtest_qmp_eventwait(qts, "DEVICE_DELETED"); } static void qpci_pc_register_nodes(void) diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h index 8e1d292a7d..a5389a5845 100644 --- a/tests/libqos/pci.h +++ b/tests/libqos/pci.h @@ -123,7 +123,7 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr); void qpci_iounmap(QPCIDevice *dev, QPCIBar addr); QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr); -void qpci_unplug_acpi_device_test(const char *id, uint8_t slot); +void qpci_unplug_acpi_device_test(QTestState *qs, const char *id, uint8_t slot); void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr); #endif diff --git a/tests/megasas-test.c b/tests/megasas-test.c index 33aa97042c..1111d331d3 100644 --- a/tests/megasas-test.c +++ b/tests/megasas-test.c @@ -66,7 +66,7 @@ static void megasas_pd_get_info_fuzz(void *obj, void *data, QGuestAllocator *all context[7] = cpu_to_le32(0); context_pa = guest_alloc(alloc, sizeof(context)); - memwrite(context_pa, context, sizeof(context)); + qtest_memwrite(dev->bus->qts, context_pa, context, sizeof(context)); qpci_io_writel(dev, bar, 0x40, context_pa); } diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110 index fad672c1ae..33b169ffd4 100755 --- a/tests/qemu-iotests/110 +++ b/tests/qemu-iotests/110 @@ -53,8 +53,12 @@ TEST_IMG="$TEST_IMG.base" _make_test_img 64M _make_test_img -b "$TEST_IMG_REL.base" 64M # qemu should be able to reconstruct the filename, so relative backing names # should work +# (We have to filter the backing file format because vmdk always +# reports it (as vmdk), whereas other image formats would do so only +# with the backing_fmt creation option, which neither vmdk nor qcow +# support) TEST_IMG="json:{'driver':'$IMGFMT','file':{'driver':'file','filename':'$TEST_IMG'}}" \ - _img_info | _filter_img_info + _img_info | _filter_img_info | grep -v 'backing file format' echo echo '=== Non-reconstructable filename ===' @@ -78,7 +82,7 @@ TEST_IMG="json:{ } ] } -}" _img_info | _filter_img_info +}" _img_info | _filter_img_info | grep -v 'backing file format' echo echo '=== Backing name is always relative to the backed image ===' @@ -110,7 +114,7 @@ TEST_IMG="json:{ } ] } -}" _img_info | _filter_img_info +}" _img_info | _filter_img_info | grep -v 'backing file format' # success, all done diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126 index 96dc048d59..e3ee65c606 100755 --- a/tests/qemu-iotests/126 +++ b/tests/qemu-iotests/126 @@ -62,8 +62,12 @@ TOP_IMG="$TEST_DIR/image:top.$IMGFMT" TEST_IMG=$BASE_IMG _make_test_img 64M TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT -# The default cluster size depends on the image format -TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size' +# (1) The default cluster size depends on the image format +# (2) vmdk only supports vmdk backing files, so it always reports the +# format of its backing file as such (but neither it nor qcow +# support the backing_fmt creation option, so we cannot use that to +# harmonize the output across all image formats this test supports) +TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format' _rm_test_img "$BASE_IMG" _rm_test_img "$TOP_IMG" @@ -79,7 +83,7 @@ TOP_IMG="file:image:top.$IMGFMT" TEST_IMG=$BASE_IMG _make_test_img 64M TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG" -TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size' +TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format' _rm_test_img "$BASE_IMG" _rm_test_img "image:top.$IMGFMT" diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138 index f353ac8219..6a731370db 100755 --- a/tests/qemu-iotests/138 +++ b/tests/qemu-iotests/138 @@ -54,15 +54,13 @@ $QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io # Put the data cluster at a multiple of 2 TB, resulting in the image apparently # having a multiple of 2^32 clusters # (To be more specific: It is at 32 PB) -poke_file "$TEST_IMG" 2048 "\x80\x80\x00\x00\x00\x00\x00\x00" +poke_file "$TEST_IMG" $((2048 + 8)) "\x00\x80\x00\x00\x00\x00\x00\x00" # An offset of 32 PB results in qemu-img check having to allocate an in-memory -# refcount table of 128 TB (16 bit refcounts, 512 byte clusters). -# This should be generally too much for any system and thus fail. -# What this test is checking is that the qcow2 driver actually tries to allocate -# such a large amount of memory (and is consequently aborting) instead of having -# truncated the cluster count somewhere (which would result in much less memory -# being allocated and then a segfault occurring). +# refcount table of 128 TB (16 bit refcounts, 512 byte clusters), if qemu-img +# don't check that referenced data cluster is far beyond the end of file. +# But starting from 4.0, qemu-img does this check, and instead of "Cannot +# allocate memory", we have an error showing that l2 entry is invalid. _check_test_img # success, all done diff --git a/tests/qemu-iotests/138.out b/tests/qemu-iotests/138.out index 3fe911f85a..aca7d47a80 100644 --- a/tests/qemu-iotests/138.out +++ b/tests/qemu-iotests/138.out @@ -5,5 +5,8 @@ QA output created by 138 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -qemu-img: Check failed: Cannot allocate memory +ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x80000000000000 size 0x200 + +1 errors were found on the image. +Data may be corrupted, or further writes to the image may corrupt it. *** done diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207 index dfd3c51bd1..b3816136f7 100755 --- a/tests/qemu-iotests/207 +++ b/tests/qemu-iotests/207 @@ -66,7 +66,7 @@ with iotests.FilePath('t.img') as disk_path, \ 'size': 4194304 }) vm.shutdown() - iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.img_info_log(remote_path) iotests.log("") iotests.img_info_log(disk_path) @@ -91,7 +91,7 @@ with iotests.FilePath('t.img') as disk_path, \ 'size': 8388608 }) vm.shutdown() - iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.img_info_log(remote_path) vm.launch() blockdev_create(vm, { 'driver': 'ssh', @@ -108,7 +108,7 @@ with iotests.FilePath('t.img') as disk_path, \ 'size': 4194304 }) vm.shutdown() - iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.img_info_log(remote_path) md5_key = subprocess.check_output( 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + @@ -146,7 +146,7 @@ with iotests.FilePath('t.img') as disk_path, \ 'size': 8388608 }) vm.shutdown() - iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.img_info_log(remote_path) sha1_key = subprocess.check_output( 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + @@ -184,7 +184,7 @@ with iotests.FilePath('t.img') as disk_path, \ 'size': 4194304 }) vm.shutdown() - iotests.img_info_log(remote_path, filter_path=disk_path) + iotests.img_info_log(remote_path) # # Invalid path and user diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out index 979d5cf745..ec9823793a 100644 --- a/tests/qemu-iotests/207.out +++ b/tests/qemu-iotests/207.out @@ -5,7 +5,7 @@ {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} +image: TEST_IMG file format: IMGFMT virtual size: 4 MiB (4194304 bytes) @@ -21,7 +21,7 @@ virtual size: 4 MiB (4194304 bytes) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} +image: TEST_IMG file format: IMGFMT virtual size: 8 MiB (8388608 bytes) @@ -30,7 +30,7 @@ virtual size: 8 MiB (8388608 bytes) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} +image: TEST_IMG file format: IMGFMT virtual size: 4 MiB (4194304 bytes) @@ -45,7 +45,7 @@ Job failed: remote host key does not match host_key_check 'wrong' {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} +image: TEST_IMG file format: IMGFMT virtual size: 8 MiB (8388608 bytes) @@ -60,7 +60,7 @@ Job failed: remote host key does not match host_key_check 'wrong' {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}} +image: TEST_IMG file format: IMGFMT virtual size: 4 MiB (4194304 bytes) diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index a543e546c2..93f87389b6 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -158,7 +158,7 @@ else TEST_IMG="nbd:127.0.0.1:10810" elif [ "$IMGPROTO" = "ssh" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - REMOTE_TEST_DIR="ssh://127.0.0.1$TEST_DIR" + REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR" TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE" elif [ "$IMGPROTO" = "nfs" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 997dc910cb..f811f69135 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -411,7 +411,7 @@ def remote_filename(path): if imgproto == 'file': return path elif imgproto == 'ssh': - return "ssh://127.0.0.1%s" % (path) + return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path) else: raise Exception("Protocol %s not supported" % (imgproto)) diff --git a/tests/qmp-cmd-test.c b/tests/qmp-cmd-test.c index d12cac539c..9f5228cd99 100644 --- a/tests/qmp-cmd-test.c +++ b/tests/qmp-cmd-test.c @@ -61,10 +61,11 @@ static void test_query(const void *data) int expected_error_class = query_error_class(cmd); QDict *resp, *error; const char *error_class; + QTestState *qts; - qtest_start(common_args); + qts = qtest_init(common_args); - resp = qmp("{ 'execute': %s }", cmd); + resp = qtest_qmp(qts, "{ 'execute': %s }", cmd); error = qdict_get_qdict(resp, "error"); error_class = error ? qdict_get_str(error, "class") : NULL; @@ -78,7 +79,7 @@ static void test_query(const void *data) } qobject_unref(resp); - qtest_end(); + qtest_quit(qts); } static bool query_is_blacklisted(const char *cmd) @@ -118,16 +119,18 @@ static void qmp_schema_init(QmpSchema *schema) QDict *resp; Visitor *qiv; SchemaInfoList *tail; + QTestState *qts; - qtest_start(common_args); - resp = qmp("{ 'execute': 'query-qmp-schema' }"); + qts = qtest_init(common_args); + + resp = qtest_qmp(qts, "{ 'execute': 'query-qmp-schema' }"); qiv = qobject_input_visitor_new(qdict_get(resp, "return")); visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort); visit_free(qiv); qobject_unref(resp); - qtest_end(); + qtest_quit(qts); schema->hash = g_hash_table_new(g_str_hash, g_str_equal); diff --git a/tests/tco-test.c b/tests/tco-test.c index f89a42cdcc..254f735370 100644 --- a/tests/tco-test.c +++ b/tests/tco-test.c @@ -45,13 +45,14 @@ typedef struct { QPCIDevice *dev; QPCIBar tco_io_bar; QPCIBus *bus; + QTestState *qts; } TestData; static void test_end(TestData *d) { g_free(d->dev); qpci_free_pc(d->bus); - qtest_end(); + qtest_quit(d->qts); } static void test_init(TestData *d) @@ -61,7 +62,6 @@ static void test_init(TestData *d) qs = qtest_initf("-machine q35 %s %s", d->noreboot ? "" : "-global ICH9-LPC.noreboot=false", !d->args ? "" : d->args); - global_qtest = qs; qtest_irq_intercept_in(qs, "ioapic"); d->bus = qpci_new_pc(qs, NULL); @@ -78,6 +78,7 @@ static void test_init(TestData *d) qpci_config_writel(d->dev, ICH9_LPC_RCBA, RCBA_BASE_ADDR | 0x1); d->tco_io_bar = qpci_legacy_iomap(d->dev, PM_IO_BASE_ADDR + 0x60); + d->qts = qs; } static void stop_tco(const TestData *d) @@ -115,17 +116,17 @@ static void clear_tco_status(const TestData *d) qpci_io_writew(d->dev, d->tco_io_bar, TCO2_STS, 0x0004); } -static void reset_on_second_timeout(bool enable) +static void reset_on_second_timeout(const TestData *td, bool enable) { uint32_t val; - val = readl(RCBA_BASE_ADDR + ICH9_CC_GCS); + val = qtest_readl(td->qts, RCBA_BASE_ADDR + ICH9_CC_GCS); if (enable) { val &= ~ICH9_CC_GCS_NO_REBOOT; } else { val |= ICH9_CC_GCS_NO_REBOOT; } - writel(RCBA_BASE_ADDR + ICH9_CC_GCS, val); + qtest_writel(td->qts, RCBA_BASE_ADDR + ICH9_CC_GCS, val); } static void test_tco_defaults(void) @@ -171,11 +172,11 @@ static void test_tco_timeout(void) stop_tco(&d); clear_tco_status(&d); - reset_on_second_timeout(false); + reset_on_second_timeout(&d, false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); - clock_step(ticks * TCO_TICK_NSEC); + qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC); /* test first timeout */ val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); @@ -190,7 +191,7 @@ static void test_tco_timeout(void) g_assert(ret == 0); /* test second timeout */ - clock_step(ticks * TCO_TICK_NSEC); + qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); @@ -215,18 +216,18 @@ static void test_tco_max_timeout(void) stop_tco(&d); clear_tco_status(&d); - reset_on_second_timeout(false); + reset_on_second_timeout(&d, false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); - clock_step(((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC); + qtest_clock_step(d.qts, ((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD); g_assert_cmpint(val & TCO_RLD_MASK, ==, 1); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 0); - clock_step(TCO_TICK_NSEC); + qtest_clock_step(d.qts, TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); @@ -235,9 +236,9 @@ static void test_tco_max_timeout(void) test_end(&d); } -static QDict *get_watchdog_action(void) +static QDict *get_watchdog_action(const TestData *td) { - QDict *ev = qmp_eventwait_ref("WATCHDOG"); + QDict *ev = qtest_qmp_eventwait_ref(td->qts, "WATCHDOG"); QDict *data; data = qdict_get_qdict(ev, "data"); @@ -258,12 +259,12 @@ static void test_tco_second_timeout_pause(void) stop_tco(&td); clear_tco_status(&td); - reset_on_second_timeout(true); + reset_on_second_timeout(&td, true); set_tco_timeout(&td, TCO_SECS_TO_TICKS(16)); load_tco(&td); start_tco(&td); - clock_step(ticks * TCO_TICK_NSEC * 2); - ad = get_watchdog_action(); + qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2); + ad = get_watchdog_action(&td); g_assert(!strcmp(qdict_get_str(ad, "action"), "pause")); qobject_unref(ad); @@ -283,12 +284,12 @@ static void test_tco_second_timeout_reset(void) stop_tco(&td); clear_tco_status(&td); - reset_on_second_timeout(true); + reset_on_second_timeout(&td, true); set_tco_timeout(&td, TCO_SECS_TO_TICKS(16)); load_tco(&td); start_tco(&td); - clock_step(ticks * TCO_TICK_NSEC * 2); - ad = get_watchdog_action(); + qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2); + ad = get_watchdog_action(&td); g_assert(!strcmp(qdict_get_str(ad, "action"), "reset")); qobject_unref(ad); @@ -308,12 +309,12 @@ static void test_tco_second_timeout_shutdown(void) stop_tco(&td); clear_tco_status(&td); - reset_on_second_timeout(true); + reset_on_second_timeout(&td, true); set_tco_timeout(&td, ticks); load_tco(&td); start_tco(&td); - clock_step(ticks * TCO_TICK_NSEC * 2); - ad = get_watchdog_action(); + qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2); + ad = get_watchdog_action(&td); g_assert(!strcmp(qdict_get_str(ad, "action"), "shutdown")); qobject_unref(ad); @@ -333,12 +334,12 @@ static void test_tco_second_timeout_none(void) stop_tco(&td); clear_tco_status(&td); - reset_on_second_timeout(true); + reset_on_second_timeout(&td, true); set_tco_timeout(&td, ticks); load_tco(&td); start_tco(&td); - clock_step(ticks * TCO_TICK_NSEC * 2); - ad = get_watchdog_action(); + qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2); + ad = get_watchdog_action(&td); g_assert(!strcmp(qdict_get_str(ad, "action"), "none")); qobject_unref(ad); @@ -358,7 +359,7 @@ static void test_tco_ticks_counter(void) stop_tco(&d); clear_tco_status(&d); - reset_on_second_timeout(false); + reset_on_second_timeout(&d, false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); @@ -366,7 +367,7 @@ static void test_tco_ticks_counter(void) do { rld = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD) & TCO_RLD_MASK; g_assert_cmpint(rld, ==, ticks); - clock_step(TCO_TICK_NSEC); + qtest_clock_step(d.qts, TCO_TICK_NSEC); ticks--; } while (!(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS) & TCO_TIMEOUT)); @@ -405,11 +406,11 @@ static void test_tco1_status_bits(void) stop_tco(&d); clear_tco_status(&d); - reset_on_second_timeout(false); + reset_on_second_timeout(&d, false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); - clock_step(ticks * TCO_TICK_NSEC); + qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC); qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_IN, 0); qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_OUT, 0); @@ -434,11 +435,11 @@ static void test_tco2_status_bits(void) stop_tco(&d); clear_tco_status(&d); - reset_on_second_timeout(true); + reset_on_second_timeout(&d, true); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); - clock_step(ticks * TCO_TICK_NSEC * 2); + qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC * 2); val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS); ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0; diff --git a/tests/test-hmp.c b/tests/test-hmp.c index e344947f7c..5029c4d2c9 100644 --- a/tests/test-hmp.c +++ b/tests/test-hmp.c @@ -73,13 +73,13 @@ static const char *hmp_cmds[] = { }; /* Run through the list of pre-defined commands */ -static void test_commands(void) +static void test_commands(QTestState *qts) { char *response; int i; for (i = 0; hmp_cmds[i] != NULL; i++) { - response = hmp("%s", hmp_cmds[i]); + response = qtest_hmp(qts, "%s", hmp_cmds[i]); if (verbose) { fprintf(stderr, "\texecute HMP command: %s\n" @@ -92,11 +92,11 @@ static void test_commands(void) } /* Run through all info commands and call them blindly (without arguments) */ -static void test_info_commands(void) +static void test_info_commands(QTestState *qts) { char *resp, *info, *info_buf, *endp; - info_buf = info = hmp("help info"); + info_buf = info = qtest_hmp(qts, "help info"); while (*info) { /* Extract the info command, ignore parameters and description */ @@ -108,7 +108,7 @@ static void test_info_commands(void) if (verbose) { fprintf(stderr, "\t%s\n", info); } - resp = hmp("%s", info); + resp = qtest_hmp(qts, "%s", info); g_free(resp); /* And move forward to the next line */ info = strchr(endp + 1, '\n'); @@ -125,14 +125,15 @@ static void test_machine(gconstpointer data) { const char *machine = data; char *args; + QTestState *qts; args = g_strdup_printf("-S -M %s", machine); - qtest_start(args); + qts = qtest_init(args); - test_info_commands(); - test_commands(); + test_info_commands(qts); + test_commands(qts); - qtest_end(); + qtest_quit(qts); g_free(args); g_free((void *)data); } diff --git a/tests/tpm-tests.c b/tests/tpm-tests.c index 582ec0cfd4..e640777aa9 100644 --- a/tests/tpm-tests.c +++ b/tests/tpm-tests.c @@ -22,7 +22,7 @@ static bool tpm_test_swtpm_skip(void) { if (!tpm_util_swtpm_has_tpm2()) { - g_test_message("swtpm not in PATH or missing --tpm2 support"); + g_test_skip("swtpm not in PATH or missing --tpm2 support"); return true; } diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index b65365934b..fe1168a90a 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -679,6 +679,7 @@ static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtioPCIDevice *dev1 = obj; QVirtioPCIDevice *dev; + QTestState *qts = dev1->pdev->bus->qts; /* plug secondary disk */ qtest_qmp_device_add("virtio-blk-pci", "drv1", @@ -693,7 +694,7 @@ static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc) qos_object_destroy((QOSGraphObject *)dev); /* unplug secondary disk */ - qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP); + qpci_unplug_acpi_device_test(qts, "drv1", PCI_SLOT_HP); } /* diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c index 0d956f36fe..163126cf07 100644 --- a/tests/virtio-net-test.c +++ b/tests/virtio-net-test.c @@ -162,13 +162,15 @@ static void stop_cont_test(void *obj, void *data, QGuestAllocator *t_alloc) static void hotplug(void *obj, void *data, QGuestAllocator *t_alloc) { + QVirtioPCIDevice *dev = obj; + QTestState *qts = dev->pdev->bus->qts; const char *arch = qtest_get_arch(); qtest_qmp_device_add("virtio-net-pci", "net1", "{'addr': %s}", stringify(PCI_SLOT_HP)); if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { - qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP); + qpci_unplug_acpi_device_test(qts, "net1", PCI_SLOT_HP); } } diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c index 5309c7c8ab..fcb22481bd 100644 --- a/tests/virtio-rng-test.c +++ b/tests/virtio-rng-test.c @@ -16,13 +16,16 @@ static void rng_hotplug(void *obj, void *data, QGuestAllocator *alloc) { + QVirtioPCIDevice *dev = obj; + QTestState *qts = dev->pdev->bus->qts; + const char *arch = qtest_get_arch(); qtest_qmp_device_add("virtio-rng-pci", "rng1", "{'addr': %s}", stringify(PCI_SLOT_HP)); if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { - qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP); + qpci_unplug_acpi_device_test(qts, "rng1", PCI_SLOT_HP); } } |