diff options
42 files changed, 370 insertions, 834 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5eeba2791b..41597c3603 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -161,9 +161,27 @@ build-clang: IMAGE: fedora CONFIGURE_ARGS: --cc=clang --cxx=clang++ TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu - ppc-softmmu s390x-softmmu x86_64-softmmu arm-linux-user + ppc-softmmu s390x-softmmu arm-linux-user MAKE_CHECK_ARGS: check +build-fuzzer: + <<: *native_build_job_definition + variables: + IMAGE: fedora + script: + - mkdir build + - cd build + - ../configure --cc=clang --cxx=clang++ --enable-fuzzing + --enable-sanitizers --target-list=x86_64-softmmu + - make -j"$JOBS" all check-build x86_64-softmmu/fuzz + - make check + - for fuzzer in i440fx-qos-fork-fuzz i440fx-qos-noreset-fuzz + i440fx-qtest-reboot-fuzz virtio-scsi-flags-fuzz virtio-scsi-fuzz ; do + echo Testing ${fuzzer} ... ; + x86_64-softmmu/qemu-fuzz-x86_64 --fuzz-target=${fuzzer} -runs=1000 + || exit 1 ; + done + build-tci: <<: *native_build_job_definition variables: diff --git a/MAINTAINERS b/MAINTAINERS index 030faf0249..5d9c56e441 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2987,7 +2987,7 @@ F: block/vpc.c vvfat M: Kevin Wolf <kwolf@redhat.com> L: qemu-block@nongnu.org -S: Supported +S: Odd Fixes F: block/vvfat.c Image format fuzzer @@ -2025,6 +2025,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q, return -EPERM; } + /* + * Unaligned requests will automatically be aligned to bl.request_alignment + * and without RESIZE we can't extend requests to write to space beyond the + * end of the image, so it's required that the image size is aligned. + */ + if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) && + !(cumulative_perms & BLK_PERM_RESIZE)) + { + if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) { + error_setg(errp, "Cannot get 'write' permission without 'resize': " + "Image size is not a multiple of request " + "alignment"); + return -EPERM; + } + } + /* Check this node */ if (!drv) { return 0; diff --git a/block/Makefile.objs b/block/Makefile.objs index 577e578bc2..19c6f371c9 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -31,7 +31,6 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o block-obj-$(CONFIG_CURL) += curl.o block-obj-$(CONFIG_RBD) += rbd.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o -block-obj-$(CONFIG_VXHS) += vxhs.o block-obj-$(CONFIG_LIBSSH) += ssh.o block-obj-y += accounting.o dirty-bitmap.o block-obj-y += write-threshold.o @@ -61,7 +60,6 @@ rbd.o-cflags := $(RBD_CFLAGS) rbd.o-libs := $(RBD_LIBS) gluster.o-cflags := $(GLUSTERFS_CFLAGS) gluster.o-libs := $(GLUSTERFS_LIBS) -vxhs.o-libs := $(VXHS_LIBS) ssh.o-cflags := $(LIBSSH_CFLAGS) ssh.o-libs := $(LIBSSH_LIBS) block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o diff --git a/block/file-posix.c b/block/file-posix.c index 8067e238cb..8cc39a1ef6 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -62,10 +62,12 @@ #include <sys/ioctl.h> #include <sys/param.h> #include <sys/syscall.h> +#include <sys/vfs.h> #include <linux/cdrom.h> #include <linux/fd.h> #include <linux/fs.h> #include <linux/hdreg.h> +#include <linux/magic.h> #include <scsi/sg.h> #ifdef __s390__ #include <asm/dasd.h> @@ -300,6 +302,28 @@ static int probe_physical_blocksize(int fd, unsigned int *blk_size) #endif } +/* + * Returns true if no alignment restrictions are necessary even for files + * opened with O_DIRECT. + * + * raw_probe_alignment() probes the required alignment and assume that 1 means + * the probing failed, so it falls back to a safe default of 4k. This can be + * avoided if we know that byte alignment is okay for the file. + */ +static bool dio_byte_aligned(int fd) +{ +#ifdef __linux__ + struct statfs buf; + int ret; + + ret = fstatfs(fd, &buf); + if (ret == 0 && buf.f_type == NFS_SUPER_MAGIC) { + return true; + } +#endif + return false; +} + /* Check if read is allowed with given memory buffer and length. * * This function is used to check O_DIRECT memory buffer and request alignment. @@ -401,6 +425,39 @@ static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) } } +static int check_hdev_writable(int fd) +{ +#if defined(BLKROGET) + /* Linux block devices can be configured "read-only" using blockdev(8). + * This is independent of device node permissions and therefore open(2) + * with O_RDWR succeeds. Actual writes fail with EPERM. + * + * bdrv_open() is supposed to fail if the disk is read-only. Explicitly + * check for read-only block devices so that Linux block devices behave + * properly. + */ + struct stat st; + int readonly = 0; + + if (fstat(fd, &st)) { + return -errno; + } + + if (!S_ISBLK(st.st_mode)) { + return 0; + } + + if (ioctl(fd, BLKROGET, &readonly) < 0) { + return -errno; + } + + if (readonly) { + return -EACCES; + } +#endif /* defined(BLKROGET) */ + return 0; +} + static void raw_parse_flags(int bdrv_flags, int *open_flags, bool has_writers) { bool read_write = false; @@ -585,6 +642,15 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } s->fd = fd; + /* Check s->open_flags rather than bdrv_flags due to auto-read-only */ + if (s->open_flags & O_RDWR) { + ret = check_hdev_writable(s->fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "The device is not writable"); + goto fail; + } + } + s->perm = 0; s->shared_perm = BLK_PERM_ALL; @@ -629,7 +695,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, s->has_discard = true; s->has_write_zeroes = true; - if ((bs->open_flags & BDRV_O_NOCACHE) != 0) { + if ((bs->open_flags & BDRV_O_NOCACHE) != 0 && !dio_byte_aligned(s->fd)) { s->needs_alignment = true; } @@ -707,6 +773,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } ret = 0; fail: + if (ret < 0 && s->fd != -1) { + qemu_close(s->fd); + } if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) { unlink(filename); } @@ -977,6 +1046,15 @@ static int raw_reconfigure_getfd(BlockDriverState *bs, int flags, } } + if (fd != -1 && (*open_flags & O_RDWR)) { + ret = check_hdev_writable(fd); + if (ret < 0) { + qemu_close(fd); + error_setg_errno(errp, -ret, "The device is not writable"); + return -1; + } + } + return fd; } @@ -3299,39 +3377,6 @@ static int hdev_probe_device(const char *filename) return 0; } -static int check_hdev_writable(BDRVRawState *s) -{ -#if defined(BLKROGET) - /* Linux block devices can be configured "read-only" using blockdev(8). - * This is independent of device node permissions and therefore open(2) - * with O_RDWR succeeds. Actual writes fail with EPERM. - * - * bdrv_open() is supposed to fail if the disk is read-only. Explicitly - * check for read-only block devices so that Linux block devices behave - * properly. - */ - struct stat st; - int readonly = 0; - - if (fstat(s->fd, &st)) { - return -errno; - } - - if (!S_ISBLK(st.st_mode)) { - return 0; - } - - if (ioctl(s->fd, BLKROGET, &readonly) < 0) { - return -errno; - } - - if (readonly) { - return -EACCES; - } -#endif /* defined(BLKROGET) */ - return 0; -} - static void hdev_parse_filename(const char *filename, QDict *options, Error **errp) { @@ -3454,15 +3499,6 @@ hdev_open_Mac_error: /* Since this does ioctl the device must be already opened */ bs->sg = hdev_is_sg(bs); - if (flags & BDRV_O_RDWR) { - ret = check_hdev_writable(s); - if (ret < 0) { - raw_close(bs); - error_setg_errno(errp, -ret, "The device is not writable"); - return ret; - } - } - return ret; } diff --git a/block/trace-events b/block/trace-events index dbe76a7613..d3533ca896 100644 --- a/block/trace-events +++ b/block/trace-events @@ -136,23 +136,6 @@ qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t o qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu" -# vxhs.c -vxhs_iio_callback(int error) "ctx is NULL: error %d" -vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d" -vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d" -vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d" -vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %"PRIu64" offset = %"PRIu64" ACB = %p. Error = %d, errno = %d" -vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d" -vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %"PRIu64 -vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %"PRIu64 -vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s" -vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s" -vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState" -vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s" -vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d" -vxhs_close(char *vdisk_guid) "Closing vdisk %s" -vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s" - # nvme.c nvme_kick(void *s, int queue) "s %p queue %d" nvme_dma_flush_queue_wait(void *s) "s %p" diff --git a/block/vxhs.c b/block/vxhs.c deleted file mode 100644 index dc0e254730..0000000000 --- a/block/vxhs.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * QEMU Block driver for Veritas HyperScale (VxHS) - * - * Copyright (c) 2017 Veritas Technologies LLC. - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include <qnio/qnio_api.h> -#include <sys/param.h> -#include "block/block_int.h" -#include "block/qdict.h" -#include "qapi/qmp/qerror.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qstring.h" -#include "trace.h" -#include "qemu/module.h" -#include "qemu/uri.h" -#include "qapi/error.h" -#include "qemu/uuid.h" -#include "crypto/tlscredsx509.h" -#include "sysemu/replay.h" - -#define VXHS_OPT_FILENAME "filename" -#define VXHS_OPT_VDISK_ID "vdisk-id" -#define VXHS_OPT_SERVER "server" -#define VXHS_OPT_HOST "host" -#define VXHS_OPT_PORT "port" - -/* Only accessed under QEMU global mutex */ -static uint32_t vxhs_ref; - -typedef enum { - VDISK_AIO_READ, - VDISK_AIO_WRITE, -} VDISKAIOCmd; - -/* - * HyperScale AIO callbacks structure - */ -typedef struct VXHSAIOCB { - BlockAIOCB common; - int err; -} VXHSAIOCB; - -typedef struct VXHSvDiskHostsInfo { - void *dev_handle; /* Device handle */ - char *host; /* Host name or IP */ - int port; /* Host's port number */ -} VXHSvDiskHostsInfo; - -/* - * Structure per vDisk maintained for state - */ -typedef struct BDRVVXHSState { - VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */ - char *vdisk_guid; - char *tlscredsid; /* tlscredsid */ -} BDRVVXHSState; - -static void vxhs_complete_aio_bh(void *opaque) -{ - VXHSAIOCB *acb = opaque; - BlockCompletionFunc *cb = acb->common.cb; - void *cb_opaque = acb->common.opaque; - int ret = 0; - - if (acb->err != 0) { - trace_vxhs_complete_aio(acb, acb->err); - ret = (-EIO); - } - - qemu_aio_unref(acb); - cb(cb_opaque, ret); -} - -/* - * Called from a libqnio thread - */ -static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error) -{ - VXHSAIOCB *acb = NULL; - - switch (opcode) { - case IRP_READ_REQUEST: - case IRP_WRITE_REQUEST: - - /* - * ctx is VXHSAIOCB* - * ctx is NULL if error is QNIOERROR_CHANNEL_HUP - */ - if (ctx) { - acb = ctx; - } else { - trace_vxhs_iio_callback(error); - goto out; - } - - if (error) { - if (!acb->err) { - acb->err = error; - } - trace_vxhs_iio_callback(error); - } - - replay_bh_schedule_oneshot_event(bdrv_get_aio_context(acb->common.bs), - vxhs_complete_aio_bh, acb); - break; - - default: - if (error == QNIOERROR_HUP) { - /* - * Channel failed, spontaneous notification, - * not in response to I/O - */ - trace_vxhs_iio_callback_chnfail(error, errno); - } else { - trace_vxhs_iio_callback_unknwn(opcode, error); - } - break; - } -out: - return; -} - -static QemuOptsList runtime_opts = { - .name = "vxhs", - .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head), - .desc = { - { - .name = VXHS_OPT_FILENAME, - .type = QEMU_OPT_STRING, - .help = "URI to the Veritas HyperScale image", - }, - { - .name = VXHS_OPT_VDISK_ID, - .type = QEMU_OPT_STRING, - .help = "UUID of the VxHS vdisk", - }, - { - .name = "tls-creds", - .type = QEMU_OPT_STRING, - .help = "ID of the TLS/SSL credentials to use", - }, - { /* end of list */ } - }, -}; - -static QemuOptsList runtime_tcp_opts = { - .name = "vxhs_tcp", - .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head), - .desc = { - { - .name = VXHS_OPT_HOST, - .type = QEMU_OPT_STRING, - .help = "host address (ipv4 addresses)", - }, - { - .name = VXHS_OPT_PORT, - .type = QEMU_OPT_NUMBER, - .help = "port number on which VxHSD is listening (default 9999)", - .def_value_str = "9999" - }, - { /* end of list */ } - }, -}; - -/* - * Parse incoming URI and populate *options with the host - * and device information - */ -static int vxhs_parse_uri(const char *filename, QDict *options) -{ - URI *uri = NULL; - char *port; - int ret = 0; - - trace_vxhs_parse_uri_filename(filename); - uri = uri_parse(filename); - if (!uri || !uri->server || !uri->path) { - uri_free(uri); - return -EINVAL; - } - - qdict_put_str(options, VXHS_OPT_SERVER ".host", uri->server); - - if (uri->port) { - port = g_strdup_printf("%d", uri->port); - qdict_put_str(options, VXHS_OPT_SERVER ".port", port); - g_free(port); - } - - qdict_put_str(options, "vdisk-id", uri->path); - - trace_vxhs_parse_uri_hostinfo(uri->server, uri->port); - uri_free(uri); - - return ret; -} - -static void vxhs_parse_filename(const char *filename, QDict *options, - Error **errp) -{ - if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) { - error_setg(errp, "vdisk-id/server and a file name may not be specified " - "at the same time"); - return; - } - - if (strstr(filename, "://")) { - int ret = vxhs_parse_uri(filename, options); - if (ret < 0) { - error_setg(errp, "Invalid URI. URI should be of the form " - " vxhs://<host_ip>:<port>/<vdisk-id>"); - } - } -} - -static void vxhs_refresh_limits(BlockDriverState *bs, Error **errp) -{ - /* XXX Does VXHS support AIO on less than 512-byte alignment? */ - bs->bl.request_alignment = 512; -} - -static int vxhs_init_and_ref(void) -{ - if (vxhs_ref++ == 0) { - if (iio_init(QNIO_VERSION, vxhs_iio_callback)) { - return -ENODEV; - } - } - return 0; -} - -static void vxhs_unref(void) -{ - if (--vxhs_ref == 0) { - iio_fini(); - } -} - -static void vxhs_get_tls_creds(const char *id, char **cacert, - char **key, char **cert, Error **errp) -{ - Object *obj; - QCryptoTLSCreds *creds; - QCryptoTLSCredsX509 *creds_x509; - - obj = object_resolve_path_component( - object_get_objects_root(), id); - - if (!obj) { - error_setg(errp, "No TLS credentials with id '%s'", - id); - return; - } - - creds_x509 = (QCryptoTLSCredsX509 *) - object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509); - - if (!creds_x509) { - error_setg(errp, "Object with id '%s' is not TLS credentials", - id); - return; - } - - creds = &creds_x509->parent_obj; - - if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) { - error_setg(errp, - "Expecting TLS credentials with a client endpoint"); - return; - } - - /* - * Get the cacert, client_cert and client_key file names. - */ - if (!creds->dir) { - error_setg(errp, "TLS object missing 'dir' property value"); - return; - } - - *cacert = g_strdup_printf("%s/%s", creds->dir, - QCRYPTO_TLS_CREDS_X509_CA_CERT); - *cert = g_strdup_printf("%s/%s", creds->dir, - QCRYPTO_TLS_CREDS_X509_CLIENT_CERT); - *key = g_strdup_printf("%s/%s", creds->dir, - QCRYPTO_TLS_CREDS_X509_CLIENT_KEY); -} - -static int vxhs_open(BlockDriverState *bs, QDict *options, - int bdrv_flags, Error **errp) -{ - BDRVVXHSState *s = bs->opaque; - void *dev_handlep; - QDict *backing_options = NULL; - QemuOpts *opts = NULL; - QemuOpts *tcp_opts = NULL; - char *of_vsa_addr = NULL; - Error *local_err = NULL; - const char *vdisk_id_opt; - const char *server_host_opt; - int ret = 0; - char *cacert = NULL; - char *client_key = NULL; - char *client_cert = NULL; - - ret = vxhs_init_and_ref(); - if (ret < 0) { - ret = -EINVAL; - goto out; - } - - /* Create opts info from runtime_opts and runtime_tcp_opts list */ - opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); - tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort); - - if (!qemu_opts_absorb_qdict(opts, options, errp)) { - ret = -EINVAL; - goto out; - } - - /* vdisk-id is the disk UUID */ - vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID); - if (!vdisk_id_opt) { - error_setg(errp, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID); - ret = -EINVAL; - goto out; - } - - /* vdisk-id may contain a leading '/' */ - if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) { - error_setg(errp, "vdisk-id cannot be more than %d characters", - UUID_FMT_LEN); - ret = -EINVAL; - goto out; - } - - s->vdisk_guid = g_strdup(vdisk_id_opt); - trace_vxhs_open_vdiskid(vdisk_id_opt); - - /* get the 'server.' arguments */ - qdict_extract_subqdict(options, &backing_options, VXHS_OPT_SERVER"."); - - if (!qemu_opts_absorb_qdict(tcp_opts, backing_options, errp)) { - ret = -EINVAL; - goto out; - } - - server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST); - if (!server_host_opt) { - error_setg(errp, QERR_MISSING_PARAMETER, - VXHS_OPT_SERVER"."VXHS_OPT_HOST); - ret = -EINVAL; - goto out; - } - - if (strlen(server_host_opt) > MAXHOSTNAMELEN) { - error_setg(errp, "server.host cannot be more than %d characters", - MAXHOSTNAMELEN); - ret = -EINVAL; - goto out; - } - - /* check if we got tls-creds via the --object argument */ - s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds")); - if (s->tlscredsid) { - vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key, - &client_cert, &local_err); - if (local_err != NULL) { - ret = -EINVAL; - goto out; - } - trace_vxhs_get_creds(cacert, client_key, client_cert); - } - - s->vdisk_hostinfo.host = g_strdup(server_host_opt); - s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts, - VXHS_OPT_PORT), - NULL, 0); - - trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host, - s->vdisk_hostinfo.port); - - of_vsa_addr = g_strdup_printf("of://%s:%d", - s->vdisk_hostinfo.host, - s->vdisk_hostinfo.port); - - /* - * Open qnio channel to storage agent if not opened before - */ - dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0, - cacert, client_key, client_cert); - if (dev_handlep == NULL) { - trace_vxhs_open_iio_open(of_vsa_addr); - ret = -ENODEV; - goto out; - } - s->vdisk_hostinfo.dev_handle = dev_handlep; - -out: - g_free(of_vsa_addr); - qobject_unref(backing_options); - qemu_opts_del(tcp_opts); - qemu_opts_del(opts); - g_free(cacert); - g_free(client_key); - g_free(client_cert); - - if (ret < 0) { - vxhs_unref(); - g_free(s->vdisk_hostinfo.host); - g_free(s->vdisk_guid); - g_free(s->tlscredsid); - s->vdisk_guid = NULL; - } - - return ret; -} - -static const AIOCBInfo vxhs_aiocb_info = { - .aiocb_size = sizeof(VXHSAIOCB) -}; - -/* - * This allocates QEMU-VXHS callback for each IO - * and is passed to QNIO. When QNIO completes the work, - * it will be passed back through the callback. - */ -static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, uint64_t offset, - QEMUIOVector *qiov, uint64_t size, - BlockCompletionFunc *cb, void *opaque, - VDISKAIOCmd iodir) -{ - VXHSAIOCB *acb = NULL; - BDRVVXHSState *s = bs->opaque; - int iio_flags = 0; - int ret = 0; - void *dev_handle = s->vdisk_hostinfo.dev_handle; - - acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque); - - /* - * Initialize VXHSAIOCB. - */ - acb->err = 0; - - iio_flags = IIO_FLAG_ASYNC; - - switch (iodir) { - case VDISK_AIO_WRITE: - ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov, - offset, size, iio_flags); - break; - case VDISK_AIO_READ: - ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov, - offset, size, iio_flags); - break; - default: - trace_vxhs_aio_rw_invalid(iodir); - goto errout; - } - - if (ret != 0) { - trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset, - acb, ret, errno); - goto errout; - } - return &acb->common; - -errout: - qemu_aio_unref(acb); - return NULL; -} - -static BlockAIOCB *vxhs_aio_preadv(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov, int flags, - BlockCompletionFunc *cb, void *opaque) -{ - return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_READ); -} - -static BlockAIOCB *vxhs_aio_pwritev(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov, int flags, - BlockCompletionFunc *cb, void *opaque) -{ - return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_WRITE); -} - -static void vxhs_close(BlockDriverState *bs) -{ - BDRVVXHSState *s = bs->opaque; - - trace_vxhs_close(s->vdisk_guid); - - g_free(s->vdisk_guid); - s->vdisk_guid = NULL; - - /* - * Close vDisk device - */ - if (s->vdisk_hostinfo.dev_handle) { - iio_close(s->vdisk_hostinfo.dev_handle); - s->vdisk_hostinfo.dev_handle = NULL; - } - - vxhs_unref(); - - /* - * Free the dynamically allocated host string etc - */ - g_free(s->vdisk_hostinfo.host); - g_free(s->tlscredsid); - s->tlscredsid = NULL; - s->vdisk_hostinfo.host = NULL; - s->vdisk_hostinfo.port = 0; -} - -static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s) -{ - int64_t vdisk_size = -1; - int ret = 0; - void *dev_handle = s->vdisk_hostinfo.dev_handle; - - ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0); - if (ret < 0) { - trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno); - return -EIO; - } - - trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size); - return vdisk_size; -} - -/* - * Returns the size of vDisk in bytes. This is required - * by QEMU block upper block layer so that it is visible - * to guest. - */ -static int64_t vxhs_getlength(BlockDriverState *bs) -{ - BDRVVXHSState *s = bs->opaque; - int64_t vdisk_size; - - vdisk_size = vxhs_get_vdisk_stat(s); - if (vdisk_size < 0) { - return -EIO; - } - - return vdisk_size; -} - -static const char *const vxhs_strong_runtime_opts[] = { - VXHS_OPT_VDISK_ID, - "tls-creds", - VXHS_OPT_HOST, - VXHS_OPT_PORT, - VXHS_OPT_SERVER".", - - NULL -}; - -static BlockDriver bdrv_vxhs = { - .format_name = "vxhs", - .protocol_name = "vxhs", - .instance_size = sizeof(BDRVVXHSState), - .bdrv_file_open = vxhs_open, - .bdrv_parse_filename = vxhs_parse_filename, - .bdrv_refresh_limits = vxhs_refresh_limits, - .bdrv_close = vxhs_close, - .bdrv_getlength = vxhs_getlength, - .bdrv_aio_preadv = vxhs_aio_preadv, - .bdrv_aio_pwritev = vxhs_aio_pwritev, - .strong_runtime_opts = vxhs_strong_runtime_opts, -}; - -static void bdrv_vxhs_init(void) -{ - bdrv_register(&bdrv_vxhs); -} - -block_init(bdrv_vxhs_init); @@ -501,7 +501,6 @@ numa="" tcmalloc="no" jemalloc="no" replication="yes" -vxhs="" bochs="yes" cloop="yes" dmg="yes" @@ -1541,10 +1540,6 @@ for opt do ;; --enable-replication) replication="yes" ;; - --disable-vxhs) vxhs="no" - ;; - --enable-vxhs) vxhs="yes" - ;; --disable-bochs) bochs="no" ;; --enable-bochs) bochs="yes" @@ -1932,7 +1927,6 @@ disabled with --disable-FEATURE, default is enabled if available: xfsctl xfsctl support qom-cast-debug cast debugging support tools build qemu-io, qemu-nbd and qemu-img tools - vxhs Veritas HyperScale vDisk backend support bochs bochs image format support cloop cloop image format support dmg dmg image format support @@ -4198,7 +4192,7 @@ pthread_setname_np_wo_tid=no cat > $TMPC << EOF #include <pthread.h> -static void *f(void *p) { pthread_setname_np("QEMU"); } +static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } int main(void) { pthread_t thread; @@ -6250,33 +6244,6 @@ if compile_prog "" "" ; then fi ########################################## -# Veritas HyperScale block driver VxHS -# Check if libvxhs is installed - -if test "$vxhs" != "no" ; then - cat > $TMPC <<EOF -#include <stdint.h> -#include <qnio/qnio_api.h> - -void *vxhs_callback; - -int main(void) { - iio_init(QNIO_VERSION, vxhs_callback); - return 0; -} -EOF - vxhs_libs="-lvxhs -lssl" - if compile_prog "" "$vxhs_libs" ; then - vxhs=yes - else - if test "$vxhs" = "yes" ; then - feature_not_found "vxhs block device" "Install libvxhs See github" - fi - vxhs=no - fi -fi - -########################################## # check for _Static_assert() have_static_assert=no @@ -7033,7 +7000,6 @@ echo "jemalloc support $jemalloc" echo "avx2 optimization $avx2_opt" echo "avx512f optimization $avx512f_opt" echo "replication support $replication" -echo "VxHS block device $vxhs" echo "bochs support $bochs" echo "cloop support $cloop" echo "dmg support $dmg" @@ -7884,11 +7850,6 @@ elif test "$pthread_setname_np_wo_tid" = "yes" ; then echo "CONFIG_PTHREAD_SETNAME_NP_WO_TID=y" >> $config_host_mak fi -if test "$vxhs" = "yes" ; then - echo "CONFIG_VXHS=y" >> $config_host_mak - echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak -fi - if test "$libpmem" = "yes" ; then echo "CONFIG_LIBPMEM=y" >> $config_host_mak fi diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst index 971b65be75..851dbdeb8a 100644 --- a/docs/system/deprecated.rst +++ b/docs/system/deprecated.rst @@ -618,3 +618,11 @@ to achieve the same fake NUMA effect or a properly configured New machine versions (since 5.1) will not accept the option but it will still work with old machine types. User can check the QAPI schema to see if the legacy option is supported by looking at MachineInfo::numa-mem-supported property. + +Block devices +------------- + +VXHS backend (removed in 5.1) +''''''''''''''''''''''''''''' + +The VXHS code does not compile since v2.12.0. It was removed in 5.1. diff --git a/docs/system/s390x/vfio-ccw.rst b/docs/system/s390x/vfio-ccw.rst index 8f65442c0f..41e0bad5b4 100644 --- a/docs/system/s390x/vfio-ccw.rst +++ b/docs/system/s390x/vfio-ccw.rst @@ -29,7 +29,7 @@ automatically, use [root@host ~]# driverctl -b css set-override 0.0.0313 vfio_ccw [root@host ~]# mdevctl define -u 7e270a25-e163-4922-af60-757fc8ed48c6 \ - -p 0.0.0313 -t vfio-ccw_io -a + -p 0.0.0313 -t vfio_ccw-io -a If using ``mdevctl`` is not possible or wanted, follow the manual procedure below. diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 47bc0f650c..b0dbf9eeed 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -274,7 +274,11 @@ static int add_bitmaps_to_list(BlockDriverState *bs, const char *bs_name) DirtyBitmapMigBitmapState *dbms; Error *local_err = NULL; - bitmap = bdrv_dirty_bitmap_first(bs); + FOR_EACH_DIRTY_BITMAP(bs, bitmap) { + if (bdrv_dirty_bitmap_name(bitmap)) { + break; + } + } if (!bitmap) { return 0; } diff --git a/nbd/server.c b/nbd/server.c index 5357f588f0..4752a6c8bc 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -102,6 +102,8 @@ struct NBDExport { }; static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); +static QTAILQ_HEAD(, NBDExport) closed_exports = + QTAILQ_HEAD_INITIALIZER(closed_exports); /* NBDExportMetaContexts represents a list of contexts to be exported, * as selected by NBD_OPT_SET_META_CONTEXT. Also used for @@ -1659,6 +1661,7 @@ void nbd_export_close(NBDExport *exp) g_free(exp->name); exp->name = NULL; QTAILQ_REMOVE(&exports, exp, next); + QTAILQ_INSERT_TAIL(&closed_exports, exp, next); } g_free(exp->description); exp->description = NULL; @@ -1722,7 +1725,9 @@ void nbd_export_put(NBDExport *exp) g_free(exp->export_bitmap_context); } + QTAILQ_REMOVE(&closed_exports, exp, next); g_free(exp); + aio_wait_kick(); } } @@ -1742,6 +1747,9 @@ void nbd_export_close_all(void) nbd_export_close(exp); aio_context_release(aio_context); } + + AIO_WAIT_WHILE(NULL, !(QTAILQ_EMPTY(&exports) && + QTAILQ_EMPTY(&closed_exports))); } static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov, diff --git a/qapi/block-core.json b/qapi/block-core.json index 463ffd83da..ab7bf3c612 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2790,7 +2790,6 @@ # # Drivers that are supported in block device operations. # -# @vxhs: Since 2.10 # @throttle: Since 2.11 # @nvme: Since 2.12 # @copy-on-read: Since 3.0 @@ -2808,7 +2807,7 @@ 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd', { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' }, 'sheepdog', - 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] } + 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } ## # @BlockdevOptionsFile: @@ -3896,22 +3895,6 @@ 'data': { '*offset': 'int', '*size': 'int' } } ## -# @BlockdevOptionsVxHS: -# -# Driver specific block device options for VxHS -# -# @vdisk-id: UUID of VxHS volume -# @server: vxhs server IP, port -# @tls-creds: TLS credentials ID -# -# Since: 2.10 -## -{ 'struct': 'BlockdevOptionsVxHS', - 'data': { 'vdisk-id': 'str', - 'server': 'InetSocketAddressBase', - '*tls-creds': 'str' } } - -## # @BlockdevOptionsThrottle: # # Driver specific block device options for the throttle driver @@ -4010,8 +3993,7 @@ 'vhdx': 'BlockdevOptionsGenericFormat', 'vmdk': 'BlockdevOptionsGenericCOWFormat', 'vpc': 'BlockdevOptionsGenericFormat', - 'vvfat': 'BlockdevOptionsVVFAT', - 'vxhs': 'BlockdevOptionsVxHS' + 'vvfat': 'BlockdevOptionsVVFAT' } } ## diff --git a/qemu-img.c b/qemu-img.c index efb6ca139e..5308773811 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -4004,20 +4004,12 @@ static int img_resize(int argc, char **argv) } if (total_size < current_size && !shrink) { + error_report("Use the --shrink option to perform a shrink operation."); warn_report("Shrinking an image will delete all data beyond the " "shrunken image's end. Before performing such an " "operation, make sure there is no important data there."); - - if (g_strcmp0(bdrv_get_format_name(blk_bs(blk)), "raw") != 0) { - error_report( - "Use the --shrink option to perform a shrink operation."); - ret = -1; - goto out; - } else { - warn_report("Using the --shrink option will suppress this message. " - "Note that future versions of qemu-img may refuse to " - "shrink images without this option."); - } + ret = -1; + goto out; } /* diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c index 9ed8bb1c9f..aaacadacca 100644 --- a/qom/qom-hmp-cmds.c +++ b/qom/qom-hmp-cmds.c @@ -96,8 +96,10 @@ static void print_qom_composition(Monitor *mon, Object *obj, int indent); static int qom_composition_compare(const void *a, const void *b, void *ignore) { - return g_strcmp0(a ? object_get_canonical_path_component(a) : NULL, - b ? object_get_canonical_path_component(b) : NULL); + g_autofree char *ac = object_get_canonical_path_component(a); + g_autofree char *bc = object_get_canonical_path_component(b); + + return g_strcmp0(ac, bc); } static int insert_qom_composition_child(Object *obj, void *opaque) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 1e5123251d..588f32e136 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -984,7 +984,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { .type = CPUID_FEATURE_WORD, .feat_names = { NULL, NULL, "avx512-4vnniw", "avx512-4fmaps", - NULL, NULL, NULL, NULL, + "fsrm", NULL, NULL, NULL, "avx512-vp2intersect", NULL, "md-clear", NULL, NULL, NULL, "serialize", NULL, "tsx-ldtrk", NULL, NULL /* pconfig */, NULL, @@ -3034,6 +3034,13 @@ static X86CPUDefinition builtin_x86_defs[] = { { /* end of list */ } } }, + { + .version = 4, + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } + } + }, { /* end of list */ } } }, @@ -3158,6 +3165,13 @@ static X86CPUDefinition builtin_x86_defs[] = { { /* end of list */ } }, }, + { .version = 4, + .note = "ARCH_CAPABILITIES, no TSX", + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } + }, + }, { /* end of list */ } } }, @@ -3512,6 +3526,20 @@ static X86CPUDefinition builtin_x86_defs[] = { { /* end of list */ } }, }, + { + .version = 4, + .props = (PropValue[]) { + { "sha-ni", "on" }, + { "avx512ifma", "on" }, + { "rdpid", "on" }, + { "fsrm", "on" }, + { "vmx-rdseed-exit", "on" }, + { "vmx-pml", "on" }, + { "vmx-eptp-switching", "on" }, + { "model", "106" }, + { /* end of list */ } + }, + }, { /* end of list */ } } }, @@ -5159,6 +5187,13 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model) object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); x86_cpu_apply_version_props(cpu, model); + + /* + * Properties in versioned CPU model are not user specified features. + * We can simply clear env->user_features here since it will be filled later + * in x86_cpu_expand_features() based on plus_features and minus_features. + */ + memset(&env->user_features, 0, sizeof(env->user_features)); } #ifndef CONFIG_USER_ONLY @@ -6364,7 +6399,6 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) unavailable_features & env->user_features[d->to.index], "This feature depends on other features that were not requested"); - env->user_features[d->to.index] |= unavailable_features; env->features[d->to.index] &= ~unavailable_features; } } diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 37fffa5cac..e1a5c174dc 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -775,6 +775,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Multiply Accumulation Single Precision */ #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) +/* Fast Short Rep Mov */ +#define CPUID_7_0_EDX_FSRM (1U << 4) /* AVX512 Vector Pair Intersection to a Pair of Mask Registers */ #define CPUID_7_0_EDX_AVX512_VP2INTERSECT (1U << 8) /* SERIALIZE instruction */ diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h index 75ba1e2a5f..587b1b8375 100644 --- a/target/i386/hvf/vmx.h +++ b/target/i386/hvf/vmx.h @@ -166,6 +166,7 @@ static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4) wvmcs(vcpu, VMCS_GUEST_CR4, guest_cr4); wvmcs(vcpu, VMCS_CR4_SHADOW, cr4); + wvmcs(vcpu, VMCS_CR4_MASK, CR4_VMXE); hv_vcpu_invalidate_tlb(vcpu); hv_vcpu_flush(vcpu); diff --git a/tests/crypto-tls-x509-helpers.c b/tests/crypto-tls-x509-helpers.c index 9b669c2a4b..01b3daf358 100644 --- a/tests/crypto-tls-x509-helpers.c +++ b/tests/crypto-tls-x509-helpers.c @@ -37,25 +37,46 @@ ASN1_TYPE pkix_asn1; * here's one we prepared earlier :-) */ gnutls_x509_privkey_t privkey; -# define PRIVATE_KEY \ - "-----BEGIN PRIVATE KEY-----\n" \ - "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVcr\n" \ - "BL40Tm6yq88FBhJNw1aaoCjmtg0l4dWQZ/e9Fimx4ARxFpT+ji4FE\n" \ - "Cgl9s/SGqC+1nvlkm9ViSo0j7MKDbnDB+VRHDvMAzQhA2X7e8M0n9\n" \ - "rPolUY2lIVC83q0BBaOBkCj2RSmT2xTEbbC2xLukSrg2WP/ihVOxc\n" \ - "kXRuyFtzAgMBAAECgYB7slBexDwXrtItAMIH6m/U+LUpNe0Xx48OL\n" \ - "IOn4a4whNgO/o84uIwygUK27ZGFZT0kAGAk8CdF9hA6ArcbQ62s1H\n" \ - "myxrUbF9/mrLsQw1NEqpuUk9Ay2Tx5U/wPx35S3W/X2AvR/ZpTnCn\n" \ - "2q/7ym9fyiSoj86drD7BTvmKXlOnOwQJBAPOFMp4mMa9NGpGuEssO\n" \ - "m3Uwbp6lhcP0cA9MK+iOmeANpoKWfBdk5O34VbmeXnGYWEkrnX+9J\n" \ - "bM4wVhnnBWtgBMCQQC+qAEmvwcfhauERKYznMVUVksyeuhxhCe7EK\n" \ - "mPh+U2+g0WwdKvGDgO0PPt1gq0ILEjspMDeMHVdTwkaVBo/uMhAkA\n" \ - "Z5SsZyCP2aTOPFDypXRdI4eqRcjaEPOUBq27r3uYb/jeboVb2weLa\n" \ - "L1MmVuHiIHoa5clswPdWVI2y0em2IGoDAkBPSp/v9VKJEZabk9Frd\n" \ - "a+7u4fanrM9QrEjY3KhduslSilXZZSxrWjjAJPyPiqFb3M8XXA26W\n" \ - "nz1KYGnqYKhLcBAkB7dt57n9xfrhDpuyVEv+Uv1D3VVAhZlsaZ5Pp\n" \ - "dcrhrkJn2sa/+O8OKvdrPSeeu/N5WwYhJf61+CPoenMp7IFci\n" \ - "-----END PRIVATE KEY-----\n" +# define PRIVATE_KEY \ + "-----BEGIN RSA PRIVATE KEY-----\n" \ + "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\n" \ + "-----END RSA PRIVATE KEY-----\n" /* * This loads the private key we defined earlier diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017 index 585512bb29..3413e34f27 100755 --- a/tests/qemu-iotests/017 +++ b/tests/qemu-iotests/017 @@ -40,7 +40,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2 vmdk qed _supported_proto generic -_unsupported_proto vxhs _unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \ "subformat=streamOptimized" diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029 index 2161a4b87a..61d78c00a4 100755 --- a/tests/qemu-iotests/029 +++ b/tests/qemu-iotests/029 @@ -41,7 +41,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # Any format supporting intenal snapshots _supported_fmt qcow2 _supported_proto generic -_unsupported_proto vxhs # Internal snapshots are (currently) impossible with refcount_bits=1, # and generally impossible with external data files _unsupported_imgopts 'refcount_bits=1[^0-9]' data_file diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index 256b2bfbc6..31c028306b 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -243,7 +243,7 @@ class TestParallelOps(iotests.QMPTestCase): node_name = 'node%d' % i job_id = 'stream-%s' % node_name pending_jobs.append(job_id) - result = self.vm.qmp('block-stream', device=node_name, job_id=job_id, base=self.imgs[i-2], speed=512*1024) + result = self.vm.qmp('block-stream', device=node_name, job_id=job_id, base=self.imgs[i-2], speed=1024) self.assert_qmp(result, 'return', {}) for job in pending_jobs: diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073 index 1dce478709..68517821e8 100755 --- a/tests/qemu-iotests/073 +++ b/tests/qemu-iotests/073 @@ -38,7 +38,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto generic -_unsupported_proto vxhs # External data files do not support compressed clusters # (TODO: Consider writing a version for external data files that does # not test compressed clusters) diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114 index 5a7b0a4998..80e5e5e591 100755 --- a/tests/qemu-iotests/114 +++ b/tests/qemu-iotests/114 @@ -38,7 +38,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto generic -_unsupported_proto vxhs # At least OpenBSD doesn't seem to have truncate _supported_os Linux # qcow2.py does not work too well with external data files diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130 index 77ad2aa13a..a7b365701c 100755 --- a/tests/qemu-iotests/130 +++ b/tests/qemu-iotests/130 @@ -42,7 +42,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 _supported_proto generic -_unsupported_proto vxhs _supported_os Linux # We are going to use lazy-refcounts _unsupported_imgopts 'compat=0.10' diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134 index 5162d21662..17fe1d6ed4 100755 --- a/tests/qemu-iotests/134 +++ b/tests/qemu-iotests/134 @@ -38,7 +38,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow qcow2 _supported_proto generic -_unsupported_proto vxhs size=128M diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156 index 7c69a6c3fa..9c7878dd2d 100755 --- a/tests/qemu-iotests/156 +++ b/tests/qemu-iotests/156 @@ -50,7 +50,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow2 qed _supported_proto generic -_unsupported_proto vxhs # Copying files around with cp does not work with external data files _unsupported_imgopts data_file diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158 index 3175968e2b..cf23742c59 100755 --- a/tests/qemu-iotests/158 +++ b/tests/qemu-iotests/158 @@ -38,7 +38,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt qcow qcow2 _supported_proto generic -_unsupported_proto vxhs size=128M diff --git a/tests/qemu-iotests/282 b/tests/qemu-iotests/282 index 081eb12080..27da2a0023 100755 --- a/tests/qemu-iotests/282 +++ b/tests/qemu-iotests/282 @@ -38,7 +38,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 _supported_fmt luks _supported_proto generic -_unsupported_proto vxhs echo "== Create non-UTF8 secret ==" echo -n -e '\x3a\x3c\x3b\xff' > non_utf8_secret diff --git a/tests/qemu-iotests/299 b/tests/qemu-iotests/299 new file mode 100644 index 0000000000..e129c7f7cb --- /dev/null +++ b/tests/qemu-iotests/299 @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# +# Test shutdown when bitmap is exported through NBD server +# +# Copyright (c) 2020 Virtuozzo International GmbH. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import iotests + +# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs +iotests.script_initialize( + supported_fmts=['qcow2'], +) + +nbd_sock = iotests.file_path('nbd.sock', base_dir=iotests.sock_dir) +nbd_uri = 'nbd+unix:///disk?socket=' + nbd_sock +size = 1024 * 1024 + +vm = iotests.VM() +vm.launch() + +vm.qmp_log('blockdev-add', **{ + 'node-name': 'disk', + 'driver': 'null-co', + 'size': 1024 * 1024, +}) + +vm.qmp_log('block-dirty-bitmap-add', **{ + 'node': 'disk', + 'name': 'bitmap0' +}) + +vm.qmp_log('nbd-server-start', **{ + 'addr': { + 'type': 'unix', + 'data': {'path': nbd_sock} + } +}, filters=[iotests.filter_qmp_testfiles]) + +vm.qmp_log('nbd-server-add', **{ + 'device': 'disk', + 'writable': True, + 'bitmap': 'bitmap0' +}) + +p = iotests.QemuIoInteractive('-f', 'raw', nbd_uri) +# wait for connection and check it: +iotests.log(p.cmd('read 0 512').rstrip(), filters=[iotests.filter_qemu_io]) + +vm.shutdown() + +p.close() diff --git a/tests/qemu-iotests/299.out b/tests/qemu-iotests/299.out new file mode 100644 index 0000000000..bba4252923 --- /dev/null +++ b/tests/qemu-iotests/299.out @@ -0,0 +1,10 @@ +{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "disk", "size": 1048576}} +{"return": {}} +{"execute": "block-dirty-bitmap-add", "arguments": {"name": "bitmap0", "node": "disk"}} +{"return": {}} +{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}} +{"return": {}} +{"execute": "nbd-server-add", "arguments": {"bitmap": "bitmap0", "device": "disk", "writable": true}} +{"return": {}} +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check index 9c461cf76d..e0d8049012 100755 --- a/tests/qemu-iotests/check +++ b/tests/qemu-iotests/check @@ -272,7 +272,6 @@ image protocol options -nbd test nbd -ssh test ssh -nfs test nfs - -vxhs test vxhs other options -xdiff graphical mode diff @@ -383,11 +382,6 @@ testlist options xpand=false ;; - -vxhs) - IMGPROTO=vxhs - xpand=false - ;; - -ssh) IMGPROTO=ssh xpand=false @@ -646,10 +640,6 @@ if [ -z $QEMU_NBD_PROG ]; then fi export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")" -if [ -z "$QEMU_VXHS_PROG" ]; then - export QEMU_VXHS_PROG="$(set_prog_path qnio_server)" -fi - if [ -x "$build_iotests/socket_scm_helper" ] then export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 9b772245cd..c6912be009 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -227,7 +227,6 @@ _filter_img_info() -e "s#$IMGFMT#IMGFMT#g" \ -e 's#nbd://127.0.0.1:[0-9]\\+$#TEST_DIR/t.IMGFMT#g' \ -e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \ - -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \ -e "/encrypted: yes/d" \ -e "/cluster_size: [0-9]\\+/d" \ -e "/table_size: [0-9]\\+/d" \ diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 7ac46edc1f..494490a272 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -124,7 +124,6 @@ fi : ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU} : ${VALGRIND_QEMU_IO=$VALGRIND_QEMU} : ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU} -: ${VALGRIND_QEMU_VXHS=$VALGRIND_QEMU} # The Valgrind own parameters may be set with # its environment variable VALGRIND_OPTS, e.g. @@ -212,19 +211,6 @@ _qemu_nbd_wrapper() return $RETVAL } -_qemu_vxhs_wrapper() -{ - local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind - ( - echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid" - VALGRIND_QEMU="${VALGRIND_QEMU_VXHS}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \ - "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@" - ) - RETVAL=$? - _qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL - return $RETVAL -} - # Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141 # Until valgrind 3.16+ is ubiquitous, we must work around a hang in # valgrind when issuing sigkill. Disable valgrind for this invocation. @@ -237,7 +223,6 @@ export QEMU=_qemu_wrapper export QEMU_IMG=_qemu_img_wrapper export QEMU_IO=_qemu_io_wrapper export QEMU_NBD=_qemu_nbd_wrapper -export QEMU_VXHS=_qemu_vxhs_wrapper if [ "$IMGOPTSSYNTAX" = "true" ]; then DRIVER="driver=$IMGFMT" @@ -279,9 +264,6 @@ else TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT REMOTE_TEST_DIR="nfs://127.0.0.1$TEST_DIR" TEST_IMG="nfs://127.0.0.1$TEST_IMG_FILE" - elif [ "$IMGPROTO" = "vxhs" ]; then - TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT - TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT" else TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT fi @@ -436,12 +418,6 @@ _make_test_img() eval "$QEMU_NBD -v -t -k '$SOCK_DIR/nbd' -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &" sleep 1 # FIXME: qemu-nbd needs to be listening before we continue fi - - # Start QNIO server on image directory for vxhs protocol - if [ $IMGPROTO = "vxhs" ]; then - eval "$QEMU_VXHS -d $TEST_DIR > /dev/null &" - sleep 1 # Wait for server to come up. - fi } _rm_test_img() @@ -468,15 +444,6 @@ _cleanup_test_img() _stop_nbd_server rm -f "$TEST_IMG_FILE" ;; - vxhs) - if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then - local QEMU_VXHS_PID - read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid" - kill ${QEMU_VXHS_PID} >/dev/null 2>&1 - rm -f "${TEST_DIR}/qemu-vxhs.pid" - fi - rm -f "$TEST_IMG_FILE" - ;; file) _rm_test_img "$TEST_DIR/t.$IMGFMT" diff --git a/tests/qemu-iotests/common.tls b/tests/qemu-iotests/common.tls index 54c331d7a5..6ba28a78d3 100644 --- a/tests/qemu-iotests/common.tls +++ b/tests/qemu-iotests/common.tls @@ -50,24 +50,45 @@ tls_x509_init() # use a fixed key so we don't waste system entropy on # each test run cat > "${tls_dir}/key.pem" <<EOF ------BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALVcr -BL40Tm6yq88FBhJNw1aaoCjmtg0l4dWQZ/e9Fimx4ARxFpT+ji4FE -Cgl9s/SGqC+1nvlkm9ViSo0j7MKDbnDB+VRHDvMAzQhA2X7e8M0n9 -rPolUY2lIVC83q0BBaOBkCj2RSmT2xTEbbC2xLukSrg2WP/ihVOxc -kXRuyFtzAgMBAAECgYB7slBexDwXrtItAMIH6m/U+LUpNe0Xx48OL -IOn4a4whNgO/o84uIwygUK27ZGFZT0kAGAk8CdF9hA6ArcbQ62s1H -myxrUbF9/mrLsQw1NEqpuUk9Ay2Tx5U/wPx35S3W/X2AvR/ZpTnCn -2q/7ym9fyiSoj86drD7BTvmKXlOnOwQJBAPOFMp4mMa9NGpGuEssO -m3Uwbp6lhcP0cA9MK+iOmeANpoKWfBdk5O34VbmeXnGYWEkrnX+9J -bM4wVhnnBWtgBMCQQC+qAEmvwcfhauERKYznMVUVksyeuhxhCe7EK -mPh+U2+g0WwdKvGDgO0PPt1gq0ILEjspMDeMHVdTwkaVBo/uMhAkA -Z5SsZyCP2aTOPFDypXRdI4eqRcjaEPOUBq27r3uYb/jeboVb2weLa -L1MmVuHiIHoa5clswPdWVI2y0em2IGoDAkBPSp/v9VKJEZabk9Frd -a+7u4fanrM9QrEjY3KhduslSilXZZSxrWjjAJPyPiqFb3M8XXA26W -nz1KYGnqYKhLcBAkB7dt57n9xfrhDpuyVEv+Uv1D3VVAhZlsaZ5Pp -dcrhrkJn2sa/+O8OKvdrPSeeu/N5WwYhJf61+CPoenMp7IFci ------END PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- EOF } diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index a4f9e11e7a..1d0252e1f0 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -306,4 +306,5 @@ 295 rw 296 rw 297 meta +299 auto quick 301 backing quick diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index c315156858..d49b3988ec 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -924,6 +924,7 @@ static void test_acpi_tcg_tpm(const char *machine, const char *tpm_if, g_free(variant); g_free(tmp_path); g_free(tmp_dir_name); + g_free(args); free_test_data(&data); #else g_test_skip("TPM disabled"); diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index 0b66e43409..6bc17ef313 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -199,16 +199,15 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) } /* Run QEMU's softmmu main with the fuzz-target dependent arguments */ - const char *init_cmdline = fuzz_target->get_init_cmdline(fuzz_target); - init_cmdline = g_strdup_printf("%s -qtest /dev/null -qtest-log %s", - init_cmdline, - getenv("QTEST_LOG") ? "/dev/fd/2" - : "/dev/null"); - + GString *cmd_line = fuzz_target->get_init_cmdline(fuzz_target); + g_string_append_printf(cmd_line, + " -qtest /dev/null -qtest-log %s", + getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null"); /* Split the runcmd into an argv and argc */ wordexp_t result; - wordexp(init_cmdline, &result, 0); + wordexp(cmd_line->str, &result, 0); + g_string_free(cmd_line, true); qemu_init(result.we_wordc, result.we_wordv, NULL); diff --git a/tests/qtest/fuzz/fuzz.h b/tests/qtest/fuzz/fuzz.h index 72d5710f6c..9ca3d107c5 100644 --- a/tests/qtest/fuzz/fuzz.h +++ b/tests/qtest/fuzz/fuzz.h @@ -50,10 +50,10 @@ typedef struct FuzzTarget { /* - * returns the arg-list that is passed to qemu/softmmu init() - * Cannot be NULL + * Returns the arguments that are passed to qemu/softmmu init(). Freed by + * the caller. */ - const char* (*get_init_cmdline)(struct FuzzTarget *); + GString *(*get_init_cmdline)(struct FuzzTarget *); /* * will run once, prior to running qemu/softmmu init. diff --git a/tests/qtest/fuzz/i440fx_fuzz.c b/tests/qtest/fuzz/i440fx_fuzz.c index e2f31e56f9..bf966d478b 100644 --- a/tests/qtest/fuzz/i440fx_fuzz.c +++ b/tests/qtest/fuzz/i440fx_fuzz.c @@ -158,9 +158,9 @@ static void i440fx_fuzz_qos_fork(QTestState *s, static const char *i440fx_qtest_argv = TARGET_NAME " -machine accel=qtest" " -m 0 -display none"; -static const char *i440fx_argv(FuzzTarget *t) +static GString *i440fx_argv(FuzzTarget *t) { - return i440fx_qtest_argv; + return g_string_new(i440fx_qtest_argv); } static void fork_init(void) diff --git a/tests/qtest/fuzz/qos_fuzz.c b/tests/qtest/fuzz/qos_fuzz.c index 0c68f5361f..d52f3ebd83 100644 --- a/tests/qtest/fuzz/qos_fuzz.c +++ b/tests/qtest/fuzz/qos_fuzz.c @@ -66,7 +66,7 @@ void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc) return allocate_objects(qts, current_path + 1, p_alloc); } -static const char *qos_build_main_args(void) +static GString *qos_build_main_args(void) { char **path = fuzz_path_vec; QOSGraphNode *test_node; @@ -88,7 +88,7 @@ static const char *qos_build_main_args(void) /* Prepend the arguments that we need */ g_string_prepend(cmd_line, TARGET_NAME " -display none -machine accel=qtest -m 64 "); - return cmd_line->str; + return cmd_line; } /* @@ -189,7 +189,7 @@ static void walk_path(QOSGraphNode *orig_path, int len) g_free(path_str); } -static const char *qos_get_cmdline(FuzzTarget *t) +static GString *qos_get_cmdline(FuzzTarget *t) { /* * Set a global variable that we use to identify the qos_path for our diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index c68f99f659..f7b1aa7fdc 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -230,6 +230,8 @@ static void test_object_add_failure_modes(void) " 'props': {'size': 1048576 } } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); + resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," " 'props': {'size': 1048576 } } }"); @@ -241,6 +243,7 @@ static void test_object_add_failure_modes(void) " {'id': 'ram1' } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* attempt to create an object with a property of a wrong type */ resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" @@ -249,17 +252,20 @@ static void test_object_add_failure_modes(void) g_assert_nonnull(resp); /* now do it right */ qmp_assert_error_class(resp, "GenericError"); + resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," " 'props': {'size': 1048576 } } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* delete ram1 object */ resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" " {'id': 'ram1' } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* attempt to create an object without the id */ resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" @@ -267,18 +273,21 @@ static void test_object_add_failure_modes(void) " 'props': {'size': 1048576 } } }"); g_assert_nonnull(resp); qmp_assert_error_class(resp, "GenericError"); + /* now do it right */ resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," " 'props': {'size': 1048576 } } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* delete ram1 object */ resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" " {'id': 'ram1' } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* attempt to set a non existing property */ resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" @@ -286,23 +295,27 @@ static void test_object_add_failure_modes(void) " 'props': {'sized': 1048576 } } }"); g_assert_nonnull(resp); qmp_assert_error_class(resp, "GenericError"); + /* now do it right */ resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," " 'props': {'size': 1048576 } } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* delete ram1 object without id */ resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" " {'ida': 'ram1' } }"); g_assert_nonnull(resp); + qobject_unref(resp); /* delete ram1 object */ resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" " {'id': 'ram1' } }"); g_assert_nonnull(resp); g_assert(qdict_haskey(resp, "return")); + qobject_unref(resp); /* delete ram1 object that does not exist anymore*/ resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" |