-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 11/20/2012 12:52 PM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)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-----