qemu: Implement qemuDomainFDAssociate

Implement passing and storage of FDs for the qemu driver. The FD tuples
are g_object instances stored in a per-domain hash table and are
automatically removed once the connection is closed.

In the future we can consider supporting also to not tie the lifetime of
the passed FDs bound to the connection.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Peter Krempa 2022-03-24 15:50:27 +01:00
parent e2670a63d2
commit f762f87534
3 changed files with 72 additions and 0 deletions

View File

@ -1869,6 +1869,7 @@ qemuDomainObjPrivateFree(void *data)
qemuDomainMasterKeyFree(priv);
g_clear_pointer(&priv->blockjobs, g_hash_table_unref);
g_clear_pointer(&priv->fds, g_hash_table_unref);
/* This should never be non-NULL if we get here, but just in case... */
if (priv->eventThread) {
@ -1896,6 +1897,7 @@ qemuDomainObjPrivateAlloc(void *opaque)
return NULL;
priv->blockjobs = virHashNew(virObjectUnref);
priv->fds = virHashNew(g_object_unref);
/* agent commands block by default, user can choose different behavior */
priv->agentTimeout = VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK;

View File

@ -253,6 +253,9 @@ struct _qemuDomainObjPrivate {
pid_t schedCoreChildFD;
GSList *threadContextAliases; /* List of IDs of thread-context objects */
/* named file descriptor groups associated with the VM */
GHashTable *fds;
};
#define QEMU_DOMAIN_PRIVATE(vm) \

View File

@ -20379,6 +20379,72 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
}
static void
qemuDomainFDHashCloseConnect(virDomainObj *vm,
virConnectPtr conn)
{
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
virStorageSourceFDTuple *data;
GHashTableIter htitr;
if (!priv->fds)
return;
g_hash_table_iter_init(&htitr, priv->fds);
while (g_hash_table_iter_next(&htitr, NULL, (void **) &data)) {
if (data->conn == conn)
g_hash_table_iter_remove(&htitr);
}
}
static int
qemuDomainFDAssociate(virDomainPtr domain,
const char *name,
unsigned int nfds,
int *fds,
unsigned int flags)
{
virDomainObj *vm = NULL;
qemuDomainObjPrivate *priv;
virStorageSourceFDTuple *new;
int ret = -1;
virCheckFlags(VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_RESTORE |
VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_WRITABLE, -1);
if (nfds == 0)
return 0;
if (!(vm = qemuDomainObjFromDomain(domain)))
return -1;
if (virDomainFdAssociateEnsureACL(domain->conn, vm->def))
goto cleanup;
priv = vm->privateData;
new = virStorageSourceFDTupleNew();
new->fds = fds;
new->nfds = nfds;
new->conn = domain->conn;
new->writable = flags & VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_WRITABLE;
new->tryRestoreLabel = flags & VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_RESTORE;
virCloseCallbacksDomainAdd(vm, domain->conn, qemuDomainFDHashCloseConnect);
g_hash_table_insert(priv->fds, g_strdup(name), new);
ret = 0;
cleanup:
virDomainObjEndAPI(&vm);
return ret;
}
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
.connectURIProbe = qemuConnectURIProbe,
@ -20627,6 +20693,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
.domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
.domainSetLaunchSecurityState = qemuDomainSetLaunchSecurityState, /* 8.0.0 */
.domainFDAssociate = qemuDomainFDAssociate, /* 9.0.0 */
};