switch-to-configuration: Stop sockets corresponding to services
If a service has a corresponding socket unit, then stop the socket before stopping the service. This prevents it from being restarted behind our backs. Also, don't restart the service; it will be restarted on demand via the socket.
This commit is contained in:
parent
e194d41b9c
commit
8adc1ee92e
@ -91,23 +91,27 @@ sub boolIsTrue {
|
|||||||
return $s eq "yes" || $s eq "true";
|
return $s eq "yes" || $s eq "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Forget about previously failed services.
|
|
||||||
system("@systemd@/bin/systemctl", "reset-failed");
|
|
||||||
|
|
||||||
# Stop all services that no longer exist or have changed in the new
|
# Stop all services that no longer exist or have changed in the new
|
||||||
# configuration.
|
# configuration.
|
||||||
my (@unitsToStop, @unitsToSkip);
|
my (@unitsToStop, @unitsToSkip);
|
||||||
my $activePrev = getActiveUnits;
|
my $activePrev = getActiveUnits;
|
||||||
while (my ($unit, $state) = each %{$activePrev}) {
|
while (my ($unit, $state) = each %{$activePrev}) {
|
||||||
my $baseUnit = $unit;
|
my $baseUnit = $unit;
|
||||||
|
|
||||||
# Recognise template instances.
|
# Recognise template instances.
|
||||||
$baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/;
|
$baseUnit = "$1\@.$2" if $unit =~ /^(.*)@[^\.]*\.(.*)$/;
|
||||||
my $prevUnitFile = "/etc/systemd/system/$baseUnit";
|
my $prevUnitFile = "/etc/systemd/system/$baseUnit";
|
||||||
my $newUnitFile = "@out@/etc/systemd/system/$baseUnit";
|
my $newUnitFile = "@out@/etc/systemd/system/$baseUnit";
|
||||||
|
|
||||||
|
my $baseName = $baseUnit;
|
||||||
|
$baseName =~ s/\.[a-z]*$//;
|
||||||
|
|
||||||
if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
|
if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
|
||||||
if (! -e $newUnitFile) {
|
if (! -e $newUnitFile) {
|
||||||
push @unitsToStop, $unit;
|
push @unitsToStop, $unit;
|
||||||
} elsif ($unit =~ /\.target$/) {
|
}
|
||||||
|
|
||||||
|
elsif ($unit =~ /\.target$/) {
|
||||||
# Cause all active target units to be restarted below.
|
# Cause all active target units to be restarted below.
|
||||||
# This should start most changed units we stop here as
|
# This should start most changed units we stop here as
|
||||||
# well as any new dependencies (including new mounts and
|
# well as any new dependencies (including new mounts and
|
||||||
@ -120,7 +124,9 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
|
}
|
||||||
|
|
||||||
|
elsif (abs_path($prevUnitFile) ne abs_path($newUnitFile)) {
|
||||||
if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
|
if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") {
|
||||||
# Do nothing. These cannot be restarted directly.
|
# Do nothing. These cannot be restarted directly.
|
||||||
} elsif ($unit =~ /\.mount$/) {
|
} elsif ($unit =~ /\.mount$/) {
|
||||||
@ -131,14 +137,26 @@ while (my ($unit, $state) = each %{$activePrev}) {
|
|||||||
} else {
|
} else {
|
||||||
my $unitInfo = parseUnit($newUnitFile);
|
my $unitInfo = parseUnit($newUnitFile);
|
||||||
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")
|
if (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "true")
|
||||||
|| $unit eq "systemd-user-sessions.service")
|
|| $unit eq "systemd-user-sessions.service"
|
||||||
|
|| $unit eq "systemd-journald.service")
|
||||||
{
|
{
|
||||||
push @unitsToSkip, $unit;
|
push @unitsToSkip, $unit;
|
||||||
} else {
|
} else {
|
||||||
|
# If this unit has a corresponding socket unit,
|
||||||
|
# then stop the socket unit as well, and restart
|
||||||
|
# the socket instead of the service.
|
||||||
|
if ($unit =~ /\.service$/ && defined $activePrev->{"$baseName.socket"}) {
|
||||||
|
push @unitsToStop, "$baseName.socket";
|
||||||
|
write_file($restartListFile, { append => 1 }, "$baseName.socket\n");
|
||||||
|
}
|
||||||
|
|
||||||
# Record that this unit needs to be started below. We
|
# Record that this unit needs to be started below. We
|
||||||
# write this to a file to ensure that the service gets
|
# write this to a file to ensure that the service gets
|
||||||
# restarted if we're interrupted.
|
# restarted if we're interrupted.
|
||||||
write_file($restartListFile, { append => 1 }, "$unit\n");
|
else {
|
||||||
|
write_file($restartListFile, { append => 1 }, "$unit\n");
|
||||||
|
}
|
||||||
|
|
||||||
push @unitsToStop, $unit;
|
push @unitsToStop, $unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,6 +174,17 @@ sub pathToUnitName {
|
|||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub unique {
|
||||||
|
my %seen;
|
||||||
|
my @res;
|
||||||
|
foreach my $name (@_) {
|
||||||
|
next if $seen{$name};
|
||||||
|
$seen{$name} = 1;
|
||||||
|
push @res, $name;
|
||||||
|
}
|
||||||
|
return @res;
|
||||||
|
}
|
||||||
|
|
||||||
# Compare the previous and new fstab to figure out which filesystems
|
# Compare the previous and new fstab to figure out which filesystems
|
||||||
# need a remount or need to be unmounted. New filesystems are mounted
|
# need a remount or need to be unmounted. New filesystems are mounted
|
||||||
# automatically by starting local-fs.target. Also handles swap
|
# automatically by starting local-fs.target. Also handles swap
|
||||||
@ -189,6 +218,7 @@ foreach my $mountPoint (keys %prevFstab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scalar @unitsToStop > 0) {
|
if (scalar @unitsToStop > 0) {
|
||||||
|
@unitsToStop = unique(@unitsToStop);
|
||||||
print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n";
|
print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n";
|
||||||
system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors?
|
system("@systemd@/bin/systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors?
|
||||||
}
|
}
|
||||||
@ -204,14 +234,12 @@ system("@out@/activate", "@out@") == 0 or $res = 2;
|
|||||||
|
|
||||||
# FIXME: Re-exec systemd if necessary.
|
# FIXME: Re-exec systemd if necessary.
|
||||||
|
|
||||||
|
# Forget about previously failed services.
|
||||||
|
system("@systemd@/bin/systemctl", "reset-failed");
|
||||||
|
|
||||||
# Make systemd reload its units.
|
# Make systemd reload its units.
|
||||||
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
|
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
|
||||||
|
|
||||||
sub unique {
|
|
||||||
my %unique = map { $_, 1 } @_;
|
|
||||||
return sort(keys(%unique));
|
|
||||||
}
|
|
||||||
|
|
||||||
# Start all active targets, as well as changed units we stopped above.
|
# Start all active targets, as well as changed units we stopped above.
|
||||||
# The latter is necessary because some may not be dependencies of the
|
# The latter is necessary because some may not be dependencies of the
|
||||||
# targets (i.e., they were manually started). FIXME: detect units
|
# targets (i.e., they were manually started). FIXME: detect units
|
||||||
@ -219,7 +247,7 @@ sub unique {
|
|||||||
# same time because we'll get a "Failed to add path to set" error from
|
# same time because we'll get a "Failed to add path to set" error from
|
||||||
# systemd.
|
# systemd.
|
||||||
my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
|
my @start = unique("default.target", split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
|
||||||
print STDERR "starting the following units: ", join(", ", @start), "\n";
|
print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
|
||||||
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
|
||||||
unlink($restartListFile);
|
unlink($restartListFile);
|
||||||
|
|
||||||
@ -227,7 +255,7 @@ unlink($restartListFile);
|
|||||||
# units.
|
# units.
|
||||||
my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // "");
|
my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // "");
|
||||||
if (scalar @reload > 0) {
|
if (scalar @reload > 0) {
|
||||||
print STDERR "reloading the following units: ", join(", ", @reload), "\n";
|
print STDERR "reloading the following units: ", join(", ", sort(@reload)), "\n";
|
||||||
system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4;
|
system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4;
|
||||||
unlink($reloadListFile);
|
unlink($reloadListFile);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user