Description: mount /proc in container if needed.  Otherwise we can't
 change its apparmor profile.  When aa_change_onexec() is fixed, we
 want to use that, and simply call it in start.c before the setup_lxc()
 call.
 The part of this patch fixing the error paths in do_start() to goto
 out_warn_father instead of return -1 should however be kept
Author: Serge Hallyn <serge.hallyn@canonical.com>
Forwarded: no

Index: lxc-aa-onexec/src/lxc/start.c
===================================================================
--- lxc-aa-onexec.orig/src/lxc/start.c	2012-03-25 20:46:06.670144000 +0000
+++ lxc-aa-onexec/src/lxc/start.c	2012-03-26 01:58:36.491914050 +0000
@@ -538,6 +538,8 @@
 #define AA_DEF_PROFILE "lxc-container-default"
 static int apparmor_load(struct lxc_handler *handler)
 {
+	int mounted;
+
 	if (!apparmor_enabled) {
 		INFO("apparmor not enabled");
 		return 0;
@@ -552,16 +554,14 @@
 		return 0;
 	}
 
-	/* aa_change_onexec makes more sense since we want to transition when
-	 * /sbin/init is exec'd.  But the transitions doesn't seem to work
-	 * then (refused).  aa_change_onexec will work since we're doing it
-	 * right before the exec, so we'll just use that for now.
-	 */
 	//if (aa_change_onexec(handler->conf->aa_profile) < 0) {
 	if (aa_change_profile(handler->conf->aa_profile) < 0) {
 		SYSERROR("failed to change apparmor profile to %s", handler->conf->aa_profile);
 		return -1;
 	}
+	if (handler->conf->umount_proc == 1)
+		umount("/proc");
+
 	INFO("changed apparmor profile to %s", handler->conf->aa_profile);
 
 	return 0;
@@ -598,7 +598,7 @@
 	if (handler->conf->need_utmp_watch) {
 		if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
 			SYSERROR("failed to remove CAP_SYS_BOOT capability");
-			return -1;
+			goto out_warn_father;
 		}
 		DEBUG("Dropped cap_sys_boot\n");
 	}
@@ -609,10 +609,10 @@
 		goto out_warn_father;
 	}
 
-	close(handler->sigfd);
-
 	if (apparmor_load(handler) < 0)
-		return -1;
+		goto out_warn_father;
+
+	close(handler->sigfd);
 
 	/* after this call, we are in error because this
 	 * ops should not return as it execs */
Index: lxc-aa-onexec/src/lxc/conf.c
===================================================================
--- lxc-aa-onexec.orig/src/lxc/conf.c	2012-03-25 20:46:06.670144000 +0000
+++ lxc-aa-onexec/src/lxc/conf.c	2012-03-26 02:25:14.849599116 +0000
@@ -1538,6 +1538,7 @@
 	}
 	memset(new, 0, sizeof(*new));
 
+	new->umount_proc = 0;
 	new->personality = -1;
 	new->console.path = NULL;
 	new->console.peer = -1;
@@ -1880,8 +1881,39 @@
 	tty_info->nbtty = 0;
 }
 
+/*
+ * make sure /proc/1 exists, else mount /proc.  Return 0 if proc was
+ * already mounted, 1 if we mounted it, -1 if we failed.
+ */
+static int mount_proc_if_needed(char *rootfs_tgt)
+{
+	struct stat statbuf;
+	char path[MAXPATHLEN];
+	int ret;
+
+	ret = snprintf(path, MAXPATHLEN, "%s/proc/1/cmdline", rootfs_tgt);
+	if (ret < 0 || ret >= MAXPATHLEN) {
+		SYSERROR("proc path name too long");
+		return -1;
+	}
+	ret = stat(path, &statbuf);
+	INFO("checking if proc mount needed\n");
+	if (ret == 0) {
+		INFO("no proc mount needed\n");
+		return 0;
+	}
+	ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs_tgt);
+	INFO("proc mount needed, mounting to %s\n", path);
+	if (mount("proc", path, "proc", 0, NULL))
+		return -1;
+	INFO("Mounted /proc for the container\n");
+	return 1;
+}
+
 int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
 {
+	int mounted;
+
 	if (setup_utsname(lxc_conf->utsname)) {
 		ERROR("failed to setup the utsname for '%s'", name);
 		return -1;
@@ -1922,6 +1954,20 @@
 		return -1;
 	}
 
+	/* aa_change_onexec makes more sense since we want to transition when
+	 * /sbin/init is exec'd.  But the transitions doesn't seem to work
+	 * then (refused).  aa_change_onexec will work since we're doing it
+	 * right before the exec, so we'll just use that for now.
+	 * In case the container fstab didn't mount /proc, we mount it.
+	 */
+	mounted = mount_proc_if_needed(lxc_conf->rootfs.mount);
+	if (mounted == -1) {
+		SYSERROR("failed to mount /proc in the container.");
+		return -1;
+	} else if (mounted == 1) {
+		lxc_conf->umount_proc = 1;
+	}
+
 	if (setup_pivot_root(&lxc_conf->rootfs)) {
 		ERROR("failed to set rootfs for '%s'", name);
 		return -1;
Index: lxc-aa-onexec/src/lxc/conf.h
===================================================================
--- lxc-aa-onexec.orig/src/lxc/conf.h	2012-03-25 20:46:06.670144000 +0000
+++ lxc-aa-onexec/src/lxc/conf.h	2012-03-26 01:55:47.715917678 +0000
@@ -213,6 +213,7 @@
 	char *ttydir;
 	int close_all_fds;
 	char *aa_profile;
+	int umount_proc;
 };
 
 /*
