Currently code has to first create the service and then separately
register it with the server. If the socket associated with a particular
service is not passed from systemd we want to skip creating the service
altogether. This means we can't put the systemd activation logic into
the constructors for virNetServerService.
This patch thus creates some helper methods against virNetServer which
combine systemd activation, service creation and service registration
into one single operation. This operation is automatically a no-op if
systemd activation is present and no sockets were passed in.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/libvirt_remote.syms | 2 +
src/rpc/virnetserver.c | 145 ++++++++++++++++++++++++++++++++++++++++
src/rpc/virnetserver.h | 23 +++++++
3 files changed, 170 insertions(+)
diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
index f05f1827f0..d855078186 100644
--- a/src/libvirt_remote.syms
+++ b/src/libvirt_remote.syms
@@ -114,6 +114,8 @@ virNetMessageSaveError;
virNetServerAddClient;
virNetServerAddProgram;
virNetServerAddService;
+virNetServerAddServiceTCP;
+virNetServerAddServiceUNIX;
virNetServerClose;
virNetServerGetClient;
virNetServerGetClients;
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 0f3fa63fbb..894feae406 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -668,6 +668,151 @@ int virNetServerAddService(virNetServerPtr srv,
return -1;
}
+
+static int
+virNetServerAddServiceActivation(virNetServerPtr srv,
+ virSystemdActivationPtr act,
+ const char *actname,
+ int auth,
+ virNetTLSContextPtr tls,
+ bool readonly,
+ size_t max_queued_clients,
+ size_t nrequests_client_max)
+{
+ int *fds;
+ size_t nfds;
+
+ if (act == NULL)
+ return 0;
+
+ virSystemdActivationClaimFDs(act, actname, &fds, &nfds);
+
+ if (nfds) {
+ virNetServerServicePtr svc;
+
+ svc = virNetServerServiceNewFDs(fds,
+ nfds,
+ false,
+ auth,
+ tls,
+ readonly,
+ max_queued_clients,
+ nrequests_client_max);
+ if (!svc)
+ return -1;
+
+ if (virNetServerAddService(srv, svc) < 0) {
+ virObjectUnref(svc);
+ return -1;
+ }
+ }
+
+ /* Intentionally return 1 any time activation is present,
+ * even if we didn't find any sockets with the matching
+ * name. The user needs to be free to disable some of the
+ * services via unit files without causing us to fallback
+ * to creating the service manually.
+ */
+ return 1;
+}
+
+
+int virNetServerAddServiceTCP(virNetServerPtr srv,
+ virSystemdActivationPtr act,
+ const char *actname,
+ const char *nodename,
+ const char *service,
+ int family,
+ int auth,
+ virNetTLSContextPtr tls,
+ bool readonly,
+ size_t max_queued_clients,
+ size_t nrequests_client_max)
+{
+ virNetServerServicePtr svc = NULL;
+ int ret;
+
+ ret = virNetServerAddServiceActivation(srv, act, actname,
+ auth,
+ tls,
+ readonly,
+ max_queued_clients,
+ nrequests_client_max);
+ if (ret < 0)
+ return -1;
+
+ if (ret == 1)
+ return 0;
+
+ if (!(svc = virNetServerServiceNewTCP(nodename,
+ service,
+ family,
+ auth,
+ tls,
+ readonly,
+ max_queued_clients,
+ nrequests_client_max)))
+ return -1;
+
+ if (virNetServerAddService(srv, svc) < 0) {
+ virObjectUnref(svc);
+ return -1;
+ }
+
+ virObjectUnref(svc);
+
+ return 0;
+}
+
+
+int virNetServerAddServiceUNIX(virNetServerPtr srv,
+ virSystemdActivationPtr act,
+ const char *actname,
+ const char *path,
+ mode_t mask,
+ gid_t grp,
+ int auth,
+ virNetTLSContextPtr tls,
+ bool readonly,
+ size_t max_queued_clients,
+ size_t nrequests_client_max)
+{
+ virNetServerServicePtr svc = NULL;
+ int ret;
+
+ ret = virNetServerAddServiceActivation(srv, act, actname,
+ auth,
+ tls,
+ readonly,
+ max_queued_clients,
+ nrequests_client_max);
+ if (ret < 0)
+ return -1;
+
+ if (ret == 1)
+ return 0;
+
+ if (!(svc = virNetServerServiceNewUNIX(path,
+ mask,
+ grp,
+ auth,
+ tls,
+ readonly,
+ max_queued_clients,
+ nrequests_client_max)))
+ return -1;
+
+ if (virNetServerAddService(srv, svc) < 0) {
+ virObjectUnref(svc);
+ return -1;
+ }
+
+ virObjectUnref(svc);
+
+ return 0;
+}
+
+
int virNetServerAddProgram(virNetServerPtr srv,
virNetServerProgramPtr prog)
{
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 6b2541588c..1b4184733f 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -27,6 +27,7 @@
#include "virnetserverservice.h"
#include "virobject.h"
#include "virjson.h"
+#include "virsystemd.h"
virNetServerPtr virNetServerNew(const char *name,
@@ -60,6 +61,28 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv);
int virNetServerAddService(virNetServerPtr srv,
virNetServerServicePtr svc);
+int virNetServerAddServiceTCP(virNetServerPtr srv,
+ virSystemdActivationPtr act,
+ const char *actname,
+ const char *nodename,
+ const char *service,
+ int family,
+ int auth,
+ virNetTLSContextPtr tls,
+ bool readonly,
+ size_t max_queued_clients,
+ size_t nrequests_client_max);
+int virNetServerAddServiceUNIX(virNetServerPtr srv,
+ virSystemdActivationPtr act,
+ const char *actname,
+ const char *path,
+ mode_t mask,
+ gid_t grp,
+ int auth,
+ virNetTLSContextPtr tls,
+ bool readonly,
+ size_t max_queued_clients,
+ size_t nrequests_client_max);
int virNetServerAddProgram(virNetServerPtr srv,
virNetServerProgramPtr prog);
--
2.21.0