From d4ea450710597440014060235042af14afa4b905 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@ubuntu.com>
Date: Tue, 31 Jul 2012 16:04:33 +0200
Subject: [PATCH 1/3] templates: use relative paths when creating containers

At the same time, allow lxc.mount.entry to specify an absolute target
path relative to /var/lib/lxc/CN/rootfs, even if rootfs is a blockdev.
Otherwise all such entries are ignored for blockdev-backed containers.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/conf.c            |   48 ++++++++++++++++++++++++++++++++++-----------
 templates/lxc-debian.in   |    4 ++--
 templates/lxc-fedora.in   |    6 +++---
 templates/lxc-lenny.in    |    4 ++--
 templates/lxc-opensuse.in |    4 ++--
 templates/lxc-sshd.in     |   16 +++++++--------
 templates/lxc-ubuntu.in   |    6 +++---
 7 files changed, 57 insertions(+), 31 deletions(-)

Index: lxc-0.7.5/src/lxc/conf.c
===================================================================
--- lxc-0.7.5.orig/src/lxc/conf.c
+++ lxc-0.7.5/src/lxc/conf.c
@@ -981,27 +981,50 @@ static inline int mount_entry_on_systemf
 }
 
 static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
-					  const struct lxc_rootfs *rootfs)
+					  const struct lxc_rootfs *rootfs,
+					  const char *lxc_name)
 {
 	char *aux;
 	char path[MAXPATHLEN];
 	unsigned long mntflags;
 	char *mntdata;
-	int ret = 0;
+	int r, ret = 0, offset;
 
 	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
 		ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
 		return -1;
 	}
 
+	/* if rootfs->path is a blockdev path, allow container fstab to
+	 * use /var/lib/lxc/CN/rootfs as the target prefix */
+	r = snprintf(path, MAXPATHLEN, "/var/lib/lxc/%s/rootfs", lxc_name);
+	if (r < 0 || r >= MAXPATHLEN)
+		goto skipvarlib;
+
+	aux = strstr(mntent->mnt_dir, path);
+	if (aux) {
+		offset = strlen(path);
+		goto skipabs;
+	}
+
+skipvarlib:
 	aux = strstr(mntent->mnt_dir, rootfs->path);
 	if (!aux) {
 		WARN("ignoring mount point '%s'", mntent->mnt_dir);
 		goto out;
 	}
+	offset = strlen(rootfs->path);
+
+skipabs:
 
 	snprintf(path, MAXPATHLEN, "%s/%s", rootfs->mount,
-		 aux + strlen(rootfs->path));
+		 aux + offset);
+	if (r < 0 || r >= MAXPATHLEN) {
+		WARN("pathnme too long for '%s'", mntent->mnt_dir);
+		ret = -1;
+		goto out;
+	}
+
 
 	ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
 			  mntflags, mntdata);
@@ -1035,7 +1058,8 @@ static int mount_entry_on_relative_rootf
 	return ret;
 }
 
-static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file)
+static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file,
+	const char *lxc_name)
 {
 	struct mntent *mntent;
 	int ret = -1;
@@ -1056,7 +1080,7 @@ static int mount_file_entries(const stru
 			continue;
 		}
 
-		if (mount_entry_on_absolute_rootfs(mntent, rootfs))
+		if (mount_entry_on_absolute_rootfs(mntent, rootfs, lxc_name))
 			goto out;
 	}
 
@@ -1067,7 +1091,8 @@ out:
 	return ret;
 }
 
-static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab)
+static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
+	const char *lxc_name)
 {
 	FILE *file;
 	int ret;
@@ -1081,13 +1106,14 @@ static int setup_mount(const struct lxc_
 		return -1;
 	}
 
-	ret = mount_file_entries(rootfs, file);
+	ret = mount_file_entries(rootfs, file, lxc_name);
 
 	endmntent(file);
 	return ret;
 }
 
-static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount)
+static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount,
+	const char *lxc_name)
 {
 	FILE *file;
 	struct lxc_list *iterator;
@@ -1107,7 +1133,7 @@ static int setup_mount_entries(const str
 
 	rewind(file);
 
-	ret = mount_file_entries(rootfs, file);
+	ret = mount_file_entries(rootfs, file, lxc_name);
 
 	fclose(file);
 	return ret;
@@ -1825,12 +1851,12 @@ int lxc_setup(const char *name, struct l
 		return -1;
 	}
 
-	if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab)) {
+	if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) {
 		ERROR("failed to setup the mounts for '%s'", name);
 		return -1;
 	}
 
