From 2dab7e26a5364a6d0f002186c4e0081e4621bf5b Mon Sep 17 00:00:00 2001
From: InformatiQ <rhanna@informatiq.org>
Date: Wed, 31 Aug 2011 00:20:09 +0200
Subject: [PATCH 01/13] * allow cloning of non-snapshot lvm devices

Signed-off-by: InformatiQ <rhanna@informatiq.org>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
---
 src/lxc/lxc-clone.in |   98 ++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index 810efac..f3e4522 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -22,7 +22,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 usage() {
-    echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v vgname]"
+    echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v vgname] [-p lxc_lv_prefix] [-t fstype]"
 }
 
 help() {
@@ -36,16 +36,20 @@ help() {
     echo "-s          : make the new rootfs a snapshot of the original"
     echo "fssize      : size if creating a new fs.  By default, 2G"
     echo "vgname      : lvm volume group name, lxc by default"
+    echo "lvprefix"   : lvm volume name prefix, none by default, e.g. --lvprefix=lxc_ then new lxc lv name will be lxc_newname"
+    echo "fstype"     : new container file system type, ext3 by default (only works for non-snapshot lvm)"
 }
 
-shortoptions='ho:n:sL:v:'
-longoptions='help,orig:,name:,snapshot,fssize,vgname'
+shortoptions='ho:n:sL:v:p:t:'
+longoptions='help,orig:,name:,snapshot,fssize:,vgname:,lvprefix:,fstype:'
 lxc_path=@LXCPATH@
 config_path=@LXCETCPATH@
 bindir=/usr/bin
 snapshot=no
 lxc_size=2G
 lxc_vg=lxc
+lxc_lv_prefix=""
+fstype=ext3
 
 getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
 if [ $? != 0 ]; then
@@ -64,6 +68,7 @@ while true; do
 	    -s|--snapshot)
 		shift
 		snapshot=yes
+                snapshot_opt="-s"
 		;;
 	    -o|--orig)
 		shift
@@ -85,6 +90,11 @@ while true; do
 		lxc_new=$1
 		shift
 		;;
+            -p|--lvprefix)
+                shift
+                lxc_lv_prefix=$1
+                shift
+                ;;
             --)
 		shift
 		break;;
@@ -143,50 +153,92 @@ trap "${bindir}/lxc-destroy -n $lxc_new; echo aborted; exit 1" SIGHUP SIGINT SIG
 mkdir -p $lxc_path/$lxc_new
 mkdir -p $config_path/$lxc_new
 
+hostname=$lxc_new
+
 echo "Tweaking configuration"
 cp $config_path/$lxc_orig/config $config_path/$lxc_new/config
 sed -i '/lxc.utsname/d' $config_path/$lxc_new/config
 echo "lxc.utsname = $hostname" >> $config_path/$lxc_new/config
 
-sed -i '/lxc.mount/d' $config_path/$lxc_new/config
-echo "lxc.mount = $config_path/$lxc_new/fstab" >> $config_path/$lxc_new/config
+grep "lxc.mount =" $config_path/$lxc_new/config >/dev/null 2>&1 && { sed -i '/lxc.mount =/d' $config_path/$lxc_new/config; echo "lxc.mount = $config_path/$lxc_new/fstab" >> $config_path/$lxc_new/config; }
 
-cp $config_path/$lxc_orig/fstab $config_path/$lxc_new/fstab
-sed -i "s@$config_path/$lxc_orig@$config_path/$lxc_new@" $config_path/$lxc_new/fstab
+if [ -e  $config_path/$lxc_orig/fstab ];then
+    cp $config_path/$lxc_orig/fstab $config_path/$lxc_new/fstab
+    sed -i "s@$config_path/$lxc_orig@$config_path/$lxc_new@" $config_path/$lxc_new/fstab
+fi
 
 echo "Copying rootfs..."
 rootfs=$lxc_path/$lxc_new/rootfs
 # First figure out if the old is a device.  For now we only support
 # lvm devices.
 mounted=0
-sed -i '/lxc.rootfs/d' $config_path/$lxc_new/config
+#is container running
+lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+    container_running=True
+fi
+sed -i '/lxc.rootfs/d' $lxc_config/$lxc_new/config
 oldroot=`grep lxc.rootfs $config_path/$lxc_orig/config | awk -F= '{ print $2 '}`
 if [ -b $oldroot ]; then
 	# this is a device.  If we don't want to snapshot, then mkfs, mount
 	# and rsync.  Trivial but not yet implemented
-	if [ $snapshot == "no" ]; then
-		echo "non-snapshot and non-lvm clone of block device not yet implemented"
-		exit 1
-	fi
+	#if [ $snapshot == "no" ]; then
+	#	echo "non-snapshot and non-lvm clone of block device not yet implemented"
+	#	exit 1
+	#fi
 	lvdisplay $oldroot > /dev/null 2>&1
 	if [ $? -ne 0 ]; then
-		echo "non-snapshot and non-lvm clone of block device not yet implemented"
-		exit 1
-	fi
+            lvm=False
+            echo "non-lvm block device cloning not yet implemented"
+            exit 1
+        else
+            lvm=TRUE
+        fi
 	# ok, create a snapshot of the lvm device
