Hello,
we (systemd Debian maintainers) are currently working on creating
a policy for how Debian packages should deal with systemd.
One of our goals is to maintain compatibility with sysvinit as good
as possible so that users can switch to and from systemd as they wish.
To be precise, this means that invoke-rc.d and update-rc.d should be
made systemd-aware, so that the changes to existing packages will be
as small as possible.
I have attached patches for invoke-rc.d and update-rc.d which make
them systemd-aware. What are your thoughts on that?
Best regards,
Michael
(for the Debian systemd maintainers)
--- /usr/sbin/update-rc.d.O 2012-07-20 16:48:26.446152769 +0200
+++ /usr/sbin/update-rc.d 2012-07-21 10:55:41.408503038 +0200
@@ -5,6 +5,7 @@
use strict;
use warnings;
+use File::Path qw(make_path); # in core since Perl 5.001
my $initd = "/etc/init.d";
my $etcd = "/etc/rc";
@@ -424,6 +425,42 @@
error("initscript does not exist: /etc/init.d/$scriptname");
}
} elsif ("disable" eq $action || "enable" eq $action) {
+ # In addition to the insserv call we also enable/disable the service
+ # for systemd by creating the appropriate symlink in case there is a
+ # native systemd service. We need to do this on our own instead of
+ # using systemctl because systemd might not even be installed yet.
+ my $service_path;
+ if (-f "/etc/systemd/system/$scriptname.service") {
+ $service_path = "/etc/systemd/system/$scriptname.service";
+ } elsif (-f "/lib/systemd/system/$scriptname.service") {
+ $service_path = "/lib/systemd/system/$scriptname.service";
+ }
+ if (defined($service_path)) {
+ my $changed_sth;
+ open my $fh, '<', $service_path or error("unable to read $service_path");
+ while (<$fh>) {
+ chomp;
+ if (/^\s*WantedBy=(.+)$/i) {
+ my $wants_dir = "/etc/systemd/system/$1.wants";
+ my $service_link = "$wants_dir/$scriptname.service";
+ if ("enable" eq $action) {
+ make_path($wants_dir);
+ symlink($service_path, $service_link);
+ } else {
+ unlink($service_link) if -e $service_link;
+ }
+ $changed_sth = 1;
+ }
+ }
+ close($fh);
+
+ # If we changed anything and this machine is running systemd, tell
+ # systemd to reload so that it will immediately pick up our
+ # changes.
+ if ($changed_sth && -e "/sys/fs/cgroup/systemd") {
+ system("systemctl", "daemon-reload");
+ }
+ }
insserv_toggle($notreally, $action, $scriptname, @args);
# Call insserv to resequence modified links
my $rc = system("insserv", @opts, $scriptname) >> 8;
--- /usr/sbin/invoke-rc.d.O 2012-07-20 14:58:14.140223575 +0200
+++ /usr/sbin/invoke-rc.d 2012-07-20 15:30:33.317403603 +0200
@@ -38,6 +38,7 @@
RETURNFAILURE=
RC=
is_upstart=
+is_systemd=
# Shell options
set +e
@@ -273,6 +274,8 @@
&& [ -e "$UPSTARTDIR/${INITSCRIPTID}.conf" ]
then
is_upstart=1
+elif test -e /sys/fs/cgroup/systemd ; then
+ is_systemd=1
elif test ! -f "${INITDPREFIX}${INITSCRIPTID}" ; then
## Verifies if the given initscript ID is known
## For sysvinit, this error is critical
@@ -383,7 +386,18 @@
esac
# test if /etc/init.d/initscript is actually executable
-if [ -n "$is_upstart" ] || testexec "${INITDPREFIX}${INITSCRIPTID}" ; then
+_executable=
+if [ -n "$is_upstart" ]; then
+ _executable=1
+elif [ -n "$is_systemd" ]; then
+ _state=$(systemctl -p LoadState show "${INITSCRIPTID}.service" 2>/dev/null)
+ if [ "$_state" != "LoadState=masked" ]; then
+ _executable=1
+ fi
+elif testexec "${INITDPREFIX}${INITSCRIPTID}"; then
+ _executable=1
+fi
+if [ "$_executable" = "1" ]; then
if test x${RC} = x && test x${MODE} = xquery ; then
RC=105
fi
@@ -496,6 +510,37 @@
initctl "$saction" "$INITSCRIPTID" && exit 0
;;
esac
+ elif [ -n "$is_systemd" ]; then
+ case $saction in
+ start|stop|restart)
+ systemctl "${saction}" "${INITSCRIPTID}.service" && exit 0
+ ;;
+ status)
+ # The status action is different because systemctl
+ # will not exit with status 0 in case the service
+ # has failed, even though status was displayed.
+ systemctl status "${INITSCRIPTID}.service"; exit 0
+ ;;
+ reload)
+ _canreload="$(systemctl -p CanReload show $service 2>/dev/null)"
+ if [ "$_canreload" = "CanReload=no" ]; then
+ "${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
+ else
+ systemctl reload "${INITSCRIPTID}.service" && exit 0
+ fi
+ ;;
+ force-stop)
+ systemctl --signal=9 kill "${INITSCRIPTID}.service" && exit 0
+ ;;
+ force-reload)
+ systemctl restart "${INITSCRIPTID}.service" && exit 0
+ ;;
+ *)
+ # We try to run non-standard actions by running
+ # the init script directly.
+ "${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
+ ;;
+ esac
else
"${INITDPREFIX}${INITSCRIPTID}" "${saction}" "$@" && exit 0
fi
_______________________________________________
Pkg-sysvinit-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-sysvinit-devel