int seconds,
unsigned int flags);
+
+/**
+ * virDomainFDAssociateFlags:
+ *
+ * Since: 9.0.0
+ */
+typedef enum {
+ /* Attempt a best-effort restore of security labels after use (Since: 9.0.0) */
+ VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_RESTORE = (1 << 0),
+ /* Use a seclabel allowing writes for the FD even if usage implies read-only mode (Since: 9.0.0) */
+ VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_WRITABLE = (1 << 1),
+} virDomainFDAssociateFlags;
+
+
+int virDomainFDAssociate(virDomainPtr domain,
+ const char *name,
+ unsigned int nfds,
+ int *fds,
+ unsigned int flags);
+
#endif /* LIBVIRT_DOMAIN_H */
int seconds,
unsigned int flags);
+typedef int
+(*virDrvDomainFDAssociate)(virDomainPtr domain,
+ const char *name,
+ unsigned int nfds,
+ int *fds,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
/**
virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet;
virDrvDomainGetMessages domainGetMessages;
virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
+ virDrvDomainFDAssociate domainFDAssociate;
};
virDispatchError(conn);
return -1;
}
+
+
+/**
+ * virDomainFDAssociate:
+ * @domain: a domain object
+ * @name: name for the file descriptor group
+ * @nfds: number of fds in @fds
+ * @fds: file descriptors to associate with domain
+ * @flags: optional flags; bitwise-OR of supported virDomainFDAssociateFlags
+ *
+ * Associate the FDs in @fd with @domain under @name. The FDs are associated as
+ * long as the connection used to associated exists and are disposed of
+ * afterwards. FD may still be kept open by the hypervisor for as long as it's
+ * needed.
+ *
+ * Security labelling (e.g. via the selinux) may be applied on the passed FDs
+ * when required for usage by the VM. By default libvirt does not restore the
+ * seclabels on the FDs afterwards to avoid keeping it open unnecessarily.
+ *
+ * Restoring of the security label can be requested by passing either
+ * VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_RESTORE for a best-effort attempt to restore
+ * the security label after use.
+ * Requesting the restore of security label will require that the file
+ * descriptors are kept open for the whole time they are used by the hypervisor,
+ * or other additional overhead.
+ *
+ * In certain cases usage of the fd group would imply read-only access. Passing
+ * VIR_DOMAIN_FD_ASSOCIATE_SECLABEL_WRITABLE in @flags ensures that a writable
+ * security label is picked in case when the file represented by the fds may
+ * be used in write mode.
+ *
+ * Returns 0 on success, -1 on error.
+ *
+ * Since: 9.0.0
+ */
+int
+virDomainFDAssociate(virDomainPtr domain,
+ const char *name,
+ unsigned int nfds,
+ int *fds,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ int rc;
+
+ VIR_DOMAIN_DEBUG(domain,
+ "name='%s', nfds=%u, fds=%p, flags=0x%x",
+ name, nfds, fds, flags);
+
+ virResetLastError();
+
+ conn = domain->conn;
+
+ if ((rc = VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn, VIR_DRV_FEATURE_FD_PASSING)) < 0)
+ goto error;
+
+ if (rc == 0) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("fd passing is not supported by this connection"));
+ goto error;
+ }
+
+ virCheckNonZeroArgGoto(nfds, error);
+ virCheckNonNullArgGoto(fds, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (!conn->driver->domainFDAssociate) {
+ virReportUnsupportedError();
+ goto error;
+ }
+
+ if ((rc = conn->driver->domainFDAssociate(domain, name, nfds, fds, flags)) < 0)
+ goto error;
+
+ return rc;
+
+ error:
+ virDispatchError(conn);
+ return -1;
+}
virDomainAbortJobFlags;
} LIBVIRT_8.4.0;
+LIBVIRT_9.0.0 {
+ global:
+ virDomainFDAssociate;
+} LIBVIRT_8.5.0;
+
# .... define new API here using predicted next version number ....
return rv;
}
+
+
+static int
+remoteDispatchDomainFdAssociate(virNetServer *server G_GNUC_UNUSED,
+ virNetServerClient *client,
+ virNetMessage *msg,
+ struct virNetMessageError *rerr,
+ remote_domain_fd_associate_args *args)
+{
+ virDomainPtr dom = NULL;
+ int *fds = NULL;
+ unsigned int nfds = 0;
+ int rv = -1;
+ virConnectPtr conn = remoteGetHypervisorConn(client);
+ size_t i;
+
+ if (!conn)
+ goto cleanup;
+
+ if (!(dom = get_nonnull_domain(conn, args->dom)))
+ goto cleanup;
+
+ fds = g_new0(int, msg->nfds);
+ for (i = 0; i < msg->nfds; i++) {
+ if ((fds[i] = virNetMessageDupFD(msg, i)) < 0)
+ goto cleanup;
+ nfds++;
+ }
+
+ if (virDomainFDAssociate(dom, args->name, nfds, fds, args->flags) < 0)
+ goto cleanup;
+
+ rv = 0;
+
+ cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ virObjectUnref(dom);
+ return rv;
+}
return rv;
}
+
+static int
+remoteDomainFDAssociate(virDomainPtr domain,
+ const char *name,
+ unsigned int nfds,
+ int *fds,
+ unsigned int flags)
+{
+ remote_domain_fd_associate_args args;
+ struct private_data *priv = domain->conn->privateData;
+ VIR_LOCK_GUARD lock = remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, domain);
+ args.name = (char *)name;
+ args.flags = flags;
+
+ if (callFull(domain->conn, priv, 0, fds, nfds, NULL, NULL,
+ REMOTE_PROC_DOMAIN_FD_ASSOCIATE,
+ (xdrproc_t) xdr_remote_domain_fd_associate_args, (char *) &args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1)
+ return -1;
+
+ return 0;
+}
+
+
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
* These can return NULL if underlying memory allocations fail,
.domainGetMessages = remoteDomainGetMessages, /* 7.1.0 */
.domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */
.domainSetLaunchSecurityState = remoteDomainSetLaunchSecurityState, /* 8.0.0 */
+ .domainFDAssociate = remoteDomainFDAssociate, /* 8.9.0 */
};
static virNetworkDriver network_driver = {
unsigned hyper size;
};
+
+struct remote_domain_fd_associate_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string name;
+ unsigned int flags;
+};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
* @generate: both
* @acl: domain:write
*/
- REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442
+ REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442,
+
+ /**
+ * @generate: none
+ * @acl: domain:write
+ */
+ REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443
};
remote_nonnull_string alias;
uint64_t size;
};
+struct remote_domain_fd_associate_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string name;
+ u_int flags;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
REMOTE_PROC_DOMAIN_SAVE_PARAMS = 440,
REMOTE_PROC_DOMAIN_RESTORE_PARAMS = 441,
REMOTE_PROC_DOMAIN_ABORT_JOB_FLAGS = 442,
+ REMOTE_PROC_DOMAIN_FD_ASSOCIATE = 443,
};