-	lvcreate -s -L $lxc_size -n $lxc_new /dev/$lxc_vg/$lxc_orig || exit 1
-	echo "lxc.rootfs = /dev/$lxc_vg/$lxc_new" >> $config_path/$lxc_new/config
-	# and mount it so we can tweak it
-	mkdir -p $lxc_path/$lxc_new/rootfs
-	mount /dev/$lxc_vg/$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }
-	mounted=1
+        if [ $container_running == "True" ]; then
+            lxc-freeze -n $lxc_orig
+        fi
+	lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot || exit 1
+        if [ $container_running == "True" ]; then
+            lxc-unfreeze -n $lxc_orig
+        fi
+        if [ $snapshot == "no" ]; then
+            #mount snapshot
+            mkdir -p ${rootfs}_snapshot
+            mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "failed to mount new rootfs_snapshot"; exit 1; }
+            #create a new lv
+            lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new
+	    echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
+	    # and mount it so we can tweak it
+            mkdir -p $lxc_path/$lxc_new/rootfs
+            mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new
+            mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }
+            mounted=1
+            rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "copy of data to new lv failed"; exit 1; }
+            umount ${rootfs}_snapshot || { echo "failed to unmount new rootfs_snapshot"; exit 1; }
+            rm -rf ${rootfs}_snapshot
+            lvremove -f $lxc_vg/${lxc_lv_prefix}$lxc_new || echo "failed to remove the snapshot"
+        else
+            lvrename $lxc_vg/${lxc_lv_prefix}}${lxc_new}_snapshot $lxc_vg/${lxc_lv_prefix}$lxc_new
+            echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
+	    # and mount it so we can tweak it
+            mkdir -p $lxc_path/$lxc_new/rootfs
+            mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }
+            mounted=1
+        fi
+
 else
-	cp -a $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs || return 1
+        if [ $container_running == True ];then
+            lxc-freeze -n $lxc_orig
+        fi
+	rsync -ax $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs || return 1
+        if [ $container_running == True ];then
+            lxc-unfreeze -n $lxc_orig
+        fi
 	echo "lxc.rootfs = $rootfs" >> $config_path/$lxc_new/config
 fi
 
 echo "Updating rootfs..."
-hostname=$lxc_new
 
 # so you can 'ssh $hostname.' or 'ssh $hostname.local'
 if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then
-- 
1.7.7


From 7cb5b327636b81f5ecf543a37017cfcaead3d18c Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Mon, 23 Jan 2012 12:59:14 -0600
Subject: [PATCH 02/13] Fix several nagging bugs in lxc-destroy

Don't delete a running container.  If it's running, abort the delete
unless a new '-f' (force) flag is given, in which case, stop it first.

Handle the case where we can't find $rootfs in config

Fix broken detection of lvm backing store

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-destroy.in |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/lxc/lxc-destroy.in b/src/lxc/lxc-destroy.in
index 91bdbe1..59d22c0 100644
--- a/src/lxc/lxc-destroy.in
+++ b/src/lxc/lxc-destroy.in
@@ -26,7 +26,8 @@
 #
 
 usage() {
-    echo "usage: $0 -n <name>"
+    echo "usage: $0 -n <name> [-f]"
+    echo "  -f: if a container is running, stop it first.  Default is to abort"
 }
 
 if [ "$(id -u)" != "0" ]; then
@@ -34,10 +35,11 @@ if [ "$(id -u)" != "0" ]; then
    exit 1
 fi
 
-shortoptions='n:'
+shortoptions='n:f'
 longoptions='name:'
 lxc_path=@LXCPATH@
 lxc_etc_path=@LXCETCPATH@
+force=0
 
 getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
 if [ $? != 0 ]; then
@@ -54,6 +56,10 @@ while true; do
 		lxc_name=$1
 		shift
 		;;
+	    -f)
+		force=1
+		shift
+		;;
             --)
 		shift
 		break;;
@@ -76,14 +82,28 @@ if [ ! -d "$lxc_path/$lxc_name" -o ! -f "$lxc_etc_path/$lxc_name/config"  ]; the
     exit 1
 fi
 
+# make sure the container isn't running
+lxc-info -n $lxc_name 2>/dev/null | grep -q RUNNING
+if [ $? -eq 0 ]; then
+	if [ $force -eq 1 ]; then
+		lxc-stop -n $lxc_name
+	else
+		echo "Container $lxc_name is running, aborting the deletion."
+		exit 1
+	fi
+fi
+
 # Deduce the type of rootfs
 # If LVM partition, destroy it.  If anything else, ignore it.  We'll support
 # deletion of others later.
-rootdev=`grep lxc.rootfs $lxc_etc_path/$lxc_name/config | awk -F= '{ print $2 '}`
-if [ -b $rootdev -o -h $rootdev ]; then
-	lvdisplay $rootdev > /dev/null 2>&1
-	if [ $? -eq 0 ]; then
-		lvremove $rootdev
+rootdev=`grep lxc.rootfs $lxc_etc_path/$lxc_name/config 2>/dev/null | sed -e 's/^[^/]*/\//'`
+if [ ! -z "$rootdev" ]; then
+	if [ -b "$rootdev" -o -h "$rootdev" ]; then
+		lvdisplay $rootdev > /dev/null 2>&1
+		if [ $? -eq 0 ]; then
+			echo "removing backing store: $rootdev"
+			lvremove -f $rootdev
+		fi
 	fi
 fi
 # recursively remove the container to remove old container configuration
-- 
1.7.7


From fd1d688560ea4eb6ab0403a96e8ea40d44692972 Mon Sep 17 00:00:00 2001
From: InformatiQ <rhanna@informatiq.org>
Date: Wed, 31 Aug 2011 00:20:09 +0200
Subject: [PATCH 03/13] *add the new opts to help() *set
 container_running=false

Signed-off-by: InformatiQ <rhanna@informatiq.org>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
---
 src/lxc/lxc-clone.in |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index f3e4522..efb87a2 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -36,8 +36,8 @@ help() {
     echo "-s          : make the new rootfs a snapshot of the original"
     echo "fssize      : size if creating a new fs.  By default, 2G"
     echo "vgname      : lvm volume group name, lxc by default"
-    echo "lvprefix"   : lvm volume name prefix, none by default, e.g. --lvprefix=lxc_ then new lxc lv name will be lxc_newname"
-    echo "fstype"     : new container file system type, ext3 by default (only works for non-snapshot lvm)"
+    echo "lvprefix    : lvm volume name prefix, none by default, e.g. --lvprefix=lxc_ then new lxc lv name will be lxc_newname"
+    echo "fstype      : new container file system type, ext3 by default (only works for non-snapshot lvm)"
 }
 
 shortoptions='ho:n:sL:v:p:t:'
@@ -176,6 +176,8 @@ mounted=0
 lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1
 if [ $? -ne 0 ]; then
     container_running=True
