return NULL;
}
+ if (src->fdtuple)
+ def->fdtuple = g_object_ref(src->fdtuple);
+
/* ssh config passthrough for libguestfs */
def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled;
def->ssh_user = g_strdup(src->ssh_user);
virStorageSourceInitiatorClear(&def->initiator);
+ g_clear_pointer(&def->fdtuple, g_object_unref);
+
/* clear everything except the class header as the object APIs
* will break otherwise */
memset((char *) def + sizeof(def->parent), 0,
g_clear_pointer(&priv->encinfo, qemuDomainSecretInfoFree);
g_clear_pointer(&priv->httpcookie, qemuDomainSecretInfoFree);
g_clear_pointer(&priv->tlsKeySecret, qemuDomainSecretInfoFree);
+ g_clear_pointer(&priv->fdpass, qemuFDPassFree);
}
}
+static int
+qemuDomainPrepareStorageSourceFDs(virStorageSource *src,
+ qemuDomainObjPrivate *priv)
+{
+ qemuDomainStorageSourcePrivate *srcpriv = NULL;
+ virStorageType actualType = virStorageSourceGetActualType(src);
+ virStorageSourceFDTuple *fdt = NULL;
+ size_t i;
+
+ if (actualType != VIR_STORAGE_TYPE_FILE &&
+ actualType != VIR_STORAGE_TYPE_BLOCK)
+ return 0;
+
+ if (!virStorageSourceIsFD(src))
+ return 0;
+
+ if (!(fdt = virHashLookup(priv->fds, src->fdgroup))) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("file descriptor group '%s' was not associated with the domain"),
+ src->fdgroup);
+ return -1;
+ }
+
+ srcpriv = qemuDomainStorageSourcePrivateFetch(src);
+
+ srcpriv->fdpass = qemuFDPassNew(src->nodestorage, priv);
+
+ for (i = 0; i < fdt->nfds; i++) {
+ g_autofree char *idx = g_strdup_printf("%zu", i);
+ int tmpfd;
+
+ if (fdt->testfds) {
+ /* when testing we want to use stable FD numbers provided by the test
+ * case */
+ tmpfd = dup2(fdt->fds[i], fdt->testfds[i]);
+ } else {
+ tmpfd = dup(fdt->fds[i]);
+ }
+
+ if (tmpfd < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to duplicate file descriptor for fd group '%s'"),
+ src->fdgroup);
+ return -1;
+ }
+
+ qemuFDPassAddFD(srcpriv->fdpass, &tmpfd, idx);
+ }
+
+ src->fdtuple = g_object_ref(fdt);
+
+ return 0;
+}
+
+
int
qemuDomainPrepareStorageSourceBlockdevNodename(virDomainDiskDef *disk,
virStorageSource *src,
if (qemuDomainPrepareStorageSourceNFS(src) < 0)
return -1;
+ if (qemuDomainPrepareStorageSourceFDs(src, priv) < 0)
+ return -1;
+
return 0;
}
}
+/**
+ * qemuDomainCleanupStorageSourceFD:
+ * @src: start of the chain to clear
+ *
+ * Cleans up the backing chain starting at @src of FD tuple structures for
+ * all FD-tuples which didn't request explicit relabelling and thus the struct
+ * is no longer needed.
+ */
+void
+qemuDomainCleanupStorageSourceFD(virStorageSource *src)
+{
+ virStorageSource *n;
+
+ for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
+ if (virStorageSourceIsFD(n) && n->fdtuple) {
+ if (!n->fdtuple->tryRestoreLabel)
+ g_clear_pointer(&n->fdtuple, g_object_unref);
+ }
+ }
+}
+
+
/**
* qemuDomainStartupCleanup:
*
void
qemuDomainStartupCleanup(virDomainObj *vm)
{
+ size_t i;
+
qemuDomainSecretDestroy(vm);
+
+ for (i = 0; i < vm->def->ndisks; i++)
+ qemuDomainCleanupStorageSourceFD(vm->def->disks[i]->src);
}