-	if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list)) {
+	if (setup_mount_entries(&lxc_conf->rootfs, &lxc_conf->mount_list, name)) {
 		ERROR("failed to setup the mount entries for '%s'", name);
 		return -1;
 	}
Index: lxc-0.7.5/templates/lxc-debian.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-debian.in
+++ lxc-0.7.5/templates/lxc-debian.in
@@ -211,8 +211,8 @@ lxc.cgroup.devices.allow = c 5:2 rwm
 lxc.cgroup.devices.allow = c 254:0 rwm
 
 # mounts point
-lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0
-lxc.mount.entry=sysfs $rootfs/sys sysfs defaults  0 0
+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
+lxc.mount.entry=sysfs sys sysfs defaults  0 0
 EOF
 
     if [ $? -ne 0 ]; then
Index: lxc-0.7.5/templates/lxc-fedora.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-fedora.in
+++ lxc-0.7.5/templates/lxc-fedora.in
@@ -225,9 +225,9 @@ lxc.cgroup.devices.allow = c 254:0 rwm
 EOF
 
     cat <<EOF > $config_path/fstab
-+proc            $rootfs_path/proc         proc    nodev,noexec,nosuid 0 0
-+devpts          $rootfs_path/dev/pts      devpts defaults 0 0
-+sysfs           $rootfs_path/sys          sysfs defaults  0 0
+proc            proc         proc    nodev,noexec,nosuid 0 0
+devpts          dev/pts      devpts defaults 0 0
+sysfs           sys          sysfs defaults  0 0
 EOF
 
     if [ $? -ne 0 ]; then
Index: lxc-0.7.5/templates/lxc-lenny.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-lenny.in
+++ lxc-0.7.5/templates/lxc-lenny.in
@@ -200,8 +200,8 @@ lxc.cgroup.devices.allow = c 5:2 rwm
 lxc.cgroup.devices.allow = c 254:0 rwm
 
 # mounts point
-lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0
-lxc.mount.entry=sysfs $rootfs/sys sysfs defaults  0 0
+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
+lxc.mount.entry=sysfs sys sysfs defaults  0 0
 EOF
 
     if [ $? -ne 0 ]; then
Index: lxc-0.7.5/templates/lxc-opensuse.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-opensuse.in
+++ lxc-0.7.5/templates/lxc-opensuse.in
@@ -312,9 +312,9 @@ lxc.cgroup.devices.allow = c 254:0 rwm
 EOF
 
     cat <<EOF > $config_path/$name/fstab
-proc            $rootfs/proc         proc	nodev,noexec,nosuid 0 0
-sysfs           $rootfs/sys          sysfs	defaults  0 0
-tmpfs           $rootfs/run          tmpfs	mode=0755,nodev,nosuid 0 0
+proc            proc         proc	nodev,noexec,nosuid 0 0
+sysfs           sys          sysfs	defaults  0 0
+tmpfs           run          tmpfs	mode=0755,nodev,nosuid 0 0
 EOF
 
     if [ $? -ne 0 ]; then
Index: lxc-0.7.5/templates/lxc-sshd.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-sshd.in
+++ lxc-0.7.5/templates/lxc-sshd.in
@@ -100,18 +100,18 @@ cat <<EOF >> $config_path/$name/config
 lxc.utsname = $name
 lxc.pts = 1024
 lxc.rootfs = $rootfs
-lxc.mount.entry=/dev $rootfs/dev none ro,bind 0 0
-lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0
-lxc.mount.entry=/bin $rootfs/bin none ro,bind 0 0
-lxc.mount.entry=/usr /$rootfs/usr none ro,bind 0 0
-lxc.mount.entry=/sbin $rootfs/sbin none ro,bind 0 0
-lxc.mount.entry=tmpfs $rootfs/var/run/sshd tmpfs mode=0644 0 0
-lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd $rootfs/sbin/init none bind 0 0
+lxc.mount.entry=/dev dev none ro,bind 0 0
+lxc.mount.entry=/lib lib none ro,bind 0 0
+lxc.mount.entry=/bin bin none ro,bind 0 0
+lxc.mount.entry=/usr usr none ro,bind 0 0
+lxc.mount.entry=/sbin sbin none ro,bind 0 0
+lxc.mount.entry=tmpfs var/run/sshd tmpfs mode=0644 0 0
+lxc.mount.entry=@LXCTEMPLATEDIR@/lxc-sshd sbin/init none bind 0 0
 EOF
 
 if [ "$(uname -m)" = "x86_64" ]; then
     cat <<EOF >> $config_path/$name/config
-lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0
+lxc.mount.entry=/lib64 lib64 none ro,bind 0 0
 EOF
 fi
 }
Index: lxc-0.7.5/templates/lxc-ubuntu.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-ubuntu.in
+++ lxc-0.7.5/templates/lxc-ubuntu.in
@@ -200,8 +200,8 @@ lxc.cgroup.devices.allow = c 10:229 rwm
 EOF
 
     cat <<EOF > $config_path/$name/fstab
-proc            $rootfs/proc         proc    nodev,noexec,nosuid 0 0
-sysfs           $rootfs/sys          sysfs defaults  0 0
+proc            proc         proc    nodev,noexec,nosuid 0 0
+sysfs           sys          sysfs defaults  0 0
 EOF
 
     if [ $? -ne 0 ]; then
@@ -333,7 +333,12 @@ do_bindhome()
     # bind-mount the user's path into the container's /home
     h=`getent passwd $user | cut -d: -f 6`
     mkdir -p $rootfs/$h
-    echo "$h $rootfs/$h none bind 0 0" >> $path/fstab
+	# use relative path in container
+	h2=${h#/}
+	while [ ${h2:0:1} = "/" ]; do
+		h2=${h2#/}
+	done
+    echo "$h $h2 none bind 0 0" >> $path/fstab
 
     # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
     pwd=`getent passwd $user`
Index: lxc-0.7.5/templates/lxc-busybox.in
===================================================================
--- lxc-0.7.5.orig/templates/lxc-busybox.in
+++ lxc-0.7.5/templates/lxc-busybox.in
@@ -242,12 +242,17 @@ lxc.mount.entry=/usr/lib $rootfs/usr/lib
 EOF
 fi
 
-if [ -d "/lib64" ] && [ -d "$rootfs/lib64" ]; then
-cat <<EOF >> $config_path/$name/config
-lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0
-lxc.mount.entry=/usr/lib64 $rootfs/usr/lib64 none ro,bind 0 0
-EOF
-fi
+    libdirs="\
+        lib \
+        usr/lib \
+        lib64 \
+        usr/lib64"
+
+    for dir in $libdirs; do
+        if [ -d "/$dir" ] && [ -d "$rootfs/$dir" ]; then
+            echo "lxc.mount.entry=/$dir $dir none ro,bind 0 0" >> $config_path/$name/config
+        fi
+    done
 }
 
 usage()