+else
+    container_running=False
 fi
 sed -i '/lxc.rootfs/d' $lxc_config/$lxc_new/config
 oldroot=`grep lxc.rootfs $config_path/$lxc_orig/config | awk -F= '{ print $2 '}`
-- 
1.7.7


From 2fd7a96e1e086b8575b92d0b6f6d4f74900ba949 Mon Sep 17 00:00:00 2001
From: InformatiQ <rhanna@informatiq.org>
Date: Wed, 31 Aug 2011 00:20:09 +0200
Subject: [PATCH 04/13] if after freezing the container the snapshot/rsync
 fails, unfreeze before exiting

Signed-off-by: InformatiQ <rhanna@informatiq.org>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
---
 src/lxc/lxc-clone.in |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index efb87a2..4b6345c 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -200,10 +200,15 @@ if [ -b $oldroot ]; then
         if [ $container_running == "True" ]; then
             lxc-freeze -n $lxc_orig
         fi
-	lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot || exit 1
+	lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot
+        RETVAL=$?
         if [ $container_running == "True" ]; then
             lxc-unfreeze -n $lxc_orig
         fi
+        if [ $RETVAL -ne 0 ]; then
+            echo "snapshot creation failed"
+            exit 1
+        fi
         if [ $snapshot == "no" ]; then
             #mount snapshot
             mkdir -p ${rootfs}_snapshot
@@ -233,10 +238,15 @@ else
         if [ $container_running == True ];then
             lxc-freeze -n $lxc_orig
         fi
-	rsync -ax $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs || return 1
+	rsync -ax $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs
+        RETVAL=$?
         if [ $container_running == True ];then
             lxc-unfreeze -n $lxc_orig
         fi
+        if [ RETVAL -ne 0 ]; then
+            echo "copying rootfs failed"
+            exit 1
+        fi
 	echo "lxc.rootfs = $rootfs" >> $config_path/$lxc_new/config
 fi
 
-- 
1.7.7


From 103feb430d2c02ae468483c09d5a489b2482ba0f Mon Sep 17 00:00:00 2001
From: "Serge E. Hallyn" <serge.hallyn@canonical.com>
Date: Mon, 24 Oct 2011 14:38:30 +0200
Subject: [PATCH 05/13] lxc-clone: fix dhclient.conf send hostname command

End the command with ';', which is needed, and put the hostname in
quotes (which doesn't really seem needed, but shown in man page).

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-clone.in |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index 4b6345c..c7a69fc 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -254,7 +254,7 @@ echo "Updating rootfs..."
 
 # so you can 'ssh $hostname.' or 'ssh $hostname.local'
 if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then
-	sed -i "s/send host-name.*$/send host-name $hostname/" $rootfs/etc/dhcp/dhclient.conf
+	sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf
 fi
 
 # set the hostname
-- 
1.7.7


From 44c643161d258d9765708c66561e399341524a97 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Mon, 23 Jan 2012 13:25:11 -0600
Subject: [PATCH 06/13] add lvm support to lxc-create

1. Some templates copy the cached pristine rootfs using 'cp a b' where b is
$lxc_path/$name/rootfs.  That doesn't do the right thing if rootfs already
exists, as it will when it is an lvm or other mount.  So switch to
'rsync a/ b/'.  (cp can be made to work too of course).

2. Update lxc-create to support backing stores.  For now only lvm is
implemented.

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-clone.in      |    2 +-
 src/lxc/lxc-create.in     |  126 ++++++++++++++++++++++++++++++++++++++++++---
 templates/lxc-debian.in   |    3 +-
 templates/lxc-opensuse.in |    3 +-
 templates/lxc-ubuntu.in   |    5 +-
 5 files changed, 126 insertions(+), 13 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index c7a69fc..78a6c04 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -44,7 +44,7 @@ shortoptions='ho:n:sL:v:p:t:'
 longoptions='help,orig:,name:,snapshot,fssize:,vgname:,lvprefix:,fstype:'
 lxc_path=@LXCPATH@
 config_path=@LXCETCPATH@
-bindir=/usr/bin
+bindir=@BINDIR@
 snapshot=no
 lxc_size=2G
 lxc_vg=lxc
diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in
index a12d8eb..e94b642 100644
--- a/src/lxc/lxc-create.in
+++ b/src/lxc/lxc-create.in
@@ -21,7 +21,12 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
 usage() {
-    echo "usage: lxc-create -n <name> [-f configuration] [-t template] [-h] -- [template_options]"
+    echo "usage: lxc-create -n <name> [-f configuration] [-t template] [-h] [fsopts] -- [template_options]"
+    echo "   fsopts: -B none"
+    echo "   fsopts: -B lvm [--lvname lvname] [--vgname vgname] [--fstype fstype] [--fssize fssize]"
+#    echo "   fsopts: -B union [--uniontype overlayfs]"
+#    echo "   fsopts: -B loop [--fstype fstype] [--fssize fssize]"
+#    echo "   fsopts: -B qemu-nbd [--type qed|qcow2|raw] [--fstype fstype] [--fssize fssize] # Qemu qed disk format"
 }
 
 help() {
@@ -33,6 +38,16 @@ help() {
     echo "name         : name of the container"
     echo "configuration: lxc configuration"
     echo "template     : lxc-template is an accessible template script"
+    echo
+    echo "The container backing store can be altered using '-B'.  By default it"
+    echo "is 'none', which is a simple directory tree under /var/lib/lxc/<name>/rootfs"
+    echo "Otherwise, the following option values may be relevant:"
+    echo "lvname       : [for -lvm] name of lv in which to create lv,"
+    echo "                container-name by default"
+    echo "vgname       : [for -lvm] name of vg in which to create lv, 'lxc' by default"
+    echo "fstype       : name of filesystem to create, ext4 by default"
+    echo "fssize       : size of filesystem to create, 500M by default"
+    echo
     if [ -z $lxc_template ]; then
         echo "for template-specific help, specify a template, for instance:"
         echo "lxc-create -t ubuntu -h"
@@ -46,12 +61,17 @@ help() {
     fi
 }
 
-shortoptions='hn:f:t:'
-longoptions='help,name:,config:,template:'
+shortoptions='hn:f:t:B:'
+longoptions='help,name:,config:,template:,backingstore:,fstype:,lvname:,vgname:,fssize:'
+localstatedir=@LOCALSTATEDIR@
 lxc_path=@LXCPATH@
 lxc_etc_path=@LXCETCPATH@
 bindir=@BINDIR@
 templatedir=@LXCTEMPLATEDIR@
+backingstore=none
+fstype=ext4
+fssize=500M
+vgname=lxc
 
 getopt=$(getopt -o $shortoptions --longoptions  $longoptions -- "$@")
 if [ $? != 0 ]; then
@@ -82,6 +102,31 @@ while true; do
 		lxc_template=$1
 		shift
 		;;
+	    -B|--backingstore)
+		shift
+		backingstore=$1
+		shift
+		;;
+	    --lvname)
+		shift
+		lvname=$1
+		shift
+		;;
+	    --vgname)
+		shift
+		vgname=$1
+		shift
+		;;
+	    --fstype)
+		shift
+		fstype=$1
+		shift
+		;;
+	    --fssize)
+		shift
+		fssize=$1
+		shift
+		;;
             --)
 		shift
 		break;;
