diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index aa8f5c4273..7c64c05090 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -50,7 +50,6 @@ #include "secret_conf.h" #include "network/bridge_driver.h" #include "virnetdevtap.h" -#include "secret_util.h" #include "device_conf.h" #include "virstoragefile.h" #include "virtpm.h" @@ -4462,29 +4461,24 @@ qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev) } static char * -qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn, - virDomainHostdevDefPtr dev) +qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr dev) { char *source = NULL; char *secret = NULL; char *username = NULL; virStorageSource src; + qemuDomainHostdevPrivatePtr hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(dev); memset(&src, 0, sizeof(src)); virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi; virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; - if (conn && iscsisrc->auth) { - const char *protocol = - virStorageNetProtocolTypeToString(VIR_STORAGE_NET_PROTOCOL_ISCSI); - bool encode = false; - int secretType = VIR_SECRET_USAGE_TYPE_ISCSI; + if (hostdevPriv->secinfo) { + qemuDomainSecretInfoPtr secinfo = hostdevPriv->secinfo; - username = iscsisrc->auth->username; - if (!(secret = virSecretGetSecretString(conn, protocol, encode, - iscsisrc->auth, secretType))) - goto cleanup; + username = secinfo->s.plain.username; + secret = secinfo->s.plain.secret; } src.protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI; @@ -4495,14 +4489,11 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn, /* Rather than pull what we think we want - use the network disk code */ source = qemuBuildNetworkDriveURI(&src, username, secret); - cleanup: - VIR_FREE(secret); return source; } char * -qemuBuildSCSIHostdevDrvStr(virConnectPtr conn, - virDomainHostdevDefPtr dev, +qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev, virQEMUCapsPtr qemuCaps) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -4510,7 +4501,7 @@ qemuBuildSCSIHostdevDrvStr(virConnectPtr conn, virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi; if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { - if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(conn, dev))) + if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(dev))) goto error; virBufferAsprintf(&buf, "file=%s,if=none,format=raw", source); } else { @@ -4808,7 +4799,6 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, static int qemuBuildHostdevCommandLine(virCommandPtr cmd, - virConnectPtr conn, const virDomainDef *def, virQEMUCapsPtr qemuCaps, unsigned int *bootHostdevNet) @@ -4957,8 +4947,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, char *drvstr; virCommandAddArg(cmd, "-drive"); - if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, hostdev, - qemuCaps))) + if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps))) return -1; virCommandAddArg(cmd, drvstr); VIR_FREE(drvstr); @@ -9197,13 +9186,9 @@ qemuBuildCommandLineValidate(virQEMUDriverPtr driver, /* * Constructs a argv suitable for launching qemu with config defined * for a given virtual machine. - * - * XXX 'conn' is only required to resolve network -> bridge name - * figure out how to remove this requirement some day */ virCommandPtr -qemuBuildCommandLine(virConnectPtr conn, - virQEMUDriverPtr driver, +qemuBuildCommandLine(virQEMUDriverPtr driver, virLogManagerPtr logManager, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, @@ -9228,9 +9213,9 @@ qemuBuildCommandLine(virConnectPtr conn, unsigned int bootHostdevNet = 0; - VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d " + VIR_DEBUG("driver=%p def=%p mon=%p json=%d " "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d", - conn, driver, def, monitor_chr, monitor_json, + driver, def, monitor_chr, monitor_json, qemuCaps, migrateURI, snapshot, vmop); if (qemuBuildCommandLineValidate(driver, def) < 0) @@ -9396,7 +9381,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (qemuBuildRedirdevCommandLine(logManager, cmd, def, qemuCaps) < 0) goto error; - if (qemuBuildHostdevCommandLine(cmd, conn, def, qemuCaps, &bootHostdevNet) < 0) + if (qemuBuildHostdevCommandLine(cmd, def, qemuCaps, &bootHostdevNet) < 0) goto error; if (migrateURI) diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index a7e7b74b5b..d5ad1b2b93 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -48,8 +48,7 @@ char *qemuBuildObjectCommandlineFromJSON(const char *type, const char *alias, virJSONValuePtr props); -virCommandPtr qemuBuildCommandLine(virConnectPtr conn, - virQEMUDriverPtr driver, +virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver, virLogManagerPtr logManager, virDomainDefPtr def, virDomainChrSourceDefPtr monitor_chr, @@ -65,7 +64,7 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn, int **nicindexes, const char *domainLibDir, const char *domainChannelTargetDir) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(16) ATTRIBUTE_NONNULL(17); + ATTRIBUTE_NONNULL(15) ATTRIBUTE_NONNULL(16); /* Generate '-device' string for chardev device */ int @@ -163,8 +162,7 @@ char *qemuBuildUSBHostdevDevStr(const virDomainDef *def, virDomainHostdevDefPtr dev, virQEMUCapsPtr qemuCaps); -char *qemuBuildSCSIHostdevDrvStr(virConnectPtr conn, - virDomainHostdevDefPtr dev, +char *qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev, virQEMUCapsPtr qemuCaps); char *qemuBuildSCSIHostdevDevStr(const virDomainDef *def, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f30597763e..d065edb11e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -932,6 +932,71 @@ qemuDomainSecretDiskPrepare(virConnectPtr conn, } +/* qemuDomainSecretHostdevDestroy: + * @disk: Pointer to a hostdev definition + * + * Clear and destroy memory associated with the secret + */ +void +qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr hostdev) +{ + qemuDomainHostdevPrivatePtr hostdevPriv = + QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + + if (!hostdevPriv->secinfo) + return; + + qemuDomainSecretInfoFree(&hostdevPriv->secinfo); +} + + +/* qemuDomainSecretHostdevPrepare: + * @conn: Pointer to connection + * @hostdev: Pointer to a hostdev definition + * + * For the right host device, generate the qemuDomainSecretInfo structure. + * + * Returns 0 on success, -1 on failure + */ +int +qemuDomainSecretHostdevPrepare(virConnectPtr conn, + virDomainHostdevDefPtr hostdev) +{ + virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; + qemuDomainSecretInfoPtr secinfo = NULL; + + if (conn && hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) { + + virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi; + virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; + + if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI && + iscsisrc->auth) { + + qemuDomainHostdevPrivatePtr hostdevPriv = + QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); + + if (VIR_ALLOC(secinfo) < 0) + return -1; + + if (qemuDomainSecretPlainSetup(conn, secinfo, + VIR_STORAGE_NET_PROTOCOL_ISCSI, + iscsisrc->auth) < 0) + goto error; + + hostdevPriv->secinfo = secinfo; + } + } + + return 0; + + error: + qemuDomainSecretInfoFree(&secinfo); + return -1; +} + + /* qemuDomainSecretDestroy: * @vm: Domain object * @@ -945,6 +1010,9 @@ qemuDomainSecretDestroy(virDomainObjPtr vm) for (i = 0; i < vm->def->ndisks; i++) qemuDomainSecretDiskDestroy(vm->def->disks[i]); + + for (i = 0; i < vm->def->nhostdevs; i++) + qemuDomainSecretHostdevDestroy(vm->def->hostdevs[i]); } @@ -971,6 +1039,11 @@ qemuDomainSecretPrepare(virConnectPtr conn, return -1; } + for (i = 0; i < vm->def->nhostdevs; i++) { + if (qemuDomainSecretHostdevPrepare(conn, vm->def->hostdevs[i]) < 0) + return -1; + } + return 0; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 3cb961b866..63f98ba7cf 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -634,6 +634,13 @@ void qemuDomainSecretDiskDestroy(virDomainDiskDefPtr disk) int qemuDomainSecretDiskPrepare(virConnectPtr conn, virDomainDiskDefPtr disk) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +void qemuDomainSecretHostdevDestroy(virDomainHostdevDefPtr disk) + ATTRIBUTE_NONNULL(1); + +int qemuDomainSecretHostdevPrepare(virConnectPtr conn, + virDomainHostdevDefPtr hostdev) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + void qemuDomainSecretDestroy(virDomainObjPtr vm) ATTRIBUTE_NONNULL(1); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0538c159ea..3d0c7c83a7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7501,8 +7501,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_NET: qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, NULL); - ret = qemuDomainAttachNetDevice(dom->conn, driver, vm, - dev->data.net); + ret = qemuDomainAttachNetDevice(driver, vm, dev->data.net); if (!ret) { alias = dev->data.net->info.alias; dev->data.net = NULL; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 77a65a75c0..3f25ef451a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -796,11 +796,10 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, } -/* XXX conn required for network -> bridge resolution */ -int qemuDomainAttachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainNetDefPtr net) +int +qemuDomainAttachNetDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainNetDefPtr net) { qemuDomainObjPrivatePtr priv = vm->privateData; char **tapfdName = NULL; @@ -839,8 +838,11 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, * as a hostdev (the hostdev code will reach over into the * netdev-specific code as appropriate), then also added to * the nets list (see cleanup:) if successful. + * + * qemuDomainAttachHostDevice uses a connection to resolve + * a SCSI hostdev secret, which is not this case, so pass NULL. */ - ret = qemuDomainAttachHostDevice(conn, driver, vm, + ret = qemuDomainAttachHostDevice(NULL, driver, vm, virDomainNetGetActualHostdev(net)); goto cleanup; } @@ -1859,6 +1861,7 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver, return ret; } + static int qemuDomainAttachHostSCSIDevice(virConnectPtr conn, virQEMUDriverPtr driver, @@ -1914,7 +1917,10 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn, if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0) goto cleanup; - if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, hostdev, priv->qemuCaps))) + if (qemuDomainSecretHostdevPrepare(conn, hostdev) < 0) + goto cleanup; + + if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps))) goto cleanup; if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, hostdev, priv->qemuCaps))) @@ -1950,6 +1956,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn, ret = 0; cleanup: + qemuDomainSecretHostdevDestroy(hostdev); if (ret < 0) { qemuHostdevReAttachSCSIDevices(driver, vm->def->name, &hostdev, 1); if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0) @@ -1964,10 +1971,12 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn, return ret; } -int qemuDomainAttachHostDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev) + +int +qemuDomainAttachHostDevice(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainHostdevDefPtr hostdev) { if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index bcce9e83af..868b4cff5c 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -43,8 +43,7 @@ int qemuDomainAttachDeviceDiskLive(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -int qemuDomainAttachNetDevice(virConnectPtr conn, - virQEMUDriverPtr driver, +int qemuDomainAttachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainNetDefPtr net); int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d966c21ff2..527300aad0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5314,7 +5314,7 @@ qemuProcessLaunch(virConnectPtr conn, logfile = qemuDomainLogContextGetWriteFD(logCtxt); VIR_DEBUG("Building emulator command line"); - if (!(cmd = qemuBuildCommandLine(conn, driver, + if (!(cmd = qemuBuildCommandLine(driver, qemuDomainLogContextGetManager(logCtxt), vm->def, priv->monConfig, priv->monJSON, priv->qemuCaps, @@ -5743,8 +5743,7 @@ qemuProcessCreatePretendCmd(virConnectPtr conn, goto cleanup; VIR_DEBUG("Building emulator command line"); - cmd = qemuBuildCommandLine(conn, - driver, + cmd = qemuBuildCommandLine(driver, NULL, vm->def, priv->monConfig,