qemu: Add secret object hotplug for TCP chardev TLS

https://bugzilla.redhat.com/show_bug.cgi?id=1300776

Complete the implementation of support for TLS encryption on
chardev TCP transports by adding the hotplug ability of a secret
to generate the passwordid for the TLS object for chrdev, RNG,
and redirdev.

Fix up the order of object removal on failure to be the inverse
of the attempted attach (for redirdev, chr, rng) - for each the
tls object was being removed before the chardev backend.

Likewise, add the ability to hot unplug that secret object as well
and be sure the order of unplug matches that inverse order of plug.

Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
John Ferlan 2016-06-17 09:44:30 -04:00
parent daf5c651f0
commit 8550e8585e
4 changed files with 149 additions and 36 deletions

View File

@ -7567,7 +7567,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
break; break;
case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainAttachRedirdevDevice(driver, vm, ret = qemuDomainAttachRedirdevDevice(conn, driver, vm,
dev->data.redirdev); dev->data.redirdev);
if (!ret) { if (!ret) {
alias = dev->data.redirdev->info.alias; alias = dev->data.redirdev->info.alias;
@ -7576,7 +7576,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
break; break;
case VIR_DOMAIN_DEVICE_CHR: case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainAttachChrDevice(driver, vm, ret = qemuDomainAttachChrDevice(conn, driver, vm,
dev->data.chr); dev->data.chr);
if (!ret) { if (!ret) {
alias = dev->data.chr->info.alias; alias = dev->data.chr->info.alias;
@ -7585,7 +7585,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
break; break;
case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_RNG:
ret = qemuDomainAttachRNGDevice(driver, vm, ret = qemuDomainAttachRNGDevice(conn, driver, vm,
dev->data.rng); dev->data.rng);
if (!ret) { if (!ret) {
alias = dev->data.rng->info.alias; alias = dev->data.rng->info.alias;

View File

@ -1480,16 +1480,31 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr cfg,
virDomainChrSourceDefPtr dev, virDomainChrSourceDefPtr dev,
char *charAlias, char *charAlias,
virJSONValuePtr *tlsProps, virJSONValuePtr *tlsProps,
char **tlsAlias) char **tlsAlias,
virJSONValuePtr *secProps,
char **secAlias)
{ {
qemuDomainChrSourcePrivatePtr chrSourcePriv =
QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP || if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES) dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
return 0; return 0;
/* Add a secret object in order to access the TLS environment.
* The secinfo will only be created for serial TCP device. */
if (chrSourcePriv && chrSourcePriv->secinfo) {
if (qemuBuildSecretInfoProps(chrSourcePriv->secinfo, secProps) < 0)
return -1;
if (!(*secAlias = qemuDomainGetSecretAESAlias(charAlias, false)))
return -1;
}
if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir, if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
dev->data.tcp.listen, dev->data.tcp.listen,
cfg->chardevTLSx509verify, cfg->chardevTLSx509verify,
NULL, *secAlias,
priv->qemuCaps, priv->qemuCaps,
tlsProps) < 0) tlsProps) < 0)
return -1; return -1;
@ -1502,7 +1517,8 @@ qemuDomainGetChardevTLSObjects(virQEMUDriverConfigPtr cfg,
} }
int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver, int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRedirdevDefPtr redirdev) virDomainRedirdevDefPtr redirdev)
{ {
@ -1515,8 +1531,11 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
char *devstr = NULL; char *devstr = NULL;
bool chardevAdded = false; bool chardevAdded = false;
bool tlsobjAdded = false; bool tlsobjAdded = false;
bool secobjAdded = false;
virJSONValuePtr tlsProps = NULL; virJSONValuePtr tlsProps = NULL;
virJSONValuePtr secProps = NULL;
char *tlsAlias = NULL; char *tlsAlias = NULL;
char *secAlias = NULL;
virErrorPtr orig_err; virErrorPtr orig_err;
qemuDomainPrepareChardevSourceTLS(redirdev->source, cfg); qemuDomainPrepareChardevSourceTLS(redirdev->source, cfg);
@ -1533,11 +1552,26 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
if (VIR_REALLOC_N(def->redirdevs, def->nredirdevs+1) < 0) if (VIR_REALLOC_N(def->redirdevs, def->nredirdevs+1) < 0)
goto cleanup; goto cleanup;
if (qemuDomainSecretChardevPrepare(conn, cfg, priv, redirdev->info.alias,
redirdev->source) < 0)
goto cleanup;
if (qemuDomainGetChardevTLSObjects(cfg, priv, redirdev->source, if (qemuDomainGetChardevTLSObjects(cfg, priv, redirdev->source,
charAlias, &tlsProps, &tlsAlias) < 0) charAlias, &tlsProps, &tlsAlias,
&secProps, &secAlias) < 0)
goto cleanup; goto cleanup;
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (secAlias) {
rc = qemuMonitorAddObject(priv->mon, "secret",
secAlias, secProps);
secProps = NULL;
if (rc < 0)
goto exit_monitor;
secobjAdded = true;
}
if (tlsAlias) { if (tlsAlias) {
rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509", rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
tlsAlias, tlsProps); tlsAlias, tlsProps);
@ -1566,6 +1600,8 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
cleanup: cleanup:
VIR_FREE(tlsAlias); VIR_FREE(tlsAlias);
virJSONValueFree(tlsProps); virJSONValueFree(tlsProps);
VIR_FREE(secAlias);
virJSONValueFree(secProps);
VIR_FREE(charAlias); VIR_FREE(charAlias);
VIR_FREE(devstr); VIR_FREE(devstr);
virObjectUnref(cfg); virObjectUnref(cfg);
@ -1573,11 +1609,13 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
exit_monitor: exit_monitor:
orig_err = virSaveLastError(); orig_err = virSaveLastError();
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
/* detach associated chardev on error */ /* detach associated chardev on error */
if (chardevAdded) if (chardevAdded)
ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (secobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
if (orig_err) { if (orig_err) {
virSetError(orig_err); virSetError(orig_err);
virFreeError(orig_err); virFreeError(orig_err);
@ -1753,7 +1791,8 @@ qemuDomainAttachChrDeviceAssignAddr(virDomainObjPtr vm,
return ret; return ret;
} }
int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, int qemuDomainAttachChrDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainChrDefPtr chr) virDomainChrDefPtr chr)
{ {
@ -1767,8 +1806,11 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
char *charAlias = NULL; char *charAlias = NULL;
bool chardevAttached = false; bool chardevAttached = false;
bool tlsobjAdded = false; bool tlsobjAdded = false;
bool secobjAdded = false;
virJSONValuePtr tlsProps = NULL; virJSONValuePtr tlsProps = NULL;
char *tlsAlias = NULL; char *tlsAlias = NULL;
virJSONValuePtr secProps = NULL;
char *secAlias = NULL;
bool need_release = false; bool need_release = false;
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
@ -1794,11 +1836,25 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
if (qemuDomainChrPreInsert(vmdef, chr) < 0) if (qemuDomainChrPreInsert(vmdef, chr) < 0)
goto cleanup; goto cleanup;
if (qemuDomainSecretChardevPrepare(conn, cfg, priv, chr->info.alias,
dev) < 0)
goto cleanup;
if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias, if (qemuDomainGetChardevTLSObjects(cfg, priv, dev, charAlias,
&tlsProps, &tlsAlias) < 0) &tlsProps, &tlsAlias,
&secProps, &secAlias) < 0)
goto cleanup; goto cleanup;
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (secAlias) {
rc = qemuMonitorAddObject(priv->mon, "secret",
secAlias, secProps);
secProps = NULL;
if (rc < 0)
goto exit_monitor;
secobjAdded = true;
}
if (tlsAlias) { if (tlsAlias) {
rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509", rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
tlsAlias, tlsProps); tlsAlias, tlsProps);
@ -1829,6 +1885,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL); qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
VIR_FREE(tlsAlias); VIR_FREE(tlsAlias);
virJSONValueFree(tlsProps); virJSONValueFree(tlsProps);
VIR_FREE(secAlias);
virJSONValueFree(secProps);
VIR_FREE(charAlias); VIR_FREE(charAlias);
VIR_FREE(devstr); VIR_FREE(devstr);
virObjectUnref(cfg); virObjectUnref(cfg);
@ -1836,11 +1894,13 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
exit_monitor: exit_monitor:
orig_err = virSaveLastError(); orig_err = virSaveLastError();
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
/* detach associated chardev on error */ /* detach associated chardev on error */
if (chardevAttached) if (chardevAttached)
qemuMonitorDetachCharDev(priv->mon, charAlias); qemuMonitorDetachCharDev(priv->mon, charAlias);
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (secobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
if (orig_err) { if (orig_err) {
virSetError(orig_err); virSetError(orig_err);
virFreeError(orig_err); virFreeError(orig_err);
@ -1852,7 +1912,8 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
int int
qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, qemuDomainAttachRNGDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng) virDomainRNGDefPtr rng)
{ {
@ -1863,12 +1924,15 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
char *charAlias = NULL; char *charAlias = NULL;
char *objAlias = NULL; char *objAlias = NULL;
char *tlsAlias = NULL; char *tlsAlias = NULL;
char *secAlias = NULL;
bool releaseaddr = false; bool releaseaddr = false;
bool chardevAdded = false; bool chardevAdded = false;
bool objAdded = false; bool objAdded = false;
bool tlsobjAdded = false; bool tlsobjAdded = false;
bool secobjAdded = false;
virJSONValuePtr props = NULL; virJSONValuePtr props = NULL;
virJSONValuePtr tlsProps = NULL; virJSONValuePtr tlsProps = NULL;
virJSONValuePtr secProps = NULL;
virDomainCCWAddressSetPtr ccwaddrs = NULL; virDomainCCWAddressSetPtr ccwaddrs = NULL;
const char *type; const char *type;
int ret = -1; int ret = -1;
@ -1923,13 +1987,28 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias))) if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias)))
goto cleanup; goto cleanup;
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) {
qemuDomainGetChardevTLSObjects(cfg, priv, rng->source.chardev, if (qemuDomainSecretChardevPrepare(conn, cfg, priv, rng->info.alias,
charAlias, &tlsProps, &tlsAlias) < 0) rng->source.chardev) < 0)
goto cleanup; goto cleanup;
if (qemuDomainGetChardevTLSObjects(cfg, priv, rng->source.chardev,
charAlias, &tlsProps, &tlsAlias,
&secProps, &secAlias) < 0)
goto cleanup;
}
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (secAlias) {
rv = qemuMonitorAddObject(priv->mon, "secret",
secAlias, secProps);
secProps = NULL;
if (rv < 0)
goto exit_monitor;
secobjAdded = true;
}
if (tlsAlias) { if (tlsAlias) {
rv = qemuMonitorAddObject(priv->mon, "tls-creds-x509", rv = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
tlsAlias, tlsProps); tlsAlias, tlsProps);
@ -1967,10 +2046,12 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0); virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0);
cleanup: cleanup:
virJSONValueFree(tlsProps); virJSONValueFree(tlsProps);
virJSONValueFree(secProps);
virJSONValueFree(props); virJSONValueFree(props);
if (ret < 0 && releaseaddr) if (ret < 0 && releaseaddr)
qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL); qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
VIR_FREE(tlsAlias); VIR_FREE(tlsAlias);
VIR_FREE(secAlias);
VIR_FREE(charAlias); VIR_FREE(charAlias);
VIR_FREE(objAlias); VIR_FREE(objAlias);
VIR_FREE(devstr); VIR_FREE(devstr);
@ -1980,12 +2061,14 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
exit_monitor: exit_monitor:
orig_err = virSaveLastError(); orig_err = virSaveLastError();
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (objAdded) if (objAdded)
ignore_value(qemuMonitorDelObject(priv->mon, objAlias)); ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && chardevAdded) if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && chardevAdded)
ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
if (tlsobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (secobjAdded)
ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
if (orig_err) { if (orig_err) {
virSetError(orig_err); virSetError(orig_err);
virFreeError(orig_err); virFreeError(orig_err);
@ -3554,6 +3637,7 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
char *charAlias = NULL; char *charAlias = NULL;
char *tlsAlias = NULL; char *tlsAlias = NULL;
char *secAlias = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1; int ret = -1;
int rc; int rc;
@ -3565,15 +3649,29 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
if (chr->source->type == VIR_DOMAIN_CHR_TYPE_TCP && if (chr->source->type == VIR_DOMAIN_CHR_TYPE_TCP &&
chr->source->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES && chr->source->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES) {
!(tlsAlias = qemuAliasTLSObjFromChardevAlias(charAlias)))
goto cleanup; if (!(tlsAlias = qemuAliasTLSObjFromChardevAlias(charAlias)))
goto cleanup;
/* Best shot at this as the secinfo is destroyed after process launch
* and this path does not recreate it. Thus, if the config has the
* secret UUID and we have a serial TCP chardev, then formulate a
* secAlias which we'll attempt to destroy. */
if (cfg->chardevTLSx509secretUUID &&
!(secAlias = qemuDomainGetSecretAESAlias(charAlias, false)))
goto cleanup;
}
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorDetachCharDev(priv->mon, charAlias); rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
if (tlsAlias && qemuMonitorDelObject(priv->mon, tlsAlias) < 0) if (rc == 0) {
goto exit_monitor; if (tlsAlias)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (secAlias)
ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
}
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup; goto cleanup;
@ -3593,12 +3691,9 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
cleanup: cleanup:
VIR_FREE(charAlias); VIR_FREE(charAlias);
VIR_FREE(tlsAlias); VIR_FREE(tlsAlias);
VIR_FREE(secAlias);
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;
exit_monitor:
ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto cleanup;
} }
@ -3608,9 +3703,11 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
virDomainRNGDefPtr rng) virDomainRNGDefPtr rng)
{ {
virObjectEventPtr event; virObjectEventPtr event;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
char *charAlias = NULL; char *charAlias = NULL;
char *objAlias = NULL; char *objAlias = NULL;
char *tlsAlias = NULL; char *tlsAlias = NULL;
char *secAlias = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
ssize_t idx; ssize_t idx;
int ret = -1; int ret = -1;
@ -3626,9 +3723,18 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias))) if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias)))
goto cleanup; goto cleanup;
if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) {
!(tlsAlias = qemuAliasTLSObjFromChardevAlias(charAlias))) if (!(tlsAlias = qemuAliasTLSObjFromChardevAlias(charAlias)))
goto cleanup; goto cleanup;
/* Best shot at this as the secinfo is destroyed after process launch
* and this path does not recreate it. Thus, if the config has the
* secret UUID and we have a serial TCP chardev, then formulate a
* secAlias which we'll attempt to destroy. */
if (cfg->chardevTLSx509secretUUID &&
!(secAlias = qemuDomainGetSecretAESAlias(charAlias, false)))
goto cleanup;
}
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
@ -3638,6 +3744,8 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
if (tlsAlias) if (tlsAlias)
ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias)); ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
if (secAlias)
ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
} }
if (qemuDomainObjExitMonitor(driver, vm) < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
@ -3661,6 +3769,8 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
VIR_FREE(charAlias); VIR_FREE(charAlias);
VIR_FREE(objAlias); VIR_FREE(objAlias);
VIR_FREE(tlsAlias); VIR_FREE(tlsAlias);
VIR_FREE(secAlias);
virObjectUnref(cfg);
return ret; return ret;
} }

