[Lxc-users] [PATCH] multiple mods to lxc-clone

Ramez Hanna rhanna at informatiq.org
Tue Aug 30 07:08:06 UTC 2011


On Tue, Aug 30, 2011 at 1:08 AM, Serge Hallyn
<serge.hallyn at canonical.com> 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 (rhanna at informatiq.org):
>> * 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 <rhanna at informatiq.org>
>> ---
>>  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
>> Lxc-users at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/lxc-users
>




More information about the lxc-users mailing list