#include "log_daemon.h"
#include "log_daemon_config.h"
+#include "admin/admin_server_dispatch.h"
#include "virutil.h"
#include "virfile.h"
#include "virpidfile.h"
virLogDaemonNew(virLogDaemonConfigPtr config, bool privileged)
{
virLogDaemonPtr logd;
- virNetServerPtr srv;
+ virNetServerPtr srv = NULL;
if (VIR_ALLOC(logd) < 0)
return NULL;
return NULL;
}
+ if (!(logd->dmn = virNetDaemonNew()))
+ goto error;
+
if (!(srv = virNetServerNew("virtlogd", 1,
1, 1, 0, config->max_clients,
config->max_clients, -1, 0,
(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;
static virNetServerPtr
-virLogDaemonNewServerPostExecRestart(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
+virLogDaemonNewServerPostExecRestart(virNetDaemonPtr dmn,
const char *name,
virJSONValuePtr object,
void *opaque)
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"),
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;
}
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;
}
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;
}
}
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;
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;
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) {
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);
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);
/* Start accepting new clients from network */
- virNetServerUpdateServices(srv, true);
+ virNetDaemonUpdateServices(logDaemon->dmn, true);
virNetDaemonRun(logDaemon->dmn);
if (execRestart &&
cleanup:
virObjectUnref(logProgram);
- virObjectUnref(srv);
+ virObjectUnref(adminProgram);
+ virObjectUnref(logSrv);
+ virObjectUnref(adminSrv);
virLogDaemonFree(logDaemon);
if (statuswrite != -1) {
if (ret != 0) {
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);