+# After copying the data over we must shut down and restart the
+# appliance in order to expand the content. The reason for this may
+# not be obvious, but it's because otherwise we'll have duplicate VGs
+# (the old VG(s) and the new VG(s)) which breaks LVM.
+#
+# The restart is only required if we're going to expand something.
+
+if ($to_be_expanded > 0) {
+ restart_appliance ();
+ expand_partitions ();
+ expand_lvs ();
+ expand_lvs_content ();
+}
+
+sub restart_appliance
+{
+ # Sync disk and exit.
+ $g->umount_all ();
+ $g->sync ();
+ undef $g;
+
+ $g = Sys::Guestfs->new ();
+ $g->set_trace (1) if $debug;
+ $g->add_drive ($outfile);
+ $g->launch ();
+
+ # Target partitions have changed from /dev/sdb to /dev/sda,
+ # so change them.
+ foreach my $part (@partitions)
+ {
+ my $target = $partitions{$part}->{target};
+ if ($target) {
+ if ($target =~ m{/dev/(.)db(.*)}) {
+ $partitions{$part}->{target} = "/dev/$1da$2";
+ } else {
+ die "internal error: unexpected partition target: $target";
+ }
+ }
+ }
+}
+
+sub expand_partitions
+{
+ foreach my $part (@partitions)
+ {
+ unless ($partitions{$part}->{ignore}) {
+ my $target = $partitions{$part}->{target};
+ if ($target) {
+ # Expand if requested.
+ if ($partitions{$part}->{will_expand_content}) {
+ if (!$quiet && !$debug) {
+ print __x("Expanding {p} using the '{meth}' method\n",
+ p => $part,
+ meth => $partitions{$part}->{expand_content_method});
+ }
+ expand_target_partition ($part)
+ }
+ }
+ }
+ }
+}
+
+sub expand_target_partition
+{
+ local $_;
+ my $part = shift;
+
+ # Assertions.
+ die unless $part;
+ die unless $partitions{$part}->{can_expand_content};
+ die unless $partitions{$part}->{will_expand_content};
+ die unless $partitions{$part}->{expand_content_method};
+ die unless $partitions{$part}->{target};
+ die unless $expand_content;
+
+ my $target = $partitions{$part}->{target};
+ my $method = $partitions{$part}->{expand_content_method};
+ if ($method eq "pvresize") {
+ $g->pvresize ($target);
+ }
+ elsif ($method eq "resize2fs") {
+ $g->e2fsck_f ($target);
+ $g->resize2fs ($target);
+ }
+ elsif ($method eq "ntfsresize") {
+ $g->ntfsresize ($target);
+ }
+ else {
+ die "internal error: unknown method: $method";
+ }
+}
+
+sub expand_lvs
+{
+ local $_;
+
+ foreach (@lv_expand) {
+ $g->lvresize_free ($_, 100);
+ }
+}
+
+sub expand_lvs_content
+{
+ local $_;
+
+ foreach (@lvs) {
+ if ($lvs{$_}->{will_expand_content}) {
+ my $method = $lvs{$_}->{expand_content_method};
+ if (!$quiet && !$debug) {
+ print __x("Expanding {p} using the '{meth}' method\n",
+ p => $_, meth => $method);
+ }
+ if ($method eq "resize2fs") {
+ $g->e2fsck_f ($_);
+ $g->resize2fs ($_);
+ } elsif ($method eq "ntfsresize") {
+ $g->ntfsresize ($_);
+ } else {
+ die "internal error: unknown method: $method";
+ }
+ }
+ }
+}
+