mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
qemu: Add the ability to hotplug the TLS X.509 environment
If the incoming XML defined a path to a TLS X.509 certificate environment, add the necessary 'tls-creds-x509' object to the VIR_DOMAIN_CHR_TYPE_TCP character device. Likewise, if the environment exists the hot unplug needs adjustment as well. Note that all the return ret were changed to goto cleanup since the cfg needs to be unref'd Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
ce61c16450
commit
2c3223785c
@ -1091,6 +1091,7 @@ struct _virDomainChrSourceDef {
|
|||||||
char *service;
|
char *service;
|
||||||
bool listen;
|
bool listen;
|
||||||
int protocol;
|
int protocol;
|
||||||
|
bool tlscreds;
|
||||||
} tcp;
|
} tcp;
|
||||||
struct {
|
struct {
|
||||||
char *bindHost;
|
char *bindHost;
|
||||||
|
@ -690,7 +690,7 @@ qemuBuildRBDSecinfoURI(virBufferPtr buf,
|
|||||||
*
|
*
|
||||||
* Returns 0 on success, -1 on failure with error set.
|
* Returns 0 on success, -1 on failure with error set.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
qemuBuildTLSx509BackendProps(const char *tlspath,
|
qemuBuildTLSx509BackendProps(const char *tlspath,
|
||||||
bool listen,
|
bool listen,
|
||||||
bool verifypeer,
|
bool verifypeer,
|
||||||
|
@ -60,10 +60,18 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
|
|||||||
const char *domainLibDir)
|
const char *domainLibDir)
|
||||||
ATTRIBUTE_NONNULL(15);
|
ATTRIBUTE_NONNULL(15);
|
||||||
|
|
||||||
|
|
||||||
/* Generate the object properties for a secret */
|
/* Generate the object properties for a secret */
|
||||||
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
|
||||||
virJSONValuePtr *propsret);
|
virJSONValuePtr *propsret);
|
||||||
|
|
||||||
|
/* Generate the object properties for a tls-creds-x509 */
|
||||||
|
int qemuBuildTLSx509BackendProps(const char *tlspath,
|
||||||
|
bool listen,
|
||||||
|
bool verifypeer,
|
||||||
|
virQEMUCapsPtr qemuCaps,
|
||||||
|
virJSONValuePtr *propsret);
|
||||||
|
|
||||||
/* Generate '-device' string for chardev device */
|
/* Generate '-device' string for chardev device */
|
||||||
int
|
int
|
||||||
qemuBuildChrDeviceStr(char **deviceStr,
|
qemuBuildChrDeviceStr(char **deviceStr,
|
||||||
|
@ -1644,12 +1644,17 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainChrDefPtr chr)
|
virDomainChrDefPtr chr)
|
||||||
{
|
{
|
||||||
int ret = -1, rc;
|
int ret = -1, rc;
|
||||||
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virErrorPtr orig_err;
|
virErrorPtr orig_err;
|
||||||
virDomainDefPtr vmdef = vm->def;
|
virDomainDefPtr vmdef = vm->def;
|
||||||
char *devstr = NULL;
|
char *devstr = NULL;
|
||||||
|
virDomainChrSourceDefPtr dev = &chr->source;
|
||||||
char *charAlias = NULL;
|
char *charAlias = NULL;
|
||||||
bool chardevAttached = false;
|
bool chardevAttached = false;
|
||||||
|
bool tlsobjAdded = false;
|
||||||
|
virJSONValuePtr tlsProps = NULL;
|
||||||
|
char *tlsAlias = 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 &&
|
||||||
@ -1673,7 +1678,29 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
|
|||||||
if (qemuDomainChrPreInsert(vmdef, chr) < 0)
|
if (qemuDomainChrPreInsert(vmdef, chr) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (cfg->chardevTLS) {
|
||||||
|
if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
|
||||||
|
dev->data.tcp.listen,
|
||||||
|
cfg->chardevTLSx509verify,
|
||||||
|
priv->qemuCaps,
|
||||||
|
&tlsProps) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(tlsAlias = qemuAliasTLSObjFromChardevAlias(chr->info.alias)))
|
||||||
|
goto cleanup;
|
||||||
|
dev->data.tcp.tlscreds = true;
|
||||||
|
}
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
|
if (tlsAlias) {
|
||||||
|
rc = qemuMonitorAddObject(priv->mon, "tls-creds-x509",
|
||||||
|
tlsAlias, tlsProps);
|
||||||
|
tlsProps = NULL; /* qemuMonitorAddObject consumes */
|
||||||
|
if (rc < 0)
|
||||||
|
goto exit_monitor;
|
||||||
|
tlsobjAdded = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0)
|
if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0)
|
||||||
goto exit_monitor;
|
goto exit_monitor;
|
||||||
chardevAttached = true;
|
chardevAttached = true;
|
||||||
@ -1693,12 +1720,17 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
|
|||||||
qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
|
qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
|
||||||
if (ret < 0 && need_release)
|
if (ret < 0 && need_release)
|
||||||
qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
|
qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
|
||||||
|
VIR_FREE(tlsAlias);
|
||||||
|
virJSONValueFree(tlsProps);
|
||||||
VIR_FREE(charAlias);
|
VIR_FREE(charAlias);
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
|
virObjectUnref(cfg);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
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);
|
||||||
@ -4281,32 +4313,40 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainChrDefPtr chr)
|
virDomainChrDefPtr chr)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
virDomainDefPtr vmdef = vm->def;
|
virDomainDefPtr vmdef = vm->def;
|
||||||
virDomainChrDefPtr tmpChr;
|
virDomainChrDefPtr tmpChr;
|
||||||
|
char *objAlias = NULL;
|
||||||
char *devstr = NULL;
|
char *devstr = NULL;
|
||||||
|
|
||||||
if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
|
if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
_("device not present in domain configuration"));
|
_("device not present in domain configuration"));
|
||||||
return ret;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tmpChr->info.alias && qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0)
|
if (!tmpChr->info.alias && qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0)
|
||||||
return ret;
|
goto cleanup;
|
||||||
|
|
||||||
sa_assert(tmpChr->info.alias);
|
sa_assert(tmpChr->info.alias);
|
||||||
|
|
||||||
|
if (cfg->chardevTLS &&
|
||||||
|
!(objAlias = qemuAliasTLSObjFromChardevAlias(tmpChr->info.alias)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
|
if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
|
||||||
return ret;
|
goto cleanup;
|
||||||
|
|
||||||
qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
|
qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
|
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0)
|
||||||
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
goto exit_monitor;
|
||||||
goto cleanup;
|
|
||||||
}
|
if (objAlias && qemuMonitorDelObject(priv->mon, objAlias) < 0)
|
||||||
|
goto exit_monitor;
|
||||||
|
|
||||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -4318,7 +4358,12 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|||||||
cleanup:
|
cleanup:
|
||||||
qemuDomainResetDeviceRemoval(vm);
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
|
virObjectUnref(cfg);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
exit_monitor:
|
||||||
|
ignore_value(qemuDomainObjExitMonitor(driver, vm));
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6155,6 +6155,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
|
|||||||
virJSONValuePtr data = NULL;
|
virJSONValuePtr data = NULL;
|
||||||
virJSONValuePtr addr = NULL;
|
virJSONValuePtr addr = NULL;
|
||||||
const char *backend_type = NULL;
|
const char *backend_type = NULL;
|
||||||
|
char *tlsalias = NULL;
|
||||||
bool telnet;
|
bool telnet;
|
||||||
|
|
||||||
if (!(backend = virJSONValueNewObject()) ||
|
if (!(backend = virJSONValueNewObject()) ||
|
||||||
@ -6200,6 +6201,13 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
|
|||||||
virJSONValueObjectAppendBoolean(data, "telnet", telnet) < 0 ||
|
virJSONValueObjectAppendBoolean(data, "telnet", telnet) < 0 ||
|
||||||
virJSONValueObjectAppendBoolean(data, "server", chr->data.tcp.listen) < 0)
|
virJSONValueObjectAppendBoolean(data, "server", chr->data.tcp.listen) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
if (chr->data.tcp.tlscreds) {
|
||||||
|
if (!(tlsalias = qemuAliasTLSObjFromChardevAlias(chrID)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueObjectAppendString(data, "tls-creds", tlsalias) < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_UDP:
|
case VIR_DOMAIN_CHR_TYPE_UDP:
|
||||||
@ -6265,6 +6273,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
VIR_FREE(tlsalias);
|
||||||
virJSONValueFree(addr);
|
virJSONValueFree(addr);
|
||||||
virJSONValueFree(data);
|
virJSONValueFree(data);
|
||||||
virJSONValueFree(backend);
|
virJSONValueFree(backend);
|
||||||
|
Loading…
Reference in New Issue
Block a user