From 9d4382acb7356a5b77ffb70a302ab3fe174448d3 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Fri, 9 Jul 2021 08:38:08 +0200 Subject: [PATCH] Detect and report outdated VMs Needrestart is awesome in detecting long running services or user sessions that are still running with old binaries. But there is another common kind of long-running process - VM Guests. Detecting the common qemu/KVM guests and reporting those to the user will help them to realize that also those guests should be considered to be restarted (or migrated onto an updated host) Signed-off-by: Christian Ehrhardt --- needrestart | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/needrestart b/needrestart index d33abc31..14a017bf 100755 --- a/needrestart +++ b/needrestart @@ -437,6 +437,7 @@ print "NEEDRESTART-VER: $NeedRestart::VERSION\n" if($opt_b && !$opt_p); my %restart; my %sessions; +my @guests; my @easy_hints; if(defined($opt_l)) { @@ -613,7 +614,7 @@ if(defined($opt_l)) { if(scalar keys %stage2 && !$uid) { $ui->progress_prep(scalar keys %stage2, __ 'Scanning candidates...'); - foreach my $pid (sort {$a <=> $b} keys %stage2) { + PIDLOOP: foreach my $pid (sort {$a <=> $b} keys %stage2) { $ui->progress_step; # skip myself @@ -656,6 +657,25 @@ if(defined($opt_l)) { print STDERR "$LOGPREF #$pid part of user manager service: uid=$1\n" if($nrconf{verbosity} > 1); push(@{ $sessions{$1}->{'user manager service'}->{ $ptable->{$pid}->{fname} } }, $pid); next; + } + if($value =~ m@/machine.slice/machine.qemu(.*).scope@) { + for my $cmdlineidx (0 .. $#{$ptable->{$pid}->{cmdline}} ) { + if ( ${$ptable->{$pid}->{cmdline}}[$cmdlineidx] eq "-name") { + foreach ( split(/,/, ${$ptable->{$pid}->{cmdline}}[$cmdlineidx+1]) ) { + if ( index($_, "guest=") == 0 ) { + my @namearg = split(/=/, $_, 2); + if ($#{namearg} == 1) { + print STDERR "$LOGPREF #$pid detected as VM guest '$namearg[1]' in group '$value'\n" if($nrconf{verbosity} > 1); + push(@guests, "VM '$namearg[1]' with pid $pid" ); + } + next PIDLOOP; + } + } + } + } + print STDERR "$LOGPREF #$pid detected as VM guest with unknown name in group '$value'\n" if($nrconf{verbosity} > 1); + push(@guests, "'Unkown VM' with pid $pid" ); + next; } elsif($value =~ m@/([^/]+\.service)$@) { ($1); @@ -757,6 +777,7 @@ if(defined($opt_l)) { } # No perfect hit - call any rc scripts instead. + print STDERR "$LOGPREF #$pid running $hook no perfect hit found $found pids $#nopids\n" if($nrconf{verbosity} > 1); if(!$found && $#nopids > -1) { foreach my $rc (@nopids) { if($is_systemd && exists($restart{"$rc.service"})) { @@ -1261,6 +1282,25 @@ if(defined($opt_l) && !$uid) { } } } + + ## GUESTS + $ui->vspace(); + if (! @guests) { + $ui->notice(__ 'No VM guests are running outdated binaries.') unless($opt_b || $opt_m eq 'e'); + } + else { + if($opt_m eq 'e') { + push(@easy_hints, __ 'outdated VM guests'); + } + else { + unless($opt_p || $opt_b) { + $ui->notice(__ 'VM guests running outdated binaries:'); + foreach ( @guests ) { + $ui->notice(__ " $_"); + } + } + } + } } # easy mode: print hint on outdated stuff