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