Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 166545
Collapse All | Expand All

(-)baselayout-1.12.9/etc/conf.d/rc (+3 lines)
Lines 244-246 svcfstype="tmpfs" Link Here
244
# due to kernel limitations.
244
# due to kernel limitations.
245
245
246
svcsize=2048
246
svcsize=2048
247
248
svclock="/var/lib/init.d/locks"
249
(-)baselayout-1.12.9/sbin/functions.sh (+1 lines)
Lines 9-14 RC_GOT_FUNCTIONS="yes" Link Here
9
# Check /etc/conf.d/rc for a description of these ...
9
# Check /etc/conf.d/rc for a description of these ...
10
declare -r svclib="/lib/rcscripts"
10
declare -r svclib="/lib/rcscripts"
11
declare -r svcdir="${svcdir:-/var/lib/init.d}"
11
declare -r svcdir="${svcdir:-/var/lib/init.d}"
12
svclock=${svclock:-/var/lib/init.d/locks}
12
svcmount="${svcmount:-no}"
13
svcmount="${svcmount:-no}"
13
svcfstype="${svcfstype:-tmpfs}"
14
svcfstype="${svcfstype:-tmpfs}"
14
svcsize="${svcsize:-1024}"
15
svcsize="${svcsize:-1024}"
(-)baselayout-1.12.9/sbin/rc (-1 / +22 lines)
Lines 517-522 then Link Here
517
	# Update the dependency cache
517
	# Update the dependency cache
518
	/sbin/depscan.sh
518
	/sbin/depscan.sh
519
519
520
	# Create locking directory
521
	if [[ ! -d "${svclock}" ]] ; then
522
		if ! mkdir -p -m 0755 "${svclock}" 2>/dev/null ; then
523
			eerror "Could not create needed directory '${svclock}'!"
524
		fi
525
	fi
526
	rm -rf "${svclock}"/* 2>/dev/null
527
520
	# Now that the dependency cache are up to date, make sure these
528
	# Now that the dependency cache are up to date, make sure these
521
	# are marked as started ...
529
	# are marked as started ...
522
	(
530
	(
Lines 689-699 else Link Here
689
				[[ -L ${x} ]] && COLDPLUG_SERVICES="${COLDPLUG_SERVICES} ${x##*/}"
697
				[[ -L ${x} ]] && COLDPLUG_SERVICES="${COLDPLUG_SERVICES} ${x##*/}"
690
			done
698
			done
691
			for x in ${COLDPLUG_SERVICES} ; do
699
			for x in ${COLDPLUG_SERVICES} ; do
700
				lock "${x}"
692
				if [[ ! -e /etc/runlevels/"${BOOTLEVEL}"/"${x}" \
701
				if [[ ! -e /etc/runlevels/"${BOOTLEVEL}"/"${x}" \
693
				&& ! -e /etc/runlevels/"${DEFAULTLEVEL}"/"${x}" ]] ; then
702
				&& ! -e /etc/runlevels/"${DEFAULTLEVEL}"/"${x}" ]] ; then
694
					myscripts="${myscripts} ${x}"
703
					myscripts="${myscripts} ${x}"
695
					mark_service_coldplugged "${x}"
704
					mark_service_coldplugged "${x}"
696
				fi
705
				fi
706
				unlock "${x}"
697
			done
707
			done
698
			if [[ -n ${myscripts} ]] ; then
708
			if [[ -n ${myscripts} ]] ; then
699
				einfo "Device initiated services:${HILITE}${myscripts}${NORMAL}"
709
				einfo "Device initiated services:${HILITE}${myscripts}${NORMAL}"
Lines 737-742 get_stop_services() { Link Here
737
	reverse_list $(trace_dependencies ${list})
747
	reverse_list $(trace_dependencies ${list})
738
}
748
}
739
749
750
# Callers should hold lock
740
dep_stop() {
751
dep_stop() {
741
	local dep needsme service="${1##*/}"
752
	local dep needsme service="${1##*/}"
742
753
Lines 776-782 if [[ ${SOFTLEVEL} != "single" && \ Link Here
776
      ${SOFTLEVEL} != "shutdown" ]]
787
      ${SOFTLEVEL} != "shutdown" ]]
777
then
788
then
778
	for i in $(get_stop_services) ; do
789
	for i in $(get_stop_services) ; do
790
		lock "${i}"
779
		dep_stop "${i}"
791
		dep_stop "${i}"
792
		unlock "${i}"
780
	done
793
	done
781
794
782
	# Wait for any services that may still be stopping ...
795
	# Wait for any services that may still be stopping ...
Lines 797-803 else Link Here
797
810
798
	# First stop non critical services
811
	# First stop non critical services
799
	for i in $(get_stop_services) ; do
812
	for i in $(get_stop_services) ; do
800
		is_critical_service "${i}" || dep_stop "${i}"
813
		if ! is_critical_service "${i}"; then
814
			lock "${i}"
815
			dep_stop "${i}"
816
			unlock "${i}"
817
		fi
801
	done
818
	done
802
819
803
	# Wait for any services that may still be stopping ...
820
	# Wait for any services that may still be stopping ...
Lines 806-812 else Link Here
806
	export STOP_CRITICAL="yes"
823
	export STOP_CRITICAL="yes"
807
	# Now stop the rest
824
	# Now stop the rest
808
	for i in $(get_stop_services) ; do
825
	for i in $(get_stop_services) ; do
826
		lock "${i}"
809
		dep_stop "${i}"
827
		dep_stop "${i}"
828
		unlock "${i}"
810
	done
829
	done
811
	unset STOP_CRITICAL
830
	unset STOP_CRITICAL
812
fi
831
fi
Lines 861-869 get_start_services() { Link Here
861
880
862
# Start scripts
881
# Start scripts
863
for i in $(get_start_services) ; do
882
for i in $(get_start_services) ; do
883
	lock "${i}"
864
	if service_stopped "${i}" ; then
884
	if service_stopped "${i}" ; then
865
		do_interactive start_service "${i}"
885
		do_interactive start_service "${i}"
866
	fi
886
	fi
887
	unlock "${i}"
867
done
888
done
868
889
869
# Wait for any services that may still be running ...
890
# Wait for any services that may still be running ...
(-)baselayout-1.12.9/sbin/rc-services.sh (-4 / +24 lines)
Lines 5-10 Link Here
5
RC_GOT_SERVICES="yes"
5
RC_GOT_SERVICES="yes"
6
6
7
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
7
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
8
[[ ${RC_GOT_LOCKING} != "yes" ]] && source "${svclib}/sh/rc-locking.sh"
8
9
9
if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
10
if [[ ${RC_GOT_DEPTREE_INFO} != "yes" ]] ; then
10
	# Only try and update if we are root
11
	# Only try and update if we are root
Lines 409-415 start_service() { Link Here
409
		# then just start it and return the exit status
410
		# then just start it and return the exit status
410
		(
411
		(
411
			profiling name "/etc/init.d/${service} start"
412
			profiling name "/etc/init.d/${service} start"
412
			"/etc/init.d/${service}" start
413
414
			SVCNAME="${service}"
415
			source "${svclib}/sh/runscript-shared.sh"
416
			source /etc/init.d/${service}
417
			svc_start
413
		)
418
		)
414
		
419
		
415
		service_started "${service}" || service_inactive "${service}" \
420
		service_started "${service}" || service_inactive "${service}" \
Lines 470-476 stop_service() { Link Here
470
		  ${STOP_CRITICAL} == "yes" ]] ; then
475
		  ${STOP_CRITICAL} == "yes" ]] ; then
