#!/bin/bash # Copy or move a Logical Volume from one Volume Group to another # possibly on another machine if [ -z "$4" ] then echo "Usage: $0 LV fromVG [host:]toVG [nocheck]" exit 1 fi # 1. Make sure LV exists on source VG # 2. Parse destination VG - if it contains a colon, it means hostname:VG # 3. Make sure LV does not exist on destination VG # 4. Get size of source LV # 5. Create destination LV # 6. Copy content # 7. Compare source vs. destination if required # 8. If match, delete source and any log files host= LV=$1 fromVG=$2 toVG=$3 task=$4 check=$5 [ "$toVG" = "${toVG/:}" ] || host="${toVG%%:*}" [ -n "$host" ] && toVG="${toVG##*:}" needed="ddrescue lvdisplay diff" for need in $needed do if ! which $need &>/dev/null then echo "Sorry, I need $need installed before this can work." exit 1 fi done if lvdisplay $fromVG/$LV &>/dev/null then if [ -n "$host" ] then if ssh $host "lvdisplay $toVG/$LV 2>/dev/null" | grep -q $LV then echo "Logical Volume $LV already exists in Volume Group $toVG on $host" exit 1 fi else if lvdisplay $toVG/$LV &>/dev/null then echo "Logical Volume $LV already exists in Volume Group $toVG" exit 1 fi fi lvsize=`lvdisplay $fromVG/$LV | grep "Current LE" | tr -s ' ' | cut -d' ' -f4` if [ -n "$host" ] then echo "Creating new LV $LV on destination VG $toVG on $host" ssh $host "lvcreate -y -l $lvsize -n $LV $toVG" echo "Copying content (be patient)..." dd if=/dev/$fromVG/$LV bs=1M | ssh $host dd bs=1M of=/dev/$toVG/$LV else echo "Creating new LV $LV on destination VG $toVG" lvcreate -y -l $lvsize -n $LV $toVG echo "Copying content..." ddrescue -f /dev/$fromVG/$LV /dev/$toVG/$LV /tmp/$LV.log fi OK=no if [ "$check" = "nocheck" ] then OK=yes else if [ -n "$host" ] then echo "Checking the copy..." diff -q <(md5sum /dev/$fromVG/$LV | cut -d' ' -f1) <(ssh $host md5sum /dev/$toVG/$LV | cut -d' ' -f1) && OK=yes else echo "Checking the copy (this will take approximately as long as the copy did)..." diff -q /dev/$fromVG/$LV /dev/$toVG/$LV && OK=yes fi fi if [ "$OK" = "yes" ] then if [ "$task" = "keep" -o "$task" = "copy" ] then rm -f /tmp/$LV.log echo "$LV successfully copied from $fromVG to $toVG" exit 0 elif [ "$task" = "move" ] then lvremove -y $fromVG/$LV rm -f /tmp/$LV.log echo "$LV successfully moved from $fromVG to $toVG" exit 0 else echo "$LV successfully copied from $fromVG to $toVG" echo "but not sure whether you wanted to delete the original, therefore keeping both." exit 0 fi else echo "Something went wrong." exit 1 fi else echo "Logical Volume $LV not found in Volume Group $fromVG" exit 1 fi