Multiple updates.
authorrjones <devnull@localhost>
Fri, 14 Sep 2007 16:03:41 +0000 (17:03 +0100)
committerrjones <devnull@localhost>
Fri, 14 Sep 2007 16:03:41 +0000 (17:03 +0100)
MANIFEST [new file with mode: 0644]
Makefile
README
README.developers
livecd-post.sh.in
livecd.ks.in
lvm.conf [new file with mode: 0644]
virt-p2v.sh

diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..ae76ccd
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,11 @@
+.cvsignore
+inittab
+livecd.ks.in
+livecd-post.sh.in
+lvm.conf
+Makefile
+MANIFEST
+p2v.init
+README
+README.developers
+virt-p2v.sh
index f9622fe..86ba446 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,8 @@
 #----------------------------------------------------------------------
 # General configuration
 
-VERSION  := 0.1
+PACKAGE  := virt-p2v
+VERSION  := 0.2
 
 # i386 images also work on x86-64, so best to stick with i386.
 ARCH     := i386
@@ -19,7 +20,7 @@ BASEREPO := http://download.fedora.redhat.com/pub/fedora/linux/releases/7/Fedora
 export http_proxy := http://127.0.0.1:3128/
 export ftp_proxy := http://127.0.0.1:3128/
 
-LABEL   := virt-p2v-$(VERSION)
+LABEL   := $(PACKAGE)-$(VERSION)
 
 #----------------------------------------------------------------------
 
@@ -36,6 +37,7 @@ build: checkroot livecd.ks
        ls -lhtr *.iso
 
 livecd.ks: livecd.ks.in livecd-post.sh Makefile
+       rm -f $@
        sed \
          -e 's|@BASEREPO@|$(BASEREPO)|g' \
          -e 's|@LANG@|$(LANG)|g' \
@@ -43,7 +45,8 @@ livecd.ks: livecd.ks.in livecd-post.sh Makefile
          -e 's|@TIMEZONE@|$(TIMEZONE)|g' \
          < $< | cat - livecd-post.sh > $@
 
-livecd-post.sh: livecd-post.sh.in p2v.init virt-p2v.sh inittab Makefile
+livecd-post.sh: livecd-post.sh.in p2v.init virt-p2v.sh inittab lvm.conf Makefile
+       rm -f $@
        sed \
          -e '/@P2V.INIT@/ r p2v.init' \
          -e '/@P2V.INIT@/ d' \
@@ -51,6 +54,8 @@ livecd-post.sh: livecd-post.sh.in p2v.init virt-p2v.sh inittab Makefile
          -e '/@VIRT-P2V.SH@/ d' \
          -e '/@INITTAB@/ r inittab' \
          -e '/@INITTAB@/ d' \
+         -e '/@LVM.CONF@/ r lvm.conf' \
+         -e '/@LVM.CONF@/ d' \
          < $< > $@
 
 # Run live CD under qemu.
@@ -82,4 +87,28 @@ checkroot:
 clean:
        rm -f *~ core livecd.ks livecd-post.sh
 
+# Manifest.
+
+dist:
+       $(MAKE) check-manifest
+       rm -rf $(PACKAGE)-$(VERSION)
+       mkdir $(PACKAGE)-$(VERSION)
+       tar -cf - -T MANIFEST | tar -C $(PACKAGE)-$(VERSION) -xf -
+       $(INSTALL) -m 0755 configure $(PACKAGE)-$(VERSION)/
+       tar zcf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION)
+       rm -rf $(PACKAGE)-$(VERSION)
+       ls -l $(PACKAGE)-$(VERSION).tar.gz
+
+check-manifest:
+       @for d in `find -type d -name CVS | grep -v '^\./debian/'`; \
+       do \
+       b=`dirname $$d`/; \
+       awk -F/ '$$1 != "D" {print $$2}' $$d/Entries | \
+       sed -e "s|^|$$b|" -e "s|^\./||"; \
+       done | sort > .check-manifest; \
+       sort MANIFEST > .orig-manifest; \
+       diff -u .orig-manifest .check-manifest; rv=$$?; \
+       rm -f .orig-manifest .check-manifest; \
+       exit $$rv
+
 .PHONY:        build boot checkroot
\ No newline at end of file
diff --git a/README b/README
index 30afc68..094a872 100644 (file)
--- a/README
+++ b/README
@@ -8,3 +8,88 @@ Written by:
 
 Copyright (C) 2007 Red Hat Inc.
 
