diff options
Diffstat (limited to 'trunk/add-service')
-rwxr-xr-x | trunk/add-service | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/trunk/add-service b/trunk/add-service new file mode 100755 index 0000000..bd51d86 --- /dev/null +++ b/trunk/add-service @@ -0,0 +1,265 @@ +#!/bin/sh +#--------------------------------------------------------------- +# Project : Mandriva Linux +# Module : rpm-helper +# File : add-service +# Version : $Id$ +# Authors : Frederic Lepied, Andrey Borzenkov +# Created On : Mon Jul 8 08:14:34 2002 +# Purpose : helper script for rpm scriptlets to add a +# service. +#--------------------------------------------------------------- + +if [ x$1 = x--no-sysv ]; then + do_sysv=no + shift +else + do_sysv=yes +fi + +if [ $# -lt 3 ]; then + echo "usage: $0 [--no-sysv] <pkg name> <number installed> [<service name>] [<unit name> ...]" 1>&2 + exit 1 +fi + +# What init system are we currently using? +if /bin/mountpoint -q /sys/fs/cgroup/systemd; then + init=systemd +else + init=sysvinit +fi + +pkg=$1 # name of the package +num=$2 # number of packages installed +if [ $do_sysv = yes ]; then + srv=$3 # name of the SysV script + shift 3 +else + srv= + shift 2 +fi +units="$*" # systemd units +units_to_enable= # units enabled by msec +systemd_migration_dir=/var/lib/rpm-helper/systemd-migration +mkdir -p "${systemd_migration_dir}" + +SYSTEMUNITDIR=/lib/systemd/system +USERUNITDIR=/etc/systemd/system +RUNTIMEUNITDIR=/run/systemd/system + +find_unit() { + unit=$(basename $1) + + # We need to normalise the systemd unit name as the native unit may not have + # the same filename (sans it's .service suffix) as sysvinit script. + # In this case, symlinks are used to mask the sysvinit file, but for enabling + # and disabling units we must use the official name. + + searchunit= + if [ -f "$SYSTEMUNITDIR/$unit" ]; then + if [ -L "$SYSTEMUNITDIR/$unit" ]; then + searchunit=$(/usr/bin/readlink "$SYSTEMUNITDIR/$unit") + else + searchunit="$SYSTEMUNITDIR/$unit" + fi + elif [ -f "$USERUNITDIR/$unit" ]; then + if [ -L "$USERUNITDIR/$unit" ]; then + searchunit=$(/usr/bin/readlink "$USERUNITDIR/$unit") + else + searchunit="$USERUNITDIR/$unit" + fi + elif [ -f "$RUNTIMEUNITDIR/$unit" ]; then + if [ -L "$RUNTIMEUNITDIR/$unit" ]; then + searchunit=$(/usr/bin/readlink "$RUNTIMEUNITDIR/$unit") + else + searchunit="$RUNTIMEUNITDIR/$unit" + fi + fi + if [ -n "$searchunit" ]; then + echo -n $searchunit + fi +} + + +# If only a sysvinit service is given, then deal with a systemd unit of the same +# name. Specific specs can enable specific unit names as needed but this should +# catch the most common usage. +if [ -z "$units" ]; then + units="$srv.service" + searchunit=$(find_unit $units) + if [ -n "$searchunit" ]; then + units=$(basename $searchunit) + fi +fi + +add_service() { + # Add the service + if [ -r /etc/sysconfig/msec ]; then + . /etc/sysconfig/msec + fi + + # High security: add only authorized services + LIST=/etc/security/msec/server + + # during the install the symlink isn't done so find the right file + # by ourselves + if [ -n "$DURING_INSTALL" -a ! -f $LIST ]; then + LIST=/etc/security/msec/server.$SECURE_LEVEL + fi + + # This is half-hearted support for msec: we check "srv" for a unit + # with name "srv.service". This should account for most(?) common + # case when SysV script srv is replaced by single unit srv.service + # If SysV name was supplied, we assume units are equivalent and do + # not need to be checked. + # TODO should msec support full unit name? + if [ -f $LIST ]; then + if [ -n "$srv" ]; then + if fgrep -qx "${srv}" $LIST; then + units_to_enable="$units" + else + srv= + fi + else + for i in $units; do + [ $i != ${i%.service} ] && ! fgrep -qx ${i%.service} $LIST && continue + [ $i != ${i%.socket} ] && ! fgrep -qx ${i%.socket} $LIST && continue + [ $i != ${i%.path} ] && ! fgrep -qx ${i%.path} $LIST && continue + units_to_enable="$units_to_enable $i" + done + fi + else + units_to_enable="$units" + fi + + # Actually do enable/disable foo + if [ -n "$units_to_enable" ]; then + /bin/systemctl --quiet enable $units_to_enable >/dev/null + fi + + # When no native systemd unit exists, the above command will actually + # just end up running chkconfig anyway, but if a native systemd unit exists + # the legacy init script will not be enabled. + # In order to enable switching back ot sysvinit, we should enable the + # sysvinit scripts too. + if [ -n "$srv" -a -f /etc/rc.d/init.d/$srv ]; then + /sbin/chkconfig --add $srv + + if [ -r /etc/sysconfig/system ]; then + . /etc/sysconfig/system + fi + + # TODO what to do with system units here? + if [ -z "$ADD_SERVICES_TO_CURRENT_PROFILE_ONLY" ]; then + # add the service to all the profiles at once + if [ -d /etc/netprofile/profiles/default/services ]; then + for dir in /etc/netprofile/profiles/*/services; do + touch $dir/$srv + done + fi + fi + fi +} + +check_sysvinit_service() { + rl=$1 + srv=$2 + + set -- /etc/rc${rl}.d/S??$srv + if [ $# -gt 1 ]; then + echo 1>&2 "add-service: Error: $srv appears multiple times at runlevel $rl: $*" + fi + + echo -n $1 +} +if [ $num = 1 ]; then + # First install mode + add_service +else + # Upgrade mode. + + # Handle migration to systemd. + # If a previously installed package only had a sysvinit script, but an + # updated package has a native systemd unit, we need to make sure we migrate + # any service enablement for various targets (née runlevels) + if [ -n "$srv" -a -n "$units" ]; then + if [ ! -f "${systemd_migration_dir}/$srv" ]; then + full_path_units= + for unit in $units; do + # We need a full path for the symlink. Also it's possible + # that $unit contains "foo.service" where foo is actually + # a sysvinit script and thus we'll not have anything native. + # We only consider a "migration" to have taken place when + # we genuinely have a native systemd unit. + unit=$(find_unit $unit) + if [ -n "$unit" ]; then + full_path_units="$full_path_units $unit" + fi + done + + if [ -n "$full_path_units" ]; then + enable_targets= + # We have not yet migrated this service + # First we check in which runlevels the legacy service is enabled + # Only bother checking runlevels 1 3 and 5 + script=$(check_sysvinit_service 1 $srv) + + # NB We only check that the link exists as the old sysvinit + # script may have been removed during migration to systemd + # native unit. + if [ -L "$script" ]; then + enable_targets="$enable_targets rescue.target" + fi + + script=$(check_sysvinit_service 3 $srv) + if [ -L "$script" ]; then + enable_targets="$enable_targets multi-user.target" + else + # As graphical.target includes everything in multi-user.target, + # we only need to check 5 when 3 does NOT give us a result. + script=$(check_sysvinit_service 5 $srv) + if [ -L "$script" ]; then + enable_targets="$enable_targets graphical.target" + fi + fi + + if [ -n "$enable_targets" ]; then + for enable_target in $enable_targets; do + wantsdir=$USERUNITDIR/${enable_target}.wants + mkdir -p $wantsdir + for unit in $full_path_units; do + if [ ! -f $wantsdir/$(basename $unit) ]; then + echo 1>&2 "Migrating sysvinit service '$srv' to systemd native unit '$(basename $unit)' for target '${enable_target}'" + ln -s $unit $wantsdir/$(basename $unit) + fi + done + done + if [ x$init = xsystemd ]; then + /bin/systemctl --system daemon-reload + fi + fi + + # It could be that a package is installed but not enabled. + # If that is the case, we should still consider it "migrated" + # even when we do not enable anything. + touch "${systemd_migration_dir}/$srv" + fi + fi + fi + + if [ x$init = xsystemd ]; then + /bin/systemctl --quiet try-restart $units + elif [ -f /etc/rc.d/init.d/$srv ]; then + script=$(check_sysvinit_service 3 $srv); + if [ -f "$script" ]; then + /sbin/chkconfig --add $srv + fi + + # restart the service if already running + if [ -f /var/lock/subsys/$srv ]; then + /sbin/service $srv restart > /dev/null || : + fi + fi +fi + +# add-service ends here |