[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