From: "Daniel P. Berrange" <berrange(a)redhat.com>
To allow the efficient correlation of container audit messages
with host hosts, include the pid namespace inode in audit
messages.
The resulting audit message will be
type=VIRT_CONTROL msg=audit(1362582468.378:50): pid=19284 uid=0 auid=0 ses=312
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='virt=lxc op=init
vm="demo" uuid=0770f019-2d4e-09e9-8e4a-719e12b3a18e vm-pid=19620 init-pid=19622
pid-ns=23434 exe="/home/berrange/src/virt/libvirt/daemon/.libs/lt-libvirtd"
hostname=? addr=? terminal=pts/6 res=success'
Note the 'pid-ns' field showing the inode number of the PID
namespace of the container init process. Since /proc/PID/ns/pid
doesn't exist on older kernels, we keep the previous 'init-pid'
field too, showing the host PID of the init process.
---
src/conf/domain_audit.c | 8 +++++---
src/conf/domain_audit.h | 3 ++-
src/lxc/lxc_process.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index c00bd11..8cd522a 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -649,7 +649,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool
success)
void
virDomainAuditInit(virDomainObjPtr vm,
- pid_t initpid)
+ pid_t initpid,
+ ino_t pidns)
{
char uuidstr[VIR_UUID_STRING_BUFLEN];
char *vmname;
@@ -668,8 +669,9 @@ virDomainAuditInit(virDomainObjPtr vm,
}
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);
+ "virt=%s op=init %s uuid=%s vm-pid=%lld init-pid=%lld
pid-ns=%lld",
+ virt, vmname, uuidstr, (long long)vm->pid, (long long)initpid,
+ (long long)pidns);
VIR_FREE(vmname);
}
diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h
index 381fe37..9486216 100644
--- a/src/conf/domain_audit.h
+++ b/src/conf/domain_audit.h
@@ -32,7 +32,8 @@ void virDomainAuditStart(virDomainObjPtr vm,
bool success)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virDomainAuditInit(virDomainObjPtr vm,
- pid_t pid)
+ pid_t pid,
+ ino_t pidns)
ATTRIBUTE_NONNULL(1);
void virDomainAuditStop(virDomainObjPtr vm,
const char *reason)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index aaa81a7..5f4a3aa 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -630,6 +630,36 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon
ATTRIBUTE_UNUSED
priv->stopReason, status);
}
+static int
+virLXCProcessGetNsInode(pid_t pid,
+ const char *nsname,
+ ino_t *inode)
+{
+ char *path = NULL;
+ struct stat sb;
+ int ret = -1;
+
+ if (virAsprintf(&path, "/proc/%llu/ns/%s",
+ (unsigned long long)pid, nsname) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (stat(path, &sb) < 0) {
+ virReportSystemError(errno,
+ _("Unable to stat %s"), path);
+ goto cleanup;
+ }
+
+ *inode = sb.st_ino;
+ ret = 0;
+
+cleanup:
+ VIR_FREE(path);
+ return ret;
+}
+
+
/* XXX a little evil */
extern virLXCDriverPtr lxc_driver;
static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
@@ -637,8 +667,20 @@ static void virLXCProcessMonitorInitNotify(virLXCMonitorPtr mon
ATTRIBUTE_UNUSED
virDomainObjPtr vm)
{
virLXCDomainObjPrivatePtr priv = vm->privateData;
+ ino_t inode;
+
priv->initpid = initpid;
- virDomainAuditInit(vm, initpid);
+
+ if (virLXCProcessGetNsInode(initpid, "pid", &inode) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_WARN("Cannot obtain pid NS inode for %llu: %s",
+ (unsigned long long)initpid,
+ err && err->message ? err->message :
"<unknown>");
+ virResetLastError();
+ } else {
+ inode = 0;
+ }
+ virDomainAuditInit(vm, initpid, inode);
if (virDomainSaveStatus(lxc_driver->caps, lxc_driver->stateDir, vm) < 0)
VIR_WARN("Cannot update XML with PID for LXC %s",
vm->def->name);
--
1.8.1.4