471
		# if we can not start the services in parallel
476
		# if we can not start the services in parallel
472
		# then just start it and return the exit status
477
		# then just start it and return the exit status
473
		( "/etc/init.d/${service}" stop )
478
		(
479
			SVCNAME="${service}"
480
			if [[ -e "${svcdir}/scheduled/${SVCNAME}" ]] ; then
481
				rm -Rf "${svcdir}/scheduled/${SVCNAME}"
482
			fi
483
			source "${svclib}/sh/runscript-shared.sh"
484
			source /etc/init.d/${service}
485
			svc_stop
486
		)
474
		service_stopped "${service}"
487
		service_stopped "${service}"
475
		retval=$?
488
		retval=$?
476
		end_service "${service}" "${retval}"
489
		end_service "${service}" "${retval}"
Lines 741-755 is_net_up() { Link Here
741
			return 0
754
			return 0
742
			;;
755
			;;
743
		lo)
756
		lo)
757
			lock "net.lo"
744
			service_started "net.lo"
758
			service_started "net.lo"
745
			return $?
759
			retval="$?"
760
			unlock "net.lo"
761
			return ${retval}
746
			;;
762
			;;
747
		yes)
763
		yes)
748
			for x in $(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
764
			for x in $(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
749
				$(dolisting "/etc/runlevels/${SOFTLEVEL}/net.*") ; do
765
				$(dolisting "/etc/runlevels/${SOFTLEVEL}/net.*") ; do
750
				local y="${x##*/}"
766
				local y="${x##*/}"
751
				[[ ${y} == "$1" ]] && return 1
767
				[[ ${y} == "$1" ]] && return 1
752
				service_started "${y}" || return 1
768
				lock "${y}"
769
				service_started "${y}"
770
				retval="$?"
771
				unlock "${y}"
772
				[[ ${retval} == 0 ]] || return 1
753
			done
773
			done
754
			return 0
774
			return 0
755
			;;
775
			;;
(-)baselayout-1.12.9/sbin/rc-locking.sh (+25 lines)
Line 0 Link Here
1
# Distributed under the terms of the GNU General Public License v2
2
3
RC_GOT_LOCKING="yes"
4
5
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
6
7
lock() {
8
	[[ ! -w ${svclock} ]] && return 0
9
	local lock="${svclock}/$1"
10
11
	until mkfifo "${lock}" 2>/dev/null; do
12
		cat "${lock}" 2>/dev/null
13
	done
14
}
15
16
unlock() {
17
	[[ ! -w ${svclock} ]] && return 0
18
	local lock="${svclock}/$1"
19
	local tmp="${lock}.$$"
20
21
	mv "${lock}" "${tmp}"
22
	touch "${tmp}"
23
	rm -f "${tmp}"
24
}
25
(-)baselayout-1.12.9/bin/rc-status (+4 lines)
Lines 32-37 runleveldir=/etc/runlevels Link Here
32
# grab settings from conf.d/rc
32
# grab settings from conf.d/rc
33
source "${svclib}/sh/rc-daemon.sh"
33
source "${svclib}/sh/rc-daemon.sh"
34
34
35
[[ ${RC_GOT_LOCKING} != "yes" ]] && source "${svclib}/sh/rc-locking.sh"
36
35
################################################################################
37
################################################################################
36
#  Parse command line options                                                  #
38
#  Parse command line options                                                  #
37
################################################################################
39
################################################################################
Lines 163-169 if [[ -x ${svcdir}/started ]]; then Link Here
163
    # stopped running without our say so
165
    # stopped running without our say so
164
    if [[ ${EUID} == 0 ]]; then
166
    if [[ ${EUID} == 0 ]]; then
165
	for service in ${started}; do
167
	for service in ${started}; do
168
		lock "${service}"
166
	    update_service_status "${service}"
169
	    update_service_status "${service}"
170
		unlock "${service}"
167
	done
171
	done
168
	started=$(ls ${svcdir}/started)
172
	started=$(ls ${svcdir}/started)
169
    fi
173
    fi
(-)baselayout-1.12.9/sbin/runscript.sh (-510 / +21 lines)
Lines 20-38 else Link Here
20
	SVCNAME="$1"
20
	SVCNAME="$1"
21
fi
21
fi
22
22
23
declare -r SVCNAME="${SVCNAME##*/}"
23
SVCNAME="${SVCNAME##*/}"
24
export SVCNAME
24
export SVCNAME
25
# Support deprecated myservice variable
25
# Support deprecated myservice variable
26
myservice="${SVCNAME}"
26
myservice="${SVCNAME}"
27
27
28
svc_trap() {
29
	trap 'eerror "ERROR:  ${SVCNAME} caught an interrupt"; exit 1' \
30
		INT QUIT TSTP
31
}
32
33
# Setup a default trap
34
svc_trap
35
36
# coldplug events can trigger init scripts, but we don't want to run them
28
# coldplug events can trigger init scripts, but we don't want to run them
37
# until after rc sysinit has completed so we punt them to the boot runlevel
29
# until after rc sysinit has completed so we punt them to the boot runlevel
38
if [[ -e /dev/.rcsysinit ]] ; then
30
if [[ -e /dev/.rcsysinit ]] ; then
Lines 69-119 if [[ ${IN_HOTPLUG} == "1" ]] ; then Link Here
69
	set +f
61
	set +f
70
fi
62
fi
71
63
72
# State variables
64
source "${svclib}/sh/runscript-shared.sh"
73
svcpause="no"
74
75
# Functions to handle dependencies and services
76
[[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
77
# Functions to control daemons
78
[[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh"
79
80
# Source configuration files.
81
# (1) Source /etc/conf.d/net if it is a net.* service
82
# (2) Source /etc/conf.d/${SVCNAME} to get initscript-specific
83
#     configuration (if it exists).
84
# (3) Source /etc/rc.conf to pick up potentially overriding
85
#     configuration, if the system administrator chose to put it
86
#     there (if it exists).
87
if net_service "${SVCNAME}" ; then
88
	conf="$(add_suffix /etc/conf.d/net)"
89
	[[ -e ${conf} ]] && source "${conf}"
90
fi
91
conf="$(add_suffix "/etc/conf.d/${SVCNAME}")"
92
[[ -e ${conf} ]] && source "${conf}"
93
conf="$(add_suffix /etc/rc.conf)"
94
[[ -e ${conf} ]] && source "${conf}"
95
96
mylevel="${SOFTLEVEL}"
97
[[ ${SOFTLEVEL} == "${BOOTLEVEL}" \
98
	|| ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] \
99
	&& mylevel="${DEFAULTLEVEL}"
100
101
# Call svc_quit if we abort AND we have obtained a lock
102
service_started "${SVCNAME}"
103
svcstarted="$?"
104
service_inactive "${SVCNAME}"
105
svcinactive="$?"
106
svc_quit() {
107
	eerror "ERROR:  ${SVCNAME} caught an interrupt"
108
	if service_inactive "${SVCNAME}" || [[ ${svcinactive} == "0" ]] ; then
109
		mark_service_inactive "${SVCNAME}"
110
	elif [[ ${svcstarted} == "0" ]] ; then
111
		mark_service_started "${SVCNAME}"
112
	else
113
		mark_service_stopped "${SVCNAME}"
114
	fi
115
	exit 1
116
}
117
65
118
usage() {
66
usage() {
119
	local IFS="|"
67
	local IFS="|"
Lines 123-583 usage() { Link Here
123
	eerror "       ${SVCNAME} without arguments for full help"
71
	eerror "       ${SVCNAME} without arguments for full help"
124
}
72
}
125
73
126
stop() {
127
	# Return success so the symlink gets removed
128
	return 0
129
}
130
131
start() {
132
	eerror "ERROR:  ${SVCNAME} does not have a start function."
133
	# Return failure so the symlink doesn't get created
134
	return 1
135
}
136
137
restart() {
138
	if ! service_stopped "${SVCNAME}" ; then
139
		svc_stop || return "$?"
140
	fi
141
	svc_start
142
}
143
144
status() {
145
	# Dummy function
146
	return 0
147
}
148
149
svc_schedule_start() {
150
	local service="$1" start="$2"
151
	[[ ! -d "${svcdir}/scheduled/${service}" ]] \
152
		&& mkdir -p "${svcdir}/scheduled/${service}"
153
	ln -snf "/etc/init.d/${service}" \
154
		"${svcdir}/scheduled/${service}/${start}"
155
}
156
157
svc_start_scheduled() {
158
	[[ ! -d "${svcdir}/scheduled/${SVCNAME}" ]] && return
159
	local x= services=
160
161
	# If we're being started in the background, then don't
162
	# tie up the daemon that called us starting our scheduled services
163
	if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then
164
		unset IN_BACKGROUND
165
		svc_start_scheduled &
166
		export IN_BACKGROUND=true
167
		return
168
	fi
169
170
	for x in $(dolisting "${svcdir}/scheduled/${SVCNAME}/") ; do
171
		services="${services} ${x##*/}"
172
	done
173
		
174
	for x in $(trace_dependencies ${services}) ; do
175
		service_stopped "${x}" && start_service "${x}"
176
		rm -f "${svcdir}/scheduled/${SVCNAME}/${x}"
177
	done
178
179
	rmdir "${svcdir}/scheduled/${SVCNAME}"
180
}
181
182
svc_stop() {
183
	local x= mydep= mydeps= retval=0
184
	local -a servicelist=()
185
186
	# Do not try to stop if it had already failed to do so
187
	if is_runlevel_stop && service_failed "${SVCNAME}" ; then
188
		return 1
189
	elif service_stopped "${SVCNAME}" ; then
190
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
191
			ewarn "WARNING:  ${SVCNAME} has not yet been started."
192
		fi
193
		return 0
194
	fi
195
	if ! mark_service_stopping "${SVCNAME}" ; then
196
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
197
			eerror "ERROR:  ${SVCNAME} is already stopping."
198
		fi
199
		return 1
200
	fi
201
	
202
	# Ensure that we clean up if we abort for any reason
203
	trap "svc_quit" INT QUIT TSTP
204
205
	mark_service_starting "${SVCNAME}"
206
	service_message "Service ${SVCNAME} stopping"
207
208
	if in_runlevel "${SVCNAME}" "${BOOTLEVEL}" && \
209
	   [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" && \
210
	      ${SOFTLEVEL} != "single" ]] ; then
211
		ewarn "WARNING:  you are stopping a boot service."
212
	fi
213
214
	if [[ ${svcpause} != "yes" && ${RC_NO_DEPS} != "yes" ]] \
215
		&& ! service_wasinactive "${SVCNAME}" ; then
216
		if net_service "${SVCNAME}" ; then 
217
			if is_runlevel_stop || ! is_net_up "${SVCNAME}" ; then
218
				mydeps="net"
219
			fi
220
		fi
221
		mydeps="${mydeps} ${SVCNAME}"
222
	fi
223
224
	# Save the IN_BACKGROUND var as we need to clear it for stopping depends
225
	local ib_save="${IN_BACKGROUND}"
226
	unset IN_BACKGROUND
227
228
	for mydep in ${mydeps} ; do
229
		for x in $(needsme "${mydep}") ; do
230
			if service_started "${x}" || service_inactive "${x}" ; then
231
				stop_service "${x}"
232
			fi
233
			service_list=( "${service_list[@]}" "${x}" )
234
		done
235
	done
236
237
	for x in "${service_list[@]}" ; do
238
		service_stopped "${x}" && continue
239
		wait_service "${x}"
240
		if ! service_stopped "${x}" ; then
241
			eerror "ERROR:  cannot stop ${SVCNAME} as ${x} is still up."
242
			retval=1
243
			break
244
		fi
245
	done
246
247
	IN_BACKGROUND="${ib_save}"
248
249
	if [[ ${retval} == "0" ]] ; then
250
		# Now that deps are stopped, stop our service
251
		( 
252
		exit() {
253
			RC_QUIET_STDOUT="no"
254
			eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
255
			eerror "This IS a bug, please fix your broken init.d"
256
			unset -f exit
257
			exit "$@"
258
		}
259
		# Stop einfo/ebegin/eend from working as parallel messes us up
260
		if [[ ${RC_PARALLEL_STARTUP} == "yes" ]] ; then
261
			[[ ${RC_VERBOSE} != "yes" \
262
			|| -e ${svcdir}/exclusive/${SVCNAME} ]] \
263
				&& RC_QUIET_STDOUT="yes"
264
		fi
265
		stop
266
		)
267
		retval="$?"
268
269
		# If a service has been marked inactive, exit now as something
270
		# may attempt to start it again later
271
		if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
272
			svcinactive=0
273
			return 0
274
		fi
275
	fi
276
277
	if [[ ${retval} != 0 ]] ; then
278
		# Did we fail to stop? create symlink to stop multible attempts at
279
		# runlevel change.  Note this is only used at runlevel change ...
280
		is_runlevel_stop && mark_service_failed "${SVCNAME}"
281
		
282
		# If we are halting the system, do it as cleanly as possible
283
		if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
284
			mark_service_stopped "${SVCNAME}"
285
		else
286
			if [[ ${svcinactive} == "0" ]] ; then
287
				mark_service_inactive "${SVCNAME}"
288
			else
289
				mark_service_started "${SVCNAME}"
290
			fi
291
		fi
292
293
		service_message "eerror" "ERROR:  ${SVCNAME} failed to stop"
294
	else
295
		svcstarted=1
296
		if service_inactive "${SVCNAME}" ; then
297
			svcinactive=0
298
		else
299
			mark_service_stopped "${SVCNAME}"
300
		fi
301
		service_message "Service ${SVCNAME} stopped"
302
	fi
303
304
	# Reset the trap
305
	svc_trap
306
	
307
	return "${retval}"
308
}
309
310
svc_start() {
311
	local x= y= retval=0 startinactive=
312
313
	# Do not try to start if i have done so already on runlevel change
314
	if is_runlevel_start && service_failed "${SVCNAME}" ; then
315
		return 1
316
	elif service_started "${SVCNAME}" ; then
317
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
318
			ewarn "WARNING:  ${SVCNAME} has already been started."
319
		fi
320
		return 0
321
	elif service_inactive "${SVCNAME}" ; then
322
		if [[ ${IN_BACKGROUND} != "true" ]] ; then
323
			if [[ ${IN_HOTPLUG} != "1" ]] ; then
324
				ewarn "WARNING:  ${SVCNAME} has already been started."
325
			fi
326
			return 0
327
		fi
328
	fi
329
330
	if ! mark_service_starting "${SVCNAME}" ; then
331
		if service_stopping "${SVCNAME}" ; then
332
			eerror "ERROR:  ${SVCNAME} is already stopping."
333
		else
334
			eerror "ERROR:  ${SVCNAME} is already starting."
335
		fi
336
		return 1
337
	fi
338
339
	# Ensure that we clean up if we abort for any reason
340
	trap "svc_quit" INT QUIT TSTP
341
342
	service_message "Service ${SVCNAME} starting"
343
344
	if broken "${SVCNAME}" ; then
345
		eerror "ERROR:  Some services needed are missing.  Run"
346
		eerror "        './${SVCNAME} broken' for a list of those"
347
		eerror "        services.  ${SVCNAME} was not started."
348
		retval=1	
349
	fi
350
351
	# Save the IN_BACKGROUND var as we need to clear it for starting depends
352
	local ib_save="${IN_BACKGROUND}"
353
	unset IN_BACKGROUND
354
355
	if [[ ${retval} == "0" && ${RC_NO_DEPS} != "yes" ]] ; then
356
		local startupservices="$(ineed "${SVCNAME}") $(valid_iuse "${SVCNAME}")"
357
		local netservices=
358
		for x in $(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
359
			$(dolisting "/etc/runlevels/${mylevel}/net.*") \
360
			$(dolisting "/var/lib/init.d/coldplugged/net.*") ; do 
361
			netservices="${netservices} ${x##*/}"
362
		done
363
364
		# Start dependencies, if any.
365
		if ! is_runlevel_start ; then
366
			for x in ${startupservices} ; do
367
				if [[ ${x} == "net" ]] && ! net_service "${SVCNAME}" \
368
					&& ! is_net_up ; then
369
					for y in ${netservices} ; do
370
						service_stopped "${y}" && start_service "${y}"
371
					done
372
				elif [[ ${x} != "net" ]] ; then
373
					service_stopped "${x}" && start_service "${x}"
374
				fi
375
			done
376
		fi
377
378
		# We also wait for any services we're after to finish incase they
379
		# have a "before" dep but we don't dep on them.
380
		if is_runlevel_start ; then
381
			startupservices="${startupservices} $(valid_iafter "${SVCNAME}")"
382
			if net_service "${SVCNAME}" ; then
383
				startupservices="${startupservices} $(valid_iafter "net")"
384
			fi
385
		fi
386
387
		if [[ " ${startupservices} " == *" net "* ]] ; then
388
			startupservices=" ${startupservices} "
389
			startupservices="${startupservices/ net / ${netservices} }"
390
			startupservices="${startupservices// net /}"
391
		fi
392
393
		# Wait for dependencies to finish.
394
		for x in ${startupservices} ; do
395
			service_started "${x}" && continue
396
			wait_service "${x}"
397
			if ! service_started "${x}" ; then
398
				# A 'need' dependency is critical for startup
399
				if ineed -t "${SVCNAME}" "${x}" >/dev/null \
400
					|| ( net_service "${x}" && ineed -t "${SVCNAME}" net \
401
					&& ! is_net_up ) ; then
402
					if service_inactive "${x}" || service_wasinactive "${x}" || \
403
						[[ -n $(dolisting "${svcdir}"/scheduled/*/"${x}") ]] ; then
404
						svc_schedule_start "${x}" "${SVCNAME}"
405
						[[ -n ${startinactive} ]] && startinactive="${startinactive}, "
406
						startinactive="${startinactive}${x}"
407
					else
408
						eerror "ERROR:  cannot start ${SVCNAME} as ${x} could not start"
409
						retval=1
410
						break
411
					fi
412
				fi
413
			fi
414
		done
415
416
		if [[ -n ${startinactive} && ${retval} == "0" ]] ; then
417
			# Change the last , to or for correct grammar.
418
			x="${startinactive##*, }"
419
			startinactive="${startinactive/%, ${x}/ or ${x}}"
420
			ewarn "WARNING:  ${SVCNAME} is scheduled to start when ${startinactive} has started."
421
			retval=1
422
		fi
423
	fi
424
		
425
	if [[ ${retval} == "0" ]] ; then
426
		IN_BACKGROUND="${ib_save}"
427
		(
428
		exit() {
429
			RC_QUIET_STDOUT="no"
430
			eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
431
			eerror "This IS a bug, please fix your broken init.d"
432
			unset -f exit
433
			exit "$@"
434
		}
435
436
		# Apply any ulimits if defined
437
		[[ -n ${RC_ULIMIT} ]] && ulimit ${RC_ULIMIT}
438
	
439
		# Stop einfo/ebegin/eend from working as parallel messes us up
440
		if [[ ${RC_PARALLEL_STARTUP} == "yes" ]] ; then
441
			[[ ${RC_VERBOSE} != "yes" \
442
			|| -e ${svcdir}/exclusive/${SVCNAME} ]] \
443
				&& RC_QUIET_STDOUT="yes"
444
		fi
445
446
		start
447
		)
448
		retval="$?"
449
450
		# If a service has been marked inactive, exit now as something
451
		# may attempt to start it again later
452
		if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
453
			svcinactive=0
454
			service_message "ewarn" "WARNING:  ${SVCNAME} has started but is inactive"
455
			return 1
456
		fi
457
	fi
458
459
	if [[ ${retval} != "0" ]] ; then
460
		if [[ ${svcinactive} == "0" ]] ; then
461
			mark_service_inactive "${SVCNAME}"
462
		else
463
			mark_service_stopped "${SVCNAME}"
464
		fi
465
466
		if [[ -z ${startinactive} ]] ; then
467
			is_runlevel_start && mark_service_failed "${SVCNAME}"
468
			service_message "eerror" "ERROR:  ${SVCNAME} failed to start"
469
		fi
470
	else
471
		svcstarted=0
472
		mark_service_started "${SVCNAME}"
473
		service_message "Service ${SVCNAME} started"
474
	fi
475
476
	# Reset the trap
477
	svc_trap
478
	
479
	return "${retval}"
480
}
481
482
svc_restart() {
483
	# We don't kill child processes if we're restarting
484
	# This is especically important for sshd ....
485
	RC_KILL_CHILDREN="no"				
486
487
	# Create a snapshot of started services
488
	rm -rf "${svcdir}/snapshot/$$"
489
	mkdir -p "${svcdir}/snapshot/$$"
490
	cp -pPR "${svcdir}"/started/* "${svcdir}"/inactive/* \
491
	"${svcdir}/snapshot/$$/" 2>/dev/null
492
	rm -f "${svcdir}/snapshot/$$/${SVCNAME}"
493
494
	# Simple way to try and detect if the service use svc_{start,stop}
495
	# to restart if it have a custom restart() funtion.
496
	if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${SVCNAME}") ]] ; then
497
		if [[ -z $(egrep 'svc_stop' "/etc/init.d/${SVCNAME}") || \
498
			-z $(egrep 'svc_start' "/etc/init.d/${SVCNAME}") ]] ; then
499
			echo
500
			ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
501
			ewarn "restart the service in its custom 'restart()' function."
502
			ewarn "Run ${SVCNAME} without arguments for more info."
503
			echo
504
			if ! service_stopped "${SVCNAME}" ; then
505
				svc_stop || return "$?"
506
			fi
507
			svc_start
508
		else
509
			restart
510
		fi
511
	else
512
		restart
513
	fi
514
	retval="$?"
515
516
	[[ -e "${svcdir}/scheduled/${SVCNAME}" ]] \
517
		&& rm -Rf "${svcdir}/scheduled/${SVCNAME}"
518
519
	# Restart dependencies as well
520
	for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
521
		x="${x##*/}"
522
		if [[ -x /etc/init.d/"${x}" ]] && service_stopped "${x}" ; then
523
			if service_inactive "${SVCNAME}" \
524
			|| service_wasinactive "${SVCNAME}" ; then
525
				svc_schedule_start "${SVCNAME}" "${x}"
526
				ewarn "WARNING:  ${x} is scheduled to start when ${SVCNAME} has started."
527
			elif service_started "${SVCNAME}" ; then
528
				start_service "${x}"
529
			fi
530
		fi
531
	done
532
	rm -rf "${svcdir}/snapshot/$$"
533
534
	service_started "${SVCNAME}" && svc_start_scheduled
535
536
	# Wait for services to come up
537
	if [[ ${IN_BACKGROUND} != "true" \
538
		&& ${IN_BACKGROUND} != "1" ]] ; then
539
		[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
540
	fi
541
542
	return ${retval}
543
}
544
545
svc_status() {
546
	# The basic idea here is to have some sort of consistent
547
	# output in the status() function which scripts can use
548
	# as an generic means to detect status.  Any other output
549
	# should thus be formatted in the custom status() function
550
	# to work with the printed " * status:  foo".
551
	local efunc="" state=""
552
553
	# If we are effectively root, check to see if required daemons are running
554
	# and update our status accordingly
555
	[[ ${EUID} == 0 ]] && update_service_status "${SVCNAME}"
556
557
	if service_stopping "${SVCNAME}" ; then
558
		efunc="eerror"
559
		state="stopping"
560
	elif service_starting "${SVCNAME}" ; then
561
		efunc="einfo"
562
		state="starting"
563
	elif service_inactive "${SVCNAME}" ; then
564
		efunc="ewarn"
565
		state="inactive"
566
	elif service_started "${SVCNAME}" ; then
567
		efunc="einfo"
568
		state="started"
569
	else
570
		efunc="eerror"
571
		state="stopped"
572
	fi
573
	[[ ${RC_QUIET_STDOUT} != "yes" ]] \
574
		&& ${efunc} "status:  ${state}"
575
576
	status
577
	# Return 0 if started, otherwise 1
578
	[[ ${state} == "started" ]]
579
}
580
581
rcscript_errors="$(bash -n "${myscript}" 2>&1)" || {
74
rcscript_errors="$(bash -n "${myscript}" 2>&1)" || {
582
	[[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
75
	[[ -n ${rcscript_errors} ]] && echo "${rcscript_errors}" >&2
583
	eerror "ERROR:  ${myscript} has syntax errors in it; aborting ..."
76
	eerror "ERROR:  ${myscript} has syntax errors in it; aborting ..."
Lines 649-654 retval=0 Link Here
649
for arg in "$@" ; do
142
for arg in "$@" ; do
650
	case "${arg}" in
143
	case "${arg}" in
651
	stop)
144
	stop)
145
		lock "${SVCNAME}"
652
		if [[ -e "${svcdir}/scheduled/${SVCNAME}" ]] ; then
146
		if [[ -e "${svcdir}/scheduled/${SVCNAME}" ]] ; then
653
			rm -Rf "${svcdir}/scheduled/${SVCNAME}"
147
			rm -Rf "${svcdir}/scheduled/${SVCNAME}"
654
		fi
148
		fi
Lines 669-714 for arg in "$@" ; do Link Here
669
		if [[ ${IN_BACKGROUND} == "true" ]] ; then
163
		if [[ ${IN_BACKGROUND} == "true" ]] ; then
670
			for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
164
			for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
671
				x="${x##*/}"
165
				x="${x##*/}"
166
				lock "${x}"
672
				if [[ -x /etc/init.d/"${x}" ]] && service_stopped "${x}" ; then
167
				if [[ -x /etc/init.d/"${x}" ]] && service_stopped "${x}" ; then
673
					svc_schedule_start "${SVCNAME}" "${x}"
168
					svc_schedule_start "${SVCNAME}" "${x}"
674
				fi
169
				fi
170
				unlock "${x}"
675
			done
171
			done
676
			rm -rf "${svcdir}/snapshot/$$"
172
			rm -rf "${svcdir}/snapshot/$$"
677
		else
173
		else
678
			rm -f "${svcdir}"/scheduled/*/"${SVCNAME}"
174
			rm -f "${svcdir}"/scheduled/*/"${SVCNAME}"
679
		fi
175
		fi
680
176
177
		unlock "${SVCNAME}"
681
		;;
178
		;;
682
	start)
179
	start)
180
		lock "${SVCNAME}"
683
		svc_start
181
		svc_start
684
		retval="$?"
182
		retval="$?"
685
		service_started "${SVCNAME}" && svc_start_scheduled
183
		service_started "${SVCNAME}"
184
		started="$?"
185
		unlock "${SVCNAME}"
186
		[[ ${started} == 0 ]] && svc_start_scheduled
686
		;;
187
		;;
687
	needsme|ineed|usesme|iuse|broken)
188
	needsme|ineed|usesme|iuse|broken)
688
		trace_dependencies "-${arg}"
189
		trace_dependencies "-${arg}"
689
		;;
190
		;;
690
	status)
191
	status)
192
		lock "${SVCNAME}"
691
		svc_status
193
		svc_status
692
		retval="$?"
194
		retval="$?"
195
		unlock "${SVCNAME}"
693
		;;
196
		;;
694
	zap)
197
	zap)
695
		einfo "Manually resetting ${SVCNAME} to stopped state."
198
		einfo "Manually resetting ${SVCNAME} to stopped state."
199
		lock "${SVCNAME}"
696
		mark_service_stopped "${SVCNAME}"
200
		mark_service_stopped "${SVCNAME}"
201
		unlock "${SVCNAME}"
697
		;;
202
		;;
698
	restart)
203
	restart)
204
		lock "${SVCNAME}"
699
		svc_restart
205
		svc_restart
700
		retval="$?"
206
		retval="$?"
207
		unlock "${SVCNAME}"
701
		;;
208
		;;
702
	condrestart|conditionalrestart)
209
	condrestart|conditionalrestart)
210
		lock "${SVCNAME}"
703
		if service_started "${SVCNAME}" ; then
211
		if service_started "${SVCNAME}" ; then
704
			svc_restart
212
			svc_restart
705
		fi
213
		fi
706
		retval="$?"
214
		retval="$?"
215
		unlock "${SVCNAME}"
707
		;;
216
		;;
708
	pause)
