[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v3 4/5] a standone-alone tool to directly share disk image fi
From: |
Coiby Xu |
Subject: |
Re: [PATCH v3 4/5] a standone-alone tool to directly share disk image file via vhost-user protocol |
Date: |
Thu, 13 Feb 2020 15:05:26 +0800 |
I forgot to put backends/vhost-user-blk-server.o as dependency for
qemu-vu target in Makefile,
qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y)
$(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y)
$(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+
+ifdef CONFIG_LINUX
+qemu-vu$(EXESUF): qemu-vu.o backends/vhost-user-blk-server.o
$(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y)
$(COMMON_LDADDS) libvhost-user.a
+endif
qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y)
$(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
I also noticed in the latest version of QEMU, `make check-qtest`
somehow doesn't run qos-test. If you need to run vhost-user-blk
testsuite, please execute the following command after applying the
above fix and the 5th patch,
MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(( ${RANDOM:-0} % 255 + 1))}
QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
QTEST_QEMU_IMG=./qemu-img QTEST_QEMU_VU_BINARY=./qemu-vu
tests/qos-test -m=quick -k --tap < /dev/null | ./scripts/tap-driver.pl
--test-name="qos-test"
On Wed, Feb 12, 2020 at 5:52 PM Coiby Xu <address@hidden> wrote:
>
> vhost-user-blk could have played as vhost-user backend but it only supports
> raw
> file and don't support VIRTIO_BLK_T_DISCARD and VIRTIO_BLK_T_WRITE_ZEROES
> operations on raw file (ioctl(fd, BLKDISCARD) is only valid for real
> block device).
>
> In the future Kevin's qemu-storage-daemon will be used to replace this
> tool.
>
> Signed-off-by: Coiby Xu <address@hidden>
> ---
> Makefile | 4 +
> configure | 3 +
> qemu-vu.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 259 insertions(+)
> create mode 100644 qemu-vu.c
>
> diff --git a/Makefile b/Makefile
> index f0e1a2fc1d..0bfd2f1ddd 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -572,6 +572,10 @@ qemu-img.o: qemu-img-cmds.h
>
> qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y)
> $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
> qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y)
> $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
> +
> +ifdef CONFIG_LINUX
> +qemu-vu$(EXESUF): qemu-vu.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y)
> $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS) libvhost-user.a
> +endif
> qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y)
> $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
>
> qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
> diff --git a/configure b/configure
> index 115dc38085..e87c9a5587 100755
> --- a/configure
> +++ b/configure
> @@ -6217,6 +6217,9 @@ if test "$want_tools" = "yes" ; then
> if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
> tools="qemu-nbd\$(EXESUF) $tools"
> fi
> + if [ "$linux" = "yes" ] ; then
> + tools="qemu-vu\$(EXESUF) $tools"
> + fi
> if [ "$ivshmem" = "yes" ]; then
> tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools"
> fi
> diff --git a/qemu-vu.c b/qemu-vu.c
> new file mode 100644
> index 0000000000..dd1032b205
> --- /dev/null
> +++ b/qemu-vu.c
> @@ -0,0 +1,252 @@
> +/*
> + * Copyright (C) 2020 Coiby Xu <address@hidden>
> + *
> + * standone-alone vhost-user-blk device server backend
> + *
> + * 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; under version 2 of the License.
> + *
> + * 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/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include <getopt.h>
> +#include <libgen.h>
> +#include "backends/vhost-user-blk-server.h"
> +#include "block/block_int.h"
> +#include "io/net-listener.h"
> +#include "qapi/error.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qstring.h"
> +#include "qemu/config-file.h"
> +#include "qemu/cutils.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/module.h"
> +#include "qemu/option.h"
> +#include "qemu-common.h"
> +#include "qemu-version.h"
> +#include "qom/object_interfaces.h"
> +#include "sysemu/block-backend.h"
> +#define QEMU_VU_OPT_CACHE 256
> +#define QEMU_VU_OPT_AIO 257
> +#define QEMU_VU_OBJ_ID "vu_disk"
> +static QemuOptsList qemu_object_opts = {
> + .name = "object",
> + .implied_opt_name = "qom-type",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
> + .desc = {
> + { }
> + },
> +};
> +static char *srcpath;
> +
> +static void usage(const char *name)
> +{
> + (printf) (
> +"Usage: %s [OPTIONS] FILE\n"
> +" or: %s -L [OPTIONS]\n"
> +"QEMU Vhost-user Server Utility\n"
> +"\n"
> +" -h, --help display this help and exit\n"
> +" -V, --version output version information and exit\n"
> +"\n"
> +"Connection properties:\n"
> +" -k, --socket=PATH path to the unix socket\n"
> +"\n"
> +"General purpose options:\n"
> +" -e, -- exit-panic When the panic callback is called, the
> program\n"
> +" will exit. Useful for make check-qtest.\n"
> +"\n"
> +"Block device options:\n"
> +" -f, --format=FORMAT set image format (raw, qcow2, ...)\n"
> +" -r, --read-only export read-only\n"
> +" -n, --nocache disable host cache\n"
> +" --cache=MODE set cache mode (none, writeback, ...)\n"
> +" --aio=MODE set AIO mode (native or threads)\n"
> +"\n"
> +QEMU_HELP_BOTTOM "\n"
> + , name, name);
> +}
> +
> +static void version(const char *name)
> +{
> + printf(
> +"%s " QEMU_FULL_VERSION "\n"
> +"Written by Coiby Xu, based on qemu-nbd by Anthony Liguori\n"
> +"\n"
> +QEMU_COPYRIGHT "\n"
> +"This is free software; see the source for copying conditions. There is
> NO\n"
> +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
> PURPOSE.\n"
> + , name);
> +}
> +
> +static VuBlockDev *vu_block_device;
> +
> +static void vus_shutdown(void)
> +{
> +
> + Error *local_err = NULL;
> + job_cancel_sync_all();
> + bdrv_close_all();
> + user_creatable_del(QEMU_VU_OBJ_ID, &local_err);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + BlockBackend *blk;
> + BlockDriverState *bs;
> + bool readonly = false;
> + char *sockpath = NULL;
> + const char *sopt = "hVrnvek:f:";
> + struct option lopt[] = {
> + { "help", no_argument, NULL, 'h' },
> + { "version", no_argument, NULL, 'V' },
> + { "exit-panic", no_argument, NULL, 'e' },
> + { "socket", required_argument, NULL, 'k' },
> + { "read-only", no_argument, NULL, 'r' },
> + { "nocache", no_argument, NULL, 'n' },
> + { "cache", required_argument, NULL, QEMU_VU_OPT_CACHE },
> + { "aio", required_argument, NULL, QEMU_VU_OPT_AIO },
> + { "format", required_argument, NULL, 'f' },
> + { NULL, 0, NULL, 0 }
> + };
> + int ch;
> + int opt_ind = 0;
> + int flags = BDRV_O_RDWR;
> + bool seen_cache = false;
> + bool seen_aio = false;
> + const char *fmt = NULL;
> + Error *local_err = NULL;
> + QDict *options = NULL;
> + bool writethrough = true;
> + bool exit_when_panic = false;
> +
> + error_init(argv[0]);
> +
> + module_call_init(MODULE_INIT_QOM);
> + qemu_init_exec_dir(argv[0]);
> +
> + while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
> + switch (ch) {
> + case 'e':
> + exit_when_panic = true;
> + break;
> + case 'n':
> + optarg = (char *) "none";
> + /* fallthrough */
> + case QEMU_VU_OPT_CACHE:
> + if (seen_cache) {
> + error_report("-n and --cache can only be specified once");
> + exit(EXIT_FAILURE);
> + }
> + seen_cache = true;
> + if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) == -1) {
> + error_report("Invalid cache mode `%s'", optarg);
> + exit(EXIT_FAILURE);
> + }
> + break;
> + case QEMU_VU_OPT_AIO:
> + if (seen_aio) {
> + error_report("--aio can only be specified once");
> + exit(EXIT_FAILURE);
> + }
> + seen_aio = true;
> + if (!strcmp(optarg, "native")) {
> + flags |= BDRV_O_NATIVE_AIO;
> + } else if (!strcmp(optarg, "threads")) {
> + /* this is the default */
> + } else {
> + error_report("invalid aio mode `%s'", optarg);
> + exit(EXIT_FAILURE);
> + }
> + break;
> + case 'r':
> + readonly = true;
> + flags &= ~BDRV_O_RDWR;
> + break;
> + case 'k':
> + sockpath = optarg;
> + if (sockpath[0] != '/') {
> + error_report("socket path must be absolute");
> + exit(EXIT_FAILURE);
> + }
> + break;
> + case 'f':
> + fmt = optarg;
> + break;
> + case 'V':
> + version(argv[0]);
> + exit(0);
> + break;
> + case 'h':
> + usage(argv[0]);
> + exit(0);
> + break;
> + case '?':
> + error_report("Try `%s --help' for more information.", argv[0]);
> + exit(EXIT_FAILURE);
> + }
> + }
> +
> + if ((argc - optind) != 1) {
> + error_report("Invalid number of arguments");
> + error_printf("Try `%s --help' for more information.\n", argv[0]);
> + exit(EXIT_FAILURE);
> + }
> + if (qemu_init_main_loop(&local_err)) {
> + error_report_err(local_err);
> + exit(EXIT_FAILURE);
> + }
> + bdrv_init();
> +
> + srcpath = argv[optind];
> + if (fmt) {
> + options = qdict_new();
> + qdict_put_str(options, "driver", fmt);
> + }
> + blk = blk_new_open(srcpath, NULL, options, flags, &local_err);
> +
> + if (!blk) {
> + error_reportf_err(local_err, "Failed to blk_new_open '%s': ",
> + argv[optind]);
> + exit(EXIT_FAILURE);
> + }
> + bs = blk_bs(blk);
> +
> + char buf[300];
> + snprintf(buf, 300, "%s,id=%s,node-name=%s,unix-socket=%s,writable=%s",
> + TYPE_VHOST_USER_BLK_SERVER, QEMU_VU_OBJ_ID,
> bdrv_get_node_name(bs),
> + sockpath, !readonly ? "on" : "off");
> + /* While calling user_creatable_del, 'object' group is required */
> + qemu_add_opts(&qemu_object_opts);
> + QemuOpts *opts = qemu_opts_parse(&qemu_object_opts, buf, true,
> &local_err);
> + if (local_err) {
> + error_report_err(local_err);
> + goto error;
> + }
> +
> + Object *obj = user_creatable_add_opts(opts, &local_err);
> +
> + if (local_err) {
> + error_report_err(local_err);
> + goto error;
> + }
> +
> + vu_block_device = VHOST_USER_BLK_SERVER(obj);
> + vu_block_device->exit_when_panic = exit_when_panic;
> +
> + do {
> + main_loop_wait(false);
> + } while (!vu_block_device->exit_when_panic ||
> !vu_block_device->vu_server->close);
> +
> + error:
> + vus_shutdown();
> + exit(EXIT_SUCCESS);
> +}
> --
> 2.25.0
>
--
Best regards,
Coiby
- [PATCH v3 0/5] vhost-user block device backend implementation, Coiby Xu, 2020/02/12
- [PATCH v3 1/5] extend libvhost to support IOThread and coroutine, Coiby Xu, 2020/02/12
- [PATCH v3 2/5] generic vhost user server, Coiby Xu, 2020/02/12
- [PATCH v3 3/5] vhost-user block device backend server, Coiby Xu, 2020/02/12
- [PATCH v3 4/5] a standone-alone tool to directly share disk image file via vhost-user protocol, Coiby Xu, 2020/02/12
- Re: [PATCH v3 4/5] a standone-alone tool to directly share disk image file via vhost-user protocol,
Coiby Xu <=
- [PATCH v3 5/5] new qTest case to test the vhost-user-blk-server, Coiby Xu, 2020/02/12