[libvirt] [PATCH] Add support for fd=name to tap and socket networking

Mark McLoughlin markmc at redhat.com
Tue Jul 21 16:47:15 UTC 2009


This allows a program to initialize a host networking device using a
file descriptor passed over a unix monitor socket.

The program must first pass the file descriptor using SCM_RIGHTS
ancillary data with the getfd monitor command. It then may do
"host_net_add tap fd=name" to use the named file descriptor.

Signed-off-by: Mark McLoughlin <markmc at redhat.com>
---
 net.c |   42 +++++++++++++++++++++++++++++++++++-------
 1 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/net.c b/net.c
index 90cf912..1838692 100644
--- a/net.c
+++ b/net.c
@@ -2410,6 +2410,23 @@ void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
     exit(exit_status);
 }
 
+static int net_handle_fd_param(Monitor *mon, const char *param)
+{
+    if (!qemu_isdigit(param[0])) {
+        int fd;
+
+        fd = monitor_get_fd(mon, param);
+        if (fd == -1) {
+            config_error(mon, "No file descriptor named %s found", param);
+            return -1;
+        }
+
+        return fd;
+    } else {
+        return strtol(param, NULL, 0);
+    }
+}
+
 int net_client_init(Monitor *mon, const char *device, const char *p)
 {
     char buf[1024];
@@ -2650,14 +2667,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
             static const char * const fd_params[] = {
                 "vlan", "name", "fd", "sndbuf", NULL
             };
+            ret = -1;
             if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
                 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
-                ret = -1;
                 goto out;
             }
-            fd = strtol(buf, NULL, 0);
+            fd = net_handle_fd_param(mon, buf);
+            if (fd == -1) {
+                goto out;
+            }
             fcntl(fd, F_SETFL, O_NONBLOCK);
             s = net_tap_fd_init(vlan, device, name, fd);
+            if (!s) {
+                close(fd);
+            }
         } else {
             static const char * const tap_params[] = {
                 "vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL
@@ -2697,15 +2720,20 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
                 "vlan", "name", "fd", NULL
             };
             int fd;
+            ret = -1;
             if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {
                 config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);
-                ret = -1;
                 goto out;
             }
-            fd = strtol(buf, NULL, 0);
-            ret = -1;
-            if (net_socket_fd_init(vlan, device, name, fd, 1))
-                ret = 0;
+            fd = net_handle_fd_param(mon, buf);
+            if (fd == -1) {
+                goto out;
+            }
+            if (!net_socket_fd_init(vlan, device, name, fd, 1)) {
+                close(fd);
+                goto out;
+            }
+            ret = 0;
         } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
             static const char * const listen_params[] = {
                 "vlan", "name", "listen", NULL
-- 
1.6.2.5




More information about the libvir-list mailing list