summaryrefslogtreecommitdiffstats
path: root/perl-install/services.pm
diff options
context:
space:
mode:
authorColin Guthrie <colin@mageia.org>2012-04-24 20:10:47 +0000
committerColin Guthrie <colin@mageia.org>2012-04-24 20:10:47 +0000
commitd6a5ac91b53160971b2381b1ec1d6b39e8aaa70f (patch)
treeb9e1078ee0620d074e2b349e185586f02cc43c36 /perl-install/services.pm
parent43ba4697a682ca16c322914147a75aeb4f5dbca3 (diff)
downloaddrakx-d6a5ac91b53160971b2381b1ec1d6b39e8aaa70f.tar
drakx-d6a5ac91b53160971b2381b1ec1d6b39e8aaa70f.tar.gz
drakx-d6a5ac91b53160971b2381b1ec1d6b39e8aaa70f.tar.bz2
drakx-d6a5ac91b53160971b2381b1ec1d6b39e8aaa70f.tar.xz
drakx-d6a5ac91b53160971b2381b1ec1d6b39e8aaa70f.zip
services: Read systemd service information.
This adds support for two different methods of working with systemd. The first, and more complete method is to query systemd for information about whether a service is enabled at boot. This mode requires that we are running under systemd and thus only works for machines in interactive mode post-install. For the installer, we also support a more rudamentary method which scans for unit files which contain simple install rules (i.e. only those services which are part of the typical multi-user or graphical targets (corresponding to runlevels 3 and 5 in the old days). This method will not show all services but it should be enough for the installer. https://bugs.mageia.org/show_bug.cgi?id=3253 https://bugs.mageia.org/show_bug.cgi?id=3740 https://bugs.mageia.org/show_bug.cgi?id=4910 https://bugs.mageia.org/show_bug.cgi?id=5122
Diffstat (limited to 'perl-install/services.pm')
-rw-r--r--perl-install/services.pm98
1 files changed, 82 insertions, 16 deletions
diff --git a/perl-install/services.pm b/perl-install/services.pm
index f7efdc5e3..1210077b1 100644
--- a/perl-install/services.pm
+++ b/perl-install/services.pm
@@ -369,31 +369,97 @@ sub xinetd_services() {
@xinetd_services;
}
-sub services_raw() {
+sub _systemd_services() {
local $ENV{LANGUAGE} = 'C';
- my (@services, @xinetd_services);
- foreach (run_program::rooted_get_stdout($::prefix, '/sbin/chkconfig', '--list')) {
- if (my ($xinetd_name, $on_off) = m!^\t(\S+):\s*(on|off)!) {
- push @xinetd_services, [ $xinetd_name, $on_off eq 'on' ];
- } elsif (my ($name, $l) = m!^(\S+)\s+(0:(on|off).*)!) {
- push @services, [ $name, [ $l =~ /(\d+):on/g ] ];
- }
+ my @services;
+ # Running system using systemd
+ log::explanations("Detected systemd running. Using systemctl introspection.");
+ foreach (run_program::rooted_get_stdout($::prefix, '/bin/systemctl', '--full', '--all', 'list-units')) {
+ if (my ($name) = m!^(\S+)\.service\s+loaded!) {
+ # We only look at non-template, non-linked service files in /lib
+ # We also check for any non-masked sysvinit files as these are
+ # also handled by systemd
+ if ($name !~ /.*\@$/g && (-e "$::prefix/lib/systemd/system/$name.service" or -e "$::prefix/etc/rc.d/init.d/$name") && ! -l "$::prefix/lib/systemd/system/$name.service") {
+ push @services, [ $name, !!run_program::rooted($::prefix, '/bin/systemctl', '--quiet', 'is-enabled', "$name.service") ];
+ }
+ }
+ }
+ @services;
+}
+
+sub _legacy_services() {
+ local $ENV{LANGUAGE} = 'C';
+ my @services;
+ my $has_systemd = has_systemd();
+ if ($has_systemd) {
+ # The system not using systemd but will be at next boot. This is
+ # is typically the case in the installer. In this mode we must read
+ # as much as is practicable from the native systemd unit files and
+ # combine that with information from chkconfig regarding legacy sysvinit
+ # scripts (which systemd will parse and include when running)
+ log::explanations("Detected systemd installed. Using fake service+chkconfig introspection.");
+ foreach (glob_("$::prefix/lib/systemd/system/*.service")) {
+ my ($name) = m!([^/]*).service$!;
+
+ # We only look at non-template, non-symlinked service files
+ if (!(/.*\@\.service$/g) && ! -l $_) {
+ # Limit ourselves to "standard" targets
+ my $wantedby = cat_($_) =~ /^WantedBy=(graphical|multi-user).target$/sm ? $1 : '';
+ if ($wantedby) {
+ # Exclude if enabled statically
+ # Note DO NOT use -e when testing for files that could
+ # be symbolic links as this will fail under a chroot
+ # setup where -e will fail if the symlink target does
+ # exist which is typically the case when viewed outside
+ # of the chroot.
+ if (!-l "$::prefix/lib/systemd/system/$wantedby.target.wants/$name.service") {
+ push @services, [ $name, !!-l "$::prefix/etc/systemd/system/$wantedby.target.wants/$name.service" ];
+ }
+ }
+ }
+ }
+ } else {
+ log::explanations("Could not detect systemd. Using chkconfig service introspection.");
+ }
+
+ # Regardless of whether we expect to use systemd on next boot, we still
+ # need to instrospect information about non-systemd native services.
+ my $runlevel;
+ my $on_off;
+ if (!$::isInstall) {
+ $runlevel = (split " ", `/sbin/runlevel`)[1];
}
- \@services, \@xinetd_services;
+ foreach (run_program::rooted_get_stdout($::prefix, '/sbin/chkconfig', '--list', '--type', 'sysv')) {
+ if (my ($name, $l) = m!^(\S+)\s+(0:(on|off).*)!) {
+ # If we expect to use systemd (i.e. installer) only show those
+ # sysvinit scripts which are not masked by a native systemd unit.
+ my $has_systemd_unit = (-e "$::prefix/lib/systemd/system/$name.service" or -l "$::prefix/lib/systemd/system/$name.service");
+ if (!$has_systemd || !$has_systemd_unit) {
+ if ($::isInstall) {
+ $on_off = $l =~ /\d+:on/g;
+ } else {
+ $on_off = $l =~ /$runlevel:on/g;
+ }
+ push @services, [ $name, $on_off ];
+ }
+ }
+ }
+ @services;
}
-#- returns:
+#- returns:
#--- the listref of installed services
#--- the listref of "on" services
sub services() {
- my ($services, $xinetd_services) = services_raw();
- my @l = @$xinetd_services;
- if ($::isInstall) {
- push @l, map { [ $_->[0], @{$_->[1]} > 0 ] } @$services;
+ my @services;
+ if (running_systemd()) {
+ @services = _systemd_services();
} else {
- my $runlevel = (split " ", `/sbin/runlevel`)[1];
- push @l, map { [ $_->[0], member($runlevel, @{$_->[1]}) ] } @$services;
+ @services = _legacy_services();
}
+
+ my @l = xinetd_services();
+ push @l, @services;
@l = sort { $a->[0] cmp $b->[0] } @l;
[ map { $_->[0] } @l ], [ map { $_->[0] } grep { $_->[1] } @l ];
}