/[vps]/baselayout-vserver/branches/baselayout-1_12/sbin/rc
Gentoo

Contents of /baselayout-vserver/branches/baselayout-1_12/sbin/rc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (show annotations) (download)
Thu Jul 13 07:55:52 2006 UTC (8 years ago) by phreak
File size: 22633 byte(s)
Merging r2151
1 #!/sbin/runscript
2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 trap ":" INT QUIT TSTP
6 source /sbin/functions.sh
7 # Only source this when this is a livecd booting ...
8 [ -f /sbin/livecd-functions.sh ] && source /sbin/livecd-functions.sh
9 umask 022
10
11 # Quick test to see if we can be interactive or not
12 if [[ ${RC_INTERACTIVE:-yes} == "yes" ]] ; then
13 if tty -s && stty -a | grep -q " icanon" ; then
14 RC_INTERACTIVE="yes"
15 else
16 RC_INTERACTIVE="no"
17 fi
18 fi
19
20 try() {
21 local errstr
22 local retval=0
23
24 if [ -c /dev/null ]; then
25 errstr="$((eval $*) 2>&1 >/dev/null)"
26 else
27 errstr="$((eval $*) 2>&1)"
28 fi
29 retval=$?
30 if [ "${retval}" -ne 0 ]
31 then
32 splash "critical" &
33
34 echo -e "${ENDCOL}${NORMAL}[${BAD} oops ${NORMAL}]"
35 echo
36 eerror "The \"${1}\" command failed with error:"
37 echo
38 echo "${errstr#*: }"
39 echo
40 eerror "Since this is a critical task, startup cannot continue."
41 echo
42 einfo "Halting"
43 /sbin/halt -f
44 fi
45
46 return ${retval}
47 }
48
49 # Check that $1 exists ...
50 check_statedir() {
51 [ -z "$1" ] && return 0
52
53 if [ ! -d "$1" ] ; then
54 if ! mkdir -p "$1" &>/dev/null ; then
55 splash "critical" &
56 echo
57 eerror "For Gentoo to function properly, \"$1\" needs to exist."
58 eerror "Please mount your root partition read/write, and execute:"
59 echo
60 eerror " # mkdir -p $1"
61 echo; echo
62 einfo "Halting"
63 /sbin/halt -f
64 fi
65 fi
66
67 return 0
68 }
69
70 # void noblock_read(var)
71 #
72 # reads a line of input into var like regular read
73 # but it does not block waiting for input
74 #
75 noblock_read() {
76 local old_tty_settings="$(stty -g)"
77 stty -icanon min 0 time 0
78 read "$@"
79 stty "${old_tty_settings}"
80 }
81
82 # bool user_want_interactive(void)
83 #
84 # return 0 if user wants interactive mode
85 #
86 user_want_interactive() {
87 [[ ${RC_INTERACTIVE} != "yes" ]] && return 1
88
89 local user_input
90 noblock_read user_input
91 [[ ${user_input} == *"I"* || ${user_input} == *"i"* ]]
92 }
93
94 # void do_interactive
95 #
96 # starts, skips, continues or drops to the shell
97 # depending on user selection
98 #
99 do_interactive() {
100 local service="$2"
101
102 user_want_interactive && svcinteractive="yes"
103 if [[ ${svcinteractive} != "yes" || ! -e "/etc/init.d/${service}" ]] ; then
104 "$@"
105 return $?
106 fi
107
108 local start_text="Start service"
109 local skip_text="Skip service"
110 local continue_text="Continue boot process"
111 local shell_text="Exit to shell"
112
113 echo
114 echo "About to start the service ${service}"
115 PS3="Enter your selection: "
116 select action in "${start_text}" "${skip_text}" "${continue_text}" \
117 "${shell_text}"
118 do
119 case ${action} in
120 "${start_text}")
121 "$@"
122 break
123 ;;
124 "${skip_text}")
125 break
126 ;;
127 "${continue_text}")
128 svcinteractive="no"
129 "$@"
130 break
131 ;;
132 "${shell_text}")
133 echo
134 sulogin "${CONSOLE}"
135 ;;
136 esac
137 done
138 }
139
140 get_critical_services() {
141 local x=
142 CRITICAL_SERVICES=
143
144 if [ -f "/etc/runlevels/${BOOTLEVEL}/.critical" ]
145 then
146 for x in $(< /etc/runlevels/${BOOTLEVEL}/.critical)
147 do
148 CRITICAL_SERVICES="${CRITICAL_SERVICES} ${x##*/}"
149 done
150 else
151 CRITICAL_SERVICES="checkroot modules checkfs localmount clock bootmisc"
152 fi
153
154 export CRITICAL_SERVICES
155
156 return 0
157 }
158
159 check_critical_services() {
160 local x
161
162 # Ensure that critical services are in the boot runlevel
163 for x in ${CRITICAL_SERVICES} ; do
164 if [[ ! -L "/etc/runlevels/${BOOTLEVEL}/${x}" ]] ; then
165 ewarn "WARNING: Adding critical service ${x} to the ${BOOTLEVEL} runlevel"
166 ln -snf "/etc/init.d/${x}" "/etc/runlevels/${BOOTLEVEL}/${x}"
167 fi
168 done
169 }
170
171 # Save $1
172 argv1="$1"
173
174 # First time boot stuff goes here. Note that 'sysinit' is an internal runlevel
175 # used to bring up local filesystems, and should not be started with /sbin/rc
176 # directly ...
177 if [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} = "sysinit" ]]
178 then
179 # Setup initial $PATH just in case
180 PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
181
182 # Help users recover their systems incase these go missing
183 [ -c /dev/null ] && dev_null=1 || dev_null=0
184 [ -c /dev/console ] && dev_console=1 || dev_console=0
185
186 # Set the console loglevel to 1 for a cleaner boot
187 # the logger should anyhow dump the ring-0 buffer at start to the
188 # logs, and that with dmesg can be used to check for problems
189 /bin/dmesg -n 1
190
191 echo
192 echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; ${BRACKET}http://www.gentoo.org/${NORMAL}"
193 echo -e " Copyright 1999-2006 Gentoo Foundation; Distributed under the GPLv2"
194 echo
195 if [[ ${RC_INTERACTIVE} == "yes" ]] ; then
196 echo -e "Press ${GOOD}I${NORMAL} to enter interactive boot mode"
197 echo
198 fi
199 check_statedir /proc
200
201 ebegin "Mounting proc at /proc"
202 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
203 mntcmd=$(get_mount_fstab /proc)
204 else
205 unset mntcmd
206 fi
207 is_vserver_sys || try mount -n ${mntcmd:--t proc proc /proc -o noexec,nosuid,nodev}
208 eend $?
209
210 # Read off the kernel commandline to see if there's any special settings
211 # especially check to see if we need to set the CDBOOT environment variable
212 # Note: /proc MUST be mounted
213 [ -f /sbin/livecd-functions.sh ] && livecd_read_commandline
214
215 if ! is_vps_sys && [ "$(get_KV)" -ge "$(KV_to_int '2.6.0')" ] ; then
216 if [[ -d /sys ]] ; then
217 ebegin "Mounting sysfs at /sys"
218 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
219 mntcmd=$(get_mount_fstab /sys)
220 else
221 unset mntcmd
222 fi
223 try mount -n ${mntcmd:--t sysfs sysfs /sys -o noexec,nosuid,nodev}
224 eend $?
225 else
226 ewarn "No /sys to mount sysfs needed in 2.6 and later kernels!"
227 fi
228 fi
229
230 check_statedir /dev
231
232 # Fix weird bug where there is a /dev/.devfsd in a unmounted /dev
233 devfs_automounted="no"
234 if [ -e "/dev/.devfsd" ]
235 then
236 mymounts="$(awk '($3 == "devfs") { print "yes"; exit 0 }' /proc/mounts)"
237 if [ "${mymounts}" != "yes" ]
238 then
239 rm -f /dev/.devfsd
240 else
241 devfs_automounted="yes"
242 fi
243 fi
244
245 # Try to figure out how the user wants /dev handled
246 # - check $RC_DEVICES from /etc/conf.d/rc
247 # - check boot parameters
248 # - make sure the required binaries exist
249 # - make sure the kernel has support
250 if [ "${RC_DEVICES}" = "static" ]
251 then
252 ebegin "Using existing device nodes in /dev"
253 eend 0
254 else
255 fellback_to_devfs="no"
256 case "${RC_DEVICES}" in
257 devfs) devfs="yes"
258 udev="no"
259 ;;
260 udev) devfs="yes"
261 udev="yes"
262 fellback_to_devfs="yes"
263 ;;
264 auto|*) devfs="yes"
265 udev="yes"
266 ;;
267 esac
268
269 # Check udev prerequisites and kernel params
270 if [ "${udev}" = "yes" ]
271 then
272 if get_bootparam "noudev" || \
273 [ ! -x /sbin/udev -o ${devfs_automounted} = "yes" ] || \
274 [ "$(get_KV)" -lt "$(KV_to_int '2.6.0')" ]
275 then
276 udev="no"
277 fi
278 fi
279
280 # Check devfs prerequisites and kernel params
281 if [ "${devfs}" = "yes" ]
282 then
283 if get_bootparam "nodevfs" || [ "${udev}" = "yes" ]
284 then
285 devfs="no"
286 fi
287 fi
288
289 # Actually start setting up /dev now
290 if [[ ${udev} == "yes" ]] ; then
291 start_addon udev
292
293 # With devfs, /dev can be mounted by the kernel ...
294 elif [[ ${devfs} == "yes" ]] ; then
295 start_addon devfs
296
297 # Did the user want udev in the config file but for
298 # some reason, udev support didnt work out ?
299 if [[ ${fellback_to_devfs} == "yes" ]] ; then
300 ewarn "You wanted udev but support for it was not available!"
301 ewarn "Please review your system after it's booted!"
302 fi
303 fi
304
305 # OK, if we got here, things are probably not right :)
306 if [[ ${devfs} == "no" && ${udev} == "no" ]] ; then
307 clear
308 echo
309 einfo "The Gentoo Linux system initialization scripts have detected that"
310 einfo "your system does not support UDEV. Since Gentoo Linux has been"
311 einfo "designed with dynamic /dev in mind, it is highly suggested that you"
312 einfo "emerge sys-fs/udev and configure your system to use it."
313 einfo "Please read the Gentoo Handbook for more information!"
314 echo
315 einfo " http://www.gentoo.org/doc/en/handbook/"
316 echo
317 einfo "Thanks for using Gentoo! :)"
318 echo
319 read -t 15 -p "(hit Enter to continue or wait 15 seconds ...)"
320 fi
321 fi
322
323 # From linux-2.5.68 we need to mount /dev/pts again ...
324 if ! is_vserver_sys && [ "$(get_KV)" -ge "$(KV_to_int '2.5.68')" ]
325 then
326 have_devpts="$(awk '($2 == "devpts") { print "yes"; exit 0 }' /proc/filesystems)"
327
328 if [ "${have_devpts}" = "yes" ]
329 then
330 # Only try to create /dev/pts if we have /dev mounted dynamically,
331 # else it might fail as / might be still mounted readonly.
332 if [ ! -d /dev/pts ] && \
333 [ "${devfs}" = "yes" -o "${udev}" = "yes" ]
334 then
335 # Make sure we have /dev/pts
336 mkdir -p /dev/pts &>/dev/null || \
337 ewarn "Could not create /dev/pts!"
338 fi
339
340 if [[ -d /dev/pts ]] ; then
341 ebegin "Mounting devpts at /dev/pts"
342 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
343 mntcmd=$(get_mount_fstab /dev/pts)
344 else
345 unset mntcmd
346 fi
347 try mount -n ${mntcmd:--t devpts devpts /dev/pts -o gid=5,mode=0620,noexec,nosuid}
348 eend $?
349 fi
350 fi
351 fi
352
353 # Start logging console output since we have all /dev stuff setup
354 bootlog start
355
356 # Start RAID/LVM/EVMS/DM volumes for /usr, /var, etc.
357 for x in ${RC_VOLUME_ORDER} ; do
358 start_addon "${x}"
359 done
360
361 # We set the forced softlevel from the kernel command line
362 # It needs to be run right after proc is mounted for the
363 # boot runlevel
364 setup_defaultlevels
365
366 # $BOOT can be used by rc-scripts to test if it is the first time
367 # the 'boot' runlevel is executed. Now also needed by some stuff in
368 # the 'sysinit' runlevel ...
369 export BOOT="yes"
370
371 start_critical_service() {
372 (
373 local retval=
374 local service="$1"
375 # Needed for some addons like dm-crypt that starts in critical services
376 local myservice="$1"
377
378 source "/etc/init.d/${service}"
379 retval=$?
380 if [[ ${retval} -ne 0 ]] ; then
381 eerror "Failed to source /etc/init.d/${service}"
382 return "${retval}"
383 fi
384
385 local conf="$(add_suffix /etc/conf.d/${service})"
386 [[ -e ${conf} ]] && source "${conf}"
387 conf="$(add_suffix /etc/rc.conf)"
388 [[ -e ${conf} ]] && source "${conf}"
389
390 start
391 retval=$?
392 [[ ${retval} -ne 0 ]] && eerror "Failed to start /etc/init.d/${service}"
393
394 return "${retval}"
395 )
396 }
397
398 # We first try to find a locally defined list of critical services
399 # for a particular runlevel. If we cannot find it, we use the
400 # defaults.
401 get_critical_services
402
403 splash "rc_init" "${argv1}"
404
405 export START_CRITICAL="yes"
406
407 # We do not want to break compatibility, so we do not fully integrate
408 # these into /sbin/rc, but rather start them by hand ...
409 for x in ${CRITICAL_SERVICES}
410 do
411 splash "svc_start" "${x}"
412 if ! start_critical_service "${x}" ; then
413 splash "critical" &>/dev/null &
414
415 echo
416 eerror "One or more critical startup scripts failed to start!"
417 eerror "Please correct this, and reboot ..."
418 echo; echo
419 einfo "Halting"
420 /sbin/halt -f
421 fi
422
423 splash "svc_started" "${x}" "0"
424 done
425
426 unset START_CRITICAL
427
428 # /var/log should be writable now, so starting saving the boot output
429 bootlog sync
430
431 # have to run this after /var/run is mounted rw #85304
432 if [ -x /sbin/irqbalance -a "$(get_KV)" -ge "$(KV_to_int '2.5.0')" ]
433 then
434 ebegin "Starting irqbalance"
435 /sbin/irqbalance
436 eend $?
437 fi
438
439 # Check that $svcdir exists ...
440 check_statedir "${svcdir}"
441
442 # Should we use tmpfs/ramfs/ramdisk for caching dependency and
443 # general initscript data? Note that the 'gentoo=<fs>' kernel
444 # option should override any other setting ...
445 for fs in tmpfs ramfs ramdisk
446 do
447 if get_bootparam "${fs}"
448 then
449 svcmount="yes"
450 svcfstype="${fs}"
451 break
452 fi
453 done
454 if [ "${svcmount}" = "yes" ]
455 then
456 ebegin "Mounting ${svcfstype} at ${svcdir}"
457 case "${svcfstype}" in
458 ramfs)
459 try mount -t ramfs svcdir "${svcdir}" \
460 -o rw,mode=0755,size="${svcsize}"k
461 ;;
462 ramdisk)
463 try dd if=/dev/zero of=/dev/ram0 bs=1k count="${svcsize}"
464 try /sbin/mke2fs -i 1024 -vm0 /dev/ram0 "${svcsize}"
465 try mount -t ext2 /dev/ram0 "${svcdir}" -o rw
466 ;;
467 tmpfs|*)
468 try mount -t tmpfs svcdir "${svcdir}" \
469 -o rw,mode=0755,size="${svcsize}"k
470 ;;
471 esac
472 eend 0
473 fi
474
475 # If booting off CD, we want to update inittab before setting the runlevel
476 if [ -f "/sbin/livecd-functions.sh" -a -n "${CDBOOT}" ]
477 then
478 ebegin "Updating inittab"
479 livecd_fix_inittab
480 eend $?
481 /sbin/telinit q &>/dev/null
482 fi
483
484 # Clear $svcdir from stale entries, but leave the caches around, as it
485 # should help speed things up a bit
486 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
487 grep -ve '\(depcache\|deptree\|envcache\)')
488
489 echo "sysinit" > "${svcdir}/softlevel"
490
491 # Ensure all critical services have are in the boot runlevel
492 check_critical_services
493
494 # Update the dependency cache
495 /sbin/depscan.sh
496
497 # Now that the dependency cache are up to date, make sure these
498 # are marked as started ...
499 (
500 # Needed for mark_service_started()
501 source "${svclib}/sh/rc-services.sh"
502
503 for x in ${CRITICAL_SERVICES}
504 do
505 mark_service_started "${x}"
506 done
507 )
508
509 # If the user's /dev/null or /dev/console are missing, we
510 # should help them out and explain how to rectify the situation
511 if [ ${dev_null} -eq 0 -o ${dev_console} -eq 0 ] \
512 && [ -e /usr/share/baselayout/issue.devfix ]
513 then
514 # Backup current /etc/issue
515 if [ -e /etc/issue -a ! -e /etc/issue.devfix ]
516 then
517 mv /etc/issue /etc/issue.devfix
518 fi
519
520 cp /usr/share/baselayout/issue.devfix /etc/issue
521 fi
522
523 # Setup login records ... this has to be done here because when
524 # we exit this runlevel, init will write a boot record to utmp
525 # If /var/run is readonly, then print a warning, not errors
526 if touch /var/run/utmp 2>/dev/null
527 then
528 > /var/run/utmp
529 touch /var/log/wtmp
530 chgrp utmp /var/run/utmp /var/log/wtmp
531 chmod 0664 /var/run/utmp /var/log/wtmp
532 # Remove /var/run/utmpx (bug from the past)
533 rm -f /var/run/utmpx
534 else
535 ewarn "Skipping /var/run/utmp initialization (ro root?)"
536 fi
537
538 # Check and save if the user wants interactive
539 user_want_interactive && svcinteractive="yes"
540 echo "${svcinteractive:-no}" > "${svcdir}/interactive"
541
542 # sysinit is now done, so allow init scripts to run normally
543 [[ -e /dev/.rcsysinit ]] && rm -f /dev/.rcsysinit
544
545 # All done logging
546 bootlog quit
547
548 exit 0
549 fi # Sysinit ends here
550
551 if [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} == "boot" ]]
552 then
553 setup_defaultlevels
554
555 if [ -n "${DEFAULTLEVEL}" -a "${DEFAULTLEVEL}" != "default" ]
556 then
557 # Setup our default runlevel runlevel that will be run
558 # the first time /sbin/rc is called with argv1 != sysinit|boot
559 echo "${DEFAULTLEVEL}" > "${svcdir}/ksoftlevel"
560 fi
561
562 # $BOOT can be used by rc-scripts to test if it is the first time
563 # the 'boot' runlevel is executed
564 export BOOT="yes"
565
566 # We reset argv1 to the bootlevel given on the kernel command line
567 # if there is one
568 argv1="${BOOTLEVEL}"
569
570 elif [[ ${RUNLEVEL} != "S" && ${RUNLEVEL} != "1" && -e ${svcdir}/ksoftlevel ]]
571 then
572 argv1="$(< ${svcdir}/ksoftlevel)"
573 rm -f "${svcdir}/ksoftlevel"
574 elif [[ ${RUNLEVEL} != "S" && ${RUNLEVEL} != "1" && ${argv1} == "single" ]]
575 then
576 /sbin/telinit S
577 exit 0
578 elif [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} != "single" ]]
579 then
580 level=$(awk -v level="${argv1}" '
581 $2 == level {
582 split($0, fields, ":")
583 print fields[2]
584 exit
585 }' /etc/inittab 2>/dev/null)
586 [[ -z ${level} ]] && level=3
587 /sbin/telinit "${level}"
588 exit 0
589 fi
590
591 # Ensure that critical services are in the boot runlevel
592 get_critical_services
593 check_critical_services
594
595 source "${svclib}/sh/rc-services.sh"
596 [[ -e "${svcdir}/interactive" ]] \
597 && svcinteractive="$(<${svcdir}/interactive)"
598
599 if [ -f "${svcdir}/softlevel" ]
600 then
601 # Set OLDSOFTLEVEL if we had a valid SOFTLEVEL
602 export OLDSOFTLEVEL="$(< ${svcdir}/softlevel)"
603 else
604 export OLDSOFTLEVEL=
605 fi
606
607 if [ -z "${argv1}" ]
608 then
609 if [ -f "${svcdir}/softlevel" ]
610 then
611 export SOFTLEVEL="$(< ${svcdir}/softlevel)"
612 else
613 export SOFTLEVEL="${BOOTLEVEL}"
614 fi
615 else
616 export SOFTLEVEL="${argv1}"
617 fi
618
619 if [ ! -f "${svcdir}/softlevel" ]
620 then
621 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
622 fi
623
624 # For keeping a list of services that fails during boot/halt
625 if [ ! -d "${svcdir}/failed" ]
626 then
627 mkdir -p -m 0755 "${svcdir}/failed"
628 else
629 rm -rf "${svcdir}"/failed/*
630 fi
631
632 splash "rc_init" "${argv1}"
633
634
635 if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
636 then
637 myscripts=
638
639 elif [ "${SOFTLEVEL}" = "single" ]
640 then
641
642 myscripts="${CRITICAL_SERVICES}"
643
644 elif [ ! -d "/etc/runlevels/${SOFTLEVEL}" ]
645 then
646 eerror "ERROR: runlevel ${SOFTLEVEL} does not exist; exiting ..."
647 exit 1
648 else
649 myscripts=
650 if [ "${SOFTLEVEL}" != "${BOOTLEVEL}" ]
651 then
652 # Normal runlevels *include* boot scripts
653 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
654 mylevels="${mylevels} $(dolisting /etc/runlevels/${BOOTLEVEL}/)"
655 else
656 # Non-normal runlevels don't include boot scripts as default
657 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
658
659 # As we're in the bootlevel, add any services that failed due
660 # to /dev/.rcsysinit existing to the list
661 if [[ -d /dev/.rcboot ]] ; then
662 COLDPLUG_SERVICES=
663 for x in $(dolisting /dev/.rcboot/) ; do
664 [[ -L ${x} ]] && COLDPLUG_SERVICES="${COLDPLUG_SERVICES} ${x##*/}"
665 done
666 for x in ${COLDPLUG_SERVICES} ; do
667 if [[ ! -e /etc/runlevels/"${BOOTLEVEL}"/"${x}" \
668 && ! -e /etc/runlevels/"${DEFAULTLEVEL}"/"${x}" ]] ; then
669 myscripts="${myscripts} ${x}"
670 mark_service_coldplugged "${x}"
671 fi
672 done
673 einfo "Device initiated services:${HILITE}${myscripts}${NORMAL}"
674 rm -rf /dev/.rcboot
675 fi
676 fi
677
678 for x in ${mylevels}
679 do
680 [ -L "${x}" ] && myscripts="${myscripts} ${x##*/}"
681 done
682 fi
683
684 # The softscripts dir contains all scripts that belong to the
685 # runlevel specified in ${svcdir}/softlevel
686 # It needs to be a new directory, else when stopping the services
687 # and the old directory is not intact, things get broken
688
689 mkdir -p -m 0755 "${svcdir}/softscripts.new"
690
691 for x in ${myscripts} ; do
692 if [[ ! -e /etc/init.d/${x} ]] ; then
693 ewarn "WARNING: /etc/init.d/${x} missing; skipping ..."
694 continue
695 fi
696 # The -f eliminates a warning if the symlink already exists,
697 # which can happen if a service is in both the boot level and
698 # the current "normal" runlevel
699 ln -snf "/etc/init.d/${x}" "${svcdir}/softscripts.new/${x}"
700 done
701
702 get_stop_services() {
703 local x list
704
705 for x in $(dolisting "${svcdir}/inactive/") \
706 $(dolisting "${svcdir}/started/") ; do
707 list="${list} ${x##*/}"
708 done
709
710 reverse_list $(trace_dependencies ${list})
711 }
712
713 dep_stop() {
714 local x dep needsme depservice
715 local service=${1##*/}
716
717 service_stopped "${service}" && return 0
718
719 # Candidate for zapping ?
720 [[ -L ${svcdir}/softscripts.new/${service} ]] \
721 && return 0
722
723 if [[ ${SOFTLEVEL} != "reboot" \
724 && ${SOFTLEVEL} != "shutdown" \
725 && ${SOFTLEVEL} != "single" ]] ; then
726 service_coldplugged "${service}" && return 0
727 if net_service "${service}" ; then
728 [[ -z ${OLDSOFTLEVEL} ]] \
729 || ! in_runlevel "${service}" "${OLDSOFTLEVEL}" \
730 && return 0
731 fi
732 fi
733
734 # Should not work for 'use'
735 if [[ -z $(needsme "${service}") ]] ; then
736 # Nothing depends on me
737 stop_service "${service}"
738 else
739 # Something may depend on me
740 needsme=0
741
742 for dep in $(needsme "${service}") ; do
743 if [[ -L "${svcdir}/softscripts.new/${dep}" ]] ; then
744 # This dep is valid
745 needsme=1
746
747 break
748 fi
749 done
750
751 [[ ${needsme} -eq 0 ]] && stop_service "${service}"
752 fi
753 }
754
755 # Stop services
756 if [[ ${SOFTLEVEL} != "single" && \
757 ${SOFTLEVEL} != "reboot" && \
758 ${SOFTLEVEL} != "shutdown" ]]
759 then
760 for i in $(get_stop_services) ; do
761 dep_stop "${i}"
762 done
763
764 # Wait for any services that may still be stopping ...
765 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
766 else
767 get_critical_services
768
769 is_critical_service() {
770 local x
771 local service=${1##*/}
772
773 for x in ${CRITICAL_SERVICES} ${LOGGER_SERVICE} ; do
774 [[ ${service} == "${x}" ]] && return 0
775 done
776
777 return 1
778 }
779
780 # First stop non critical services
781 for i in $(get_stop_services) ; do
782 is_critical_service "${i}" || dep_stop "${i}"
783 done
784
785 # Wait for any services that may still be stopping ...
786 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
787
788 export STOP_CRITICAL="yes"
789 # Now stop the rest
790 for i in $(get_stop_services) ; do
791 dep_stop "${i}"
792 done
793 unset STOP_CRITICAL
794 fi
795
796 # Only change softlevel AFTER all the services have been stopped,
797 # else they will not get the depend's right (wrong SOFTLEVEL)
798
799 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
800
801 if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
802 # Clear $svcdir from stale entries, but leave the caches around, as it
803 # should help speed things up a bit
804 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
805 grep -ve '\(depcache\|deptree\|envcache\)')
806
807 # Call halt.sh with LC_ALL=C so that bash doesn't load any locales
808 # which could interfere with unmounting /usr
809 LC_ALL=C exec /etc/init.d/halt.sh "${SOFTLEVEL}"
810
811 # Should never get here
812 exit 0
813 fi
814
815 if [[ ${SOFTLEVEL} == "single" ]] ; then
816 /sbin/halt -f
817 exit 0
818 fi
819
820 # Move the old softscritps directory to a different one
821 # and make the new softscripts directory the current
822
823 mv -f "${svcdir}/softscripts" "${svcdir}/softscripts.old"
824 mv -f "${svcdir}/softscripts.new" "${svcdir}/softscripts"
825
826 get_start_services() {
827 local x list
828
829 get_critical_services
830 list=${CRITICAL_SERVICES}
831
832 [[ -n ${LOGGER_SERVICE} && \
833 -L ${svcdir}/softscripts/${LOGGER_SERVICE} ]] && \
834 list="${list} ${LOGGER_SERVICE}"
835
836 for x in $(dolisting "${svcdir}/softscripts/") ; do
837 list="${list} ${x##*/}"
838 done
839
840 trace_dependencies ${list}
841 }
842
843 # Start scripts
844 for i in $(get_start_services) ; do
845 if service_stopped "${i}" ; then
846 do_interactive start_service "${i}"
847 fi
848 done
849
850 # Wait for any services that may still be running ...
851 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
852
853 # Clean the old runlevel
854 rm -rf "${svcdir}/softscripts.old" &>/dev/null
855
856 # Depends gets nuked, so update them
857 # (this problem should be solved now, but i think it will be a good idea
858 # to recreate the deps after a change in runlevel)
859
860 #/sbin/depscan.sh &>/dev/null
861
862 # We want devfsd running after a change of runlevel (this is mostly if we return
863 # from runlevel 'single')
864 if [ -z "`ps --no-heading -C 'devfsd'`" -a \
865 -n "`gawk '/\/dev devfs/ { print }' /proc/mounts 2>/dev/null`" ]
866 then
867 if [ "${RC_DEVFSD_STARTUP}" != "no" ]
868 then
869 /sbin/devfsd /dev &>/dev/null
870 fi
871 fi
872
873 # Runlevel end, so clear stale fail list
874 rm -rf "${svcdir}/failed" &>/dev/null
875
876 # If we were in the boot runlevel, it is done now ...
877 if [[ -n ${BOOT} ]]; then
878 unset BOOT
879 # Save our interactive mode into the default runlevel
880 user_want_interactive && svcinteractive="yes"
881 echo "${svcinteractive}" > "${svcdir}/interactive"
882 else
883 # As we're not boot, we remove the interactive file
884 [[ -e "${svcdir}/interactive" ]] && rm -f "${svcdir}/interactive"
885 fi
886
887 # Remove the cached CONSOLETYPE
888 unset CONSOLETYPE
889
890 splash "rc_exit"
891
892 # vim:ts=4

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20