>From add46c2b45bff5181ff8fa3deba483c8fbca34dd Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Tue, 22 Mar 2011 15:30:24 +0000 Subject: [PATCH 3/3] Add --root (root choice) option. This option allows the root filesystem to be chosen more intelligently for operating systems that are (correctly or otherwise) identified as multi-boot. This changes the default behaviour so that instead of just printing an error and dying, which all users hated, it now defaults to asking the user which root filesystem they want to use. You can get the old behaviour by specifying --root=single. There are various other behaviours available too. --- v2v/virt-v2v.pl | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 100 insertions(+), 6 deletions(-) diff --git a/v2v/virt-v2v.pl b/v2v/virt-v2v.pl index 264fe21..4309d9e 100755 --- a/v2v/virt-v2v.pl +++ b/v2v/virt-v2v.pl @@ -244,6 +244,45 @@ I in the configuration file. =cut +my $root_choice = "ask"; + +=item B<--root=ask> + +=item B<--root=single> + +=item B<--root=first> + +=item B<--root=/dev/sdX> + +Choose the root filesystem to be converted. + +In the case where the virtual machine is dual-boot or multi-boot, or +where the VM has other filesystems that look like operating systems, +this option can be used to select the root filesystem (a.k.a. "C: +drive" or "/") of the operating system that is to be converted. The +Windows Recovery Console, certain attached DVD drives, and bugs in +libguestfs inspection heuristics, can make a guest look like a +multi-boot operating system. + +The default in virt-v2v E 0.7.1 was I<--root=single>, which +causes virt-v2v to die if a multi-boot operating system is found. + +Since virt-v2v E 0.7.2 the default is now I<--root=ask>: If the VM +is found to be multi-boot, then virt-v2v will stop and list the +possible root filesystems and ask the user which to use. This +requires that virt-v2v is run interactively. + +I<--root=first> means to choose the first root device in the case of a +multi-boot operating system. Since this is a heuristic, it may +sometimes choose the wrong one. + +You can also name a specific root device, eg. I<--root=/dev/sda2> +would mean to use the second partition on the first hard drive. If +the named root device does not exist or was not detected as a root +device, then virt-v2v will fail. + +=cut + my $list_profiles = 0; =item B<--list-profiles> @@ -321,6 +360,7 @@ GetOptions ("help|?" => sub { -exitval => 1 }) if (defined($bridge)); $bridge = $value; }, + "root=s" => \$root_choice, "p|profile=s" => \$profile, "list-profiles" => \$list_profiles ) or pod2usage(2); @@ -539,20 +579,74 @@ sub inspect_guest my $oses = inspect_operating_systems ($g, \%fses); - # Only work on single-root operating systems. + # Get list of roots, sorted. my $root_dev; - my @roots = keys %$oses; + my @roots = sort (keys %$oses); if(@roots == 0) { v2vdie __('No root device found in this operating system image.'); } - if(@roots > 1) { - v2vdie __('Multiboot operating systems are not supported by virt-v2v.'); + if (@roots == 1) { + $root_dev = $roots[0]; + } else { + # > 1 roots found. Depends on the --root option / $root_choice. + if ($root_choice eq "ask") { + # List out the roots and ask user to choose. + print "***\n"; + print "Dual- or multi-boot operating system detected. Choose the root filesystem\n"; + print "that contains the main operating system from the list below:\n"; + print "\n"; + my $i = 1; + foreach (@roots) { + print " [$i] $_\n"; + $i++; + } + $i--; + print "\n"; + my $j = 0; + while ($j < 1 || $j > $i) { + print "Enter 1..$i: "; + $j = int (); + } + $root_dev = $roots[$j]; + } + elsif ($root_choice eq "single") { + v2vdie __('Multi-boot operating systems are not supported by virt-v2v. Use the --root option to change how virt-v2v handles this.') + } + elsif ($root_choice eq "first") { + # Choose the first one. + $root_dev = $roots[0]; + } + elsif ($root_choice =~ m|^/dev/[hsv]d(.*)|) { + # Choose the named root. + my $partnum = $1; + foreach (@roots) { + if ($_ =~ m|^/dev/.d$partnum$|) { + $root_dev = $_; + last; + } + } + unless (defined ($root_dev)) { + v2vdie __x('Root device "{choice}" not found. Roots found were: {roots}.', + choice => $root_choice, + roots => join ' ', @roots) + } + } + elsif ($root_choice =~ m|^/dev/|) { + $root_dev = $root_choice; + unless (exists $oses->{$root_dev}) { + v2vdie __x('Root device "{choice}" not found. Roots found were: {roots}.', + choice => $root_choice, + roots => join ' ', @roots) + } + } + else { + v2vdie __x('Unknown --root option "{choice}".', + choice => $root_choice) + } } - $root_dev = $roots[0]; - # Mount up the disks and check for applications. my $os = $oses->{$root_dev}; -- 1.7.4.1