diff options
author | Michael Stapelberg <michael@stapelberg.de> | 2013-09-19 02:07:30 +0000 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-09-19 02:10:18 +0000 |
commit | 4edc04d8c083e4faed6589efb9424dcfb679abab (patch) | |
tree | d1ec4fc9e5d543b658bcfe86cd9bc51c79b32708 | |
parent | 5e1ccabdf749871e9b9f382aa3e844a1831dddf1 (diff) | |
download | init-system-helpers-4edc04d8c083e4faed6589efb9424dcfb679abab.tar.gz |
Fix mask/unmask implementation (Thanks Michael Biebl)
Turns out that I mistakenly linked the same symlinks to /dev/null that
one would normally link to the service file, but mask links are
orthogonal to that. As an example, for rsyslog.service, the mask link is
/etc/systemd/system/rsyslog.service -> /dev/null, not
/etc/systemd/system/mult-user.targe.wants/rsyslog.service
fixes #714903
-rwxr-xr-x | script/deb-systemd-helper | 74 | ||||
-rw-r--r-- | t/001-deb-systemd-helper.t | 13 |
2 files changed, 32 insertions, 55 deletions
diff --git a/script/deb-systemd-helper b/script/deb-systemd-helper index c11f30f..92290ae 100755 --- a/script/deb-systemd-helper +++ b/script/deb-systemd-helper @@ -93,7 +93,6 @@ use Data::Dumper; my $quiet = 0; my $enabled_state_dir = '/var/lib/systemd/deb-systemd-helper-enabled'; -my $masked_state_dir = '/var/lib/systemd/deb-systemd-helper-masked'; # Globals are bad, but in this specific case, it really makes things much # easier to write and understand. @@ -372,67 +371,40 @@ sub rmdir_if_empty { sub mask_service { my ($scriptname, $service_path) = @_; - my $dsh_state = dsh_state_path($service_path); - my @entries = state_file_entries($dsh_state); - debug "Contents: " . Dumper(\@entries); + my $mask_link = '/etc/systemd/system/' . basename($service_path); - for my $service_link (@entries) { - my $statefile = $service_link; - $statefile =~ s,^/etc/systemd/system/,$masked_state_dir/,; - next if -e $statefile; - - my $old_dest; - if (-l $service_link) { - $old_dest = readlink($service_link); - unlink($service_link); - } else { - make_path(dirname($service_link)); - } - print STDERR "ln -s '/dev/null' '$service_link'\n" unless $quiet; - symlink('/dev/null', $service_link) or - error("unable to link $service_link to /dev/null: $!"); - $changed_sth = 1; + if (-e $mask_link) { + # If the link already exists, don’t do anything. + return if -l $mask_link && readlink($mask_link) eq '/dev/null'; - # Store the old destination of the symlink so that we can unmask - # properly later. - make_path(dirname($statefile)); - open(my $fh, '>>', $statefile); - print $fh $old_dest if defined($old_dest); - close($fh); + # Otherwise, error out. + error("$mask_link already exists"); } + + make_path(dirname($mask_link)); + print STDERR "ln -s '/dev/null' '$mask_link'\n" unless $quiet; + symlink('/dev/null', $mask_link) or + error("unable to link $mask_link to /dev/null: $!"); + $changed_sth = 1; } sub unmask_service { my ($scriptname, $service_path) = @_; - my $dsh_state = dsh_state_path($service_path); - my @entries = state_file_entries($dsh_state); - debug "Contents: " . Dumper(\@entries); - - for my $service_link (@entries) { - my $statefile = $service_link; - $statefile =~ s,^/etc/systemd/system/,$masked_state_dir/,; - next if ! -e $statefile; - - my @entries = state_file_entries($statefile); - - if (! -l $service_link || readlink($service_link) ne '/dev/null') { - debug "Not unmasking $service_link because it is not a link to /dev/null"; - next; - } - unlink($service_link); + my $mask_link = '/etc/systemd/system/' . basename($service_path); - if (@entries > 0) { - my $service_path = $entries[0]; - make_path(dirname($service_link)); - print STDERR "ln -s '$service_path' '$service_link'\n" unless $quiet; - symlink($service_path, $service_link) or - error("unable to link $service_link to $service_path: $!"); - $changed_sth = 1; - } + # Not masked? Nothing to do. + return unless -e $mask_link; - unlink($statefile); + if (! -l $mask_link || readlink($mask_link) ne '/dev/null') { + debug "Not unmasking $mask_link because it is not a link to /dev/null"; + return; } + + print STDERR "rm '$mask_link'\n" unless $quiet; + unlink($mask_link) or + error("unable to remove $mask_link: $!"); + $changed_sth = 1; } my $result = GetOptions( diff --git a/t/001-deb-systemd-helper.t b/t/001-deb-systemd-helper.t index 9c1773f..3d9c3b3 100644 --- a/t/001-deb-systemd-helper.t +++ b/t/001-deb-systemd-helper.t @@ -180,11 +180,15 @@ is_debian_installed($random_unit); # ┃ Verify “mask” (when enabled) results in the symlink pointing to /dev/null ┃ # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +my $mask_path = "/etc/systemd/system/$random_unit"; +ok(! -l $mask_path, 'mask link does not exist yet'); + $retval = system("DPKG_MAINTSCRIPT_PACKAGE=test $dsh mask $random_unit"); -is(readlink($symlink_path), '/dev/null', 'service masked'); +ok(-l $mask_path, 'mask link exists'); +is(readlink($mask_path), '/dev/null', 'service masked'); $retval = system("DPKG_MAINTSCRIPT_PACKAGE=test $dsh unmask $random_unit"); -isnt(readlink($symlink_path), '/dev/null', 'service no longer masked'); +ok(! -e $mask_path, 'mask link does not exist anymore'); # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ # ┃ Verify “mask” (when disabled) works the same way ┃ @@ -194,9 +198,10 @@ $retval = system("DPKG_MAINTSCRIPT_PACKAGE=test $dsh disable $random_unit"); ok(! -e $symlink_path, 'symlink no longer exists'); $retval = system("DPKG_MAINTSCRIPT_PACKAGE=test $dsh mask $random_unit"); -is(readlink($symlink_path), '/dev/null', 'service masked'); +ok(-l $mask_path, 'mask link exists'); +is(readlink($mask_path), '/dev/null', 'service masked'); $retval = system("DPKG_MAINTSCRIPT_PACKAGE=test $dsh unmask $random_unit"); -ok(! -e $symlink_path, 'symlink no longer exists'); +ok(! -e $mask_path, 'symlink no longer exists'); done_testing; |