Set autosync on the libguestfs handle, install signal handlers for SIGINT and
SIGQUIT which explicitly close the handle, and add an END { } block which closes
the handle in virt-v2v.pl.
Note that these measures still don't work when the user kills virt-v2v with
Ctrl-C. We suppose this is because qemu is also receiving the SIGINT and
shutting down before it can be shut down cleanly by libguestfs. However, the
above changes should improve matters if this can be fixed.
---
v2v/virt-v2v.pl | 24 ++++++++++++++++++++----
1 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/v2v/virt-v2v.pl b/v2v/virt-v2v.pl
index e475098..ee2210f 100755
--- a/v2v/virt-v2v.pl
+++ b/v2v/virt-v2v.pl
@@ -312,7 +312,10 @@ exit(1) unless(defined($dom));
my @storage = $conn->get_local_storage();
# Open a libguestfs handle on the guest's storage devices
-my $g = get_guestfs_handle(@storage);
+my $g = get_guestfs_handle(\@storage, $transferiso);
+
+$SIG{'INT'} = \&close_guest_handle;
+$SIG{'QUIT'} = \&close_guest_handle;
# Inspect the guest
my $os = inspect_guest($g);
@@ -323,16 +326,26 @@ my $guestos = Sys::VirtV2V::GuestOS->instantiate($g, $os);
# Modify the guest and its metadata for the target hypervisor
Sys::VirtV2V::Converter->convert($vmm, $guestos, $config, $dom, $os);
-$g->umount_all();
-$g->sync();
-
$vmm->define_domain($dom->toString());
exit(0);
+# We should always attempt to shut down the guest gracefully
+END {
+ close_guest_handle();
+}
+
###############################################################################
## Helper functions
+sub close_guest_handle
+{
+ if (defined($g)) {
+ $g->umount_all();
+ $g->sync();
+ }
+}
+
sub get_guestfs_handle
{
my $g = open_guest(\@_, rw => 1);
@@ -344,6 +357,9 @@ sub get_guestfs_handle
# Enable selinux in the guest
$g->set_selinux(1);
+ # Enable autosync to defend against data corruption on unclean shutdown
+ $g->set_autosync(1);
+
$g->launch ();
return $g;
--
1.6.6