+         http://et.redhat.com/~rjones/virt-p2v/
+
+Binaries
+----------------------------------------------------------------------
+
+Binaries are available from the website (live CD images which can be
+burned directly to a CD and booted on the p2v candidate machine).
+
+http://et.redhat.com/~rjones/virt-p2v/
+
+Building
+----------------------------------------------------------------------
+
+Requirements:
+ * livecd-creator (on Fedora the package is 'livecd-tools')
+ * qemu (only for testing)
+
+(1) Edit Makefile - there is some general configuration at the
+    top which you may want to change.
+
+(2) 'make build' will build an ISO image called virt-p2v-$VERSION.iso
+
+(3) Burn the image on to a CD using standard tools.
+
+Booting from USB device
+----------------------------------------------------------------------
+
+If you wish to boot from a USB keydrive, use the livecd-iso-to-disk
+tool:
+
+  livecd-iso-to-disk virt-p2v-$VERSION.iso /dev/sdX1
+
+(Replace /dev/sdX1 with the actual USB device).
+
+In my experience I also had to set up a suitable MBR:
+
+  cat /usr/lib/syslinux/mbr.bin > /dev/sdX
+
+Running
+----------------------------------------------------------------------
+
+Boot the candidate machine from the live CD or USB keydrive.
+
+You will need to have network access to another machine where it will
+save the virtual disk images.  Ideally that machine will have ssh
+access (sshd service running), but there is also a simple network
+daemon that you can run on the target machine.  Note that the target
+machine is usually the Xen host, but it doesn't need to be: you could
+copy the images to a staging machine, and later copy them over to the
+Xen host.
+
+Note that the live CD doesn't modify any data on the candidate
+machine.
+
+Answer the questions.  There is a tutorial and explanation of some of
+the questions on the website which you may wish to follow:
+http://et.redhat.com/~rjones/virt-p2v/
+
+While the live CD is booted a shell is available on other virtual
+consoles.  Go to a virtual console using [ALT] [F2] and log in as root
+with no password.
+
+If it works, the result will be disk images for each filesystem from
+the candidate machine, which should boot directly or with the minimum
+of changes.
+
+Booting P2V candidate under Xen
+----------------------------------------------------------------------
+
+
+Testing
+----------------------------------------------------------------------
+
+If you want to test the live CD without actually P2V-ing a real
+server, then you can run the ISO directly in qemu.  (To do any sort of
+realistic testing you will also need an operating system image,
+eg. from /var/lib/xen/images, to experiment with).  For example:
+
+  $ cp /var/lib/xen/images/rhel5gax32fv.img .
+  $ make boot HDA=rhel5gax32fv.img
+  qemu -m 512 -cdrom virt-p2v-0.1.iso -boot d -hda rhel5gax32fv.img
+
+
+Network daemon
+----------------------------------------------------------------------
index 8dd9561..6ba0733 100644 (file)
@@ -35,6 +35,10 @@ virt-p2v.sh
   live CD has booted.  All the P2V stuff happens from this script. It
   uses the 'dialog' program to ask questions.
 
+inittab
+
+  Replacement /etc/inittab.
+
 General implementation plan
 ----------------------------------------------------------------------
 
@@ -79,5 +83,5 @@ Non-generic virt-p2v
 
 The above describes the generic virt-p2v, which asks users questions
 after boot.  It is also possible to build your own live CD, based on
-virt-p2v which has various settings compiled in, so it runs
-automatically.
\ No newline at end of file
+virt-p2v, which has various settings compiled in so it runs
+automatically.
index 48ca5c5..985dda8 100644 (file)
@@ -27,6 +27,11 @@ cat > /etc/inittab << '__EOF4123__'
 @INITTAB@
 __EOF4123__
 
+# Install custom lvm.conf.new (the shell script will rename to
+# lvm.conf when the time comes).
+cat > /etc/lvm/lvm.conf.new << '__EOF4312__'
+@LVM.CONF@
+__EOF4312__
 
 # Turn off firstboot for livecd boots.
 echo "RUN_FIRSTBOOT=NO" > /etc/sysconfig/firstboot
index c69d693..03b9897 100644 (file)
@@ -27,6 +27,7 @@ device-mapper
 util-linux
 module-init-tools
 gzip
+kpartx
 
 # For remote communications
 openssh-clients
@@ -51,6 +52,7 @@ strace
 vim-minimal
 vim-enhanced
 bind-utils
