/[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 2050 - (show annotations) (download)
Fri Jun 2 20:02:40 2006 UTC (7 years, 10 months ago) by uberlord
File size: 23088 byte(s)
    Allow LC_* and LANG vars through to runscript.sh by default.

    net.lo now comes after bootmisc, #135118 thanks to Oldrich Jedlicka.

    arping.sh now has MAC address support, #134253 thanks to Oldrich Jedlicka.

    pppd.sh now updates secret files with a blank password, #134337

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