@@ -109,11 +154,21 @@ if [ -z "$lxc_name" ]; then
     exit 1
 fi
 
+if [ -z "$lvname" ]; then
+    lvname="$lxc_name"
+fi
+
 if [ "$(id -u)" != "0" ]; then
    echo "This command has to be run as root"
    exit 1
 fi
 
+if [ $backingstore != "none" -a $backingstore != "lvm" ]; then
+    echo "only 'none' and 'lvm' backing stores are known"
+    usage
+    exit 1
+fi
+
 if [ ! -r $lxc_path ]; then
     echo "no configuration path defined !"
     exit 1
@@ -124,7 +179,47 @@ if [ -d "$lxc_path/$lxc_name" -o -d "$lxc_etc_path/$lxc_name" ]; then
     exit 1
 fi
 
-trap "${bindir}/lxc-destroy -n $lxc_name; echo aborted; exit 1" SIGHUP SIGINT SIGTERM
+rootfs="$lxc_path/$lxc_name/rootfs"
+if [ $backingstore = "lvm" ]; then
+    which vgscan > /dev/null
+    if [ $? -ne 0 ]; then
+        echo "vgscan not found.  Please install lvm2 package"
+        exit 1
+    fi
+    grep -q "\<$fstype\>" /proc/filesystems
+    if [ $? -ne 0 ]; then
+        echo "$fstype is not listed in /proc/filesystems"
+        usage
+        exit 1
+    fi
+
+    vgscan | grep -q "Found volume group \"$vgname\""
+    if [ $? -ne 0 ]; then
+        echo "Could not find volume group \"$vgname\""
+        usage
+        exit 1
+    fi
+
+    rootdev=/dev/$vgname/$lvname
+    lvdisplay $rootdev > /dev/null 2>&1
+    if [ $? -eq 0 ]; then
+        echo "backing store already exists: $rootdev"
+        echo "please delete it (using \"lvremove $rootdev\") and try again"
+        exit 1
+    fi
+fi
+
+cleanup() {
+    if [ $backingstore = "lvm" ]; then
+        umount $rootfs
+        lvremove -f $rootdev
+    fi
+    ${bindir}/lxc-destroy -n $lxc_name
+    echo aborted
+    exit 1
+}
+
+trap cleanup SIGHUP SIGINT SIGTERM
 
 mkdir -p $lxc_path/$lxc_name
 mkdir -p $lxc_etc_path/$lxc_name
@@ -140,13 +235,21 @@ else
     cp $lxc_config $lxc_etc_path/$lxc_name/config
 fi
 
+# Create the fs as needed
+mkdir $rootfs
+if [ $backingstore = "lvm" ]; then
+    lvcreate -L $fssize -n $lxc_name $vgname || exit 1
+    udevadm settle
+    mkfs -t $fstype $rootdev || exit 1
+    mount -t $fstype $rootdev $rootfs
+fi
+
 if [ ! -z $lxc_template ]; then
 
     type ${templatedir}/lxc-$lxc_template >/dev/null
     if [ $? -ne 0 ]; then
-	echo "unknown template '$lxc_template'"
-	${bindir}/lxc-destroy -n $lxc_name
-	exit 1
+        echo "unknown template '$lxc_template'"
+        cleanup
     fi
 
     if [ -z "$lxc_config" ]; then
@@ -185,4 +288,13 @@ if [ ! -z $lxc_template ]; then
     echo "'$lxc_template' template installed"
 fi
 
+if [ $backingstore = "lvm" ]; then
+    echo "Unmounting LVM"
+    umount $rootfs
+
+    # TODO: make the templates set this right from the start?
+    sed -i '/lxc.rootfs/d' $lxc_path/$lxc_name/config
+    echo "lxc.rootfs = $rootdev" >> $lxc_path/$lxc_name/config
+fi
+
 echo "'$lxc_name' created"
diff --git a/templates/lxc-debian.in b/templates/lxc-debian.in
index 4cc9830..0a594f5 100644
--- a/templates/lxc-debian.in
+++ b/templates/lxc-debian.in
@@ -142,7 +142,8 @@ copy_debian()
 
     # make a local copy of the minidebian
     echo -n "Copying rootfs to $rootfs..."
-    cp -a "$cache/rootfs-$SUITE-$arch" $rootfs || return 1
+    mkdir -p $rootfs
+    rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1
     return 0
 }
 
diff --git a/templates/lxc-opensuse.in b/templates/lxc-opensuse.in
index 8e4d6f4..3f7d60b 100644
--- a/templates/lxc-opensuse.in
+++ b/templates/lxc-opensuse.in
@@ -222,7 +222,8 @@ copy_opensuse()
 
     # make a local copy of the mini opensuse
     echo -n "Copying rootfs to $rootfs ..."