+file
 
 
 
diff --git a/lvm.conf b/lvm.conf
new file mode 100644 (file)
index 0000000..f2abead
--- /dev/null
+++ b/lvm.conf
@@ -0,0 +1,71 @@
+# Heavily customised lvm.conf for live CD.
+# $Id$
+
+devices {
+    dir = "/dev"
+    scan = [ "/dev" ]
+
+    # Set the filter so that only /dev/dm-* (device mapper) devices
+    # are scanned.
+    filter = [ "a|^/dev/dm-|", "r/.*/" ]
+
+    cache_dir = "/etc/lvm/cache"
+    cache_file_prefix = ""
+    write_cache_state = 1
+
+    # Allow device-mapper devices to be scanned, and disable
+    # block-device sanity checking.
+    types = [ "device-mapper", 16 ]
+    sysfs_scan = 0
+
+    md_component_detection = 1
+    ignore_suspended_devices = 0
+}
+
+log {
+    verbose = 0
+    syslog = 1
+    overwrite = 0
+    level = 0
+    indent = 1
+    command_names = 0
+    prefix = "  "
+}
+
+backup {
+    backup = 1
+    backup_dir = "/etc/lvm/backup"
+    archive = 1
+    archive_dir = "/etc/lvm/archive"
+    retain_min = 10
+    retain_days = 30
+}
+
+shell {
+    history_size = 100
+}
+
+global {
+    umask = 077
+    test = 0
+    units = "h"
+    activation = 1
+    proc = "/proc"
+    locking_type = 1
+    fallback_to_clustered_locking = 1
+    fallback_to_local_locking = 1
+    locking_dir = "/var/lock/lvm"
+}
+
+activation {
+    missing_stripe_filler = "/dev/ioerror"
+    reserved_stack = 256
+    reserved_memory = 8192
+    process_priority = -18
+    mirror_region_size = 512
+    mirror_log_fault_policy = "allocate"
+    mirror_device_fault_policy = "remove"
+}
+
+# This file must end with a newline
+
index d472578..688664e 100755 (executable)
@@ -28,22 +28,18 @@ override_remote_transport=
 # (only if override_remote_transport is 'ssh')
 override_remote_directory=
 
-# list of local physical devices to examine, separated by spaces,
+# list of local physical devices to send, separated by spaces,
 # if empty ask user.
 # this is usually a list of whole disk devices (eg. "sda")
-override_physical_devices=""
+override_devices_to_send=""
 
-# list of filesystems to send (eg. "sda1 sda2 VolGroup00/LogVol00")
-override_filesystems_to_send=""
-
-# list of root filesystems to examine (eg. "sda3" or
+# the root filesystem containing /etc/fstab (eg. "sda3" or
 # "VolGroup00/LogVol00")
-override_root_filesystems=""
+override_root_filesystem=""
 
 # network configuration
 #  - if empty, ask user
-#  - if contains a filesystem name (eg. "VolGroup00/LogVol00") try to
-#    auto-configure network from that
+#  - "auto" means try to autoconfigure from root filesystem
 # (XXX needs to contain more ways to override in future)
 override_network=""
 
