diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c97b787c56cde73366af1f59f305d5c5f02af8cf..3437302dd15f933bc4c1b4e1efbde00896b2f26e 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -516,6 +516,37 @@ qemuBlockStorageSourceGetGlusterProps(virStorageSourcePtr src) } +static virJSONValuePtr +qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src) +{ + const char *protocol = virStorageNetProtocolTypeToString(src->protocol); + virJSONValuePtr server = NULL; + virJSONValuePtr ret = NULL; + + if (src->nhosts != 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("VxHS protocol accepts only one host")); + return NULL; + } + + if (!(server = qemuBlockStorageSourceBuildJSONSocketAddress(src->hosts, true))) + return NULL; + + /* VxHS disk specification example: + * { driver:"vxhs", + * vdisk-id:"eb90327c-8302-4725-4e85ed4dc251", + * server:{type:"tcp", host:"1.2.3.4", port:9999}} + */ + if (virJSONValueObjectCreate(&ret, + "s:driver", protocol, + "s:vdisk-id", src->path, + "a:server", server, NULL) < 0) + virJSONValueFree(server); + + return ret; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -546,6 +577,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) goto cleanup; break; + case VIR_STORAGE_NET_PROTOCOL_VXHS: + if (!(fileprops = qemuBlockStorageSourceGetVxHSProps(src))) + goto cleanup; + break; + case VIR_STORAGE_NET_PROTOCOL_NBD: case VIR_STORAGE_NET_PROTOCOL_RBD: case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: @@ -556,7 +592,6 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) case VIR_STORAGE_NET_PROTOCOL_FTPS: case VIR_STORAGE_NET_PROTOCOL_TFTP: case VIR_STORAGE_NET_PROTOCOL_SSH: - case VIR_STORAGE_NET_PROTOCOL_VXHS: case VIR_STORAGE_NET_PROTOCOL_NONE: case VIR_STORAGE_NET_PROTOCOL_LAST: break; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6e9d8aa43e578f6ba8fdde0552e32366acbf66ab..9b3e3fc04667b3649d35ce2cdc720f28678ccfd4 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -994,12 +994,16 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src, ret = virBufferContentAndReset(&buf); break; + case VIR_STORAGE_NET_PROTOCOL_VXHS: + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("VxHS protocol does not support URI syntax")); + goto cleanup; + case VIR_STORAGE_NET_PROTOCOL_SSH: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'ssh' protocol is not yet supported")); goto cleanup; - case VIR_STORAGE_NET_PROTOCOL_VXHS: case VIR_STORAGE_NET_PROTOCOL_LAST: case VIR_STORAGE_NET_PROTOCOL_NONE: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -1329,6 +1333,10 @@ qemuDiskSourceNeedsProps(virStorageSourcePtr src) src->nhosts > 1) return true; + if (actualType == VIR_STORAGE_TYPE_NETWORK && + src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS) + return true; + return false; } diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c index 9190a37baed5100b270f203ada1e04b348faa89e..6286c2e7adc4398ff03a21b42d65e7b13d8f7838 100644 --- a/src/qemu/qemu_parse_command.c +++ b/src/qemu/qemu_parse_command.c @@ -736,6 +736,11 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, if (VIR_STRDUP(def->src->path, vdi) < 0) goto error; } + } else if (STRPREFIX(def->src->path, "vxhs:")) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("VxHS protocol does not support URI syntax '%s'"), + def->src->path); + goto error; } else { def->src->type = VIR_STORAGE_TYPE_FILE; } @@ -1944,6 +1949,10 @@ qemuParseCommandLine(virCapsPtr caps, disk->src->type = VIR_STORAGE_TYPE_NETWORK; disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG; val += strlen("sheepdog:"); + } else if (STRPREFIX(val, "vxhs:")) { + disk->src->type = VIR_STORAGE_TYPE_NETWORK; + disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_VXHS; + val += strlen("vxhs:"); } else { disk->src->type = VIR_STORAGE_TYPE_FILE; } @@ -2020,13 +2029,18 @@ qemuParseCommandLine(virCapsPtr caps, goto error; break; + case VIR_STORAGE_NET_PROTOCOL_VXHS: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("VxHS protocol does not support URI " + "syntax '%s'"), disk->src->path); + goto error; + break; case VIR_STORAGE_NET_PROTOCOL_HTTP: case VIR_STORAGE_NET_PROTOCOL_HTTPS: case VIR_STORAGE_NET_PROTOCOL_FTP: case VIR_STORAGE_NET_PROTOCOL_FTPS: case VIR_STORAGE_NET_PROTOCOL_TFTP: case VIR_STORAGE_NET_PROTOCOL_SSH: - case VIR_STORAGE_NET_PROTOCOL_VXHS: case VIR_STORAGE_NET_PROTOCOL_LAST: case VIR_STORAGE_NET_PROTOCOL_NONE: /* ignored for now */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 053aba1a6cea8e5a6eda47ec204cf0a13db7c56d..e6cc41e1309d788b210ccd81b9ef9a657a8b7341 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4579,6 +4579,32 @@ qemuProcessStartValidateShmem(virDomainObjPtr vm) } +static int +qemuProcessStartValidateDisks(virDomainObjPtr vm, + virQEMUCapsPtr qemuCaps) +{ + size_t i; + + for (i = 0; i < vm->def->ndisks; i++) { + virStorageSourcePtr src = vm->def->disks[i]->src; + + /* This is a best effort check as we can only check if the command + * option exists, but we cannot determine whether the running QEMU + * was build with '--enable-vxhs'. */ + if (src->type == VIR_STORAGE_TYPE_NETWORK && + src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VXHS)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("VxHS protocol is not supported with this " + "QEMU binary")); + return -1; + } + } + + return 0; +} + + static int qemuProcessStartValidateXML(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -4665,6 +4691,9 @@ qemuProcessStartValidate(virQEMUDriverPtr driver, virCPUValidateFeatures(vm->def->os.arch, vm->def->cpu) < 0) return -1; + if (qemuProcessStartValidateDisks(vm, qemuCaps) < 0) + return -1; + VIR_DEBUG("Checking for any possible (non-fatal) issues"); qemuProcessStartWarnShmem(vm); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args new file mode 100644 index 0000000000000000000000000000000000000000..b62ace3de1d724e5ca08cb19436830a7133743a3 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-vxhs.args @@ -0,0 +1,27 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-cpu qemu32 \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-usb \ +-drive file.driver=vxhs,file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,\ +file.server.type=tcp,file.server.host=192.168.0.1,file.server.port=9999,\ +format=raw,if=none,id=drive-virtio-disk0,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\ +id=virtio-disk0 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 579cdb6f083cdf91cda3e008685a10d47e7ca4de..bf43beb1060020135ed0ee5bdd59b0736788c846 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -933,6 +933,7 @@ mymain(void) # endif DO_TEST("disk-drive-network-rbd-ipv6", NONE); DO_TEST_FAILURE("disk-drive-network-rbd-no-colon", NONE); + DO_TEST("disk-drive-network-vxhs", QEMU_CAPS_VXHS); DO_TEST("disk-drive-no-boot", QEMU_CAPS_BOOTINDEX); DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid",