On Tue, Aug 30, 2011 at 1:08 AM, Serge Hallyn <[email protected]> wrote: > Thanks, Ramez. It looks good to me. My only comment would be that > if the rootfs copy fails (either rsync or lvm clone), and you've > frozen the original container, then you need to unfreeze the original > container before erroring out. > > -serge good catch thanks resending in a bit > > Quoting Ramez Hanna ([email protected]): >> * allow cloning of non-snapshot lvm devices >> * if no -s then create a copy of the lvm block device and copy data >> from the orig to the new container device >> * first take a snapshot, then use this snapshot to copy data, >> remove snapshot after done >> * if orig container is running freeze it while copying >> * in case lvm block device, the container is only frozen during >> creation of snapshot ~1 sec >> * use rsync -ax insted of cp -a >> * in case copying a live contrainer it won't copy runtine mounted >> files such as /proc, /sys and some /dev >> * new opts >> * fstype: type of fs for the newly created lvm device in case of >> non-snapshot lvm >> * lvprefix: prefix for new lvm device name. >> * do not delete the lines lxc.mount by default >> * check is fstab exists then copy it >> * only modify lines that contain "lxc.mount =", debian template >> seems to not have that line but uses lxc.mount. lines which get >> screwed >> >> >> Signed-off-by: InformatiQ <[email protected]> >> --- >> src/lxc/lxc-clone.in | 98 >> ++++++++++++++++++++++++++++++++++++++------------ >> 1 files changed, 75 insertions(+), 23 deletions(-) >> mode change 100644 => 100755 src/lxc/lxc-clone.in >> >> diff --git a/src/lxc/lxc-clone.in b/src/lxc/lxc-clone.in >> old mode 100644 >> new mode 100755 >> index 91944a0..d42160b >> --- a/src/lxc/lxc-clone.in >> +++ b/src/lxc/lxc-clone.in >> @@ -1,4 +1,4 @@ >> -#!/bin/bash >> +#!/bin/bash >> >> # >> # lxc: linux Container library >> @@ -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,15 +36,19 @@ 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=/var/lib/lxc >> 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 >> @@ -63,6 +67,7 @@ while true; do >> -s|--snapshot) >> shift >> snapshot=yes >> + snapshot_opt="-s" >> ;; >> -o|--orig) >> shift >> @@ -84,6 +89,11 @@ while true; do >> lxc_new=$1 >> shift >> ;; >> + -p|--lvprefix) >> + shift >> + lxc_lv_prefix=$1 >> + shift >> + ;; >> --) >> shift >> break;; >> @@ -141,50 +151,92 @@ trap "${bindir}/lxc-destroy -n $lxc_new; echo >> aborted; exit 1" SIGHUP SIGINT SIG >> >> mkdir -p $lxc_path/$lxc_new >> >> +hostname=$lxc_new >> + >> echo "Tweaking configuration" >> cp $lxc_path/$lxc_orig/config $lxc_path/$lxc_new/config >> sed -i '/lxc.utsname/d' $lxc_path/$lxc_new/config >> echo "lxc.utsname = $hostname" >> $lxc_path/$lxc_new/config >> >> -sed -i '/lxc.mount/d' $lxc_path/$lxc_new/config >> -echo "lxc.mount = $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config >> +grep "lxc.mount =" $lxc_path/$lxc_new/config >/dev/null 2>&1 && { sed >> -i '/lxc.mount =/d' $lxc_path/$lxc_new/config; echo "lxc.mount = >> $lxc_path/$lxc_new/fstab" >> $lxc_path/$lxc_new/config; } >> >> -cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab >> -sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@" $lxc_path/$lxc_new/fstab >> +if [ -e $lxc_path/$lxc_orig/fstab ];then >> + cp $lxc_path/$lxc_orig/fstab $lxc_path/$lxc_new/fstab >> + sed -i "s@$lxc_path/$lxc_orig@$lxc_path/$lxc_new@" >> $lxc_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 >> +#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_path/$lxc_new/config >> oldroot=`grep lxc.rootfs $lxc_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" >> $lxc_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" >> >> $lxc_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" >> >> $lxc_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" >> $lxc_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.6 >> >> ------------------------------------------------------------------------------ >> EMC VNX: the world's simplest storage, starting under $10K >> The only unified storage solution that offers unified management >> Up to 160% more powerful than alternatives and 25% more efficient. >> Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev >> _______________________________________________ >> Lxc-users mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/lxc-users >
------------------------------------------------------------------------------ Special Offer -- Download ArcSight Logger for FREE! Finally, a world-class log management solution at an even better price-free! And you'll get a free "Love Thy Logs" t-shirt when you download Logger. Secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsisghtdev2dev _______________________________________________ Lxc-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/lxc-users
