switch-to-configuration.pl: Handle successful auto-restarts

switch-to-configuration.pl is currently hard-coded to assume that if a
unit is in the "auto-restart" state that something has gone wrong, but
this is not strictly true. For example, I run offlineimap as a oneshot
service restarting itself every minute (on success). NixOS currently
thinks that offlineimap has failed to start as it enters the
auto-restart state, because it doesn't consider why the unit failed.

This commit changes switch-to-configuration.pl to inspect the full
status of a unit in auto-restart state, and now only considers it failed
if the ExecMainStatus is non-zero.
This commit is contained in:
Oliver Charles 2014-02-02 10:24:49 +00:00 committed by Eelco Dolstra
parent 4a55391f1f
commit 0d18d39e98

View File

@ -93,8 +93,13 @@ sub parseFstab {
sub parseUnit {
my ($filename) = @_;
parseKeyValues(read_file($filename));
}
sub parseKeyValues {
my @lines = @_;
my $info = {};
foreach my $line (read_file($filename)) {
foreach my $line (@_) {
# FIXME: not quite correct.
$line =~ /^([^=]+)=(.*)$/ or next;
$info->{$1} = $2;
@ -337,8 +342,21 @@ system("@systemd@/bin/systemctl", "reload", "dbus.service");
my (@failed, @new, @restarting);
my $activeNew = getActiveUnits;
while (my ($unit, $state) = each %{$activeNew}) {
push @failed, $unit if $state->{state} eq "failed" || $state->{substate} eq "auto-restart";
push @new, $unit if $state->{state} ne "failed" && !defined $activePrev->{$unit};
if ($state->{state} eq "failed") {
push @failed, $unit;
}
elsif ($state->{state} eq "auto-restart") {
# A unit in auto-restart state is a failure *if* it previously failed to start
my $lines = `@systemd@/bin/systemctl show '$unit'`;
my $info = parseKeyValues(split "\n", $lines);
if ($info->{ExecMainStatus} ne '0') {
push @failed, $unit;
}
}
elsif ($state->{state} ne "failed" && !defined $activePrev->{$unit}) {
push @new, $unit;
}
}
print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"