[pve-devel] [RFC PATCH 1/1] Add run_or_get_killed utility
Emmanuel Kasper
e.kasper at proxmox.com
Mon Jun 19 11:21:08 CEST 2017
This runs subroutine in a forked process
and kills it after a timeout
---
src/PVE/Tools.pm | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
index da7da5d..0bf94ae 100644
--- a/src/PVE/Tools.pm
+++ b/src/PVE/Tools.pm
@@ -841,6 +841,49 @@ sub next_spice_port {
return next_unused_port(61000, 61099, $family, $address);
}
+# sigkill a $sub running in a fork if it can't write a pipe after $timeout
+# the $sub has to return a single scalar
+sub run_or_get_killed {
+ my ($sub, $timeout) = @_;
+
+ my $res;
+
+ my $pipe = IO::Pipe->new();
+ my $child = fork();
+ if (!defined($child)) {
+ warn "fork failed: $!\n";
+ return $res;
+ }
+
+ if (!$child) {
+ $pipe->writer();
+ eval {
+ $res = $sub->();
+ print {$pipe} "$res";
+ $pipe->close();
+ };
+ if (my $err = $@) {
+ warn $err;
+ POSIX::_exit(1);
+ }
+ POSIX::_exit(0);
+ }
+
+ $pipe->reader();
+
+ my $readvalues = sub {
+ $res = (<$pipe> =~ /^(.*)$/)[0];
+ };
+ eval {
+ run_with_timeout($timeout, $readvalues);
+ };
+ warn $@ if $@;
+ $pipe->close();
+ kill('KILL', $child);
+ waitpid($child, 0);
+ return $res;
+}
+
# NOTE: NFS syscall can't be interrupted, so alarm does
# not work to provide timeouts.
# from 'man nfs': "Only SIGKILL can interrupt a pending NFS operation"
--
2.11.0
More information about the pve-devel
mailing list