From 6885b51e5f26f5c78b104c1f57e8e661416aaee8 Mon Sep 17 00:00:00 2001 From: Ashish Mittal Date: Wed, 30 Aug 2017 11:06:00 -0400 Subject: [PATCH] qemu: Add TLS support for Veritas HyperScale (VxHS) Alter qemu command line generation in order to possibly add TLS for a suitably configured domain. Sample TLS args generated by libvirt - -object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\ endpoint=client,verify-peer=yes \ -drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\ 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 Update the qemuxml2argvtest with a couple of examples. One for a simple case and the other a bit more complex where multiple VxHS disks are added where at least one uses a VxHS that doesn't require TLS credentials and thus sets the domain disk source attribute "tls = 'no'". Update the hotplug to be able to handle processing the tlsAlias whether it's to add the TLS object when hotplugging a disk or to remove the TLS object when hot unplugging a disk. The hot plug/unplug code is largely generic, but the addition code does make the VXHS specific checks only because it needs to grab the correct config directory and generate the object as the command line would do. Signed-off-by: Ashish Mittal Signed-off-by: John Ferlan --- src/qemu/qemu_block.c | 2 + src/qemu/qemu_command.c | 33 +++++++++ src/qemu/qemu_hotplug.c | 73 +++++++++++++++++++ ...2argv-disk-drive-network-tlsx509-vxhs.args | 43 +++++++++++ ...l2argv-disk-drive-network-tlsx509-vxhs.xml | 20 ++++- tests/qemuxml2argvtest.c | 5 ++ ...xmlout-disk-drive-network-tlsx509-vxhs.xml | 20 ++++- 7 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 6faecb0aeb..8d232de3e3 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -545,11 +545,13 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src) /* VxHS disk specification example: * { driver:"vxhs", + * tls-creds:"objvirtio-disk0_tls0", * vdisk-id:"eb90327c-8302-4725-4e85ed4dc251", * server:{type:"tcp", host:"1.2.3.4", port:9999}} */ if (virJSONValueObjectCreate(&ret, "s:driver", protocol, + "S:tls-creds", src->tlsAlias, "s:vdisk-id", src->path, "a:server", server, NULL) < 0) virJSONValueFree(server); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index abeb248468..4f141e0ac3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -794,6 +794,35 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd, } +/* qemuBuildDiskSrcTLSx509CommandLine: + * + * Add TLS object if the disk src uses a secure communication channel + * + * Returns 0 on success, -1 w/ error on some sort of failure. + */ +static int +qemuBuildDiskSrcTLSx509CommandLine(virCommandPtr cmd, + virStorageSourcePtr src, + const char *srcalias, + virQEMUCapsPtr qemuCaps) +{ + + + /* other protocols may be added later */ + if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS && + src->haveTLS == VIR_TRISTATE_BOOL_YES) { + if (!(src->tlsAlias = qemuAliasTLSObjFromSrcAlias(srcalias))) + return -1; + + return qemuBuildTLSx509CommandLine(cmd, src->tlsCertdir, + false, src->tlsVerify, + false, srcalias, qemuCaps); + } + + return 0; +} + + static char * qemuBuildNetworkDriveURI(virStorageSourcePtr src, qemuDomainSecretInfoPtr secinfo) @@ -2221,6 +2250,10 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd, if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0) return -1; + if (qemuBuildDiskSrcTLSx509CommandLine(cmd, disk->src, disk->info.alias, + qemuCaps) < 0) + return -1; + virCommandAddArg(cmd, "-drive"); if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps))) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4913e18e69..b77731df08 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -155,6 +155,46 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver, } +static int +qemuDomainAddDiskSrcTLSObject(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virStorageSourcePtr src, + const char *srcalias) +{ + int ret = -1; + qemuDomainObjPrivatePtr priv = vm->privateData; + virJSONValuePtr tlsProps = NULL; + + if (qemuDomainGetTLSObjects(priv->qemuCaps, NULL, + src->tlsCertdir, + false, + src->tlsVerify, + srcalias, &tlsProps, &src->tlsAlias, + NULL, NULL) < 0) + goto cleanup; + + if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, + NULL, NULL, src->tlsAlias, &tlsProps) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virJSONValueFree(tlsProps); + + return ret; +} + + +static void +qemuDomainDelDiskSrcTLSObject(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virStorageSourcePtr src) +{ + qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL, src->tlsAlias); +} + + static int qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -376,6 +416,14 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0) goto error; + if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0) + goto error; + + if (disk->src->haveTLS && + qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src, + disk->info.alias) < 0) + goto error; + if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps))) goto error; @@ -453,6 +501,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, virDomainAuditDisk(vm, NULL, disk->src, "attach", false); error: + qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src); + if (releaseaddr) qemuDomainReleaseDeviceAddress(vm, &disk->info, src); @@ -667,6 +717,14 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) goto error; + if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0) + goto error; + + if (disk->src->haveTLS && + qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src, + disk->info.alias) < 0) + goto error; + if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps))) goto error; @@ -737,6 +795,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, virDomainAuditDisk(vm, NULL, disk->src, "attach", false); error: + qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src); + ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true)); goto cleanup; } @@ -777,6 +837,14 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver, if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; + if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0) + goto error; + + if (disk->src->haveTLS && + qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src, + disk->info.alias) < 0) + goto error; + if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps))) goto error; @@ -827,6 +895,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver, virDomainAuditDisk(vm, NULL, disk->src, "attach", false); error: + qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src); + ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true)); goto cleanup; } @@ -3679,6 +3749,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ignore_value(qemuMonitorDelObject(priv->mon, encAlias)); VIR_FREE(encAlias); + if (disk->src->haveTLS) + ignore_value(qemuMonitorDelObject(priv->mon, disk->src->tlsAlias)); + if (qemuDomainObjExitMonitor(driver, vm) < 0) return -1; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args new file mode 100644 index 0000000000..572c9f36ca --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args @@ -0,0 +1,43 @@ +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 \ +-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\ +endpoint=client,verify-peer=yes \ +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\ +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 \ +-object tls-creds-x509,id=objvirtio-disk1_tls0,dir=/etc/pki/qemu,\ +endpoint=client,verify-peer=yes \ +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk1_tls0,\ +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc252,file.server.type=tcp,\ +file.server.host=192.168.0.2,file.server.port=9999,format=raw,if=none,\ +id=drive-virtio-disk1,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\ +id=virtio-disk1 \ +-drive file.driver=vxhs,file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc253,\ +file.server.type=tcp,file.server.host=192.168.0.3,file.server.port=9999,\ +format=raw,if=none,id=drive-virtio-disk2,cache=none \ +-device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\ +id=virtio-disk2 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.xml index 61b5e2e791..a66e81f065 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.xml @@ -16,13 +16,31 @@ /usr/bin/qemu-system-x86_64 - + eb90327c-8302-4725-9e1b-4e85ed4dc251
+ + + + + + + eb90327c-8302-4725-9e1b-4e85ed4dc252 +
+ + + + + + + + eb90327c-8302-4725-9e1b-4e85ed4dc252 +
+ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 70be0c32d0..1958ad4282 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -942,6 +942,11 @@ mymain(void) 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); + driver.config->vxhsTLS = 1; + DO_TEST("disk-drive-network-tlsx509-vxhs", QEMU_CAPS_VXHS, + QEMU_CAPS_OBJECT_TLS_CREDS_X509); + driver.config->vxhsTLS = 0; + VIR_FREE(driver.config->vxhsTLSx509certdir); DO_TEST("disk-drive-no-boot", QEMU_CAPS_BOOTINDEX); DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid", diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-network-tlsx509-vxhs.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-network-tlsx509-vxhs.xml index 16f0883e04..7053affd17 100644 --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-network-tlsx509-vxhs.xml +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-network-tlsx509-vxhs.xml @@ -16,13 +16,31 @@ /usr/bin/qemu-system-x86_64 - + eb90327c-8302-4725-9e1b-4e85ed4dc251
+ + + + + + + eb90327c-8302-4725-9e1b-4e85ed4dc252 +
+ + + + + + + + eb90327c-8302-4725-9e1b-4e85ed4dc252 +
+