[libvirt] [PATCH 3/4] logd: add support for admin protocol in virtlogd

Daniel P. Berrange berrange at redhat.com
Fri Jan 19 17:09:17 UTC 2018


Add a virtlogd-admin-sock can serves the admin protocol for the virtlogd
daemon and define a virtlogd:///{system,session}  URI scheme for
connecting to it.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/Makefile.am                      |   1 +
 src/libvirt-admin.c                  |  20 ++++--
 src/logging/log_daemon.c             | 135 ++++++++++++++++++++++++++---------
 src/logging/log_daemon_config.c      |   3 +
 src/logging/log_daemon_config.h      |   1 +
 src/logging/test_virtlogd.aug.in     |   4 ++
 src/logging/virtlogd-admin.socket.in |  10 +++
 src/logging/virtlogd.aug             |   1 +
 src/logging/virtlogd.service.in      |   1 +
 9 files changed, 136 insertions(+), 40 deletions(-)
 create mode 100644 src/logging/virtlogd-admin.socket.in

diff --git a/src/Makefile.am b/src/Makefile.am
index fd8756f10c..828306fd35 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2672,6 +2672,7 @@ virtlogd_LDFLAGS = \
 		$(PIE_LDFLAGS) \
 		$(NULL)
 virtlogd_LDADD = \
+		libvirt_driver_admin.la \
 		libvirt-net-rpc-server.la \
 		libvirt-net-rpc.la \
 		libvirt_util.la \
diff --git a/src/libvirt-admin.c b/src/libvirt-admin.c
index 48e6d7fc8a..9d1bff536b 100644
--- a/src/libvirt-admin.c
+++ b/src/libvirt-admin.c
@@ -38,8 +38,9 @@
 
 #define VIR_FROM_THIS VIR_FROM_ADMIN
 
-#define LIBVIRTD_ADMIN_SOCK_NAME "/libvirt-admin-sock"
-#define LIBVIRTD_ADMIN_UNIX_SOCKET LOCALSTATEDIR "/run/libvirt" LIBVIRTD_ADMIN_SOCK_NAME
+#define LIBVIRTD_ADMIN_SOCK_NAME "libvirt-admin-sock"
+#define VIRTLOGD_ADMIN_SOCK_NAME "virtlogd-admin-sock"
+
 
 VIR_LOG_INIT("libvirt-admin");
 
@@ -128,18 +129,25 @@ getSocketPath(virURIPtr uri)
     }
 
     if (!sock_path) {
-        if (STRNEQ_NULLABLE(uri->scheme, "libvirtd")) {
+        const char *sockbase = NULL;
+        if (STREQ_NULLABLE(uri->scheme, "libvirtd")) {
+            sockbase = LIBVIRTD_ADMIN_SOCK_NAME;
+        } else if (STREQ_NULLABLE(uri->scheme, "virtlogd")) {
+            sockbase = VIRTLOGD_ADMIN_SOCK_NAME;
+        } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("Unsupported URI scheme '%s'"),
                            NULLSTR(uri->scheme));
             goto error;
         }
