[libvirt] [PATCH 10/23] Add support for creating sockets & RPC servers from a pre-opened fd

Daniel P. Berrange berrange at redhat.com
Thu Aug 9 15:20:15 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

In order to support systemd socket based activation, it needs to
be possible to create virNetSocketPtr and virNetServerServicePtr
instance from a pre-opened file descriptor
---
 src/libvirt_private.syms      |  2 ++
 src/rpc/virnetserverservice.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserverservice.h |  5 +++++
 src/rpc/virnetsocket.c        | 20 ++++++++++++++++++
 src/rpc/virnetsocket.h        |  3 +++
 5 files changed, 79 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 78d944f..a0db0e5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1557,6 +1557,7 @@ virNetServerServiceGetMaxRequests;
 virNetServerServiceGetPort;
 virNetServerServiceGetTLSContext;
 virNetServerServiceIsReadonly;
+virNetServerServiceNewFD;
 virNetServerServiceNewTCP;
 virNetServerServiceNewUNIX;
 virNetServerServiceSetDispatcher;
@@ -1582,6 +1583,7 @@ virNetSocketNewConnectExternal;
 virNetSocketNewConnectSSH;
 virNetSocketNewConnectTCP;
 virNetSocketNewConnectUNIX;
+virNetSocketNewListenFD;
 virNetSocketNewListenTCP;
 virNetSocketNewListenUNIX;
 virNetSocketRead;
diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c
index eda5ef9..53ff503 100644
--- a/src/rpc/virnetserverservice.c
+++ b/src/rpc/virnetserverservice.c
@@ -200,6 +200,55 @@ error:
     return NULL;
 }
 
+virNetServerServicePtr virNetServerServiceNewFD(int fd,
+                                                int auth,
+                                                bool readonly,
+                                                size_t nrequests_client_max,
+                                                virNetTLSContextPtr tls)
+{
+    virNetServerServicePtr svc;
+    int i;
+
+    if (virNetServerServiceInitialize() < 0)
+        return NULL;
+
+    if (!(svc = virObjectNew(virNetServerServiceClass)))
+        return NULL;
+
+    svc->auth = auth;
+    svc->readonly = readonly;
+    svc->nrequests_client_max = nrequests_client_max;
+    svc->tls = virObjectRef(tls);
+
+    svc->nsocks = 1;
+    if (VIR_ALLOC_N(svc->socks, svc->nsocks) < 0)
+        goto no_memory;
+
+    if (virNetSocketNewListenFD(fd,
+                                &svc->socks[0]) < 0)
+        goto error;
+
+    for (i = 0 ; i < svc->nsocks ; i++) {
+        /* IO callback is initially disabled, until we're ready
+         * to deal with incoming clients */
+        if (virNetSocketAddIOCallback(svc->socks[i],
+                                      0,
+                                      virNetServerServiceAccept,
+                                      svc,
+                                      virObjectFreeCallback) < 0)
+            goto error;
+    }
+
+
+    return svc;
+
+no_memory:
+    virReportOOMError();
+error:
+    virObjectUnref(svc);
+    return NULL;
+}
+
 
 int virNetServerServiceGetPort(virNetServerServicePtr svc)
 {
diff --git a/src/rpc/virnetserverservice.h b/src/rpc/virnetserverservice.h
index cb18e2d..48f49e7 100644
--- a/src/rpc/virnetserverservice.h
+++ b/src/rpc/virnetserverservice.h
@@ -50,6 +50,11 @@ virNetServerServicePtr virNetServerServiceNewUNIX(const char *path,
                                                   bool readonly,
                                                   size_t nrequests_client_max,
                                                   virNetTLSContextPtr tls);
+virNetServerServicePtr virNetServerServiceNewFD(int fd,
+                                                int auth,
+                                                bool readonly,
+                                                size_t nrequests_client_max,
+                                                virNetTLSContextPtr tls);
 
 int virNetServerServiceGetPort(virNetServerServicePtr svc);
 
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index b6f156b..69c25bd 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -399,6 +399,26 @@ int virNetSocketNewListenUNIX(const char *path ATTRIBUTE_UNUSED,
 }
 #endif
 
+int virNetSocketNewListenFD(int fd,
+                            virNetSocketPtr *retsock)
+{
+    virSocketAddr addr;
+    *retsock = NULL;
+
+    memset(&addr, 0, sizeof(addr));
+
+    addr.len = sizeof(addr.data);
+    if (getsockname(fd, &addr.data.sa, &addr.len) < 0) {
+        virReportSystemError(errno, "%s", _("Unable to get local socket name"));
+        return -1;
+    }
+
+    if (!(*retsock = virNetSocketNew(&addr, NULL, false, fd, -1, 0)))
+        return -1;
+
+    return 0;
+}
+
 
 int virNetSocketNewConnectTCP(const char *nodename,
                               const char *service,
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index cc3f912..3750955 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -52,6 +52,9 @@ int virNetSocketNewListenUNIX(const char *path,
                               gid_t grp,
                               virNetSocketPtr *addr);
 
+int virNetSocketNewListenFD(int fd,
+                            virNetSocketPtr *addr);
+
 int virNetSocketNewConnectTCP(const char *nodename,
                               const char *service,
                               virNetSocketPtr *addr);
-- 
1.7.11.2




More information about the libvir-list mailing list