[libvirt] Add support for QEMU file descriptor sets

Stefan Berger stefanb at linux.vnet.ibm.com
Tue Jan 22 18:09:50 UTC 2013


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);
 




More information about the libvir-list mailing list