X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=virt-p2v.sh;h=228e1fc57aa101bd9a34e4a9c4ba4cce1e04a2fe;hb=ed6daabef5e8dfab691520e94e2c39458cd3a8ec;hp=474c73242967f3d52af342997e711e7ac152f317;hpb=91349debdcb64fd626524c22a79b9750deb9f325;p=virt-p2v.git diff --git a/virt-p2v.sh b/virt-p2v.sh index 474c732..228e1fc 100755 --- a/virt-p2v.sh +++ b/virt-p2v.sh @@ -6,9 +6,27 @@ # Copyright (C) 2007 Red Hat Inc. # Written by Richard W.M. Jones # +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# # $Id$ +# Because we're running from a start-up script, we don't have much +# of a login environment, so set one up. export PATH=/usr/sbin:/sbin:/usr/local/bin:/usr/kerberos/bin:/usr/bin:/bin +export HOME=/root +export LOGNAME=root # The defaults here make a generic virt-p2v.sh script, but if you want # to build a partially-/fully-automatic P2V solution, then you can set @@ -82,12 +100,12 @@ function word_in_list { # Use the function read_line instead of the shell built-in read. # It reads from the console. function read_line { - read "$*" /dev/console 2>&1 + PS1='\u@\h:\w\$ ' bash } #---------------------------------------------------------------------- @@ -233,10 +251,17 @@ function search_parts { # $parts is returned. } +# This generates a snapshot device name from a device name. +# eg. sda -> snap_sda +# Sets $dname. +function snap_name { + dname=`echo -n snap_"$1" | tr -cs '[:alnum:]' _` +} + #---------------------------------------------------------------------- # Network configuration functions. -# `auto_network $fs' tries to configure the network from the +# `auto_network' tries to configure the network from the # root filesystem. Returns true or false. function auto_network { # Make sure this file exists, otherwise Fedora gives a warning. @@ -272,7 +297,7 @@ function auto_network { echo "(Hint: if not sure, there is a shell on console [ALT] [F2])" echo -n " (y/n) " local line - read_line line /dev/$1 +fi + # We can safely write files into /tmp without modifying anything. cd /tmp #---------------------------------------------------------------------- # Dialog with the user. -log -log virt-p2v starting up at `date` - if [ "$greeting" != "no" ]; then dialog \ --title "virt-p2v" \ @@ -405,9 +437,12 @@ while [ "$state" != "exit" ]; do else stat=off fi + log running blockdev --getsize /dev/$d gigs=$(($(blockdev --getsize /dev/$d)/2/1024/1024)) + log /dev/$d has size $gigs deviceslist="$deviceslist $d /dev/$d(${gigs}GB) $stat" done + log deviceslist="$deviceslist" dialog \ --extra-button --extra-label "Back" --nocancel \ @@ -504,6 +539,7 @@ done clear +#---------------------------------------------------------------------- # De-activate all volume groups and switch to new dm-only LVM config. log deactivating volume groups @@ -514,13 +550,14 @@ rm -f /etc/lvm/cache/.cache # Snapshot the block devices. for d in $devices_to_send; do - log snapshotting block device /dev/$d ... + snap_name $d + log snapshotting block device /dev/$d to $dname ... - snapshot $d snap_$d + snapshot $d $dname # The block devices are whole disks. Use kpartx to repartition them. - log running kpartx -a /dev/mapper/snap_$d ... - kpartx -a /dev/mapper/snap_$d + log running kpartx -a /dev/mapper/$dname ... + kpartx -a /dev/mapper/$dname done # Rescan for LVs. @@ -529,19 +566,21 @@ vgscan vgchange -a y # Mount the root filesystem on /mnt/root. If it's a physical -# device then we want to mount (eg) /dev/mapper/snap_sda1. -# If it's a LVM device (which it probably won't be for Linux because -# Linux doesn't support it) then we can just mount the LVM -# partition. +# device then we want to mount (eg) /dev/mapper/snap_sda2. +# If it's a LVM device then we can just mount the LVM partition. log mount $root_filesystem as /mnt/root -if [ -f /dev/mapper/snap_$root_filesystem ]; then - mount /dev/mapper/snap_$root_filesystem /mnt/root +snap_name $root_filesystem +root_filesystem_dname="$dname" + +if [ -b /dev/mapper/$root_filesystem_dname ]; then + mount /dev/mapper/$root_filesystem_dname /mnt/root else mount /dev/$root_filesystem /mnt/root fi +#---------------------------------------------------------------------- # Now see if we can get a network configuration. log network configuration $network @@ -563,26 +602,93 @@ case "$network" in ;; auto) - echo "Trying to auto-configure network from /dev/$network ..." + echo "Trying to auto-configure network from root filesystem ..." echo - if ! auto_network "$network"; then + if ! auto_network; then echo "Auto-configuration failed. Starting a shell." echo shell fi esac +#---------------------------------------------------------------------- +# Rewrite /mnt/root/etc/fstab + +log rewriting /etc/fstab + +cp /mnt/root/etc/fstab /mnt/root/etc/fstab.p2vsaved +while read dev mountpoint fstype options freq passno; do + # If device is /dev/sd* then on the target fullvirt machine + # it will be /dev/sd* + if matches_regexp "^/dev/sd[[:alpha:]]+[[:digit:]]+$" "$dev"; then + dev=`echo $dev | sed 's|^/dev/sd|/dev/hd|'` + fi + # Print out again with all the fields nicely lined up. + printf "%-23s %-23s %-7s %-15s %d %d\n" \ + "$dev" "$mountpoint" "$fstype" "$options" "$freq" "$passno" +done < /mnt/root/etc/fstab.p2vsaved > /mnt/root/etc/fstab +#---------------------------------------------------------------------- +# XXX Look for other files which might need to be changed here ... +# We've now finished with /mnt/root (the real root filesystem), +# so unmount it and synch everything. +umount /mnt/root +sync + +#---------------------------------------------------------------------- +# Send the device snapshots (underlying device + changes in ramdisk) +# to the remote server. + +log sending disks + +# XXX Effectively this is using the hostname derived from network +# configuration, but we might want to ask the user instead. +# XXX How do we ensure that we won't overwrite target files? Currently +# tries to use the current date as a uniquifier. + +# Names will be something like +# p2v-oirase-200709011249-hda.img +basename=p2v-`hostname -s|tr -cd '[0-9a-zA-Z]'`-`date +'%Y%m%d%H%M'` + +for dev in $devices_to_send; do + rdev=`echo $dev | sed 's|^sd|hd|'` + name="$basename-$rdev.img" + log sending $dev to $name + + snap_name $dev + + sectors=`blockdev --getsize /dev/mapper/$dname` + + gigs=$(($sectors/2/1024/1024)) + echo "Sending /dev/$dev (${gigs} GB) to remote machine" + + dd if=/dev/mapper/$dname | gzip --best | + case "$remote_transport" in + ssh) + ssh -p "$remote_port" "$remote_host" \ + "zcat > $remote_directory/$name" + ;; + tcp) + echo "p2v $name $sectors" > header + echo > newline + cat header - newline | nc "$remote_host" "$remote_port" + ;; + esac +done + #---------------------------------------------------------------------- # Clean up. -umount /mnt/root -drop_snapshot snap +#for d in $devices_to_send; do +# snap_name $d +# kpartx -d /dev/mapper/$dname +# drop_snapshot $dname +#done # This file must end with a newline