217
	pause)
709
		svcpause="yes"
218
		svcpause="yes"
219
		lock "${SVCNAME}"
710
		svc_stop
220
		svc_stop
711
		retval="$?"
221
		retval="$?"
222
		unlock "${SVCNAME}"
712
		svcpause="no"
223
		svcpause="no"
713
		;;
224
		;;
714
	--quiet|--nocolor|--nodeps|--verbose|--debug)
225
	--quiet|--nocolor|--nodeps|--verbose|--debug)
(-)baselayout-1.12.9/sbin/runscript-shared.sh (+534 lines)
Line 0 Link Here
1
[[ ${RC_GOT_FUNCTIONS} != "yes" ]] && source /sbin/functions.sh
2
3
# State variables
4
svcpause="no"
5
6
# Functions to handle dependencies and services
7
[[ ${RC_GOT_SERVICES} != "yes" ]] && source "${svclib}/sh/rc-services.sh"
8
# Functions to control daemons
9
[[ ${RC_GOT_DAEMON} != "yes" ]] && source "${svclib}/sh/rc-daemon.sh"
10
11
# Source configuration files.
12
# (1) Source /etc/conf.d/net if it is a net.* service
13
# (2) Source /etc/conf.d/${SVCNAME} to get initscript-specific
14
#     configuration (if it exists).
15
# (3) Source /etc/rc.conf to pick up potentially overriding
16
#     configuration, if the system administrator chose to put it
17
#     there (if it exists).
18
if net_service "${SVCNAME}" ; then
19
	conf="$(add_suffix /etc/conf.d/net)"