-    cp -a $cache/rootfs-$arch $rootfs || return 1
+    mkdir -p $rootfs
+    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
     return 0
 }
 
diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in
index cf91b80..17a5cdd 100644
--- a/templates/lxc-ubuntu.in
+++ b/templates/lxc-ubuntu.in
@@ -6,8 +6,6 @@
 # This script consolidates and extends the existing lxc ubuntu scripts
 #
 
-# XXX todo: add -lvm option
-
 # Copyright © 2011 Serge Hallyn <serge.hallyn@canonical.com>
 # Copyright © 2010 Wilhelm Meier
 # Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
@@ -119,7 +117,8 @@ copy_ubuntu()
 
     # make a local copy of the miniubuntu
     echo -n "Copying rootfs to $rootfs ..."
-    cp -a $cache/rootfs-$arch $rootfs || return 1
+    mkdir -p $rootfs
+    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
     return 0
 }
 
-- 
1.7.7


From 38119993a31d7124ed96a2b0fe1e5ab05d3f3930 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Mon, 23 Jan 2012 17:12:46 -0600
Subject: [PATCH 07/13] lxc-clone.in: define localstatedir, as @LXCPATH@ might
 be defined in terms of it

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-clone.in |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index 78a6c04..3a7f270 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -42,6 +42,7 @@ help() {
 
 shortoptions='ho:n:sL:v:p:t:'
 longoptions='help,orig:,name:,snapshot,fssize:,vgname:,lvprefix:,fstype:'
+localstatedir=@LOCALSTATEDIR@
 lxc_path=@LXCPATH@
 config_path=@LXCETCPATH@
 bindir=@BINDIR@
-- 
1.7.7


From e947492ef1e3f9a0a8cb833b3025b04670c03fdb Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@server-4676.novalocal>
Date: Thu, 9 Feb 2012 18:38:21 +0000
Subject: [PATCH 08/13] lxc-clone: support btrfs and clean up safely

btrfs support from Scott Moser.

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-clone.in |  249 ++++++++++++++++++++++++++------------------------
 1 files changed, 128 insertions(+), 121 deletions(-)

diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in
index 3a7f270..2d79fba 100644
--- a/src/lxc/lxc-clone.in
+++ b/src/lxc/lxc-clone.in
@@ -21,6 +21,8 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
+set -e
+
 usage() {
     echo "usage: lxc-clone -o <orig> -n <new> [-s] [-h] [-L fssize] [-v vgname] [-p lxc_lv_prefix] [-t fstype]"
 }
@@ -62,48 +64,49 @@ eval set -- "$getopt"
 
 while true; do
         case "$1" in
-	    -h|--help)
-		help
-		exit 1
-		;;
-	    -s|--snapshot)
-		shift
-		snapshot=yes
-                snapshot_opt="-s"
-		;;
-	    -o|--orig)
-		shift
-		lxc_orig=$1
-		shift
-		;;
-	    -L|--fssize)
-		shift
-		lxc_size=$1
-		shift
-		;;
-	    -v|--vgname)
-		shift
-		lxc_vg=$1
-		shift
-		;;
-	    -n|--new)
-		shift
-		lxc_new=$1
-		shift
-		;;
-            -p|--lvprefix)
-                shift
-                lxc_lv_prefix=$1
-                shift
-                ;;
-            --)
-		shift
-		break;;
-            *)
-		echo $1
-		usage
-		exit 1
-		;;
+            -h|--help)
+            help
+            exit 1
+            ;;
+        -s|--snapshot)
+            shift
+            snapshot=yes
+            snapshot_opt="-s"
+            ;;
+        -o|--orig)
+            shift
+            lxc_orig=$1
+            shift
+            ;;
+        -L|--fssize)
+            shift
+            lxc_size=$1
+            shift
+            ;;
+        -v|--vgname)
+            shift
+            lxc_vg=$1
+            shift
+            ;;
+        -n|--new)
+            shift
+            lxc_new=$1
+            shift
+            ;;
+        -p|--lvprefix)
+            shift
+            lxc_lv_prefix=$1
+            shift
+            ;;
+        --)
+            shift
+            break
+            ;;
+        *)
+            echo $1
+            usage
+            exit 1
+            ;;
         esac
 done
 
@@ -149,11 +152,28 @@ if [ -d "$lxc_path/$lxc_new" -o -f "$config_path/$lxc_new/config" ]; then
     exit 1
 fi
 
-trap "${bindir}/lxc-destroy -n $lxc_new; echo aborted; exit 1" SIGHUP SIGINT SIGTERM
+mounted=0
+frozen=0
+oldroot=`grep lxc.rootfs $config_path/$lxc_orig/config | awk -F= '{ print $2 '}`
+
+cleanup() {
+    if [ -b $oldroot ]; then
+        if [ $mounted -eq 1 ]; then
+            umount $rootfs || true
+        fi
+        lvremove -f $rootdev || true
+    fi
+    ${bindir}/lxc-destroy -n $lxc_new || true
+    if [ $frozen -eq 1 ]; then
+        lxc-unfreeze -n $lxc_orig
+    fi
+    echo aborted
+    exit 1
+}
+trap cleanup SIGHUP SIGINT SIGTERM
 
 mkdir -p $lxc_path/$lxc_new
 mkdir -p $config_path/$lxc_new
-
 hostname=$lxc_new
 
 echo "Tweaking configuration"
@@ -170,92 +190,79 @@ fi
 
 echo "Copying rootfs..."
 rootfs=$lxc_path/$lxc_new/rootfs
-# First figure out if the old is a device.  For now we only support
-# lvm devices.
-mounted=0
-#is container running
-lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1
-if [ $? -ne 0 ]; then
-    container_running=True
-else
-    container_running=False
-fi
-sed -i '/lxc.rootfs/d' $lxc_config/$lxc_new/config
+
+container_running=True
+lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1 || container_running=False
+
+sed -i '/lxc.rootfs/d' $config_path/$lxc_new/config
 oldroot=`grep lxc.rootfs $config_path/$lxc_orig/config | awk -F= '{ print $2 '}`
 if [ -b $oldroot ]; then
