/[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 1959 - (show annotations) (download)
Wed Apr 5 17:44:34 2006 UTC (8 years, 7 months ago) by uberlord
File size: 23509 byte(s)
    runscript.sh now stores the fact that it failed to to /dev/.rcsysinit
    existing in the directory /dev/.rcafterinit. rc adds services in
    /dev/.rcafterinit to the boot list and then rm -f's that directory. This
    solves the issue of udev-089 forcing coldplug removal.
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 bootmisc"
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 # Swap needs to be activated *after* /dev has been fully setup so that
376 # the fstab can be properly parsed. This first pass we send to /dev/null
377 # in case the user has swap points setup on different partitions. We
378 # will run swapon again in localmount and that one will report errors.
379 ebegin "Activating (possible) swap"
380 /sbin/swapon -a >& /dev/null
381 eend 0
382
383 # We set the forced softlevel from the kernel command line
384 # It needs to be run right after proc is mounted for the
385 # boot runlevel
386 setup_defaultlevels
387
388 # $BOOT can be used by rc-scripts to test if it is the first time
389 # the 'boot' runlevel is executed. Now also needed by some stuff in
390 # the 'sysinit' runlevel ...
391 export BOOT="yes"
392
393 start_critical_service() {
394 (
395 local retval=
396 local service="$1"
397 # Needed for some addons like dm-crypt that starts in critical services
398 local myservice="$1"
399
400 source "/etc/init.d/${service}"
401 retval=$?
402 if [[ ${retval} -ne 0 ]] ; then
403 eerror "Failed to source /etc/init.d/${service}"
404 return "${retval}"
405 fi
406
407 local conf="$(add_suffix /etc/conf.d/${service})"
408 [[ -e ${conf} ]] && source "${conf}"
409 conf="$(add_suffix /etc/rc.conf)"
410 [[ -e ${conf} ]] && source "${conf}"
411
412 start
413 retval=$?
414 [[ ${retval} -ne 0 ]] && eerror "Failed to start /etc/init.d/${service}"
415
416 return "${retval}"
417 )
418 }
419
420 # We first try to find a locally defined list of critical services
421 # for a particular runlevel. If we cannot find it, we use the
422 # defaults.
423 get_critical_services
424
425 splash "rc_init" "${argv1}"
426
427 export START_CRITICAL="yes"
428
429 # We do not want to break compatibility, so we do not fully integrate
430 # these into /sbin/rc, but rather start them by hand ...
431 for x in ${CRITICAL_SERVICES}
432 do
433 splash "svc_start" "${x}"
434 if ! start_critical_service "${x}" ; then
435 splash "critical" &>/dev/null &
436
437 echo
438 eerror "One of more critical startup scripts failed to start!"
439 eerror "Please correct this, and reboot ..."
440 echo; echo
441 /sbin/sulogin ${CONSOLE}
442 einfo "Unmounting filesystems"
443 /bin/mount -a -o remount,ro &>/dev/null
444 einfo "Rebooting"
445 /sbin/reboot -f
446 fi
447
448 splash "svc_started" "${x}" "0"
449 done
450
451 unset START_CRITICAL
452
453 # /var/log should be writable now, so starting saving the boot output
454 bootlog sync
455
456 # have to run this after /var/run is mounted rw #85304
457 if [ -x /sbin/irqbalance -a "$(get_KV)" -ge "$(KV_to_int '2.5.0')" ]
458 then
459 ebegin "Starting irqbalance"
460 /sbin/irqbalance
461 eend $?
462 fi
463
464 # Check that $svcdir exists ...
465 check_statedir "${svcdir}"
466
467 # Should we use tmpfs/ramfs/ramdisk for caching dependency and
468 # general initscript data? Note that the 'gentoo=<fs>' kernel
469 # option should override any other setting ...
470 for fs in tmpfs ramfs ramdisk
471 do
472 if get_bootparam "${fs}"
473 then
474 svcmount="yes"
475 svcfstype="${fs}"
476 break
477 fi
478 done
479 if [ "${svcmount}" = "yes" ]
480 then
481 ebegin "Mounting ${svcfstype} at ${svcdir}"
482 case "${svcfstype}" in
483 ramfs)
484 try mount -t ramfs svcdir "${svcdir}" \
485 -o rw,mode=0755,size="${svcsize}"k
486 ;;
487 ramdisk)
488 try dd if=/dev/zero of=/dev/ram0 bs=1k count="${svcsize}"
489 try /sbin/mke2fs -i 1024 -vm0 /dev/ram0 "${svcsize}"
490 try mount -t ext2 /dev/ram0 "${svcdir}" -o rw
491 ;;
492 tmpfs|*)
493 try mount -t tmpfs svcdir "${svcdir}" \
494 -o rw,mode=0755,size="${svcsize}"k
495 ;;
496 esac
497 eend 0
498 fi
499
500 # If booting off CD, we want to update inittab before setting the runlevel
501 if [ -f "/sbin/livecd-functions.sh" -a -n "${CDBOOT}" ]
502 then
503 ebegin "Updating inittab"
504 livecd_fix_inittab
505 eend $?
506 /sbin/telinit q &>/dev/null
507 fi
508
509 # Clear $svcdir from stale entries, but leave the caches around, as it
510 # should help speed things up a bit
511 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
512 grep -ve '\(depcache\|deptree\|envcache\)')
513
514 echo "sysinit" > "${svcdir}/softlevel"
515
516 # Ensure all critical services have are in the boot runlevel
517 check_critical_services
518
519 # Update the dependency cache
520 /sbin/depscan.sh
521
522 # Now that the dependency cache are up to date, make sure these
523 # are marked as 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/.rcafterinit ]] ; then
687 for x in $(dolisting /dev/.rcafterinit/) ; do
688 [[ -L ${x} ]] && myscripts="${myscripts} ${x##*/}"
689 done
690 einfo "Device initiated services:${HILITE}${myscripts}${NORMAL}"
691 rm -rf /dev/.rcafterinit
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 this is a 'net' service, we do not want to stop it if it was
744 # not in the previous runlevel, and we are not shutting down,
745 # rebooting or going to single runlevel. This is because the user
746 # (or hotplut) might have started it (net.ppp?) ...
747 if net_service "${service}" && \
748 [[ ${SOFTLEVEL} != "reboot" && \
749 ${SOFTLEVEL} != "shutdown" && \
750 ${SOFTLEVEL} != "single" ]] ; then
751 if [[ -z ${OLDSOFTLEVEL} ]] || \
752 ! in_runlevel "${service}" "${OLDSOFTLEVEL}"
753 then
754 # This service is not in the previous runlevel, so
755 # do not stop it ...
756 return 0
757 fi
758 fi
759
760 # Should not work for 'use'
761 if [[ -z $(needsme "${service}") ]] ; then
762 # Nothing depends on me
763 stop_service "${service}"
764 else
765 # Something may depend on me
766 needsme=0
767
768 for dep in $(needsme "${service}") ; do
769 if [[ -L "${svcdir}/softscripts.new/${dep}" ]] ; then
770 # This dep is valid
771 needsme=1
772
773 break
774 fi
775 done
776
777 [[ ${needsme} -eq 0 ]] && stop_service "${service}"
778 fi
779 }
780
781 # Stop services
782 if [[ ${SOFTLEVEL} != "single" && \
783 ${SOFTLEVEL} != "reboot" && \
784 ${SOFTLEVEL} != "shutdown" ]]
785 then
786 for i in $(get_stop_services) ; do
787 dep_stop "${i}"
788 done
789
790 # Wait for any services that may still be stopping ...
791 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
792 else
793 get_critical_services
794
795 is_critical_service() {
796 local x
797 local service=${1##*/}
798
799 for x in ${CRITICAL_SERVICES} ${LOGGER_SERVICE} ; do
800 [[ ${service} == "${x}" ]] && return 0
801 done
802
803 return 1
804 }
805
806 # First stop non critical services
807 for i in $(get_stop_services) ; do
808 is_critical_service "${i}" || dep_stop "${i}"
809 done
810
811 # Wait for any services that may still be stopping ...
812 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
813
814 export STOP_CRITICAL="yes"
815 # Now stop the rest
816 for i in $(get_stop_services) ; do
817 dep_stop "${i}"
818 done
819 unset STOP_CRITICAL
820 fi
821
822 # Only change softlevel AFTER all the services have been stopped,
823 # else they will not get the depend's right (wrong SOFTLEVEL)
824
825 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
826
827 if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
828 # Clear $svcdir from stale entries, but leave the caches around, as it
829 # should help speed things up a bit
830 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
831 grep -ve '\(depcache\|deptree\|envcache\)')
832
833 source /etc/init.d/halt.sh
834
835 if [[ ${SOFTLEVEL} == "reboot" ]] ; then
836 source /etc/init.d/reboot.sh
837 else
838 source /etc/init.d/shutdown.sh
839 fi
840
841 # Should never get here
842 exit 0
843 fi
844
845 if [[ ${SOFTLEVEL} == "single" ]] ; then
846 /sbin/sulogin ${CONSOLE}
847 exit 0
848 fi
849
850 # Move the old softscritps directory to a different one
851 # and make the new softscripts directory the current
852
853 mv -f "${svcdir}/softscripts" "${svcdir}/softscripts.old"
854 mv -f "${svcdir}/softscripts.new" "${svcdir}/softscripts"
855
856 get_start_services() {
857 local x list
858
859 get_critical_services
860 list=${CRITICAL_SERVICES}
861
862 [[ -n ${LOGGER_SERVICE} && \
863 -L ${svcdir}/softscripts/${LOGGER_SERVICE} ]] && \
864 list="${list} ${LOGGER_SERVICE}"
865
866 for x in $(dolisting "${svcdir}/softscripts/") ; do
867 list="${list} ${x##*/}"
868 done
869
870 trace_dependencies ${list}
871 }
872
873 # Start scripts
874 for i in $(get_start_services) ; do
875 if service_stopped "${i}" ; then
876 do_interactive start_service "${i}"
877 fi
878 done
879
880 # Wait for any services that may still be running ...
881 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && wait
882
883 # Clean the old runlevel
884 rm -rf "${svcdir}/softscripts.old" &>/dev/null
885
886 # Depends gets nuked, so update them
887 # (this problem should be solved now, but i think it will be a good idea
888 # to recreate the deps after a change in runlevel)
889
890 #/sbin/depscan.sh &>/dev/null
891
892 # We want devfsd running after a change of runlevel (this is mostly if we return
893 # from runlevel 'single')
894 if [ -z "`ps --no-heading -C 'devfsd'`" -a \
895 -n "`gawk '/\/dev devfs/ { print }' /proc/mounts 2>/dev/null`" ]
896 then
897 if [ "${RC_DEVFSD_STARTUP}" != "no" ]
898 then
899 /sbin/devfsd /dev &>/dev/null
900 fi
901 fi
902
903 # Runlevel end, so clear stale fail list
904 rm -rf "${svcdir}/failed" &>/dev/null
905
906 # If we were in the boot runlevel, it is done now ...
907 if [[ -n ${BOOT} ]]; then
908 unset BOOT
909 # Save our interactive mode into the default runlevel
910 user_want_interactive && svcinteractive="yes"
911 echo "${svcinteractive}" > "${svcdir}/interactive"
912 else
913 # As we're not boot, we remove the interactive file
914 [[ -e "${svcdir}/interactive" ]] && rm -f "${svcdir}/interactive"
915 fi
916
917 # Remove the cached CONSOLETYPE
918 unset CONSOLETYPE
919
920 splash "rc_exit"
921
922 # 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