diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 0f3924a47b..939d2139d6 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, + 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) diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h index db35d097fe..63a8f758b9 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, + pid_t 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 756d7bd41e..0115db184a 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 aec2d4ccd3..6fffd68d62 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -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) { diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c index 3e00751811..4d177c9596 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, (pid_t)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 bb8349a05a..9b06a37204 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, + pid_t 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 079bc3abc4..94a74dd138 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, + pid_t 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 e4372178eb..0f041f6c55 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 */ };