]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Implement qemuDomainFDAssociate
authorPeter Krempa <pkrempa@redhat.com>
Thu, 24 Mar 2022 14:50:27 +0000 (15:50 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 9 Jan 2023 13:59:42 +0000 (14:59 +0100)
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>
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c

index 7be431dd19289e56ed4748be5a1b10bc0307b077..2d8ff652b0d29b4dc00250f03f6933bfbf1a9292 100644 (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;
index 4b0593d5db7041330eea0f7188bf051c97b19c53..69b7e7da5d93c80b84673ebae77ec4434abba17a 100644 (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) \
index d9f7ce234e6a89bccfaa8299075e82d14c08379b..0a98551f8a3331019c10b9ed95b6a3d578d9eb95 100644 (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 */
 };