-	# this is a device.  If we don't want to snapshot, then mkfs, mount
-	# and rsync.  Trivial but not yet implemented
-	#if [ $snapshot == "no" ]; then
-	#	echo "non-snapshot and non-lvm clone of block device not yet implemented"
-	#	exit 1
-	#fi
-	lvdisplay $oldroot > /dev/null 2>&1
-	if [ $? -ne 0 ]; then
-            lvm=False
-            echo "non-lvm block device cloning not yet implemented"
-            exit 1
-        else
-            lvm=TRUE
-        fi
-	# ok, create a snapshot of the lvm device
-        if [ $container_running == "True" ]; then
-            lxc-freeze -n $lxc_orig
-        fi
-	lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot
-        RETVAL=$?
-        if [ $container_running == "True" ]; then
-            lxc-unfreeze -n $lxc_orig
-        fi
-        if [ $RETVAL -ne 0 ]; then
-            echo "snapshot creation failed"
-            exit 1
-        fi
-        if [ $snapshot == "no" ]; then
-            #mount snapshot
-            mkdir -p ${rootfs}_snapshot
-            mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "failed to mount new rootfs_snapshot"; exit 1; }
-            #create a new lv
-            lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new
-	    echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
-	    # and mount it so we can tweak it
-            mkdir -p $lxc_path/$lxc_new/rootfs
-            mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new
-            mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }
-            mounted=1
-            rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "copy of data to new lv failed"; exit 1; }
-            umount ${rootfs}_snapshot || { echo "failed to unmount new rootfs_snapshot"; exit 1; }
-            rm -rf ${rootfs}_snapshot
-            lvremove -f $lxc_vg/${lxc_lv_prefix}$lxc_new || echo "failed to remove the snapshot"
-        else
-            lvrename $lxc_vg/${lxc_lv_prefix}}${lxc_new}_snapshot $lxc_vg/${lxc_lv_prefix}$lxc_new
-            echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
-	    # and mount it so we can tweak it
-            mkdir -p $lxc_path/$lxc_new/rootfs
-            mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; exit 1; }
-            mounted=1
-        fi
+    type vgscan || { echo "Please install lvm"; false; }
+    lvdisplay $oldroot > /dev/null 2>&1 || { echo "non-lvm blockdev cloning not supported"; false; }
+    lvm=TRUE
+    # ok, create a snapshot of the lvm device
+    if [ $container_running = "True" ]; then
+        lxc-freeze -n $lxc_orig
+        frozen=1
+    fi
+    lvcreate -s -L $lxc_size -n ${lxc_lv_prefix}${lxc_new}_snapshot $oldroot
+    if [ $container_running = "True" ]; then
+        lxc-unfreeze -n $lxc_orig
+        frozen=0
+    fi
+    if [ $snapshot = "no" ]; then
+        #mount snapshot
+        mkdir -p ${rootfs}_snapshot
+        mount /dev/$lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot ${rootfs}_snapshot || { echo "failed to mount new rootfs_snapshot"; false; }
+        #create a new lv
+        lvcreate -L $lxc_size $lxc_vg -n ${lxc_lv_prefix}$lxc_new
+        echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
+        # and mount it so we can tweak it
+        mkdir -p $lxc_path/$lxc_new/rootfs
+        mkfs -t $fstype /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new
+        mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; }
+        mounted=1
+        rsync -ax ${rootfs}_snapshot/ ${rootfs}/ || { echo "copy of data to new lv failed"; false; }
+        umount ${rootfs}_snapshot
+        rmdir ${rootfs}_snapshot
+        lvremove -f $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot
+    else
+        lvrename $lxc_vg/${lxc_lv_prefix}${lxc_new}_snapshot $lxc_vg/${lxc_lv_prefix}$lxc_new
+        echo "lxc.rootfs = /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new" >> $config_path/$lxc_new/config
+        # and mount it so we can tweak it
+        mkdir -p $lxc_path/$lxc_new/rootfs
+        mount /dev/$lxc_vg/${lxc_lv_prefix}$lxc_new $rootfs || { echo "failed to mount new rootfs"; false; }
+        mounted=1
+    fi
+
+elif out=$(btrfs subvolume list "$lxc_path/$lxc_orig/rootfs" 2>&1); then
+
+    out=$(btrfs subvolume snapshot "$lxc_path/$lxc_orig/rootfs" "$rootfs" 2>&1) || { echo "failed btrfs snapshot"; false; }
+    echo "lxc.rootfs = $rootfs" >> "$config_path/$lxc_new/config"
 
 else
-        if [ $container_running == True ];then
-            lxc-freeze -n $lxc_orig
-        fi
-	rsync -ax $lxc_path/$lxc_orig/rootfs $lxc_path/$lxc_new/rootfs
-        RETVAL=$?
-        if [ $container_running == True ];then
-            lxc-unfreeze -n $lxc_orig
-        fi
-        if [ RETVAL -ne 0 ]; then
-            echo "copying rootfs failed"
-            exit 1
-        fi
-	echo "lxc.rootfs = $rootfs" >> $config_path/$lxc_new/config
+    if [ $snapshot = "yes" ]; then
+        echo "Can't snapshot a directory"
+        cleanup
+    fi
+    if [ $container_running = "True" ]; then
+        lxc-freeze -n $lxc_orig
+        frozen=1
+    fi
+    mkdir -p $lxc_path/$lxc_new/rootfs/
+    rsync -ax $lxc_path/$lxc_orig/rootfs/ $lxc_path/$lxc_new/rootfs/
+    echo "lxc.rootfs = $rootfs" >> $config_path/$lxc_new/config
+    if [ $container_running = "True" ]; then
+        lxc-unfreeze -n $lxc_orig
+        frozen=0
+    fi
 fi
 
 echo "Updating rootfs..."
 
 # so you can 'ssh $hostname.' or 'ssh $hostname.local'
 if [ -f $rootfs/etc/dhcp/dhclient.conf ]; then