@@ -97,6 +93,8 @@ function shell {
 #----------------------------------------------------------------------
 # Device mapper snapshotting.
 
+next_ramdisk=1
+
 # Create a device-mapper snapshot of a device with ramdisk overlay.
 # Example:
 #   snapshot sda1 snap
@@ -104,6 +102,10 @@ function shell {
 function snapshot {
     local dev=$1 name=$2
 
+    # Next free ramdisk (/dev/ram$i)
+    local i=$next_ramdisk
+    next_ramdisk=$(($next_ramdisk+1))
+
     # Get size of the device in sectors.
     local sectors=`blockdev --getsize /dev/$dev`
 
@@ -111,7 +113,7 @@ function snapshot {
        --table="0 $sectors snapshot-origin /dev/$dev"
     if [ $? -ne 0 ]; then exit 1; fi
     dmsetup create $name \
-       --table="0 $sectors snapshot /dev/mapper/${name}_org /dev/ram1 n 64"
+       --table="0 $sectors snapshot /dev/mapper/${name}_org /dev/ram$i n 64"
     if [ $? -ne 0 ]; then exit 1; fi
 }
 
@@ -120,6 +122,8 @@ function snapshot {
 #   drop_snapshot snap
 # drops a snapshot called /dev/mapper/snap
 function drop_snapshot {
+    local name=$1
+
     dmsetup remove /dev/mapper/$name
     dmsetup remove /dev/mapper/${name}_org
 }
@@ -232,11 +236,9 @@ function search_parts {
 #----------------------------------------------------------------------
 # Network configuration functions.
 
-# `auto_network $fs' mounts /dev/$fs read-only on /mnt/root and then
-# tries to configure the network from it.  Returns true or false.
+# `auto_network $fs' tries to configure the network from the
+# root filesystem.  Returns true or false.
 function auto_network {
-    if ! mount -o ro /dev/$1 /mnt; then return 1; fi
-
     # Make sure this file exists, otherwise Fedora gives a warning.
     touch /etc/resolv.conf
 
@@ -247,13 +249,11 @@ function auto_network {
     mv network-scripts network-scripts.saved
 
     # Originally I symlinked these, but that causes dhclient to
-    # keep open /mnt (as its cwd is in network-scripts subdir).
+    # keep open /mnt/root (as its cwd is in network-scripts subdir).
     # So now we will copy them recursively instead.
-    cp -r /mnt/etc/sysconfig/network .
-    cp -r /mnt/etc/sysconfig/networking .
-    cp -r /mnt/etc/sysconfig/network-scripts .
-    # This also means we can umount /mnt early.
-    umount /mnt
+    cp -r /mnt/root/etc/sysconfig/network .
+    cp -r /mnt/root/etc/sysconfig/networking .
+    cp -r /mnt/root/etc/sysconfig/network-scripts .
 
     /etc/init.d/network start
     local status=$?
@@ -389,9 +389,9 @@ while [ "$state" != "exit" ]; do
 
        # Block devices configuration.
        devices)
-           if [ -n "$override_physical_devices" ]; then
-               physical_devices="$override_physical_devices"
-               state=filesystems
+           if [ -n "$override_devices_to_send" ]; then
+               devices_to_send="$override_devices_to_send"
+               state=root
            else
                # Returns the list of physical devices in $devices
                search_devices
@@ -400,7 +400,7 @@ while [ "$state" != "exit" ]; do
 
                deviceslist=""
                for d in $devices; do
-                   if word_in_list $d $physical_devices; then
+                   if word_in_list $d $devices_to_send; then
                        stat=on
                    else
                        stat=off
@@ -412,58 +412,31 @@ while [ "$state" != "exit" ]; do
                dialog \
                    --extra-button --extra-label "Back" --nocancel \
                    --single-quoted \
-                   --checklist "Pick local disks to examine" 15 50 8 \
+                   --checklist "Pick disks to send" 15 50 8 \
                    $deviceslist \
                    2> line
                if [ $? -eq 3 ]; then state=directory
                else
-                   physical_devices=`cat line`
-                   state=filesystems
+                   devices_to_send=`cat line`
+                   state=root
                fi
            fi
            ;;
-       filesystems)
-           if [ -n "$override_filesystems_to_send" ]; then
-               filesystems_to_send="$override_filesystems_to_send"
-               state=roots
+
+       # Root filesystem.
+       root)
+           if [ -n "$override_root_filesystem" ]; then
+               root_filesystem="$override_root_filesystem"
+               state=network
            else
                # Returns the list of possible partitions / LVs in $parts
-               search_parts $physical_devices
+               search_parts $devices_to_send
 
                log partitions returned by search_parts: $parts
 
                partslist=""
-               for p in $parts; do
-                   if word_in_list $p $filesystems_to_send; then
-                       stat=on
-                   else
-                       stat=off
-                   fi
-                   gigs=$(($(blockdev --getsize /dev/$p)/2/1024/1024))
-                   partslist="$partslist $p /dev/$p(${gigs}GB) $stat"
-               done
-
-               dialog \
-                   --extra-button --extra-label "Back" --nocancel \
-                   --single-quoted \
-                   --checklist "Pick filesystems to send" 15 70 8 \
-                   $partslist \
-                   2> line
-               if [ $? -eq 3 ]; then state=devices
-               else
-                   filesystems_to_send=`cat line`
-                   state=roots
-               fi
-           fi
-           ;;
-       roots)
-           if [ -n "$override_root_filesystems" ]; then
-               root_filesystems="$override_root_filesystems"
-               state=network
-           else
-               partslist=""
-               for r in $filesystems_to_send; do
-                   if word_in_list $r $root_filesystems; then
+               for r in $parts; do
+                   if word_in_list $r $root_filesystem; then
                        stat=on
                    else
                        stat=off
@@ -474,12 +447,12 @@ while [ "$state" != "exit" ]; do
                dialog \
                    --extra-button --extra-label "Back" --nocancel \
                    --single-quoted \
-                   --checklist "Pick partition(s) containing a root (/) filesystem" 10 70 5 \
+                   --radiolist "Pick partition containing the root (/) filesystem" 10 70 5 \
                    $partslist \
                    2> line
-               if [ $? -eq 3 ]; then state=filesystems
+               if [ $? -eq 3 ]; then state=devices
                else
-                   root_filesystems=`cat line`
+                   root_filesystem=`cat line`
                    state=network
                fi
            fi
@@ -491,24 +464,14 @@ while [ "$state" != "exit" ]; do
                network="$override_network"
                state=verify
            else
-               partslist=""
-               for r in $root_filesystems; do
-                   if [ "$r" = "$network" ]; then
-                       stat=on
-                   else
-                       stat=off
-                   fi
-                   partslist="$partslist $r Auto-configure $stat"
-               done
-
                dialog \
                    --extra-button --extra-label "Back" --nocancel \
                    --radiolist "Network configuration" 10 70 5 \
-                   $partslist \
+                   "auto" "Auto-configure from root filesystem" on \
                    "ask" "Manual configuration" off \
                    "sh" "Configure from the shell" off \
                    2> line
-               if [ $? -eq 3 ]; then state=roots
+               if [ $? -eq 3 ]; then state=root
                else
                    network=`cat line`
                    state=verify
@@ -523,7 +486,7 @@ while [ "$state" != "exit" ]; do
            else
                dialog \
                    --title "Summary" \
-                   --yesno "Transport: $remote_transport\nRemote host: $remote_host\nRemote port: $remote_port\nRemote directory (ssh only): $remote_directory\nFilesystems to send: $filesystems_to_send\nRoot filesystem(s): $root_filesystems\nNetwork configuration: $network\n\nProceed with these settings?" \
+                   --yesno "Transport: $remote_transport\nRemote host: $remote_host\nRemote port: $remote_port\nRemote directory (ssh only): $remote_directory\nDisks to send: $devices_to_send\nRoot filesystem: $root_filesystem\nNetwork configuration: $network\n\nProceed with these settings?" \
                    23 70
                if [ $? -eq 1 ]; then
                    state=transport
@@ -541,6 +504,42 @@ done
 
 clear
 
+# De-activate all volume groups and switch to new dm-only LVM config.
+log deactivating volume groups
+
+vgchange -a n
+mv /etc/lvm/lvm.conf.new /etc/lvm/lvm.conf
+rm -f /etc/lvm/cache/.cache
+
+# Snapshot the block devices.
+for d in $devices_to_send; do
+    log snapshotting block device /dev/$d ...
+
+    snapshot $d snap_$d
+
+    # 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
+done
+
+# Rescan for LVs.
+log running vgscan
+vgscan
+
+# 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.
+
+log mount $root_filesystem as /mnt/root
+
+if [ -f /dev/mapper/snap_$root_filesystem ]; then
+    mount /dev/mapper/snap_$root_filesystem /mnt/root
+else
+    mount /dev/$root_filesystem /mnt/root
+fi
+
 # Now see if we can get a network configuration.
 log network configuration $network
 
@@ -550,10 +549,6 @@ case "$network" in
        echo
        echo "Please configure the network from this shell."
        echo
-       echo "You can modify any file under /etc (especially /etc/sysconfig)."
-       echo "No changes are made to the system disks unless you mount them"
-       echo "and explicitly modify them."
-       echo
        echo "When finished, exit with ^D or exit"
        echo
        shell
@@ -565,7 +560,7 @@ case "$network" in
        shell
        ;;
 
-    *)
+    auto)
        echo "Trying to auto-configure network from /dev/$network ..."
        echo
        if ! auto_network "$network"; then
@@ -575,20 +570,17 @@ case "$network" in
        fi
 esac
 
-# Mount the root filesystem(s) using device-mapper snapshots.
-# The snapshots are called snap0, snap1, etc. with the number
-# corresponding to its index in $root_filesystems array.
-
-
-
-
 
 
 
 
 
 
+#----------------------------------------------------------------------
+# Clean up.
 
+umount /mnt/root
+drop_snapshot snap
 
 # This file must end with a newline