]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
Log an audit message with the LXC init pid
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 20 Nov 2012 17:49:25 +0000 (17:49 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 22 Nov 2012 10:46:40 +0000 (10:46 +0000)
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'

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/conf/domain_audit.c
src/conf/domain_audit.h
src/libvirt_private.syms
src/lxc/lxc_controller.c
src/lxc/lxc_monitor.c
src/lxc/lxc_monitor.h
src/lxc/lxc_process.c
src/lxc/lxc_protocol.x

index 0f3924a47bb7fa5303a571ba4fca78ffe012b026..939d2139d621176505b717e869d8c77f6cfa3f1c 100644 (file)
@@ -605,6 +605,32 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
     virDomainAuditLifecycle(vm, "start", reason, success);
 }
 
+void
+virDomainAuditInit(virDomainObjPtr vm,
+                   pid_t 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, (long long)initpid);
+
+    VIR_FREE(vmname);
+}
 
 void
 virDomainAuditStop(virDomainObjPtr vm, const char *reason)
index db35d097fe6797b5d7b16a5c7a06e236c73cfe4d..63a8f758b92c884e3ef45158df1a180619dbf98f 100644 (file)
@@ -31,6 +31,9 @@ void virDomainAuditStart(virDomainObjPtr vm,
                          const char *reason,
                          bool success)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+void virDomainAuditInit(virDomainObjPtr vm,
+                        pid_t pid)
+    ATTRIBUTE_NONNULL(1);
 void virDomainAuditStop(virDomainObjPtr vm,
                         const char *reason)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
index 756d7bd41e3fbecc645bda72a5d59b66208068b1..0115db184a189952bef9c6f6eb59da159b9f8c55 100644 (file)
@@ -258,6 +258,7 @@ virDomainAuditCgroupPath;
 virDomainAuditDisk;
 virDomainAuditFS;
 virDomainAuditHostdev;
+virDomainAuditInit;
 virDomainAuditMemory;
 virDomainAuditNet;
 virDomainAuditNetDevice;
index aec2d4ccd356908c529ab24fd7276805a77eac8d..6fffd68d62bb90e9d402ff095c51490d2f3823a0 100644 (file)
@@ -125,6 +125,7 @@ struct _virLXCController {
 
     /* Server socket */
     virNetServerPtr server;
+    bool firstClient;
     virNetServerClientPtr client;
     virNetServerProgramPtr prog;
     bool inShutdown;
@@ -134,6 +135,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)
 {
@@ -154,6 +157,7 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
         goto no_memory;
 
     ctrl->timerShutdown = -1;
+    ctrl->firstClient = true;
 
     if (!(ctrl->name = strdup(name)))
         goto no_memory;
@@ -591,6 +595,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;
 }
 
@@ -1278,8 +1287,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)))
@@ -1346,6 +1357,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)
 {
index 3e00751811b98462eb15de3f76bf542020e6a4d5..4d177c9596b1c7498968978a0e99a65c3c715d5f 100644 (file)
@@ -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, (pid_t)msg->initpid, mon->vm);
+}
+
+
 static void virLXCMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
                                    int reason ATTRIBUTE_UNUSED,
                                    void *opaque)
index bb8349a05a8a1cfeb0d6a87d9461b9aabab09968..9b06a37204c7af243f93b1d3edd842867af4b87a 100644 (file)
@@ -40,10 +40,15 @@ typedef void (*virLXCMonitorCallbackExitNotify)(virLXCMonitorPtr mon,
                                                 virLXCProtocolExitStatus status,
                                                 virDomainObjPtr vm);
 
+typedef void (*virLXCMonitorCallbackInitNotify)(virLXCMonitorPtr mon,
+                                                pid_t pid,
+                                                virDomainObjPtr vm);
+
 struct _virLXCMonitorCallbacks {
     virLXCMonitorCallbackDestroy destroy;
     virLXCMonitorCallbackEOFNotify eofNotify;
     virLXCMonitorCallbackExitNotify exitNotify;
+    virLXCMonitorCallbackInitNotify initNotify;
 };
 
 virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm,
index 079bc3abc47a7f77a527aa1d3937d299e1b2fc64..94a74dd138352d3cb587b257e63bb1f2d49711e0 100644 (file)
@@ -637,9 +637,17 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED
               priv->stopReason, status);
 }
 
+static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
+                                           pid_t initpid,
+                                           virDomainObjPtr vm)
+{
+    virDomainAuditInit(vm, initpid);
+}
+
 static virLXCMonitorCallbacks monitorCallbacks = {
     .eofNotify = virLXCProcessMonitorEOFNotify,
     .exitNotify = virLXCProcessMonitorExitNotify,
+    .initNotify = virLXCProcessMonitorInitNotify,
 };
 
 
index e4372178eb310a4439c0b11e8c62696f0aaf2e28..0f041f6c55ad79e0be5a90a54be7259c49830beb 100644 (file)
@@ -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 */
 };