Add two API calls to virCommand for generating the parameters necessary
for passing to the QEMU -add-fd option, for example "set=10,fd=20",
and the file descriptor set for the path= option, such as for example
"/dev/fdset/10"
Regards,
Stefan
---
src/libvirt_private.syms | 2 +
src/util/vircommand.c | 65 +++++++++++++++++++++++++++++++++++++++++++----
src/util/vircommand.h | 6 ++++
3 files changed, 68 insertions(+), 5 deletions(-)
Index: libvirt/src/libvirt_private.syms
===================================================================
--- libvirt.orig/src/libvirt_private.syms
+++ libvirt/src/libvirt_private.syms
@@ -165,6 +165,8 @@ virCommandSetPreExecHook;
virCommandSetWorkingDirectory;
virCommandToString;
virCommandTransferFD;
+virCommandTransferFDGetDevSet;
+virCommandTransferFDGetFDSet;
virCommandWait;
virCommandWriteArgLog;
virFork;
Index: libvirt/src/util/vircommand.c
===================================================================
--- libvirt.orig/src/util/vircommand.c
+++ libvirt/src/util/vircommand.c
@@ -109,7 +109,7 @@ struct _virCommand {
* Returns true if @set contains @fd,
* false otherwise.
*/
-static bool
+static int
virCommandFDIsSet(int fd,
const int *set,
int set_size)
@@ -118,9 +118,9 @@ virCommandFDIsSet(int fd,
while (i < set_size)
if (set[i++] == fd)
- return true;
+ return i--;
- return false;
+ return -1;
}
/*
@@ -145,7 +145,7 @@ virCommandFDSet(int fd,
if (fd < 0 || !set || !set_size)
return -1;
- if (virCommandFDIsSet(fd, *set, *set_size))
+ if (virCommandFDIsSet(fd, *set, *set_size) >= 0)
return 0;
if (VIR_REALLOC_N(*set, *set_size + 1) < 0) {
@@ -523,7 +523,7 @@ virExecWithHook(const char *const*argv,
for (i = 3; i < openmax; i++) {
if (i == infd || i == childout || i == childerr)
continue;
- if (!keepfd || !virCommandFDIsSet(i, keepfd, keepfd_size)) {
+ if (!keepfd || virCommandFDIsSet(i, keepfd, keepfd_size) < 0) {
tmpfd = i;
VIR_MASS_CLOSE(tmpfd);
} else if (virSetInherit(i, true) < 0) {
@@ -896,6 +896,61 @@ virCommandTransferFD(virCommandPtr cmd,
VIR_FORCE_CLOSE(fd);
}
+/**
+ * virCommandTransferFDGetFDSet:
+ * @cmd: the command to modify
+ * @fd: fd to reassign to the child
+ *
+ * Get the parameters for the the QEMU -add-fd command line option
+ * for the given file descriptor. The file descriptor must previously
+ * have been 'transferred' in a virCommandTransfer() call.
+ * This function for example returns "set=10,fd=20" for file descriptor 20.
+ */
+char *
+virCommandTransferFDGetFDSet(virCommandPtr cmd, int fd)
+{
+ char *result = NULL;
+ int idx = virCommandFDIsSet(fd, cmd->transfer, cmd->transfer_size);
+
+ if (idx >= 0) {
+ if (virAsprintf(&result, "set=%d,fd=%d", idx, fd) < 0) {
+ virReportOOMError();
+ }
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("file descriptor %d has not been transferred"), fd);
+ }
+
+ return result;
+}
+
+/**
+ * virCommandTransferFDGetDevSet:
+ * @cmd: the command to modify
+ * @fd: fd to reassign to the child
+ *
+ * Get the parameters for the the QEMU path= parameter where a file
+ * descriptor is accessed via a file descriptor set, for example
+ * /dev/fdset/10. The file descriptor must previously have been
+ * 'transferred' in a virCommandTransfer() call.
+ */
+char *
+virCommandTransferFDGetDevSet(virCommandPtr cmd, int fd)
+{
+ char *result = NULL;
+ int idx = virCommandFDIsSet(fd, cmd->transfer, cmd->transfer_size);
+
+ if (idx >= 0) {
+ if (virAsprintf(&result, "/dev/fdset/%d", idx) < 0) {
+ virReportOOMError();
+ }
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("file descriptor %d has not been transferred"), fd);
+ }
+ return result;
+}
+
/**
* virCommandSetPidFile:
Index: libvirt/src/util/vircommand.h
===================================================================
--- libvirt.orig/src/util/vircommand.h
+++ libvirt/src/util/vircommand.h
@@ -58,6 +58,12 @@ void virCommandPreserveFD(virCommandPtr
void virCommandTransferFD(virCommandPtr cmd,
int fd);
+char *virCommandTransferFDGetFDSet(virCommandPtr cmd,
+ int fd);
+
+char *virCommandTransferFDGetDevSet(virCommandPtr cmd,
+ int fd);
+
void virCommandSetPidFile(virCommandPtr cmd,
const char *pidfile) ATTRIBUTE_NONNULL(2);