diff --git a/po/POTFILES.in b/po/POTFILES.in index 725ec668ce2680d387a9ffb716a19b6316734050..4dc147600df4841d6d7295d694bb9b945524d3ed 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -82,6 +82,7 @@ src/logging/log_daemon.c src/logging/log_daemon_config.c src/logging/log_daemon_dispatch.c src/logging/log_handler.c +src/logging/log_manager.c src/lxc/lxc_cgroup.c src/lxc/lxc_fuse.c src/lxc/lxc_hostdev.c diff --git a/src/Makefile.am b/src/Makefile.am index c658204b4c099d1e6e1eef4324c797458e1d670e..3c98c386033bc52277125987187e2ea7f3af6c39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -216,7 +216,9 @@ DRIVER_SOURCES = \ locking/lock_manager.c locking/lock_manager.h \ locking/lock_driver.h \ locking/lock_driver_nop.h locking/lock_driver_nop.c \ - locking/domain_lock.h locking/domain_lock.c + locking/domain_lock.h locking/domain_lock.c \ + logging/log_manager.c logging/log_manager.h \ + $(NULL) LOCK_DRIVER_SANLOCK_SOURCES = \ locking/lock_driver_sanlock.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b112023f1b2dd6d6db746f8f777f7f91d0755fbc..42528a445b49929fb9448a7fe717febae0830c06 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1004,6 +1004,14 @@ virLockManagerPluginUsesState; virLockManagerRelease; +# logging/log_manager.h +virLogManagerDomainGetLogFilePosition; +virLogManagerDomainOpenLogFile; +virLogManagerDomainReadLogFile; +virLogManagerFree; +virLogManagerNew; + + # nodeinfo.h nodeAllocPages; nodeCapsInitNUMA; diff --git a/src/logging/log_manager.c b/src/logging/log_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..5ff5f126407effd94d644356b45a46e7a536418d --- /dev/null +++ b/src/logging/log_manager.c @@ -0,0 +1,291 @@ +/* + * log_manager.c: log management client + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * . + * + * Author: Daniel P. Berrange + */ + +#include + +#include "configmake.h" + +#include "log_manager.h" +#include "log_protocol.h" +#include "viralloc.h" +#include "virutil.h" +#include "virstring.h" +#include "virerror.h" +#include "virfile.h" + +#include "rpc/virnetclient.h" + +#define VIR_FROM_THIS VIR_FROM_LOGGING + +struct _virLogManager { + virNetClientPtr client; + virNetClientProgramPtr program; + unsigned int serial; +}; + + +static char * +virLogManagerDaemonPath(bool privileged) +{ + char *path; + if (privileged) { + if (VIR_STRDUP(path, LOCALSTATEDIR "/run/libvirt/virtlogd-sock") < 0) + return NULL; + } else { + char *rundir = NULL; + + if (!(rundir = virGetUserRuntimeDirectory())) + return NULL; + + if (virAsprintf(&path, "%s/virtlogd-sock", rundir) < 0) { + VIR_FREE(rundir); + return NULL; + } + + VIR_FREE(rundir); + } + return path; +} + + +static virNetClientPtr +virLogManagerConnect(bool privileged, + virNetClientProgramPtr *prog) +{ + virNetClientPtr client = NULL; + char *logdpath; + char *daemonPath = NULL; + + *prog = NULL; + + if (!(logdpath = virLogManagerDaemonPath(privileged))) + goto error; + + if (!privileged && + !(daemonPath = virFileFindResourceFull("virtlogd", + NULL, NULL, + abs_topbuilddir "/src", + SBINDIR, + "VIRTLOGD_PATH"))) + goto error; + + if (!(client = virNetClientNewUNIX(logdpath, + daemonPath != NULL, + daemonPath))) + goto error; + + if (!(*prog = virNetClientProgramNew(VIR_LOG_MANAGER_PROTOCOL_PROGRAM, + VIR_LOG_MANAGER_PROTOCOL_PROGRAM_VERSION, + NULL, + 0, + NULL))) + goto error; + + if (virNetClientAddProgram(client, *prog) < 0) + goto error; + + VIR_FREE(daemonPath); + VIR_FREE(logdpath); + + return client; + + error: + VIR_FREE(daemonPath); + VIR_FREE(logdpath); + virNetClientClose(client); + virObjectUnref(client); + virObjectUnref(*prog); + return NULL; +} + + +virLogManagerPtr +virLogManagerNew(bool privileged) +{ + virLogManagerPtr mgr; + + if (VIR_ALLOC(mgr) < 0) + goto error; + + if (!(mgr->client = virLogManagerConnect(privileged, &mgr->program))) + goto error; + + return mgr; + + error: + virLogManagerFree(mgr); + return NULL; +} + + +void +virLogManagerFree(virLogManagerPtr mgr) +{ + if (!mgr) + return; + + if (mgr->client) + virNetClientClose(mgr->client); + virObjectUnref(mgr->program); + virObjectUnref(mgr->client); + + VIR_FREE(mgr); +} + + +int +virLogManagerDomainOpenLogFile(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + unsigned int flags, + ino_t *inode, + off_t *offset) +{ + struct virLogManagerProtocolDomainOpenLogFileArgs args; + struct virLogManagerProtocolDomainOpenLogFileRet ret; + int *fdout = NULL; + size_t fdoutlen = 0; + int rv = -1; + + memset(&args, 0, sizeof(args)); + memset(&ret, 0, sizeof(ret)); + + args.driver = (char *)driver; + memcpy(args.dom.uuid, domuuid, VIR_UUID_BUFLEN); + args.dom.name = (char *)domname; + args.flags = flags; + + if (virNetClientProgramCall(mgr->program, + mgr->client, + mgr->serial++, + VIR_LOG_MANAGER_PROTOCOL_PROC_DOMAIN_OPEN_LOG_FILE, + 0, NULL, &fdoutlen, &fdout, + (xdrproc_t)xdr_virLogManagerProtocolDomainOpenLogFileArgs, &args, + (xdrproc_t)xdr_virLogManagerProtocolDomainOpenLogFileRet, &ret) < 0) + goto cleanup; + + if (fdoutlen != 1) { + if (fdoutlen) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("too many file descriptors received")); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no file descriptor received")); + } + goto cleanup; + } + + *inode = ret.pos.inode; + *offset = ret.pos.offset; + + rv = fdout[0]; + cleanup: + if (rv < 0) { + while (fdoutlen) + VIR_FORCE_CLOSE(fdout[--fdoutlen]); + } + VIR_FREE(fdout); + + return rv; +} + + +int +virLogManagerDomainGetLogFilePosition(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + unsigned int flags, + ino_t *inode, + off_t *offset) +{ + struct virLogManagerProtocolDomainGetLogFilePositionArgs args; + struct virLogManagerProtocolDomainGetLogFilePositionRet ret; + int rv = -1; + + memset(&args, 0, sizeof(args)); + memset(&ret, 0, sizeof(ret)); + + args.driver = (char *)driver; + memcpy(args.dom.uuid, domuuid, VIR_UUID_BUFLEN); + args.dom.name = (char *)domname; + args.flags = flags; + + if (virNetClientProgramCall(mgr->program, + mgr->client, + mgr->serial++, + VIR_LOG_MANAGER_PROTOCOL_PROC_DOMAIN_GET_LOG_FILE_POSITION, + 0, NULL, NULL, NULL, + (xdrproc_t)xdr_virLogManagerProtocolDomainGetLogFilePositionArgs, &args, + (xdrproc_t)xdr_virLogManagerProtocolDomainGetLogFilePositionRet, &ret) < 0) + goto cleanup; + + *inode = ret.pos.inode; + *offset = ret.pos.offset; + + rv = 0; + cleanup: + return rv; +} + + +char * +virLogManagerDomainReadLogFile(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + ino_t inode, + off_t offset, + size_t maxlen, + unsigned int flags) +{ + struct virLogManagerProtocolDomainReadLogFileArgs args; + struct virLogManagerProtocolDomainReadLogFileRet ret; + int *fdout = NULL; + size_t fdoutlen = 0; + char *rv = NULL; + + memset(&args, 0, sizeof(args)); + memset(&ret, 0, sizeof(ret)); + + args.driver = (char *)driver; + memcpy(args.dom.uuid, domuuid, VIR_UUID_BUFLEN); + args.dom.name = (char *)domname; + args.flags = flags; + args.pos.inode = inode; + args.pos.offset = offset; + args.maxlen = maxlen; + + if (virNetClientProgramCall(mgr->program, + mgr->client, + mgr->serial++, + VIR_LOG_MANAGER_PROTOCOL_PROC_DOMAIN_READ_LOG_FILE, + 0, NULL, &fdoutlen, &fdout, + (xdrproc_t)xdr_virLogManagerProtocolDomainReadLogFileArgs, &args, + (xdrproc_t)xdr_virLogManagerProtocolDomainReadLogFileRet, &ret) < 0) + goto cleanup; + + rv = ret.data; + cleanup: + return rv; +} diff --git a/src/logging/log_manager.h b/src/logging/log_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..3dfe516faed097cb5f02d8ac140d614f8bbc7d3f --- /dev/null +++ b/src/logging/log_manager.h @@ -0,0 +1,61 @@ +/* + * log_manager.h: log management client + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * . + * + * Author: Daniel P. Berrange + */ + + +#ifndef __VIR_LOG_MANAGER_H__ +# define __VIR_LOG_MANAGER_H__ + +# include "internal.h" + +typedef struct _virLogManager virLogManager; +typedef virLogManager *virLogManagerPtr; + +virLogManagerPtr virLogManagerNew(bool privileged); + +void virLogManagerFree(virLogManagerPtr mgr); + +int virLogManagerDomainOpenLogFile(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + unsigned int flags, + ino_t *inode, + off_t *offset); + +int virLogManagerDomainGetLogFilePosition(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + unsigned int flags, + ino_t *inode, + off_t *offset); + +char *virLogManagerDomainReadLogFile(virLogManagerPtr mgr, + const char *driver, + const unsigned char *domuuid, + const char *domname, + ino_t inode, + off_t offset, + size_t maxlen, + unsigned int flags); + +#endif /* __VIR_LOG_MANAGER_H__ */