View File

@ -43,7 +43,8 @@ int qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
int qemuDomainAttachNetDevice(virQEMUDriverPtr driver, int qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainNetDefPtr net); virDomainNetDefPtr net);
int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver, int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRedirdevDefPtr hostdev); virDomainRedirdevDefPtr hostdev);
int qemuDomainAttachHostDevice(virConnectPtr conn, int qemuDomainAttachHostDevice(virConnectPtr conn,
@ -92,13 +93,15 @@ int qemuDomainAttachLease(virQEMUDriverPtr driver,
int qemuDomainDetachLease(virQEMUDriverPtr driver, int qemuDomainDetachLease(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainLeaseDefPtr lease); virDomainLeaseDefPtr lease);
int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, int qemuDomainAttachChrDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainChrDefPtr chr); virDomainChrDefPtr chr);
int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainChrDefPtr chr); virDomainChrDefPtr chr);
int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, int qemuDomainAttachRNGDevice(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng); virDomainRNGDefPtr rng);
int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,

View File

@ -118,7 +118,7 @@ testQemuHotplugAttach(virDomainObjPtr vm,
ret = qemuDomainAttachDeviceDiskLive(NULL, &driver, vm, dev); ret = qemuDomainAttachDeviceDiskLive(NULL, &driver, vm, dev);
break; break;
case VIR_DOMAIN_DEVICE_CHR: case VIR_DOMAIN_DEVICE_CHR:
ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr); ret = qemuDomainAttachChrDevice(NULL, &driver, vm, dev->data.chr);
break; break;
default: default:
VIR_TEST_VERBOSE("device type '%s' cannot be attached\n", VIR_TEST_VERBOSE("device type '%s' cannot be attached\n",