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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2091 - (show annotations) (download)
Wed Jun 14 21:13:31 2006 UTC (8 years, 5 months ago) by uberlord
File size: 23081 byte(s)
    {start,stop}_volumes moved to rc and halt.sh respectively.

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

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20