Add a virtlockd-admin-sock can serves the admin protocol for the virtlockd daemon and define a virtlockd:///{system,session} URI scheme for connecting to it. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- cfg.mk | 1 - src/Makefile.am | 1 + src/libvirt-admin.c | 3 + src/locking/lock_daemon.c | 145 ++++++++++++++++++++++++++-------- src/locking/lock_daemon_config.c | 3 + src/locking/lock_daemon_config.h | 1 + src/locking/test_virtlockd.aug.in | 4 + src/locking/virtlockd-admin.socket.in | 10 +++ src/locking/virtlockd.aug | 1 + src/locking/virtlockd.conf | 6 ++ src/locking/virtlockd.service.in | 1 + 11 files changed, 142 insertions(+), 34 deletions(-) create mode 100644 src/locking/virtlockd-admin.socket.in diff --git a/cfg.mk b/cfg.mk index 1a5de2b154..5d369aadb2 100644 --- a/cfg.mk +++ b/cfg.mk @@ -775,7 +775,6 @@ sc_prohibit_cross_inclusion: case $$dir in \ util/) safe="util";; \ access/ | conf/) safe="($$dir|conf|util)";; \ - locking/) safe="($$dir|util|conf|rpc)";; \ cpu/| network/| node_device/| rpc/| security/| storage/) \ safe="($$dir|util|conf|storage)";; \ xenapi/ | xenconfig/ ) safe="($$dir|util|conf|xen|cpu)";; \ diff --git a/src/Makefile.am b/src/Makefile.am index 828306fd35..42eee2ad90 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2646,6 +2646,7 @@ virtlockd_LDFLAGS = \ $(PIE_LDFLAGS) \ $(NULL) virtlockd_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 9d1bff536b..de595a9f7f 100644 --- a/src/libvirt-admin.c +++ b/src/libvirt-admin.c @@ -40,6 +40,7 @@ #define LIBVIRTD_ADMIN_SOCK_NAME "libvirt-admin-sock" #define VIRTLOGD_ADMIN_SOCK_NAME "virtlogd-admin-sock" +#define VIRTLOCKD_ADMIN_SOCK_NAME "virtlockd-admin-sock" VIR_LOG_INIT("libvirt-admin"); @@ -134,6 +135,8 @@ getSocketPath(virURIPtr uri) sockbase = LIBVIRTD_ADMIN_SOCK_NAME; } else if (STREQ_NULLABLE(uri->scheme, "virtlogd")) { sockbase = VIRTLOGD_ADMIN_SOCK_NAME; + } else if (STREQ_NULLABLE(uri->scheme, "virtlockd")) { + sockbase = VIRTLOCKD_ADMIN_SOCK_NAME; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported URI scheme '%s'"), diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index b1f0665aaa..79ab90fc91 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -32,6 +32,7 @@ #include "lock_daemon.h" #include "lock_daemon_config.h" +#include "admin/admin_server_dispatch.h" #include "virutil.h" #include "virfile.h" #include "virpidfile.h" @@ -148,7 +149,7 @@ static virLockDaemonPtr virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged) { virLockDaemonPtr lockd; - virNetServerPtr srv; + virNetServerPtr srv = NULL; if (VIR_ALLOC(lockd) < 0) return NULL; @@ -160,6 +161,9 @@ virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged) return NULL; } + if (!(lockd->dmn = virNetDaemonNew())) + goto error; + if (!(srv = virNetServerNew("virtlockd", 1, 1, 1, 0, config->max_clients, config->max_clients, -1, 0, @@ -170,9 +174,23 @@ virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged) (void*)(intptr_t)(privileged ? 0x1 : 0x0)))) goto error; - if (!(lockd->dmn = virNetDaemonNew()) || - virNetDaemonAddServer(lockd->dmn, srv) < 0) + if (virNetDaemonAddServer(lockd->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, + remoteAdmClientNew, + remoteAdmClientPreExecRestart, + remoteAdmClientFree, + lockd->dmn))) goto error; + + if (virNetDaemonAddServer(lockd->dmn, srv) < 0) + goto error; virObjectUnref(srv); srv = NULL; @@ -206,6 +224,14 @@ virLockDaemonNewServerPostExecRestart(virNetDaemonPtr dmn ATTRIBUTE_UNUSED, virLockDaemonClientPreExecRestart, virLockDaemonClientFree, opaque); + } else if (STREQ(name, "admin")) { + return virNetServerNewPostExecRestart(object, + name, + remoteAdmClientNew, + remoteAdmClientNewPostExecRestart, + remoteAdmClientPreExecRestart, + remoteAdmClientFree, + dmn); } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected server name '%s' during restart"), @@ -420,10 +446,12 @@ virLockDaemonForkIntoBackground(const char *argv0) static int virLockDaemonUnixSocketPaths(bool privileged, - char **sockfile) + char **sockfile, + char **adminSockfile) { if (privileged) { - if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/virtlockd-sock") < 0) + if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/virtlockd-sock") < 0 || + VIR_STRDUP(*adminSockfile, LOCALSTATEDIR "/run/libvirt/virtlockd-admin-sock") < 0) goto error; } else { char *rundir = NULL; @@ -440,7 +468,8 @@ virLockDaemonUnixSocketPaths(bool privileged, } umask(old_umask); - if (virAsprintf(sockfile, "%s/virtlockd-sock", rundir) < 0) { + if (virAsprintf(sockfile, "%s/virtlockd-sock", rundir) < 0 || + virAsprintf(adminSockfile, "%s/virtlockd-admin-sock", rundir) < 0) { VIR_FREE(rundir); goto error; } @@ -557,29 +586,50 @@ virLockDaemonSetupSignals(virNetDaemonPtr dmn) static int -virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv) +virLockDaemonSetupNetworkingSystemD(virNetServerPtr lockSrv, 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, "virtlockd-admin-sock")) { + srv = adminSrv; + } else if (strstr(path, "virtlockd-sock")) { + srv = lockSrv; + } 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; } @@ -1112,8 +1162,10 @@ virLockDaemonUsage(const char *argv0, bool privileged) } int main(int argc, char **argv) { - virNetServerPtr srv = NULL; + virNetServerPtr lockSrv = NULL; + virNetServerPtr adminSrv = NULL; virNetServerProgramPtr lockProgram = NULL; + virNetServerProgramPtr adminProgram = NULL; char *remote_config_file = NULL; int statuswrite = -1; int ret = 1; @@ -1123,6 +1175,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; @@ -1250,12 +1303,13 @@ int main(int argc, char **argv) { VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file)); if (virLockDaemonUnixSocketPaths(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 (virLockDaemonExecRestartStatePath(privileged, &state_file) < 0) { @@ -1330,22 +1384,30 @@ int main(int argc, char **argv) { goto cleanup; } - srv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd"); - if ((rv = virLockDaemonSetupNetworkingSystemD(srv)) < 0) { + lockSrv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd"); + adminSrv = virNetDaemonGetServer(lockDaemon->dmn, "admin"); + if ((rv = virLockDaemonSetupNetworkingSystemD(lockSrv, adminSrv)) < 0) { ret = VIR_LOCK_DAEMON_ERR_NETWORK; goto cleanup; } /* Only do this, if systemd did not pass a FD */ - if (rv == 0 && - virLockDaemonSetupNetworkingNative(srv, sock_file) < 0) { - ret = VIR_LOCK_DAEMON_ERR_NETWORK; - goto cleanup; + if (rv == 0) { + if (virLockDaemonSetupNetworkingNative(lockSrv, sock_file) < 0 || + virLockDaemonSetupNetworkingNative(adminSrv, admin_sock_file) < 0) { + ret = VIR_LOCK_DAEMON_ERR_NETWORK; + goto cleanup; + } } - virObjectUnref(srv); + virObjectUnref(lockSrv); + virObjectUnref(adminSrv); } - srv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd"); + lockSrv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd"); + /* If exec-restarting from old virtlockd, we won't have an + * admin server present */ + if (virNetDaemonHasServer(lockDaemon->dmn, "admin")) + adminSrv = virNetDaemonGetServer(lockDaemon->dmn, "admin"); if (timeout != -1) { VIR_DEBUG("Registering shutdown timeout %d", timeout); @@ -1366,11 +1428,25 @@ int main(int argc, char **argv) { goto cleanup; } - if (virNetServerAddProgram(srv, lockProgram) < 0) { + if (virNetServerAddProgram(lockSrv, lockProgram) < 0) { ret = VIR_LOCK_DAEMON_ERR_INIT; goto cleanup; } + if (adminSrv != NULL) { + if (!(adminProgram = virNetServerProgramNew(ADMIN_PROGRAM, + ADMIN_PROTOCOL_VERSION, + adminProcs, + adminNProcs))) { + ret = VIR_LOCK_DAEMON_ERR_INIT; + goto cleanup; + } + if (virNetServerAddProgram(adminSrv, adminProgram) < 0) { + ret = VIR_LOCK_DAEMON_ERR_INIT; + goto cleanup; + } + } + /* Disable error func, now logging is setup */ virSetErrorFunc(NULL, virLockDaemonErrorHandler); @@ -1401,8 +1477,10 @@ int main(int argc, char **argv) { ret = 0; cleanup: - virObjectUnref(srv); virObjectUnref(lockProgram); + virObjectUnref(adminProgram); + virObjectUnref(lockSrv); + virObjectUnref(adminSrv); virLockDaemonFree(lockDaemon); if (statuswrite != -1) { if (ret != 0) { @@ -1418,6 +1496,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); return ret; diff --git a/src/locking/lock_daemon_config.c b/src/locking/lock_daemon_config.c index 20824b870c..efa5655a30 100644 --- a/src/locking/lock_daemon_config.c +++ b/src/locking/lock_daemon_config.c @@ -72,6 +72,7 @@ virLockDaemonConfigNew(bool privileged ATTRIBUTE_UNUSED) return NULL; data->max_clients = 1024; + data->admin_max_clients = 5000; return data; } @@ -100,6 +101,8 @@ virLockDaemonConfigLoadOptions(virLockDaemonConfigPtr 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; return 0; } diff --git a/src/locking/lock_daemon_config.h b/src/locking/lock_daemon_config.h index 6ab84c6a0a..3e642208f5 100644 --- a/src/locking/lock_daemon_config.h +++ b/src/locking/lock_daemon_config.h @@ -34,6 +34,7 @@ struct _virLockDaemonConfig { char *log_filters; char *log_outputs; unsigned int max_clients; + unsigned int admin_max_clients; }; diff --git a/src/locking/test_virtlockd.aug.in b/src/locking/test_virtlockd.aug.in index 799818e5d1..2d69816b5c 100644 --- a/src/locking/test_virtlockd.aug.in +++ b/src/locking/test_virtlockd.aug.in @@ -3,6 +3,8 @@ module Test_virtlockd = log_filters=\"3:remote 4:event\" log_outputs=\"3:syslog:libvirtd\" log_buffer_size = 64 +max_clients = 10 +admin_max_clients = 10 " test Virtlockd.lns get conf = @@ -10,3 +12,5 @@ log_buffer_size = 64 { "log_filters" = "3:remote 4:event" } { "log_outputs" = "3:syslog:libvirtd" } { "log_buffer_size" = "64" } + { "max_clients" = "10" } + { "admin_max_clients" = "10" } diff --git a/src/locking/virtlockd-admin.socket.in b/src/locking/virtlockd-admin.socket.in new file mode 100644 index 0000000000..1fa0a3dc33 --- /dev/null +++ b/src/locking/virtlockd-admin.socket.in @@ -0,0 +1,10 @@ +[Unit] +Description=Virtual machine lock manager admin socket +Before=libvirtd.service + +[Socket] +ListenStream=@localstatedir@/run/libvirt/virtlockd-admin-sock +Server=virtlockd.service + +[Install] +WantedBy=sockets.target diff --git a/src/locking/virtlockd.aug b/src/locking/virtlockd.aug index ec8d2b5c0a..7b152ed407 100644 --- a/src/locking/virtlockd.aug +++ b/src/locking/virtlockd.aug @@ -29,6 +29,7 @@ module Virtlockd = | str_entry "log_outputs" | int_entry "log_buffer_size" | int_entry "max_clients" + | int_entry "admin_max_clients" (* Each enty in the config is one of the following three ... *) let entry = logging_entry diff --git a/src/locking/virtlockd.conf b/src/locking/virtlockd.conf index 4c935d0a2c..24b69aa425 100644 --- a/src/locking/virtlockd.conf +++ b/src/locking/virtlockd.conf @@ -65,3 +65,9 @@ # to virtlockd. So 'max_clients' will affect how many VMs can # be run on a host #max_clients = 1024 + +# Same processing controls, but this time for the admin interface. +# For description of each option, be so kind to scroll few lines +# upwards. + +#admin_max_clients = 5 diff --git a/src/locking/virtlockd.service.in b/src/locking/virtlockd.service.in index 07e48478b7..3c9d587032 100644 --- a/src/locking/virtlockd.service.in +++ b/src/locking/virtlockd.service.in @@ -1,6 +1,7 @@ [Unit] Description=Virtual machine lock manager Requires=virtlockd.socket +Requires=virtlockd-admin.socket Before=libvirtd.service Documentation=man:virtlockd(8) Documentation=https://libvirt.org -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list