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(a)redhat.com>
---
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