[libvirt] [PATCH] Log an audit message with the LXC init pid
Daniel J Walsh
dwalsh at redhat.com
Tue Nov 20 19:12:18 UTC 2012
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 11/20/2012 12:52 PM, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
>
> Currently the LXC driver logs audit messages when a container is started or
> stopped. These audit messages, however, contain the PID of the libvirt_lxc
> supervisor process. To enable sysadmins to correlate with audit messages
> generated by processes /inside/ the container, we need to include the
> container init process PID.
>
> We can't do this in the main 'start' audit message, since the init PID is
> not available at that point. Instead we output a completely new audit
> record, that lists both PIDs.
>
> type=VIRT_CONTROL msg=audit(1353433750.071:363): pid=20180 uid=0 auid=501
> ses=3 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
> msg='virt=lxc op=init vm="busy" uuid=dda7b947-0846-1759-2873-0f375df7d7eb
> vm-pid=20371 init-pid=20372
> exe="/home/berrange/src/virt/libvirt/daemon/.libs/lt-libvirtd" hostname=?
> addr=? terminal=pts/6 res=success' --- src/conf/domain_audit.c | 26
> ++++++++++++++++++++++++++ src/conf/domain_audit.h | 3 +++
> src/libvirt_private.syms | 1 + src/lxc/lxc_controller.c | 31
> ++++++++++++++++++++++++++++++- src/lxc/lxc_monitor.c | 23
> +++++++++++++++++++++++ src/lxc/lxc_monitor.h | 5 +++++
> src/lxc/lxc_process.c | 8 ++++++++ src/lxc/lxc_protocol.x | 7
> ++++++- 8 files changed, 102 insertions(+), 2 deletions(-)
>
> diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index
> 0f3924a..34cd92e 100644 --- a/src/conf/domain_audit.c +++
> b/src/conf/domain_audit.c @@ -605,6 +605,32 @@
> virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
> virDomainAuditLifecycle(vm, "start", reason, success); }
>
> +void +virDomainAuditInit(virDomainObjPtr vm, + unsigned
> long long initpid) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char
> *vmname; + const char *virt; + + virUUIDFormat(vm->def->uuid,
> uuidstr); + + if (!(vmname = virAuditEncode("vm", vm->def->name))) { +
> VIR_WARN("OOM while encoding audit message"); + return; + } + +
> if (!(virt = virDomainVirtTypeToString(vm->def->virtType))) { +
> VIR_WARN("Unexpected virt type %d while encoding audit message",
> vm->def->virtType); + virt = "?"; + } + +
> VIR_AUDIT(VIR_AUDIT_RECORD_MACHINE_CONTROL, true, + "virt=%s
> op=init %s uuid=%s vm-pid=%lld init-pid=%lld", + virt, vmname,
> uuidstr, (long long)vm->pid, initpid); + + VIR_FREE(vmname); +}
>
> void virDomainAuditStop(virDomainObjPtr vm, const char *reason) diff --git
> a/src/conf/domain_audit.h b/src/conf/domain_audit.h index db35d09..94b1198
> 100644 --- a/src/conf/domain_audit.h +++ b/src/conf/domain_audit.h @@ -31,6
> +31,9 @@ void virDomainAuditStart(virDomainObjPtr vm, const char *reason,
> bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +void
> virDomainAuditInit(virDomainObjPtr vm, + unsigned
> long long pid) + ATTRIBUTE_NONNULL(1); void
> virDomainAuditStop(virDomainObjPtr vm, const char *reason)
> ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git
> a/src/libvirt_private.syms b/src/libvirt_private.syms index
> 5a07139..23369e7 100644 --- a/src/libvirt_private.syms +++
> b/src/libvirt_private.syms @@ -258,6 +258,7 @@ virDomainAuditCgroupPath;
> virDomainAuditDisk; virDomainAuditFS; virDomainAuditHostdev;
> +virDomainAuditInit; virDomainAuditMemory; virDomainAuditNet;
> virDomainAuditNetDevice; diff --git a/src/lxc/lxc_controller.c
> b/src/lxc/lxc_controller.c index 4746897..65d117a 100644 ---
> a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -123,6 +123,7
> @@ struct _virLXCController {
>
> /* Server socket */ virNetServerPtr server; + bool firstClient;
> virNetServerClientPtr client; virNetServerProgramPtr prog; bool
> inShutdown; @@ -132,6 +133,8 @@ struct _virLXCController { #include
> "lxc_controller_dispatch.h"
>
> static void virLXCControllerFree(virLXCControllerPtr ctrl); +static int
> virLXCControllerEventSendInit(virLXCControllerPtr ctrl, +
> pid_t initpid);
>
> static void virLXCControllerQuitTimer(int timer ATTRIBUTE_UNUSED, void
> *opaque) { @@ -152,6 +155,7 @@ static virLXCControllerPtr
> virLXCControllerNew(const char *name) goto no_memory;
>
> ctrl->timerShutdown = -1; + ctrl->firstClient = true;
>
> if (!(ctrl->name = strdup(name))) goto no_memory; @@ -588,6 +592,11 @@
> static void *virLXCControllerClientPrivateNew(virNetServerClientPtr
> client, virNetServerClientSetCloseHook(client,
> virLXCControllerClientCloseHook); VIR_DEBUG("Got new client %p", client);
> ctrl->client = client; + + if (ctrl->initpid && ctrl->firstClient) +
> virLXCControllerEventSendInit(ctrl, ctrl->initpid); + ctrl->firstClient
> = false; + return dummy; }
>
> @@ -1283,8 +1292,10 @@ virLXCControllerEventSend(virLXCControllerPtr ctrl,
> { virNetMessagePtr msg;
>
> - if (!ctrl->client) + if (!ctrl->client) { +
> VIR_WARN("Dropping event %d becuase libvirtd is not connected", procnr);
> return; + }
>
> VIR_DEBUG("Send event %d client=%p", procnr, ctrl->client); if (!(msg =
> virNetMessageNew(false))) @@ -1352,6 +1363,24 @@
> virLXCControllerEventSendExit(virLXCControllerPtr ctrl,
>
>
> static int +virLXCControllerEventSendInit(virLXCControllerPtr ctrl, +
> pid_t initpid) +{ + virLXCProtocolInitEventMsg msg; + +
> VIR_DEBUG("Init pid %llu", (unsigned long long)initpid); + memset(&msg,
> 0, sizeof(msg)); + msg.initpid = initpid; + +
> virLXCControllerEventSend(ctrl, +
> VIR_LXC_PROTOCOL_PROC_INIT_EVENT, +
> (xdrproc_t)xdr_virLXCProtocolInitEventMsg, +
> (void*)&msg); + return 0; +} + + +static int
> virLXCControllerRun(virLXCControllerPtr ctrl) { int rc = -1; diff --git
> a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 3e00751..97ff828
> 100644 --- a/src/lxc/lxc_monitor.c +++ b/src/lxc/lxc_monitor.c @@ -65,12
> +65,20 @@ static void virLXCMonitorHandleEventExit(virNetClientProgramPtr
> prog, virNetClientPtr client, void *evdata, void *opaque); +static void
> +virLXCMonitorHandleEventInit(virNetClientProgramPtr prog, +
> virNetClientPtr client, + void *evdata, void
> *opaque);
>
> static virNetClientProgramEvent virLXCProtocolEvents[] = { {
> VIR_LXC_PROTOCOL_PROC_EXIT_EVENT, virLXCMonitorHandleEventExit,
> sizeof(virLXCProtocolExitEventMsg),
> (xdrproc_t)xdr_virLXCProtocolExitEventMsg }, + {
> VIR_LXC_PROTOCOL_PROC_INIT_EVENT, + virLXCMonitorHandleEventInit, +
> sizeof(virLXCProtocolInitEventMsg), +
> (xdrproc_t)xdr_virLXCProtocolInitEventMsg }, };
>
>
> @@ -88,6 +96,21 @@ virLXCMonitorHandleEventExit(virNetClientProgramPtr prog
> ATTRIBUTE_UNUSED, }
>
>
> +static void +virLXCMonitorHandleEventInit(virNetClientProgramPtr prog
> ATTRIBUTE_UNUSED, + virNetClientPtr client
> ATTRIBUTE_UNUSED, + void *evdata, void
> *opaque) +{ + virLXCMonitorPtr mon = opaque; +
> virLXCProtocolInitEventMsg *msg = evdata; + + VIR_DEBUG("Event init
> %llu", + (unsigned long long)msg->initpid); + if
> (mon->cb.initNotify) + mon->cb.initNotify(mon, msg->initpid,
> mon->vm); +} + + static void virLXCMonitorEOFNotify(virNetClientPtr client
> ATTRIBUTE_UNUSED, int reason ATTRIBUTE_UNUSED, void *opaque) diff --git
> a/src/lxc/lxc_monitor.h b/src/lxc/lxc_monitor.h index bb8349a..fd8efd9
> 100644 --- a/src/lxc/lxc_monitor.h +++ b/src/lxc/lxc_monitor.h @@ -40,10
> +40,15 @@ typedef void (*virLXCMonitorCallbackExitNotify)(virLXCMonitorPtr
> mon, virLXCProtocolExitStatus status, virDomainObjPtr vm);
>
> +typedef void (*virLXCMonitorCallbackInitNotify)(virLXCMonitorPtr mon, +
> unsigned long long pid, +
> virDomainObjPtr vm); + struct _virLXCMonitorCallbacks {
> virLXCMonitorCallbackDestroy destroy; virLXCMonitorCallbackEOFNotify
> eofNotify; virLXCMonitorCallbackExitNotify exitNotify; +
> virLXCMonitorCallbackInitNotify initNotify; };
>
> virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm, diff --git
> a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 079bc3a..c1ef2bd
> 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -637,9
> +637,17 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon
> ATTRIBUTE_UNUSED priv->stopReason, status); }
>
> +static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon
> ATTRIBUTE_UNUSED, + unsigned long
> long initpid, + virDomainObjPtr
> vm) +{ + virDomainAuditInit(vm, initpid); +} + static
> virLXCMonitorCallbacks monitorCallbacks = { .eofNotify =
> virLXCProcessMonitorEOFNotify, .exitNotify =
> virLXCProcessMonitorExitNotify, + .initNotify =
> virLXCProcessMonitorInitNotify, };
>
>
> diff --git a/src/lxc/lxc_protocol.x b/src/lxc/lxc_protocol.x index
> e437217..0f041f6 100644 --- a/src/lxc/lxc_protocol.x +++
> b/src/lxc/lxc_protocol.x @@ -14,9 +14,14 @@ struct
> virLXCProtocolExitEventMsg { enum virLXCProtocolExitStatus status; };
>
> +struct virLXCProtocolInitEventMsg { + unsigned hyper initpid; +}; +
> const VIR_LXC_PROTOCOL_PROGRAM = 0x12341234; const
> VIR_LXC_PROTOCOL_PROGRAM_VERSION = 1;
>
> enum virLXCProtocolProcedure { - VIR_LXC_PROTOCOL_PROC_EXIT_EVENT = 1 /*
> skipgen skipgen */ + VIR_LXC_PROTOCOL_PROC_EXIT_EVENT = 1, /* skipgen
> skipgen */ + VIR_LXC_PROTOCOL_PROC_INIT_EVENT = 2 /* skipgen skipgen */
> };
>
This looks good, but I still have two problems.
I don't think we are properly auditing the case where the container was
started but failed.
I need libvirt to drop the CONTAINER_initpid.pid file into /run/libvirt/lxc,
so that virt-sandbox-service execute could find the initpid. Or we need to
add a protocol so clients can ask the server for the pid of the init process.
We need this info to be able to join the container.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with undefined - http://www.enigmail.net/
iEYEARECAAYFAlCr1hEACgkQrlYvE4MpobN43gCgiqZdI4uamJT4hC+EGYryYDxa
DTYAniZ3VBPLzbXhb0yCPqiERKVxgUKr
=zlEl
-----END PGP SIGNATURE-----
More information about the libvir-list
mailing list