20
	[[ -e ${conf} ]] && source "${conf}"
21
fi
22
conf="$(add_suffix "/etc/conf.d/${SVCNAME}")"
23
[[ -e ${conf} ]] && source "${conf}"
24
conf="$(add_suffix /etc/rc.conf)"
25
[[ -e ${conf} ]] && source "${conf}"
26
27
mylevel="${SOFTLEVEL}"
28
[[ ${SOFTLEVEL} == "${BOOTLEVEL}" \
29
	|| ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] \
30
	&& mylevel="${DEFAULTLEVEL}"
31
32
# Call svc_quit if we abort AND we have obtained a lock
33
#lock "${SVCNAME}"
34
#service_started "${SVCNAME}"
35
#svcstarted="$?"
36
#service_inactive "${SVCNAME}"
37
#svcinactive="$?"
38
#unlock "${SVCNAME}"
39
40
svc_trap() {
41
	trap 'eerror "ERROR:  ${SVCNAME} caught an interrupt"; exit 1' \
42
		INT QUIT TSTP
43
}
44
45
# Setup a default trap
46
svc_trap
47
48
svc_quit() {
49
	eerror "ERROR:  ${SVCNAME} caught an interrupt"
50
	if service_inactive "${SVCNAME}" || [[ ${svcinactive} == "0" ]] ; then
51
		mark_service_inactive "${SVCNAME}"
52
	elif [[ ${svcstarted} == "0" ]] ; then
53
		mark_service_started "${SVCNAME}"
54
	else
55
		mark_service_stopped "${SVCNAME}"
56
	fi
57
	exit 1
58
}
59
60
stop() {
61
	# Return success so the symlink gets removed
62
	return 0
63
}
64
65
start() {
66
	eerror "ERROR:  ${SVCNAME} does not have a start function."
67
	# Return failure so the symlink doesn't get created
68
	return 1
69
}
70
71
restart() {
72
	if ! service_stopped "${SVCNAME}" ; then
73
		svc_stop || return "$?"
74
	fi
75
	svc_start
76
}
77
78
status() {
79
	# Dummy function
80
	return 0
81
}
82
83
svc_schedule_start() {
84
	local service="$1" start="$2"
85
86
	[[ ! -d "${svcdir}/scheduled/${service}" ]] \
87
		&& mkdir -p "${svcdir}/scheduled/${service}"
88
	ln -snf "/etc/init.d/${service}" \
89
		"${svcdir}/scheduled/${service}/${start}"
90
}
91
92
svc_start_scheduled() {
93
	[[ ! -d "${svcdir}/scheduled/${SVCNAME}" ]] && return
94
	local x= services=
95
96
	# If we're being started in the background, then don't
97
	# tie up the daemon that called us starting our scheduled services
98
	if [[ ${IN_BACKGROUND} == "true" || ${IN_BACKGROUND} == "1" ]] ; then
99
		unset IN_BACKGROUND
100
		svc_start_scheduled &
101
		export IN_BACKGROUND=true
102
		return
103
	fi
104
105
	lock "${SVCNAME}"
106
	for x in $(dolisting "${svcdir}/scheduled/${SVCNAME}/") ; do
107
		services="${services} ${x##*/}"
108
	done
109
	unlock "${SVCNAME}"
110
111
	for x in $(trace_dependencies ${services}) ; do
112
		lock "${x}"
113
		service_stopped "${x}" && start_service "${x}"
114
		unlock "${x}"
115
		rm -f "${svcdir}/scheduled/${SVCNAME}/${x}"
116
	done
117
118
	rmdir "${svcdir}/scheduled/${SVCNAME}"
119
}
120
121
svc_stop() {
122
	local x= mydep= mydeps= retval=0
123
	local -a servicelist=()
124
125
	# Do not try to stop if it had already failed to do so
126
	if is_runlevel_stop && service_failed "${SVCNAME}" ; then
127
		return 1
128
	elif service_stopped "${SVCNAME}" ; then
129
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
130
			ewarn "WARNING:  ${SVCNAME} has not yet been started."
131
		fi
132
		return 0
133
	fi
134
	if ! mark_service_stopping "${SVCNAME}" ; then
135
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
136
			eerror "ERROR:  ${SVCNAME} is already stopping."
137
		fi
138
		return 1
139
	fi
140
141
	# Ensure that we clean up if we abort for any reason
142
	trap "svc_quit" INT QUIT TSTP
143
144
	mark_service_starting "${SVCNAME}"
145
	service_message "Service ${SVCNAME} stopping"
146
147
	if in_runlevel "${SVCNAME}" "${BOOTLEVEL}" && \
148
	   [[ ${SOFTLEVEL} != "reboot" && ${SOFTLEVEL} != "shutdown" && \
149
	      ${SOFTLEVEL} != "single" ]] ; then
150
		ewarn "WARNING:  you are stopping a boot service."
151
	fi
152
153
	if [[ ${svcpause} != "yes" && ${RC_NO_DEPS} != "yes" ]] \
154
		&& ! service_wasinactive "${SVCNAME}" ; then
155
		if net_service "${SVCNAME}" ; then
156
			if is_runlevel_stop || ! is_net_up "${SVCNAME}" ; then
157
				mydeps="net"
158
			fi
159
		fi
160
		mydeps="${mydeps} ${SVCNAME}"
161
	fi
162
163
	# Save the IN_BACKGROUND var as we need to clear it for stopping depends
164
	local ib_save="${IN_BACKGROUND}"
165
	unset IN_BACKGROUND
166
167
	for mydep in ${mydeps} ; do
168
		for x in $(needsme "${mydep}") ; do
169
			if service_started "${x}" || service_inactive "${x}" ; then
170
				stop_service "${x}"
171
			fi
172
			service_list=( "${service_list[@]}" "${x}" )
173
		done
174
	done
175
176
	for x in "${service_list[@]}" ; do
177
		service_stopped "${x}" && continue
178
		wait_service "${x}"
179
		if ! service_stopped "${x}" ; then
180
			eerror "ERROR:  cannot stop ${SVCNAME} as ${x} is still up."
181
			retval=1
182
			break
183
		fi
184
	done
185
186
	IN_BACKGROUND="${ib_save}"
187
188
	if [[ ${retval} == "0" ]] ; then
189
		# Now that deps are stopped, stop our service
190
		(
191
		exit() {
192
			RC_QUIET_STDOUT="no"
193
			eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
194
			eerror "This IS a bug, please fix your broken init.d"
195
			unset -f exit
196
			exit "$@"
197
		}
198
		# Stop einfo/ebegin/eend from working as parallel messes us up
199
		if [[ ${RC_PARALLEL_STARTUP} == "yes" ]] ; then
200
			[[ ${RC_VERBOSE} != "yes" \
201
			|| -e ${svcdir}/exclusive/${SVCNAME} ]] \
202
				&& RC_QUIET_STDOUT="yes"
203
		fi
204
		stop
205
		)
206
		retval="$?"
207
208
		# If a service has been marked inactive, exit now as something
209
		# may attempt to start it again later
210
		if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
211
			svcinactive=0
212
			return 0
213
		fi
214
	fi
215
216
	if [[ ${retval} != 0 ]] ; then
217
		# Did we fail to stop? create symlink to stop multible attempts at
218
		# runlevel change.  Note this is only used at runlevel change ...
219
		is_runlevel_stop && mark_service_failed "${SVCNAME}"
220
221
		# If we are halting the system, do it as cleanly as possible
222
		if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
223
			mark_service_stopped "${SVCNAME}"
224
		else
225
			if [[ ${svcinactive} == "0" ]] ; then
226
				mark_service_inactive "${SVCNAME}"
227
			else
228
				mark_service_started "${SVCNAME}"
229
			fi
230
		fi
231
232
		service_message "eerror" "ERROR:  ${SVCNAME} failed to stop"
233
	else
234
		svcstarted=1
235
		if service_inactive "${SVCNAME}" ; then
236
			svcinactive=0
237
		else
238
			mark_service_stopped "${SVCNAME}"
239
		fi
240
		service_message "Service ${SVCNAME} stopped"
241
	fi
242
243
	# Reset the trap
244
	svc_trap
245
246
	return "${retval}"
247
}
248
249
svc_start() {
250
	local x= y= retval=0 startinactive=
251
252
	# Do not try to start if i have done so already on runlevel change
253
	if is_runlevel_start && service_failed "${SVCNAME}" ; then
254
		return 1
255
	elif service_started "${SVCNAME}" ; then
256
		if [[ ${IN_HOTPLUG} != "1" ]] ; then
257
			ewarn "WARNING:  ${SVCNAME} has already been started."
258
		fi
259
		return 0
260
	elif service_inactive "${SVCNAME}" ; then
261
		if [[ ${IN_BACKGROUND} != "true" ]] ; then
262
			if [[ ${IN_HOTPLUG} != "1" ]] ; then
263
				ewarn "WARNING:  ${SVCNAME} has already been started."
264
			fi
265
			return 0
266
		fi
267
	fi
268
269
	if ! mark_service_starting "${SVCNAME}" ; then
270
		if service_stopping "${SVCNAME}" ; then
271
			eerror "ERROR:  ${SVCNAME} is already stopping."
272
		else
273
			eerror "ERROR:  ${SVCNAME} is already starting."
274
		fi
275
		return 1
276
	fi
277
278
	# Ensure that we clean up if we abort for any reason
279
	trap "svc_quit" INT QUIT TSTP
280
281
	service_message "Service ${SVCNAME} starting"
282
283
	if broken "${SVCNAME}" ; then
284
		eerror "ERROR:  Some services needed are missing.  Run"
285
		eerror "        './${SVCNAME} broken' for a list of those"
286
		eerror "        services.  ${SVCNAME} was not started."
287
		retval=1
288
	fi
289
290
	# Save the IN_BACKGROUND var as we need to clear it for starting depends
291
	local ib_save="${IN_BACKGROUND}"
292
	unset IN_BACKGROUND
293
294
	if [[ ${retval} == "0" && ${RC_NO_DEPS} != "yes" ]] ; then
295
		local startupservices="$(ineed "${SVCNAME}") $(valid_iuse "${SVCNAME}")"
296
		local netservices=
297
		for x in $(dolisting "/etc/runlevels/${BOOTLEVEL}/net.*") \
298
			$(dolisting "/etc/runlevels/${mylevel}/net.*") \
299
			$(dolisting "/var/lib/init.d/coldplugged/net.*") ; do
300
			netservices="${netservices} ${x##*/}"
301
		done
302
303
		# Start dependencies, if any.
304
		if ! is_runlevel_start ; then
305
			for x in ${startupservices} ; do
306
				if [[ ${x} == "net" ]] && ! net_service "${SVCNAME}" \
307
					&& ! is_net_up ; then
308
					for y in ${netservices} ; do
309
						service_stopped "${y}" && start_service "${y}"
310
					done
311
				elif [[ ${x} != "net" ]] ; then
312
					service_stopped "${x}" && start_service "${x}"
313
				fi
314
			done
315
		fi
316
317
		# We also wait for any services we're after to finish incase they
318
		# have a "before" dep but we don't dep on them.
319
		if is_runlevel_start ; then
320
			startupservices="${startupservices} $(valid_iafter "${SVCNAME}")"
321
			if net_service "${SVCNAME}" ; then
322
				startupservices="${startupservices} $(valid_iafter "net")"
323
			fi
324
		fi
325
326
		if [[ " ${startupservices} " == *" net "* ]] ; then
327
			startupservices=" ${startupservices} "
328
			startupservices="${startupservices/ net / ${netservices} }"
329
			startupservices="${startupservices// net /}"
330
		fi
331
332
		# Wait for dependencies to finish.
333
		for x in ${startupservices} ; do
334
			lock "${x}"
335
			if service_started "${x}"; then
336
				unlock "${x}"
337
				continue
338
			fi
339
			wait_service "${x}"
340
			if ! service_started "${x}" ; then
341
				# A 'need' dependency is critical for startup
342
				if ineed -t "${SVCNAME}" "${x}" >/dev/null \
343
					|| ( net_service "${x}" && ineed -t "${SVCNAME}" net \
344
					&& ! is_net_up ) ; then
345
					if service_inactive "${x}" || service_wasinactive "${x}" || \
346
						[[ -n $(dolisting "${svcdir}"/scheduled/*/"${x}") ]] ; then
347
						svc_schedule_start "${x}" "${SVCNAME}"
348
						[[ -n ${startinactive} ]] && startinactive="${startinactive}, "
349
						startinactive="${startinactive}${x}"
350
					else
351
						eerror "ERROR:  cannot start ${SVCNAME} as ${x} could not start"
352
						retval=1
353
						unlock "${x}"
354
						break
355
					fi
356
				fi
357
			fi
358
			unlock "${x}"
359
		done
360
361
		if [[ -n ${startinactive} && ${retval} == "0" ]] ; then
362
			# Change the last , to or for correct grammar.
363
			x="${startinactive##*, }"
364
			startinactive="${startinactive/%, ${x}/ or ${x}}"
365
			ewarn "WARNING:  ${SVCNAME} is scheduled to start when ${startinactive} has started."
366
			retval=1
367
		fi
368
	fi
369
370
	if [[ ${retval} == "0" ]] ; then
371
		IN_BACKGROUND="${ib_save}"
372
		(
373
		exit() {
374
			RC_QUIET_STDOUT="no"
375
			eerror "DO NOT USE EXIT IN INIT.D SCRIPTS"
376
			eerror "This IS a bug, please fix your broken init.d"
377
			unset -f exit
378
			exit "$@"
379
		}
380
381
		# Apply any ulimits if defined
382
		[[ -n ${RC_ULIMIT} ]] && ulimit ${RC_ULIMIT}
383
384
		# Stop einfo/ebegin/eend from working as parallel messes us up
385
		if [[ ${RC_PARALLEL_STARTUP} == "yes" ]] ; then
386
			[[ ${RC_VERBOSE} != "yes" \
387
			|| -e ${svcdir}/exclusive/${SVCNAME} ]] \
388
				&& RC_QUIET_STDOUT="yes"
389
		fi
390
391
		start
392
		)
393
		retval="$?"
394
395
		# If a service has been marked inactive, exit now as something
396
		# may attempt to start it again later
397
		if [[ ${retval} == "0" ]] && service_inactive "${SVCNAME}" ; then
398
			svcinactive=0
399
			service_message "ewarn" "WARNING:  ${SVCNAME} has started but is inactive"
400
			return 1
401
		fi
402
	fi
403
404
	if [[ ${retval} != "0" ]] ; then
405
		if [[ ${svcinactive} == "0" ]] ; then
406
			mark_service_inactive "${SVCNAME}"
407
		else
408
			mark_service_stopped "${SVCNAME}"
409
		fi
410
411
		if [[ -z ${startinactive} ]] ; then
412
			is_runlevel_start && mark_service_failed "${SVCNAME}"
413
			service_message "eerror" "ERROR:  ${SVCNAME} failed to start"
414
		fi
415
	else
416
		svcstarted=0
417
		mark_service_started "${SVCNAME}"
418
		service_message "Service ${SVCNAME} started"
419
	fi
420
421
	# Reset the trap
422
	svc_trap
423
424
	return "${retval}"
425
}
426
427
svc_restart() {
428
	# We don't kill child processes if we're restarting
429
	# This is especically important for sshd ....
430
	RC_KILL_CHILDREN="no"
431
432
	# Create a snapshot of started services
433
	rm -rf "${svcdir}/snapshot/$$"
434
	mkdir -p "${svcdir}/snapshot/$$"
435
	cp -pPR "${svcdir}"/started/* "${svcdir}"/inactive/* \
436
	"${svcdir}/snapshot/$$/" 2>/dev/null
437
	rm -f "${svcdir}/snapshot/$$/${SVCNAME}"
438
439
	# Simple way to try and detect if the service use svc_{start,stop}
440
	# to restart if it have a custom restart() funtion.
441
	if [[ -n $(egrep '^[[:space:]]*restart[[:space:]]*()' "/etc/init.d/${SVCNAME}") ]] ; then
442
		if [[ -z $(egrep 'svc_stop' "/etc/init.d/${SVCNAME}") || \
443
			-z $(egrep 'svc_start' "/etc/init.d/${SVCNAME}") ]] ; then
444
			echo
445
			ewarn "Please use 'svc_stop; svc_start' and not 'stop; start' to"
446
			ewarn "restart the service in its custom 'restart()' function."
447
			ewarn "Run ${SVCNAME} without arguments for more info."
448
			echo
449
			if ! service_stopped "${SVCNAME}" ; then
450
				svc_stop || return "$?"
451
			fi
452
			svc_start
453
		else
454
			restart
455
		fi
456
	else
457
		restart
458
	fi
459
	retval="$?"
460
461
	[[ -e "${svcdir}/scheduled/${SVCNAME}" ]] \
462
		&& rm -Rf "${svcdir}/scheduled/${SVCNAME}"
463
464
	# Restart dependencies as well
465
	for x in $(dolisting "${svcdir}/snapshot/$$/") ; do
466
		x="${x##*/}"
467
		lock "${x}"
468
		if [[ -x /etc/init.d/"${x}" ]] && service_stopped "${x}" ; then
469
			if service_inactive "${SVCNAME}" \
470
			|| service_wasinactive "${SVCNAME}" ; then
471
				svc_schedule_start "${SVCNAME}" "${x}"
472
				ewarn "WARNING:  ${x} is scheduled to start when ${SVCNAME} has started."
473
			elif service_started "${SVCNAME}" ; then
474
				start_service "${x}"
475
			fi
476
		fi
477
		unlock "${x}"
478
	done
479
	rm -rf "${svcdir}/snapshot/$$"
480
481
	service_started "${SVCNAME}"
482
	started="$?"
483
	if [[ ${started} == 0 ]]; then
484
		unlock "${SVCNAME}"
485
		svc_start_scheduled
486
		lock "${SVCNAME}"
487
	fi
488
489
	# Wait for services to come up
490
	if [[ ${IN_BACKGROUND} != "true" \
491
		&& ${IN_BACKGROUND} != "1" ]] ; then
492
		[[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
493
	fi
494
495
	return ${retval}
496
}
497
498
svc_status() {
499
	# The basic idea here is to have some sort of consistent
500
	# output in the status() function which scripts can use
501
	# as an generic means to detect status.  Any other output
502
	# should thus be formatted in the custom status() function
503
	# to work with the printed " * status:  foo".
504
	local efunc="" state=""
505
506
	# If we are effectively root, check to see if required daemons are running
507
	# and update our status accordingly
508
	[[ ${EUID} == 0 ]] && update_service_status "${SVCNAME}"
509
510
	if service_stopping "${SVCNAME}" ; then
511
		efunc="eerror"
512
		state="stopping"
513
	elif service_starting "${SVCNAME}" ; then
514
		efunc="einfo"
515
		state="starting"
516
	elif service_inactive "${SVCNAME}" ; then
517
		efunc="ewarn"
518
		state="inactive"
519
	elif service_started "${SVCNAME}" ; then
520
		efunc="einfo"
521
		state="started"
522
	else
523
		efunc="eerror"
524
		state="stopped"
525
	fi
526
527
	[[ ${RC_QUIET_STDOUT} != "yes" ]] \
528
		&& ${efunc} "status:  ${state}"
529
530
	status
531
	# Return 0 if started, otherwise 1
532
	[[ ${state} == "started" ]]
533
}
534

Return to bug 166545