]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add support for creating sockets & RPC servers from a pre-opened fd
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 9 Aug 2012 14:09:19 +0000 (15:09 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 20 Aug 2012 12:34:34 +0000 (13:34 +0100)
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
src/rpc/virnetserverservice.c
src/rpc/virnetserverservice.h
src/rpc/virnetsocket.c
src/rpc/virnetsocket.h

index 7539edc7b0825e205d783048bb6011b252c09033..7bc513fb3a59e81fb24063b9361c058827bfd023 100644 (file)
@@ -1567,6 +1567,7 @@ virNetServerServiceGetMaxRequests;
 virNetServerServiceGetPort;
 virNetServerServiceGetTLSContext;
 virNetServerServiceIsReadonly;
+virNetServerServiceNewFD;
 virNetServerServiceNewTCP;
 virNetServerServiceNewUNIX;
 virNetServerServiceSetDispatcher;
@@ -1592,6 +1593,7 @@ virNetSocketNewConnectExternal;
 virNetSocketNewConnectSSH;
 virNetSocketNewConnectTCP;
 virNetSocketNewConnectUNIX;
+virNetSocketNewListenFD;
 virNetSocketNewListenTCP;
 virNetSocketNewListenUNIX;
 virNetSocketRead;
index eda5ef91c10ff6d45791ba0ae3047456957b3124..53ff50310efe4228b4ffebaf5bf58b848e893e55 100644 (file)
@@ -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)
 {
index cb18e2d8041468e2ca5bf691049095161bc2f6c8..48f49e73e0e1e50570c78906da07699967ff7f7c 100644 (file)
@@ -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);
 
index b6f156b5e828e9aa15ce3e9c4d3b8bdfb50f0dac..69c25bd02f2999a74c43199653b8cd03d2d1e1d4 100644 (file)
@@ -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,
index cc3f912713121c5d55382ec4b09a82bc0e831463..3750955ee45c7fccb8b2bed718460ec0a2622f30 100644 (file)
@@ -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);