1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
#!/bin/bash
#---------------------------------------------------------------
# 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}"
USERUNITDIR=/etc/systemd/system
RUNTIMEUNITDIR=/run/systemd/system
SYSTEMUNITDIR=/lib/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 "$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
elif [ -f "$SYSTEMUNITDIR/$unit" ]; then
if [ -L "$SYSTEMUNITDIR/$unit" ]; then
searchunit=$(/usr/bin/readlink "$SYSTEMUNITDIR/$unit")
else
searchunit="$SYSTEMUNITDIR/$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.
reloaded=no
# 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 unit in $full_path_units; do
bn_unit="$(basename $unit)"
if [[ "$bn_unit" =~ "@.service" ]]; then
# We cannot simply link template units
if [ x$init = xsystemd -a x$reloaded = xno ]; then
/bin/systemctl --system daemon-reload
reloaded=yes
fi
echo 1>&2 "Migrating sysvinit service '$srv' to systemd native template unit '$bn_unit'"
/bin/systemctl enable $bn_unit
else
for enable_target in $enable_targets; do
wantsdir=$USERUNITDIR/${enable_target}.wants
mkdir -p $wantsdir
if [ ! -f $wantsdir/$bn_unit ]; then
echo 1>&2 "Migrating sysvinit service '$srv' to systemd native unit '$bn_unit' for target '${enable_target}'"
ln -s $unit $wantsdir/$bn_unit
reloaded=no
fi
done
fi
done
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
# Package install may have changed the unit file, so reload the daemon
# before trying to restart anything
if [ x$reloaded = xno ]; then
/bin/systemctl --system daemon-reload
fi
# There may be template units, so attempt to find all instances and
# restart them.
for unit in $units; do
if [[ "$unit" =~ "@.service" ]]; then
instances=$(/bin/systemctl -a --full list-units | grep -E "${unit%@.service}@[^ ]+.service" | awk '{ print $1 }')
if [ -n "$instances" ]; then
for iunit in $instances; do
/bin/systemctl --quiet try-restart $iunit
done
fi
else
/bin/systemctl --quiet try-restart $unit
fi
done
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
|