-	sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf
+    sed -i "s/send host-name.*$/send host-name \"$hostname\";/" $rootfs/etc/dhcp/dhclient.conf
 fi
 
 # set the hostname
@@ -269,7 +276,7 @@ EOF
 
 # if this was a block device, then umount it now
 if [ $mounted -eq 1 ]; then
-	umount $rootfs
+    umount $rootfs
 fi
 
 echo "'$lxc_new' created"
-- 
1.7.7


From 98e34d32a93ed116a9382c8b86c6da2d223ec6fb Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Mon, 23 Jan 2012 17:26:25 -0600
Subject: [PATCH 09/13] lxc-create: fix error with lvm

when --lvname is given, use that for lvcreate instead of using
lxc_name, which is wrong.

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-create.in |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in
index e94b642..f714bf8 100644
--- a/src/lxc/lxc-create.in
+++ b/src/lxc/lxc-create.in
@@ -238,7 +238,7 @@ fi
 # Create the fs as needed
 mkdir $rootfs
 if [ $backingstore = "lvm" ]; then
-    lvcreate -L $fssize -n $lxc_name $vgname || exit 1
+    lvcreate -L $fssize -n $lvname $vgname || exit 1
     udevadm settle
     mkfs -t $fstype $rootdev || exit 1
     mount -t $fstype $rootdev $rootfs
-- 
1.7.7


From 63b40d3438f2311cc6ee306afc62980240c5a6c5 Mon Sep 17 00:00:00 2001
From: Ubuntu <ubuntu@server-4676.novalocal>
Date: Thu, 9 Feb 2012 19:14:54 +0000
Subject: [PATCH 10/13] add btrfs support to lxc-create

From Scott Moser.

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 src/lxc/lxc-create.in |   49 ++++++++++++++++++++++++++++++++++---------------
 1 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in
index f714bf8..22ef3fe 100644
--- a/src/lxc/lxc-create.in
+++ b/src/lxc/lxc-create.in
@@ -24,6 +24,8 @@ usage() {
     echo "usage: lxc-create -n <name> [-f configuration] [-t template] [-h] [fsopts] -- [template_options]"
     echo "   fsopts: -B none"
     echo "   fsopts: -B lvm [--lvname lvname] [--vgname vgname] [--fstype fstype] [--fssize fssize]"
+    echo "   fsopts: -B btrfs"
+    echo "           flag is not necessary, if possible btrfs support will be used"
 #    echo "   fsopts: -B union [--uniontype overlayfs]"
 #    echo "   fsopts: -B loop [--fstype fstype] [--fssize fssize]"
 #    echo "   fsopts: -B qemu-nbd [--type qed|qcow2|raw] [--fstype fstype] [--fssize fssize] # Qemu qed disk format"
@@ -68,7 +70,7 @@ lxc_path=@LXCPATH@
 lxc_etc_path=@LXCETCPATH@
 bindir=@BINDIR@
 templatedir=@LXCTEMPLATEDIR@
-backingstore=none
+backingstore=_unset
 fstype=ext4
 fssize=500M
 vgname=lxc
@@ -163,16 +165,13 @@ if [ "$(id -u)" != "0" ]; then
    exit 1
 fi
 
-if [ $backingstore != "none" -a $backingstore != "lvm" ]; then
-    echo "only 'none' and 'lvm' backing stores are known"
-    usage
-    exit 1
-fi
-
-if [ ! -r $lxc_path ]; then
-    echo "no configuration path defined !"
-    exit 1
-fi
+case "$backingstore" in
+    lvm|none|btrfs|_unset) :;;
+    *) echo "'$backingstore' is not known ('none', 'lvm', 'btrfs')"
+        usage
+        exit 1
+        ;;
+esac
 
 if [ -d "$lxc_path/$lxc_name" -o -d "$lxc_etc_path/$lxc_name" ]; then
     echo "'$lxc_name' already exists"
@@ -180,6 +179,21 @@ if [ -d "$lxc_path/$lxc_name" -o -d "$lxc_etc_path/$lxc_name" ]; then
 fi
 
 rootfs="$lxc_path/$lxc_name/rootfs"
+
+if [ "$backingstore" = "_unset" -o "$backingstore" = "btrfs" ]; then
+# if no backing store was given, then see if btrfs would work
+    if which btrfs >/dev/null 2>&1 &&
+        btrfs filesystem df "$lxc_path/" >/dev/null 2>&1; then
+        backingstore="btrfs"
+    else
+        if [ "$backingstore" = "btrfs" ]; then
+            echo "missing 'btrfs' command or $lxc_path is not btrfs";
+            exit 1;
+        fi
+        backingstore="none"
+    fi
+fi
+
 if [ $backingstore = "lvm" ]; then
     which vgscan > /dev/null
     if [ $? -ne 0 ]; then
@@ -207,6 +221,12 @@ if [ $backingstore = "lvm" ]; then
         echo "please delete it (using \"lvremove $rootdev\") and try again"
         exit 1
     fi