+
         if (STREQ_NULLABLE(uri->path, "/system")) {
-            if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0)
+            if (virAsprintf(&sock_path, LOCALSTATEDIR "/run/libvirt/%s",
+                            sockbase) < 0)
                 goto error;
         } else if (STREQ_NULLABLE(uri->path, "/session")) {
-            if (!rundir || virAsprintf(&sock_path, "%s%s", rundir,
-                                       LIBVIRTD_ADMIN_SOCK_NAME) < 0)
+            if (!rundir || virAsprintf(&sock_path, "%s/%s", rundir,
+                                       sockbase) < 0)
                 goto error;
         } else {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c
index 7e8c9cfc29..ec2fd0b933 100644
--- a/src/logging/log_daemon.c
+++ b/src/logging/log_daemon.c
@@ -32,6 +32,7 @@
 
 #include "log_daemon.h"
 #include "log_daemon_config.h"
+#include "admin/admin_server_dispatch.h"
 #include "virutil.h"
 #include "virfile.h"
 #include "virpidfile.h"
@@ -137,7 +138,7 @@ static virLogDaemonPtr
 virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
 {
     virLogDaemonPtr logd;
-    virNetServerPtr srv;
+    virNetServerPtr srv = NULL;
 
     if (VIR_ALLOC(logd) < 0)
         return NULL;
@@ -149,6 +150,9 @@ virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
         return NULL;
     }
 
+    if (!(logd->dmn = virNetDaemonNew()))
+        goto error;
+
     if (!(srv = virNetServerNew("virtlogd", 1,
                                 1, 1, 0, config->max_clients,
                                 config->max_clients, -1, 0,
@@ -159,8 +163,22 @@ virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
                                 (void*)(intptr_t)(privileged ? 0x1 : 0x0))))
         goto error;
 
-    if (!(logd->dmn = virNetDaemonNew()) ||
-        virNetDaemonAddServer(logd->dmn, srv) < 0)
+    if (virNetDaemonAddServer(logd->dmn, srv) < 0)
+        goto error;
+    virObjectUnref(srv);
+    srv = NULL;
+
+    if (!(srv = virNetServerNew("admin", 1,
+                                1, 1, 0, config->admin_max_clients,
+                                config->admin_max_clients, -1, 0,
+                                NULL,
+                                remoteAdmClientInitHook,
+                                NULL,
+                                remoteAdmClientFreeFunc,
+                                logd->dmn)))
+        goto error;
+
+    if (virNetDaemonAddServer(logd->dmn, srv) < 0)
         goto error;
     virObjectUnref(srv);
     srv = NULL;
@@ -337,10 +355,12 @@ virLogDaemonForkIntoBackground(const char *argv0)
 
 static int
 virLogDaemonUnixSocketPaths(bool privileged,
-                            char **sockfile)
+                            char **sockfile,
+                            char **adminSockfile)
 {
     if (privileged) {
-        if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/virtlogd-sock") < 0)
+        if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/virtlogd-sock") < 0 ||
+            VIR_STRDUP(*adminSockfile, LOCALSTATEDIR "/run/libvirt/virtlogd-admin-sock") < 0)
             goto error;
     } else {
         char *rundir = NULL;
@@ -357,7 +377,8 @@ virLogDaemonUnixSocketPaths(bool privileged,
         }
         umask(old_umask);
 
-        if (virAsprintf(sockfile, "%s/virtlogd-sock", rundir) < 0) {
+        if (virAsprintf(sockfile, "%s/virtlogd-sock", rundir) < 0 ||
+            virAsprintf(adminSockfile, "%s/virtlogd-admin-sock", rundir) < 0) {
             VIR_FREE(rundir);
             goto error;
         }
@@ -468,29 +489,50 @@ virLogDaemonSetupSignals(virNetDaemonPtr dmn)
 
 
 static int
-virLogDaemonSetupNetworkingSystemD(virNetServerPtr srv)
+virLogDaemonSetupNetworkingSystemD(virNetServerPtr logSrv, virNetServerPtr adminSrv)
 {
-    virNetServerServicePtr svc;
     unsigned int nfds;
+    size_t i;
 
     if ((nfds = virGetListenFDs()) == 0)
         return 0;
-    if (nfds > 1)
+    if (nfds > 2)
         VIR_DEBUG("Too many (%d) file descriptors from systemd", nfds);
-    nfds = 1;
 
-    /* Systemd passes FDs, starting immediately after stderr,
-     * so the first FD we'll get is '3'. */
-    if (!(svc = virNetServerServiceNewFD(3, 0,
+    for (i = 0; i < nfds && i < 2; i++) {
+        virNetServerServicePtr svc;
+        char *path = virGetUNIXSocketPath(3 + i);
+        virNetServerPtr srv;
+
+        if (!path)
+            return -1;
+
+        if (strstr(path, "virtlogd-admin-sock")) {
+            srv = adminSrv;
+        } else if (strstr(path, "virtlogd-sock")) {
+            srv = logSrv;
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unknown UNIX socket %s passed in"),
+                           path);
+            VIR_FREE(path);
+            return -1;
+        }
+        VIR_FREE(path);
+
+        /* Systemd passes FDs, starting immediately after stderr,
+         * so the first FD we'll get is '3'. */
+        if (!(svc = virNetServerServiceNewFD(3 + i, 0,
 #if WITH_GNUTLS
-                                         NULL,
+                                             NULL,
 #endif
-                                         false, 0, 1)))
-        return -1;
+                                             false, 0, 1)))
+            return -1;
 
-    if (virNetServerAddService(srv, svc, NULL) < 0) {
-        virObjectUnref(svc);
-        return -1;
+        if (virNetServerAddService(srv, svc, NULL) < 0) {
+            virObjectUnref(svc);
+            return -1;
+        }
     }
     return 1;
 }
@@ -861,8 +903,10 @@ virLogDaemonUsage(const char *argv0, bool privileged)
 }
 
 int main(int argc, char **argv) {
-    virNetServerPtr srv = NULL;
+    virNetServerPtr logSrv = NULL;
+    virNetServerPtr adminSrv = NULL;
     virNetServerProgramPtr logProgram = NULL;
+    virNetServerProgramPtr adminProgram = NULL;
     char *remote_config_file = NULL;
     int statuswrite = -1;
     int ret = 1;
@@ -872,6 +916,7 @@ int main(int argc, char **argv) {
     char *pid_file = NULL;
     int pid_file_fd = -1;
     char *sock_file = NULL;
+    char *admin_sock_file = NULL;
     int timeout = -1;        /* -t: Shutdown timeout */
     char *state_file = NULL;
     bool implicit_conf = false;
@@ -999,12 +1044,13 @@ int main(int argc, char **argv) {
     VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file));
 
     if (virLogDaemonUnixSocketPaths(privileged,
-                                    &sock_file) < 0) {
+                                    &sock_file,
+                                    &admin_sock_file) < 0) {
         VIR_ERROR(_("Can't determine socket paths"));
         exit(EXIT_FAILURE);
     }
-    VIR_DEBUG("Decided on socket paths '%s'",
-              sock_file);
+    VIR_DEBUG("Decided on socket paths '%s' and '%s'",
+              sock_file, admin_sock_file);
 
     if (virLogDaemonExecRestartStatePath(privileged,
                                          &state_file) < 0) {
@@ -1081,22 +1127,27 @@ int main(int argc, char **argv) {
             goto cleanup;
         }
 
-        srv = virNetDaemonGetServer(logDaemon->dmn, "virtlogd");
-        if ((rv = virLogDaemonSetupNetworkingSystemD(srv)) < 0) {
+        logSrv = virNetDaemonGetServer(logDaemon->dmn, "virtlogd");
+        adminSrv = virNetDaemonGetServer(logDaemon->dmn, "admin");
+        if ((rv = virLogDaemonSetupNetworkingSystemD(logSrv, adminSrv)) < 0) {
             ret = VIR_LOG_DAEMON_ERR_NETWORK;
             goto cleanup;
         }
 
         /* Only do this, if systemd did not pass a FD */
-        if (rv == 0 &&
-            virLogDaemonSetupNetworkingNative(srv, sock_file) < 0) {
-            ret = VIR_LOG_DAEMON_ERR_NETWORK;
-            goto cleanup;
+        if (rv == 0) {
+            if (virLogDaemonSetupNetworkingNative(logSrv, sock_file) < 0 ||
+                virLogDaemonSetupNetworkingNative(adminSrv, admin_sock_file) < 0) {
+                ret = VIR_LOG_DAEMON_ERR_NETWORK;
+                goto cleanup;
+            }
         }
-        virObjectUnref(srv);
+        virObjectUnref(logSrv);
+        virObjectUnref(adminSrv);
     }
 
-    srv = virNetDaemonGetServer(logDaemon->dmn, "virtlogd");
+    logSrv = virNetDaemonGetServer(logDaemon->dmn, "virtlogd");
+    adminSrv = virNetDaemonGetServer(logDaemon->dmn, "admin");
 
     if (timeout != -1) {
         VIR_DEBUG("Registering shutdown timeout %d", timeout);
@@ -1116,7 +1167,19 @@ int main(int argc, char **argv) {
         ret = VIR_LOG_DAEMON_ERR_INIT;
         goto cleanup;
     }
-    if (virNetServerAddProgram(srv, logProgram) < 0) {
+    if (virNetServerAddProgram(logSrv, logProgram) < 0) {
+        ret = VIR_LOG_DAEMON_ERR_INIT;
+        goto cleanup;
+    }
+
+    if (!(adminProgram = virNetServerProgramNew(ADMIN_PROGRAM,
+                                                ADMIN_PROTOCOL_VERSION,
+                                                adminProcs,
+                                                adminNProcs))) {
+        ret = VIR_LOG_DAEMON_ERR_INIT;
+        goto cleanup;
+    }
+    if (virNetServerAddProgram(adminSrv, adminProgram) < 0) {
         ret = VIR_LOG_DAEMON_ERR_INIT;
         goto cleanup;
     }
@@ -1138,7 +1201,8 @@ int main(int argc, char **argv) {
 
     /* Start accepting new clients from network */
 
-    virNetServerUpdateServices(srv, true);
+    virNetServerUpdateServices(logSrv, true);
+    virNetServerUpdateServices(adminSrv, true);
     virNetDaemonRun(logDaemon->dmn);
 
     if (execRestart &&
@@ -1151,7 +1215,9 @@ int main(int argc, char **argv) {
 
  cleanup:
     virObjectUnref(logProgram);
-    virObjectUnref(srv);
+    virObjectUnref(adminProgram);
+    virObjectUnref(logSrv);
+    virObjectUnref(adminSrv);
     virLogDaemonFree(logDaemon);
     if (statuswrite != -1) {
         if (ret != 0) {
@@ -1167,6 +1233,7 @@ int main(int argc, char **argv) {
         virPidFileReleasePath(pid_file, pid_file_fd);
     VIR_FREE(pid_file);
     VIR_FREE(sock_file);
+    VIR_FREE(admin_sock_file);
     VIR_FREE(state_file);
     VIR_FREE(run_dir);
     VIR_FREE(remote_config_file);
diff --git a/src/logging/log_daemon_config.c b/src/logging/log_daemon_config.c
index cf58e6230e..3226b2c484 100644
--- a/src/logging/log_daemon_config.c
+++ b/src/logging/log_daemon_config.c
@@ -73,6 +73,7 @@ virLogDaemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
         return NULL;
 
     data->max_clients = 1024;
+    data->admin_max_clients = 5000;
     data->max_size = 1024 * 1024 * 2;
     data->max_backups = 3;
 
@@ -103,6 +104,8 @@ virLogDaemonConfigLoadOptions(virLogDaemonConfigPtr data,
         return -1;
     if (virConfGetValueUInt(conf, "max_clients", &data->max_clients) < 0)
         return -1;
+    if (virConfGetValueUInt(conf, "admin_max_clients", &data->admin_max_clients) < 0)
+        return -1;
     if (virConfGetValueSizeT(conf, "max_size", &data->max_size) < 0)
         return -1;
     if (virConfGetValueSizeT(conf, "max_backups", &data->max_backups) < 0)
diff --git a/src/logging/log_daemon_config.h b/src/logging/log_daemon_config.h
index 72d77d5e6f..53101b0610 100644
--- a/src/logging/log_daemon_config.h
+++ b/src/logging/log_daemon_config.h
@@ -34,6 +34,7 @@ struct _virLogDaemonConfig {
     char *log_filters;
     char *log_outputs;
     unsigned int max_clients;
+    unsigned int admin_max_clients;
 
     size_t max_backups;
     size_t max_size;
diff --git a/src/logging/test_virtlogd.aug.in b/src/logging/test_virtlogd.aug.in
index 3e6888fd48..ee3fae5cde 100644
--- a/src/logging/test_virtlogd.aug.in
+++ b/src/logging/test_virtlogd.aug.in
@@ -2,6 +2,8 @@ module Test_virtlogd =
   let conf = "log_level = 3
 log_filters=\"3:remote 4:event\"
 log_outputs=\"3:syslog:virtlogd\"
+max_clients = 10
+admin_max_clients = 10
 max_size = 131072
 max_backups = 3
 "
@@ -10,5 +12,7 @@ max_backups = 3
         { "log_level" = "3" }
         { "log_filters" = "3:remote 4:event" }
         { "log_outputs" = "3:syslog:virtlogd" }
+	{ "max_clients" = "10" }
+	{ "admin_max_clients" = "10" }
         { "max_size" = "131072" }
         { "max_backups" = "3" }
diff --git a/src/logging/virtlogd-admin.socket.in b/src/logging/virtlogd-admin.socket.in
new file mode 100644
index 0000000000..595e6c4c4b
--- /dev/null
+++ b/src/logging/virtlogd-admin.socket.in
@@ -0,0 +1,10 @@
+[Unit]
+Description=Virtual machine log manager socket
+Before=libvirtd.service
+
+[Socket]
+ListenStream=@localstatedir@/run/libvirt/virtlogd-admin-sock
+Service=virtlogd.service
+
+[Install]
+WantedBy=sockets.target
diff --git a/src/logging/virtlogd.aug b/src/logging/virtlogd.aug
index 5ed174230d..4fdcba72af 100644
--- a/src/logging/virtlogd.aug
+++ b/src/logging/virtlogd.aug
@@ -29,6 +29,7 @@ module Virtlogd =
                      | str_entry "log_outputs"
                      | int_entry "log_buffer_size"
                      | int_entry "max_clients"
+                     | int_entry "admin_max_clients"
                      | int_entry "max_size"
                      | int_entry "max_backups"
 
diff --git a/src/logging/virtlogd.service.in b/src/logging/virtlogd.service.in
index aa9aa698b5..3d9ae36150 100644
--- a/src/logging/virtlogd.service.in
+++ b/src/logging/virtlogd.service.in
@@ -1,6 +1,7 @@
 [Unit]
 Description=Virtual machine log manager
 Requires=virtlogd.socket
+Requires=virtlogd-admin.socket
 Before=libvirtd.service
 Documentation=man:virtlogd(8)
 Documentation=https://libvirt.org
-- 
2.14.3




More information about the libvir-list mailing list