From 5435f17ed66ea4ec48b9c187bbf6296954c61c0b Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 9 Aug 2012 15:09:19 +0100 Subject: [PATCH] Add support for creating sockets & RPC servers from a pre-opened fd 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 7539edc7b0..7bc513fb3a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1567,6 +1567,7 @@ virNetServerServiceGetMaxRequests; virNetServerServiceGetPort; virNetServerServiceGetTLSContext; virNetServerServiceIsReadonly; +virNetServerServiceNewFD; virNetServerServiceNewTCP; virNetServerServiceNewUNIX; virNetServerServiceSetDispatcher; @@ -1592,6 +1593,7 @@ virNetSocketNewConnectExternal; virNetSocketNewConnectSSH; virNetSocketNewConnectTCP; virNetSocketNewConnectUNIX; +virNetSocketNewListenFD; virNetSocketNewListenTCP; virNetSocketNewListenUNIX; virNetSocketRead; diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c index eda5ef91c1..53ff50310e 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 cb18e2d804..48f49e73e0 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 b6f156b5e8..69c25bd02f 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 cc3f912713..3750955ee4 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); -- GitLab