[libvirt-users] Handling connection closes in (older) Sys::Virt

I hope this is the correct mailing list for discussing the Sys::Virt Perl module. It appears that the most recent version has a new method called register_close_callback that, I believe, can be used to catch errors when the connection to libvirt is closed, e.g. due to libvirt restart or a network related issue. (I've been testing this simply by killing the the SSH process in the libvirt server.) However, Debian still ships libvirt 0.9.12 in stable backports and testing, as probably do many other mainstream distributions. The latest Perl bindings that can be installed from CPAN is thus 0.9.12 and it does not have support for close callbacks. Not only that, when a Perl program loses the (ssh) connection to libvirt, Perl just crashes: Program received signal SIGPIPE, Broken pipe. 0x00007ffff73de0d0 in __write_nocancel () from /lib/libpthread.so.0 Setting a $SIG{PIPE} handler does not seem to help. Is there any possibility of a Perl program surviving and gracefully handling a closed libvirt connection with libvirt version 0.9.12 or older? Henrik

On Wed, Nov 14, 2012 at 10:15:25AM +0200, Henrik Ahlgren wrote:
I hope this is the correct mailing list for discussing the Sys::Virt Perl module.
It appears that the most recent version has a new method called register_close_callback that, I believe, can be used to catch errors when the connection to libvirt is closed, e.g. due to libvirt restart or a network related issue. (I've been testing this simply by killing the the SSH process in the libvirt server.)
However, Debian still ships libvirt 0.9.12 in stable backports and testing, as probably do many other mainstream distributions. The latest Perl bindings that can be installed from CPAN is thus 0.9.12 and it does not have support for close callbacks. Not only that, when a Perl program loses the (ssh) connection to libvirt, Perl just crashes:
Program received signal SIGPIPE, Broken pipe. 0x00007ffff73de0d0 in __write_nocancel () from /lib/libpthread.so.0
Setting a $SIG{PIPE} handler does not seem to help. Is there any possibility of a Perl program surviving and gracefully handling a closed libvirt connection with libvirt version 0.9.12 or older?
You definitely need to figure out how to set the SIGPIPE handler to 'ignore'. libvirt.so does not do this, because it is bad practice for a library to set application global state like this. Not sure what you tried, but I'd definitely expect this to work: $SIG{'PIPE'} = 'IGNORE'; Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Wed, Nov 14, 2012 at 10:08:45AM +0000, Daniel P. Berrange wrote:
You definitely need to figure out how to set the SIGPIPE handler to 'ignore'. libvirt.so does not do this, because it is bad practice for a library to set application global state like this. Not sure what you tried, but I'd definitely expect this to work:
$SIG{'PIPE'} = 'IGNORE';
I don't know what I'm doing wrong, but consider the following simple test script. Perhaps this is a Debian issue? #!/usr/bin/perl use Sys::Virt 0.9.2; my $vmm = Sys::Virt->new(address => "qemu+ssh://root\@SOME.HOST/system") or die; $SIG{'PIPE'} = 'IGNORE'; $| = 1; while (1) { eval { my $dummy = $vmm->get_node_info }; print "."; sleep 1; } Let's run it and go to SOME.HOST to kill the SSH process: $ gdb perl GNU gdb (GDB) 7.0.1-debian Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /usr/bin/perl...(no debugging symbols found)...done. (gdb) run lv.pl Starting program: /usr/bin/perl lv.pl [Thread debugging using libthread_db enabled] ...... Program received signal SIGPIPE, Broken pipe. 0x00007ffff73de0d0 in __write_nocancel () from /lib/libpthread.so.0 (gdb) bt #0 0x00007ffff73de0d0 in __write_nocancel () from /lib/libpthread.so.0 #1 0x00007ffff6876226 in ?? () from /usr/lib/libvirt.so.0 #2 0x00007ffff687643e in ?? () from /usr/lib/libvirt.so.0 #3 0x00007ffff6867d31 in ?? () from /usr/lib/libvirt.so.0 #4 0x00007ffff68685e1 in ?? () from /usr/lib/libvirt.so.0 #5 0x00007ffff6868c47 in ?? () from /usr/lib/libvirt.so.0 #6 0x00007ffff6869421 in ?? () from /usr/lib/libvirt.so.0 #7 0x00007ffff68436cc in ?? () from /usr/lib/libvirt.so.0 #8 0x00007ffff684376c in ?? () from /usr/lib/libvirt.so.0 #9 0x00007ffff684e5e5 in ?? () from /usr/lib/libvirt.so.0 #10 0x00007ffff68191e0 in virNodeGetInfo () from /usr/lib/libvirt.so.0 #11 0x00007ffff6c16b48 in XS_Sys__Virt_get_node_info (my_perl=<value optimized out>, cv=<value optimized out>) at Virt.xs:1450 #12 0x00007ffff7b1d675 in Perl_pp_entersub () from /usr/lib/libperl.so.5.10 #13 0x00007ffff7b1bbb6 in Perl_runops_standard () from /usr/lib/libperl.so.5.10 #14 0x00007ffff7ac078c in perl_run () from /usr/lib/libperl.so.5.10 #15 0x0000000000400f24 in main () (gdb)

On Wed, Nov 14, 2012 at 12:46:15PM +0200, Henrik Ahlgren wrote:
On Wed, Nov 14, 2012 at 10:08:45AM +0000, Daniel P. Berrange wrote:
You definitely need to figure out how to set the SIGPIPE handler to 'ignore'. libvirt.so does not do this, because it is bad practice for a library to set application global state like this. Not sure what you tried, but I'd definitely expect this to work:
$SIG{'PIPE'} = 'IGNORE';
I don't know what I'm doing wrong, but consider the following simple test script. Perhaps this is a Debian issue?
#!/usr/bin/perl use Sys::Virt 0.9.2; my $vmm = Sys::Virt->new(address => "qemu+ssh://root\@SOME.HOST/system") or die; $SIG{'PIPE'} = 'IGNORE'; $| = 1; while (1) { eval { my $dummy = $vmm->get_node_info }; print "."; sleep 1; }
Let's run it and go to SOME.HOST to kill the SSH process:
If you strace this, do you see the SIGPIPE handler being set to IGNORE. On my system I do: $ strace ./demo.pl 2>&1 | grep SIGPIPE rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, NULL, 8) = 0 rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, 8) = 0 and I don't see any EPIPE error when killing ssh Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Wed, Nov 14, 2012 at 10:58:03AM +0000, Daniel P. Berrange wrote:
$ strace ./demo.pl 2>&1 | grep SIGPIPE rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, NULL, 8) = 0 rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, {SIG_IGN, [], SA_RESTORER, 0x343ca0efe0}, 8) = 0
and I don't see any EPIPE error when killing ssh
Daniel
$ strace ./lv.pl 2>&1 | grep SIGPIPE rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7fcf3318aff0}, {SIG_DFL, [], 0}, 8) = 0 This is with lv 0.9.12-4~bpo60+1 and the stock squeeze Perl 5.10.1.
participants (2)
-
Daniel P. Berrange
-
Henrik Ahlgren