From ee3a898983decff24e06334c70d19761b0e87c3e Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Fri, 9 Jun 2017 12:06:12 +0200 Subject: [PATCH] pvereport: improve output and add timeouts to commands Each command may not run longer than 10 seconds. This avoids situations where no output gets generated because of a infinitely hanging command (e.g. check for dead NFS storage) Also ensure that commands are separated with a new line from each other to improve readability. Signed-off-by: Thomas Lamprecht --- PVE/Report.pm | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/PVE/Report.pm b/PVE/Report.pm index 6717d286..eaf7c82f 100644 --- a/PVE/Report.pm +++ b/PVE/Report.pm @@ -7,6 +7,8 @@ use PVE::Tools; $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; +my $cmd_timeout = 10; # generous timeout + my $report; my @general = ('hostname', 'pveversion --verbose', 'cat /etc/hosts', 'top -b -n 1 | head -n 15', @@ -92,36 +94,41 @@ sub dir2text { PVE::Tools::dir_glob_foreach($target_dir, $regexp, sub { my ($file) = @_; - $report .= "# cat $target_dir$file\n"; + $report .= "\n# cat $target_dir$file\n"; $report .= PVE::Tools::file_get_contents($target_dir.$file)."\n"; }); } -# execute commands and display their output as if they've been done on a interactive shell -# so the local sysadmin can reproduce what we're doing -sub do_execute { - my ($command) = @_; - $report .= "# $command \n"; - open (COMMAND, "$command 2>&1 |"); - while () { - $report .= $_; - } -} - sub generate { + + my $record_output = sub { + $report .= shift . "\n"; + }; + + my $run_cmd_params = { + outfunc => $record_output, + errfunc => $record_output, + timeout => $cmd_timeout, + noerr => 1, # avoid checking programs exit code + }; + foreach my $subreport (@global_report) { my $title = $subreport->{'title'}; my @commands = @{$subreport->{'commands'}}; $report .= "\n==== $title ====\n"; foreach my $command (@commands) { - if (ref $command eq 'CODE') { - &$command; - } else { - do_execute($command); - next; - } + eval { + if (ref $command eq 'CODE') { + PVE::Tools::run_with_timeout($cmd_timeout, $command); + } else { + $report .= "\n# $command\n"; + PVE::Tools::run_command($command, %$run_cmd_params); + } + }; + $report .= "\nERROR: $@\n" if $@; } } -return $report; + + return $report; }