If something die()s, the error status can get lost in cleanup when various child processes exit and overwrite $?. Specifically, the RHEV target uses a child process for NFS access, and libguestfs launches a qemu child process. This change ensures that DESTROY and END blocks which perform operations on child processes explicitly preserve $?. --- lib/Sys/VirtV2V/Target/RHEV.pm | 10 ++++++++++ v2v/virt-v2v.pl | 7 +++++++ 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/lib/Sys/VirtV2V/Target/RHEV.pm b/lib/Sys/VirtV2V/Target/RHEV.pm index f14c54f..445893a 100644 --- a/lib/Sys/VirtV2V/Target/RHEV.pm +++ b/lib/Sys/VirtV2V/Target/RHEV.pm @@ -143,11 +143,16 @@ sub DESTROY { my $self = shift; + my $retval = $?; + # Make certain the child process dies with the object if (defined($self->{pid})) { kill(9, $self->{pid}); waitpid($self->{pid}, WNOHANG); + $retval ||= $?; } + + $? = $retval; } package Sys::VirtV2V::Target::RHEV::Vol; @@ -441,6 +446,8 @@ sub DESTROY { my $self = shift; + my $retval = $?; + my $eh = Sys::VirtV2V::ExecHelper->run('umount', $self->{mountdir}); if ($eh->status() != 0) { print STDERR user_message(__x("Failed to unmount {path}. Command ". @@ -449,6 +456,7 @@ sub DESTROY path => $self->{domain_path}, status => $eh->status(), output => $eh->output())); + $retval ||= $eh->status(); } rmdir($self->{mountdir}) @@ -456,6 +464,8 @@ sub DESTROY "{dir}: {error}", dir => $self->{mountdir}, error => $!)); + + $? = $retval; } =item create_volume(name, size) diff --git a/v2v/virt-v2v.pl b/v2v/virt-v2v.pl index 15d0d5b..7951303 100755 --- a/v2v/virt-v2v.pl +++ b/v2v/virt-v2v.pl @@ -350,6 +350,9 @@ exit(0); # We should always attempt to shut down the guest gracefully END { close_guest_handle(); + + # die() sets $? to 255, which is untidy. + $? = $? == 255 ? 1 : $?; } ############################################################################### @@ -364,10 +367,14 @@ sub close_guest_handle $g->umount_all(); $g->sync(); + my $retval = $? + # Note that this undef is what actually causes the underlying handle to # be closed. This is required to allow the RHEV target's temporary mount # directory to be unmounted and deleted prior to exit. $g = undef; + + $? ||= $retval; } } -- 1.6.6.1