-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/20/2012 12:52 PM, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > 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----- -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list