From: "Daniel P. Berrange" <berrange(a)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