mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-21 19:02:25 +00:00
logd: add support for admin protocol in virtlogd
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@redhat.com>
This commit is contained in:
parent
8aca141081
commit
85d45ff05d
@ -2670,6 +2670,7 @@ virtlogd_LDFLAGS = \
|
||||
$(PIE_LDFLAGS) \
|
||||
$(NULL)
|
||||
virtlogd_LDADD = \
|
||||
libvirt_driver_admin.la \
|
||||
libvirt-net-rpc-server.la \
|
||||
libvirt-net-rpc.la \
|
||||
libvirt_util.la \
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
remoteAdmClientNew,
|
||||
remoteAdmClientPreExecRestart,
|
||||
remoteAdmClientFree,
|
||||
logd->dmn)))
|
||||
goto error;
|
||||
|
||||
if (virNetDaemonAddServer(logd->dmn, srv) < 0)
|
||||
goto error;
|
||||
virObjectUnref(srv);
|
||||
srv = NULL;
|
||||
@ -189,7 +207,7 @@ virLogDaemonGetHandler(virLogDaemonPtr dmn)
|
||||
|
||||
|
||||
static virNetServerPtr
|
||||
virLogDaemonNewServerPostExecRestart(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
|
||||
virLogDaemonNewServerPostExecRestart(virNetDaemonPtr dmn,
|
||||
const char *name,
|
||||
virJSONValuePtr object,
|
||||
void *opaque)
|
||||
@ -202,6 +220,14 @@ virLogDaemonNewServerPostExecRestart(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
|
||||
virLogDaemonClientPreExecRestart,
|
||||
virLogDaemonClientFree,
|
||||
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"),
|
||||
@ -354,10 +380,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;
|
||||
@ -374,7 +402,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;
|
||||
}
|
||||
@ -485,29 +514,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;
|
||||
}
|
||||
@ -878,8 +928,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;
|
||||
@ -889,6 +941,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;
|
||||
@ -1016,12 +1069,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) {
|
||||
@ -1098,22 +1152,30 @@ 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");
|
||||
/* If exec-restarting from old virtlogd, we won't have an
|
||||
* admin server present */
|
||||
if (virNetDaemonHasServer(logDaemon->dmn, "admin"))
|
||||
adminSrv = virNetDaemonGetServer(logDaemon->dmn, "admin");
|
||||
|
||||
if (timeout != -1) {
|
||||
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
||||
@ -1133,11 +1195,25 @@ 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 (adminSrv != NULL) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable error func, now logging is setup */
|
||||
virSetErrorFunc(NULL, virLogDaemonErrorHandler);
|
||||
|
||||
@ -1155,7 +1231,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
/* Start accepting new clients from network */
|
||||
|
||||
virNetServerUpdateServices(srv, true);
|
||||
virNetDaemonUpdateServices(logDaemon->dmn, true);
|
||||
virNetDaemonRun(logDaemon->dmn);
|
||||
|
||||
if (execRestart &&
|
||||
@ -1168,7 +1244,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) {
|
||||
@ -1184,6 +1262,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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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" }
|
||||
|
10
src/logging/virtlogd-admin.socket.in
Normal file
10
src/logging/virtlogd-admin.socket.in
Normal file
@ -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
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user