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-0.8.0~rc1/src/lxc/start.c
===================================================================
--- lxc-0.8.0~rc1.orig/src/lxc/start.c	2012-04-23 23:03:55.207946270 -0500
+++ lxc-0.8.0~rc1/src/lxc/start.c	2012-04-23 23:04:04.399946115 -0500
@@ -511,6 +511,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;
@@ -525,16 +527,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;
@@ -571,7 +571,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");
 	}
@@ -582,10 +582,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-0.8.0~rc1/src/lxc/conf.c
===================================================================
--- lxc-0.8.0~rc1.orig/src/lxc/conf.c	2012-04-23 23:03:05.015947121 -0500
+++ lxc-0.8.0~rc1/src/lxc/conf.c	2012-04-23 23:04:04.399946115 -0500
@@ -1651,6 +1651,7 @@
 	}
 	memset(new, 0, sizeof(*new));
 
+	new->umount_proc = 0;
 	new->personality = -1;
 	new->console.path = NULL;
 	new->console.peer = -1;
@@ -2057,8 +2058,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;
@@ -2099,6 +2131,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-0.8.0~rc1/src/lxc/conf.h
===================================================================
--- lxc-0.8.0~rc1.orig/src/lxc/conf.h	2012-04-23 23:02:00.935948206 -0500
+++ lxc-0.8.0~rc1/src/lxc/conf.h	2012-04-23 23:04:04.399946115 -0500
@@ -218,6 +218,7 @@
 	char *ttydir;
 	int close_all_fds;
 	char *aa_profile;
+	int umount_proc;
 };
 
 /*