+elif [ "$backingstore" = "btrfs" ]; then
+    mkdir "$lxc_path/$lxc_name"
+    if ! out=$(btrfs subvolume create "$rootfs" 2>&1); then
+        echo "failed to create subvolume in $rootfs: $out";
+        exit 1;
+    fi
 fi
 
 cleanup() {
@@ -236,7 +256,7 @@ else
 fi
 
 # Create the fs as needed
-mkdir $rootfs
+[ -d "$rootfs" ] || mkdir $rootfs
 if [ $backingstore = "lvm" ]; then
     lvcreate -L $fssize -n $lvname $vgname || exit 1
     udevadm settle
@@ -280,9 +300,8 @@ if [ ! -z $lxc_template ]; then
 
     ${templatedir}/lxc-$lxc_template --path=$lxc_path/$lxc_name --name=$lxc_name $*
     if [ $? -ne 0 ]; then
-	echo "failed to execute template '$lxc_template'"
-	${bindir}/lxc-destroy -n $lxc_name
-	exit 1
+        echo "failed to execute template '$lxc_template'"
+        cleanup
     fi
 
     echo "'$lxc_template' template installed"
-- 
1.7.7


From 40e5e18f8ca834d4d83d81d7596837839be68c47 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn@canonical.com>
Date: Tue, 17 Apr 2012 18:38:59 +0200
Subject: [PATCH 11/13] Update manpages to reflect some updated options.

(which reminds me a lxc-clone manpage still needs to be written)

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
---
 doc/lxc-create.sgml.in  |   29 ++++++++++++++++++++++++++++-
 doc/lxc-destroy.sgml.in |   25 ++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/doc/lxc-create.sgml.in b/doc/lxc-create.sgml.in
index f3e8524..ebf95c4 100644
--- a/doc/lxc-create.sgml.in
+++ b/doc/lxc-create.sgml.in
@@ -50,7 +50,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     <cmdsynopsis>
       <command>lxc-create <replaceable>-n name</replaceable>
        <optional>-f config_file</optional>
-       <optional>-t template</optional></command>
+       <optional>-B backingstore</optional>
+       <optional>-t template</optional>
+       </command>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -114,6 +116,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 	</listitem>
       </varlistentry>
 
+      <varlistentry>
+	<term>
+	  <option>-B <replaceable>backingstore</replaceable></option>
+	</term>
+	<listitem>
+	  <para>
+	    'backingstore' is one of 'none', 'lvm', or 'btrfs'.  The
+	    default is 'none', meaning that the container root filesystem
+	    will be a directory under <filename>@LXCPATH@/container/rootfs</filename>.
+	    The option 'btrfs' need not be specified as it will be used
+	    automatically if the <filename>@LXCPATH@</filename> filesystem is found to
+	    be btrfs.  If backingstore is 'lvm', then an lvm block device will be
+	    used and the following further options are available:
+	    <replaceable>--lvname lvname1</replaceable> will create an LV
+	    named <filename>lvname1</filename> rather than the default, which
+	    is the container name.  <replaceable>--vgname vgname1</replaceable>
+	    will create the LV in volume group <filename>vgname1</filename>
+	    rather than the default, <filename>lxc</filename>.
+	    <replaceable>--fstype FSTYPE</replaceable> will create an FSTYPE
+	    filesystem on the LV, rather than the default, which is ext4.
+	    <replaceable>--fssize SIZE</replaceable> will create a LV (and
+	    filesystem) of size SIZE rather than the default, which is 1G.
+	  </para>
+	</listitem>
+
     </variablelist>
 
   </refsect1>
diff --git a/doc/lxc-destroy.sgml.in b/doc/lxc-destroy.sgml.in
index eda425c..e75de57 100644
--- a/doc/lxc-destroy.sgml.in
+++ b/doc/lxc-destroy.sgml.in
@@ -49,7 +49,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>lxc-destroy <replaceable>-n
-      name</replaceable></command>
+      name</replaceable>
+      <optional>-f</optional>
+      </command>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -64,6 +66,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   </refsect1>
 
   <refsect1>
+
+    <title>Options</title>
+
+    <variablelist>
+      <varlistentry>
+	<term>
+	  <option>-f</option>
+	</term>
+	<listitem>
+	  <para>
+	    If a container is running, stop it first.  If this option is
+	    not specified and the container is running, then
+	    <command>lxc-destroy</command> will be aborted.
+	  </para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+
+  </refsect1>
+
+  <refsect1>
     <title>Diagnostic</title>
 
     <variablelist>
-- 
1.7.7


From 51024a44b4d06ba4253659dca705e5c2f678ecc8 Mon Sep 17 00:00:00 2001
From: Frederic Crozat <fcrozat@suse.com>
Date: Wed, 18 Apr 2012 15:47:52 +0200
Subject: [PATCH 12/13] Remove btrfs subvolume when removing rootfs

---
 src/lxc/lxc-destroy.in |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/src/lxc/lxc-destroy.in b/src/lxc/lxc-destroy.in
index 59d22c0..5271450 100644
--- a/src/lxc/lxc-destroy.in
+++ b/src/lxc/lxc-destroy.in
@@ -106,6 +106,11 @@ if [ ! -z "$rootdev" ]; then
 		fi
 	fi
 fi
+# if rootfs is a btrfs subvolume, drop it
+if out=$(btrfs subvolume list $lxc_path/$lxc_name/rootfs 2>&1); then
+	out=$(btrfs subvolume delete $lxc_path/$lxc_name/rootfs 2>&1) || { echo "failed to remove btrfs subvolume $lxc_path/$lxc_name/rootfs "; false; }
+fi
+
 # recursively remove the container to remove old container configuration
 rm -rf --preserve-root $lxc_path/$lxc_name
 rm -rf --preserve-root $lxc_etc_path/$lxc_name
-- 
1.7.7


From b4eed4332db5f9ece1870ccaaab74cd219e03b19 Mon Sep 17 00:00:00 2001
From: Frederic Crozat <fcrozat@suse.com>
Date: Wed, 18 Apr 2012 16:03:03 +0200
Subject: [PATCH 13/13] use ext3 by default on SLES

---
 src/lxc/lxc-create.in |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc-create.in b/src/lxc/lxc-create.in
index 22ef3fe..602fa0b 100644
--- a/src/lxc/lxc-create.in
+++ b/src/lxc/lxc-create.in
@@ -47,7 +47,7 @@ help() {
     echo "lvname       : [for -lvm] name of lv in which to create lv,"
     echo "                container-name by default"
     echo "vgname       : [for -lvm] name of vg in which to create lv, 'lxc' by default"
-    echo "fstype       : name of filesystem to create, ext4 by default"
+    echo "fstype       : name of filesystem to create, ext3 by default"
     echo "fssize       : size of filesystem to create, 500M by default"
     echo
     if [ -z $lxc_template ]; then
@@ -71,7 +71,7 @@ lxc_etc_path=@LXCETCPATH@
 bindir=@BINDIR@
 templatedir=@LXCTEMPLATEDIR@
 backingstore=_unset
-fstype=ext4
+fstype=ext3
 fssize=500M
 vgname=lxc
 
-- 
1.7.7

