/[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 1534 - (show annotations) (download)
Tue Sep 13 23:24:39 2005 UTC (8 years, 10 months ago) by vapier
File size: 24808 byte(s)
dont mount $svcdir with -n since /etc/mtab is writable
1 #!/sbin/runscript
2 # Copyright 1999-2005 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 try() {
12 local errstr
13 local retval=0
14
15 if [ -c /dev/null ]; then
16 errstr="$((eval $*) 2>&1 >/dev/null)"
17 else
18 errstr="$((eval $*) 2>&1)"
19 fi
20 retval=$?
21 if [ "${retval}" -ne 0 ]
22 then
23 splash "critical" &
24
25 echo -e "${ENDCOL}${NORMAL}[${BAD} oops ${NORMAL}]"
26 echo
27 eerror "The \"${1}\" command failed with error:"
28 echo
29 echo "${errstr#*: }"
30 echo
31 eerror "Since this is a critical task, startup cannot continue."
32 echo
33 /sbin/sulogin ${CONSOLE}
34 einfo "Unmounting filesystems"
35 if [ -c /dev/null ]; then
36 /bin/mount -a -o remount,ro &>/dev/null
37 else
38 /bin/mount -a -o remount,ro
39 fi
40 einfo "Rebooting"
41 /sbin/reboot -f
42 fi
43
44 return ${retval}
45 }
46
47 # Check that $1 exists ...
48 check_statedir() {
49 [ -z "$1" ] && return 0
50
51 if [ ! -d "$1" ] ; then
52 if ! mkdir -p "$1" &>/dev/null ; then
53 splash "critical" &
54 echo
55 eerror "For Gentoo to function properly, \"$1\" needs to exist."
56 if [[ ${RC_FORCE_AUTO} == "yes" ]] ; then
57 eerror "Attempting to create \"$1\" for you ..."
58 mount -o remount,rw /
59 mkdir -p "$1"
60 else
61 eerror "Please mount your root partition read/write, and execute:"
62 echo
63 eerror " # mkdir -p $1"
64 echo; echo
65 /sbin/sulogin ${CONSOLE}
66 fi
67 einfo "Unmounting filesystems"
68 /bin/mount -a -o remount,ro &>/dev/null
69 einfo "Rebooting"
70 /sbin/reboot -f
71 fi
72 fi
73
74 return 0
75 }
76
77 udev_version() {
78 local version=0
79
80 if [ -x "/sbin/udev" ]
81 then
82 version=$(/sbin/udev -V)
83 # We need it without a leading '0', else bash do the wrong thing
84 version="${version##0}"
85 # Older udev's will print nothing
86 [ -z "${version}" ] && version=0
87 fi
88
89 echo "${version}"
90 }
91
92 # void noblock_read(var)
93 #
94 # reads a line of input into var like regular read
95 # but it does not block waiting for input
96 #
97 noblock_read() {
98 local old_tty_settings="$(stty -g)"
99 stty -icanon min 0 time 0
100 read "$@"
101 stty "${old_tty_settings}"
102 }
103
104 # bool user_want_interactive(void)
105 #
106 # return 0 if user wants interactive mode
107 #
108 user_want_interactive() {
109 local user_input
110 noblock_read user_input
111 [[ ${user_input} == *"I"* || ${user_input} == *"i"* ]]
112 }
113
114 # void do_interactive
115 #
116 # starts, skips, continues or drops to the shell
117 # depending on user selection
118 #
119 do_interactive() {
120 local service="$1"
121 shift
122
123 local start_text="Start service"
124 local skip_text="Skip service"
125 local continue_text="Continue boot process"
126 local shell_text="Exit to shell"
127
128 echo
129 echo "About to start the service ${service}"
130 PS3="Enter your selection: "
131 select action in "${start_text}" "${skip_text}" "${continue_text}" \
132 "${shell_text}"
133 do
134 case ${action} in
135 "${start_text}")
136 "$@"
137 break
138 ;;
139 "${skip_text}")
140 break
141 ;;
142 "${continue_text}")
143 interactive="no"
144 "$@"
145 break
146 ;;
147 "${shell_text}")
148 echo
149 sulogin "${CONSOLE}"
150 ;;
151 esac
152 done
153 }
154
155 populate_udev() {
156 # Now populate /dev
157 /sbin/udevstart
158
159 # Not provided by sysfs but needed
160 ln -snf /proc/self/fd /dev/fd
161 ln -snf fd/0 /dev/stdin
162 ln -snf fd/1 /dev/stdout
163 ln -snf fd/2 /dev/stderr
164 [ -e /proc/kcore ] && ln -snf /proc/kcore /dev/core
165
166 # Create nodes that udev can't
167 [ -x /sbin/dmsetup ] && /sbin/dmsetup mknodes &>/dev/null
168 [ -x /sbin/lvm ] && /sbin/lvm vgscan -P --mknodes --ignorelockingfailure &>/dev/null
169 [ -x /sbin/evms_activate ] && /sbin/evms_activate -q &>/dev/null
170
171 # Create problematic directories
172 mkdir -p /dev/{pts,shm}
173
174 # Same thing as /dev/.devfsd
175 touch /dev/.udev
176
177 return 0
178 }
179
180 get_critical_services() {
181 local x=
182 CRITICAL_SERVICES=
183
184 if [ -f "/etc/runlevels/${BOOTLEVEL}/.critical" ]
185 then
186 for x in $(< /etc/runlevels/${BOOTLEVEL}/.critical)
187 do
188 CRITICAL_SERVICES="${CRITICAL_SERVICES} ${x##*/}"
189 done
190 else
191 CRITICAL_SERVICES="checkroot hostname modules checkfs localmount clock"
192 fi
193
194 export CRITICAL_SERVICES
195
196 return 0
197 }
198
199 # Save $1
200 argv1="$1"
201
202 # First time boot stuff goes here. Note that 'sysinit' is an internal runlevel
203 # used to bring up local filesystems, and should not be started with /sbin/rc
204 # directly ...
205 if [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} = "sysinit" ]]
206 then
207 # Setup initial $PATH just in case
208 PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
209
210 # Help users recover their systems incase these go missing
211 [ -c /dev/null ] && dev_null=1 || dev_null=0
212 [ -c /dev/console ] && dev_console=1 || dev_console=0
213
214 echo
215 echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; ${BRACKET}http://www.gentoo.org/${NORMAL}"
216 echo -e " Copyright 1999-2005 Gentoo Foundation; Distributed under the GPLv2"
217 echo
218 echo -e "Press ${GOOD}I${NORMAL} to enter interactive boot mode"
219 echo
220 check_statedir /proc
221
222 ebegin "Mounting proc at /proc"
223 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
224 mntcmd=$(get_mount_fstab /proc)
225 else
226 unset mntcmd
227 fi
228 try mount -n ${mntcmd:--t proc proc /proc}
229 eend $?
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}
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" || \
294 [ ! -x /sbin/udev -o -e "/dev/.devfsd" ] || \
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 then
306 devfs="no"
307 fi
308 fi
309
310 # Actually start setting up /dev now
311 if [[ ${udev} = "yes" ]] ; then
312 # Setup temporary storage for /dev
313 ebegin "Mounting /dev for udev"
314 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
315 mntcmd=$(get_mount_fstab /dev)
316 else
317 unset mntcmd
318 fi
319 if [[ -n ${mntcmd} ]] ; then
320 try mount -n ${mntcmd}
321 else
322 if egrep -qs tmpfs /proc/filesystems ; then
323 mntcmd="tmpfs"
324 else
325 mntcmd="ramfs"
326 fi
327 # many video drivers require exec access in /dev #92921
328 try mount -n -t ${mntcmd} udev /dev -o exec,nosuid,mode=0755
329 fi
330 eend $?
331
332 # Selinux lovin; /selinux should be mounted by selinux-patched init
333 if [[ -x /sbin/restorecon ]] && [[ -c /selinux/null ]] ; then
334 restorecon /dev &> /selinux/null
335 fi
336
337 # Actually get udev rolling
338 ebegin "Configuring system to use udev"
339 if [[ ${RC_DEVICE_TARBALL} = "yes" ]] && [[ -s /lib/udev-state/devices.tar.bz2 ]]
340 then
341 einfo " Populating /dev with device nodes ..."
342 try tar -jxpf /lib/udev-state/devices.tar.bz2 -C /dev
343 fi
344 populate_udev
345
346 # Setup hotplugging (if possible)
347 if [ -e /proc/sys/kernel/hotplug ] ; then
348 if [ "$(udev_version)" -ge "48" ] ; then
349 einfo " Setting /sbin/udevsend as hotplug agent ..."
350 echo "/sbin/udevsend" > /proc/sys/kernel/hotplug
351 elif [ -x /sbin/hotplug ] ; then
352 einfo " Using /sbin/hotplug as hotplug agent ..."
353 else
354 einfo " Setting /sbin/udev as hotplug agent ..."
355 echo "/sbin/udev" > /proc/sys/kernel/hotplug
356 fi
357 fi
358 eend 0
359
360 # With devfs, /dev can be mounted by the kernel ...
361 elif [ "${devfs}" = "yes" ]
362 then
363 mymounts="$(awk '($2 == "devfs") { print "yes"; exit 0 }' /proc/filesystems)"
364 # Is devfs support compiled in?
365 if [ "${mymounts}" = "yes" ]
366 then
367 if [ "${devfs_automounted}" = "no" ]
368 then
369 ebegin "Mounting devfs at /dev"
370 try mount -n -t devfs devfs /dev
371 eend $?
372 else
373 ebegin "Kernel automatically mounted devfs at /dev"
374 eend 0
375 fi
376 ebegin "Starting devfsd"
377 /sbin/devfsd /dev >/dev/null
378 eend $? "Could not start /sbin/devfsd"
379 else
380 devfs="no"
381 fi
382
383 # Did the user want udev in the config file but for
384 # some reason, udev support didnt work out ?
385 if [ "${fellback_to_devfs}" = "yes" ]
386 then
387 ewarn "You wanted udev but support for it was not available!"
388 ewarn "Please review your system after it's booted!"
389 fi
390 fi
391
392 # OK, if we got here, things are probably not right :)
393 if [ "${devfs}" = "no" ] && [ "${udev}" = "no" ]
394 then
395 clear
396 echo
397 einfo "The Gentoo Linux system initialization scripts have detected that"
398 einfo "your system does not support DEVFS or UDEV. Since Gentoo Linux"
399 einfo "has been designed with these dynamic /dev managers in mind, it is"
400 einfo "highly suggested that you build support for it into your kernel."
401 einfo "Please read the Gentoo Handbook for more information!"
402 echo
403 einfo " http://www.gentoo.org/doc/en/handbook/"
404 echo
405 einfo "Thanks for using Gentoo! :)"
406 echo
407 read -t 15 -p "(hit Enter to continue or wait 15 seconds ...)"
408 fi
409 fi
410
411 # From linux-2.5.68 we need to mount /dev/pts again ...
412 if [ "$(get_KV)" -ge "$(KV_to_int '2.5.68')" ]
413 then
414 have_devpts="$(awk '($2 == "devpts") { print "yes"; exit 0 }' /proc/filesystems)"
415
416 if [ "${have_devpts}" = "yes" ]
417 then
418 # Only try to create /dev/pts if we have /dev mounted dynamically,
419 # else it might fail as / might be still mounted readonly.
420 if [ ! -d /dev/pts ] && \
421 [ "${devfs}" = "yes" -o "${udev}" = "yes" ]
422 then
423 # Make sure we have /dev/pts
424 mkdir -p /dev/pts &>/dev/null || \
425 ewarn "Could not create /dev/pts!"
426 fi
427
428 if [[ -d /dev/pts ]] ; then
429 ebegin "Mounting devpts at /dev/pts"
430 if [[ ${RC_USE_FSTAB} = "yes" ]] ; then
431 mntcmd=$(get_mount_fstab /dev/pts)
432 else
433 unset mntcmd
434 fi
435 try mount -n ${mntcmd:--t devpts -o gid=5,mode=0620 devpts /dev/pts}
436 eend $?
437 fi
438 fi
439 fi
440
441 # Start logging console output since we have all /dev stuff setup
442 bootlog start
443
444 # Swap needs to be activated *after* /dev has been fully setup so that
445 # the fstab can be properly parsed. This first pass we send to /dev/null
446 # in case the user has swap points setup on different partitions. We
447 # will run swapon again in localmount and that one will report errors.
448 ebegin "Activating (possible) swap"
449 /sbin/swapon -a >& /dev/null
450 eend 0
451
452 # Set the console loglevel to 1 for a cleaner boot
453 # the logger should anyhow dump the ring-0 buffer at start to the
454 # logs, and that with dmesg can be used to check for problems
455 /bin/dmesg -n 1
456
457 # We set the forced softlevel from the kernel command line
458 # It needs to be run right after proc is mounted for the
459 # boot runlevel
460 setup_defaultlevels
461
462 # $BOOT can be used by rc-scripts to test if it is the first time
463 # the 'boot' runlevel is executed. Now also needed by some stuff in
464 # the 'sysinit' runlevel ...
465 export BOOT="yes"
466
467 start_critical_service() {
468 (
469 local retval=
470 local service=$1
471 # Needed for some addons like dm-crypt that starts in critical services
472 local myservice=$1
473
474 source "/etc/init.d/${service}" || eerror "Failed to source /etc/init.d/${service}"
475 retval=$?
476 [ "${retval}" -ne 0 ] && return "${retval}"
477 [ -e "/etc/conf.d/${service}" ] && source "/etc/conf.d/${service}"
478 source /etc/rc.conf
479
480 start || eerror "Failed to start /etc/init.d/${service}"
481 retval=$?
482
483 return "${retval}"
484 )
485 }
486
487 # We first try to find a locally defined list of critical services
488 # for a particular runlevel. If we cannot find it, we use the
489 # defaults.
490 get_critical_services
491
492 splash "rc_init" "${argv1}"
493
494 export START_CRITICAL="yes"
495
496 # We do not want to break compatibility, so we do not fully integrate
497 # these into /sbin/rc, but rather start them by hand ...
498 for x in ${CRITICAL_SERVICES}
499 do
500 splash "svc_start" "${x}"
501 user_want_interactive && interactive="yes"
502 if ! start_critical_service "${x}" ; then
503 splash "critical" &>/dev/null &
504
505 echo
506 eerror "One of more critical startup scripts failed to start!"
507 eerror "Please correct this, and reboot ..."
508 echo; echo
509 /sbin/sulogin ${CONSOLE}
510 einfo "Unmounting filesystems"
511 /bin/mount -a -o remount,ro &>/dev/null
512 einfo "Rebooting"
513 /sbin/reboot -f
514 fi
515
516 splash "svc_started" "${x}" "0"
517 done
518
519 unset START_CRITICAL
520
521 # /var/log should be writable now, so starting saving the boot output
522 bootlog sync
523
524 # have to run this after /var/run is mounted rw #85304
525 if [ -x /sbin/irqbalance -a "$(get_KV)" -ge "$(KV_to_int '2.5.0')" ]
526 then
527 ebegin "Starting irqbalance"
528 /sbin/irqbalance
529 eend $?
530 fi
531
532 # Check that $svcdir exists ...
533 check_statedir "${svcdir}"
534
535 # Should we use tmpfs/ramfs/ramdisk for caching dependency and
536 # general initscript data? Note that the 'gentoo=<fs>' kernel
537 # option should override any other setting ...
538 for fs in tmpfs ramfs ramdisk
539 do
540 if get_bootparam "${fs}"
541 then
542 svcmount="yes"
543 svcfstype="${fs}"
544 break
545 fi
546 done
547 if [ "${svcmount}" = "yes" ]
548 then
549 ebegin "Mounting ${svcfstype} at ${svcdir}"
550 case "${svcfstype}" in
551 ramfs)
552 try mount -t ramfs svcdir "${svcdir}" \
553 -o rw,mode=0755,size="${svcsize}"k
554 ;;
555 ramdisk)
556 try dd if=/dev/zero of=/dev/ram0 bs=1k count="${svcsize}"
557 try /sbin/mke2fs -i 1024 -vm0 /dev/ram0 "${svcsize}"
558 try mount -t ext2 /dev/ram0 "${svcdir}" -o rw
559 ;;
560 tmpfs|*)
561 try mount -t tmpfs svcdir "${svcdir}" \
562 -o rw,mode=0755,size="${svcsize}"k
563 ;;
564 esac
565 eend 0
566 fi
567
568 # If booting off CD, we want to update inittab before setting the runlevel
569 if [ -f "/sbin/livecd-functions.sh" -a -n "${CDBOOT}" ]
570 then
571 ebegin "Updating inittab"
572 livecd_fix_inittab
573 eend $?
574 /sbin/telinit q &>/dev/null
575 fi
576
577 # Clear $svcdir from stale entries, but leave the caches around, as it
578 # should help speed things up a bit
579 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
580 grep -ve '\(depcache\|deptree\|envcache\)')
581
582 echo "sysinit" > "${svcdir}/softlevel"
583 echo "${interactive}" > "${svcdir}/interactive"
584
585 # Update the dependency cache
586 /sbin/depscan.sh -u
587
588 # Now that the dependency cache are up to date, make sure these
589 # are marked as started ...
590 (
591 # Needed for mark_service_started()
592 source "${svclib}/sh/rc-services.sh"
593
594 for x in ${CRITICAL_SERVICES}
595 do
596 mark_service_started "${x}"
597 done
598 )
599
600 # If the user's /dev/null or /dev/console are missing, we
601 # should help them out and explain how to rectify the situation
602 if [ ${dev_null} -eq 0 -o ${dev_console} -eq 0 ] \
603 && [ -e /usr/share/baselayout/issue.devfix ]
604 then
605 # Backup current /etc/issue
606 if [ -e /etc/issue -a ! -e /etc/issue.devfix ]
607 then
608 mv /etc/issue /etc/issue.devfix
609 fi
610
611 cp /usr/share/baselayout/issue.devfix /etc/issue
612 fi
613
614 # Setup login records ... this has to be done here because when
615 # we exit this runlevel, init will write a boot record to utmp
616 # If /var/run is readonly, then print a warning, not errors
617 if touch /var/run/utmp 2>/dev/null
618 then
619 > /var/run/utmp
620 touch /var/log/wtmp
621 chgrp utmp /var/run/utmp /var/log/wtmp
622 chmod 0664 /var/run/utmp /var/log/wtmp
623 # Remove /var/run/utmpx (bug from the past)
624 rm -f /var/run/utmpx
625 else
626 ewarn "Skipping /var/run/utmp initialization (ro root?)"
627 fi
628
629 # All done logging
630 bootlog quit
631
632 exit 0
633 fi # Sysinit ends here
634
635 if [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} == "boot" ]]
636 then
637 setup_defaultlevels
638
639 if [ -n "${DEFAULTLEVEL}" -a "${DEFAULTLEVEL}" != "default" ]
640 then
641 # Setup our default runlevel runlevel that will be run
642 # the first time /sbin/rc is called with argv1 != sysinit|boot
643 echo "${DEFAULTLEVEL}" > "${svcdir}/ksoftlevel"
644 fi
645
646 # $BOOT can be used by rc-scripts to test if it is the first time
647 # the 'boot' runlevel is executed
648 export BOOT="yes"
649
650 # We reset argv1 to the bootlevel given on the kernel command line
651 # if there is one
652 argv1="${BOOTLEVEL}"
653
654 elif [[ ${RUNLEVEL} != "S" && ${RUNLEVEL} != "1" && -e ${svcdir}/ksoftlevel ]]
655 then
656 argv1="$(< ${svcdir}/ksoftlevel)"
657 rm -f "${svcdir}/ksoftlevel"
658 elif [[ ${RUNLEVEL} != "S" && ${RUNLEVEL} != "1" && ${argv1} == "single" ]]
659 then
660 /sbin/telinit S
661 exit 0
662 elif [[ ( ${RUNLEVEL} == "S" || ${RUNLEVEL} == "1" ) && ${argv1} != "single" ]]
663 then
664 level=$(awk -v level="${argv1}" '
665 $2 == level {
666 split($0, fields, ":")
667 print fields[2]
668 exit
669 }' /etc/inittab 2>/dev/null)
670 [[ -z ${level} ]] && level=3
671 /sbin/telinit "${level}"
672 exit 0
673 fi
674
675 source "${svclib}/sh/rc-services.sh"
676
677 if [ -f "${svcdir}/softlevel" ]
678 then
679 # Set OLDSOFTLEVEL if we had a valid SOFTLEVEL
680 export OLDSOFTLEVEL="$(< ${svcdir}/softlevel)"
681 else
682 export OLDSOFTLEVEL=
683 fi
684
685 if [ -z "${argv1}" ]
686 then
687 if [ -f "${svcdir}/softlevel" ]
688 then
689 export SOFTLEVEL="$(< ${svcdir}/softlevel)"
690 else
691 export SOFTLEVEL="${BOOTLEVEL}"
692 fi
693 else
694 export SOFTLEVEL="${argv1}"
695 fi
696
697 if [ ! -f "${svcdir}/softlevel" ]
698 then
699 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
700 fi
701
702 # For keeping a list of services that fails during boot/halt
703 if [ ! -d "${svcdir}/failed" ]
704 then
705 mkdir -p -m 0755 "${svcdir}/failed"
706 else
707 rm -rf "${svcdir}"/failed/*
708 fi
709
710 splash "rc_init" "${argv1}"
711
712 if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
713 then
714 myscripts=
715
716 elif [ "${SOFTLEVEL}" = "single" ]
717 then
718 get_critical_services
719
720 myscripts="${CRITICAL_SERVICES}"
721
722 elif [ ! -d "/etc/runlevels/${SOFTLEVEL}" ]
723 then
724 eerror "ERROR: runlevel ${SOFTLEVEL} does not exist; exiting ..."
725 exit 1
726 else
727 myscripts=
728 if [ "${SOFTLEVEL}" != "${BOOTLEVEL}" ]
729 then
730 # Normal runlevels *include* boot scripts
731 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
732 mylevels="${mylevels} $(dolisting /etc/runlevels/${BOOTLEVEL}/)"
733 else
734 # Non-normal runlevels don't include boot scripts as default
735 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
736 fi
737
738 [ "${OLDSOFTLEVEL}" = "${BOOTLEVEL}" -o "${OLDSOFTLEVEL}" = "single" ] \
739 && /bin/dmesg -n 1
740
741 for x in ${mylevels}
742 do
743 [ -L "${x}" ] && myscripts="${myscripts} ${x##*/}"
744 done
745 fi
746
747 # The softscripts dir contains all scripts that belong to the
748 # runlevel specified in ${svcdir}/softlevel
749 # It needs to be a new directory, else when stopping the services
750 # and the old directory is not intact, things get broken
751
752 mkdir -p -m 0755 "${svcdir}/softscripts.new"
753
754 for x in ${myscripts} ; do
755 if [[ ! -e /etc/init.d/${x} ]] ; then
756 ewarn "WARNING: /etc/init.d/${x} missing; skipping ..."
757 continue
758 fi
759 # The -f eliminates a warning if the symlink already exists,
760 # which can happen if a service is in both the boot level and
761 # the current "normal" runlevel
762 ln -snf "/etc/init.d/${x}" "${svcdir}/softscripts.new/${x}"
763 done
764
765 get_stop_services() {
766 local x list
767
768 for x in $(dolisting "${svcdir}/inactive/") \
769 $(dolisting "${svcdir}/started/") ; do
770 list="${list} ${x##*/}"
771 done
772
773 reverse_list $(trace_dependencies ${list})
774 }
775
776 dep_stop() {
777 local x dep needsme depservice
778 local myservice=${1##*/}
779
780 service_stopped "${myservice}" && return 0
781
782 # Candidate for zapping ?
783 [[ ! -L ${svcdir}/softscripts.new/${myservice} ]] || \
784 return 0
785
786 # If this is a 'net' service, we do not want to stop it if it was
787 # not in the previous runlevel, and we are not shutting down,
788 # rebooting or going to single runlevel. This is because the user
789 # (or hotplut) might have started it (net.ppp?) ...
790 if net_service "${myservice}" && \
791 [[ ${SOFTLEVEL} != "reboot" && \
792 ${SOFTLEVEL} != "shutdown" && \
793 ${SOFTLEVEL} != "single" ]] ; then
794 if [[ -z ${OLDSOFTLEVEL} ]] || \
795 ! in_runlevel "${myservice}" "${OLDSOFTLEVEL}"
796 then
797 # This service is not in the previous runlevel, so
798 # do not stop it ...
799 return 0
800 fi
801 fi
802
803 # Should not work for 'use'
804 if [[ -z $(needsme "${myservice}") ]] ; then
805 # Nothing depends on me
806 stop_service "${myservice}"
807 else
808 # Something may depend on me
809 needsme=0
810
811 for dep in $(needsme "${myservice}") ; do
812 #if service_started "${dep}" && \
813 if [[ -L "${svcdir}/softscripts.new/${dep}" ]] ; then
814 # This dep is valid
815 needsme=1
816
817 break
818 fi
819 done
820
821 [[ ${needsme} -eq 0 ]] && stop_service "${myservice}"
822 fi
823 }
824
825 # Stop services
826 if [[ ${SOFTLEVEL} != "single" && \
827 ${SOFTLEVEL} != "reboot" && \
828 ${SOFTLEVEL} != "shutdown" ]]
829 then
830 for i in $(get_stop_services) ; do
831 dep_stop "${i}"
832 done
833
834 # Wait for any services that may still be stopping ...
835 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
836 else
837 get_critical_services
838
839 is_critical_service() {
840 local x
841 local myservice=${1##*/}
842
843 for x in ${CRITICAL_SERVICES} ${LOGGER_SERVICE} ; do
844 [[ ${myservice} == "${x}" ]] && return 0
845 done
846
847 return 1
848 }
849
850 # First stop non critical services
851 for i in $(get_stop_services) ; do
852 is_critical_service "${i}" || dep_stop "${i}"
853 done
854
855 # Wait for any services that may still be stopping ...
856 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
857
858 export STOP_CRITICAL="yes"
859 # Now stop the rest
860 for i in $(get_stop_services) ; do
861 dep_stop "${i}"
862 done
863 unset STOP_CRITICAL
864 fi
865
866 # Only change softlevel AFTER all the services have been stopped,
867 # else they will not get the depend's right (wrong SOFTLEVEL)
868
869 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
870
871 if [[ ${SOFTLEVEL} == "reboot" || ${SOFTLEVEL} == "shutdown" ]] ; then
872 source /sbin/functions.sh
873
874 # Clear $svcdir from stale entries, but leave the caches around, as it
875 # should help speed things up a bit
876 rm -rf $(ls -d1 "${svcdir}/"* 2>/dev/null | \
877 grep -ve '\(depcache\|deptree\|envcache\)')
878
879 source /etc/init.d/halt.sh
880
881 if [[ ${SOFTLEVEL} == "reboot" ]] ; then
882 source /etc/init.d/reboot.sh
883 else
884 source /etc/init.d/shutdown.sh
885 fi
886
887 # Should never get here
888 exit 0
889 fi
890
891 if [[ ${SOFTLEVEL} == "single" ]] ; then
892 /sbin/sulogin ${CONSOLE}
893 exit 0
894 fi
895
896 # Move the old softscritps directory to a different one
897 # and make the new softscripts directory the current
898
899 mv -f "${svcdir}/softscripts" "${svcdir}/softscripts.old"
900 mv -f "${svcdir}/softscripts.new" "${svcdir}/softscripts"
901
902 get_start_services() {
903 local x list
904
905 get_critical_services
906 list=${CRITICAL_SERVICES}
907
908 [[ -n ${LOGGER_SERVICE} && \
909 -L ${svcdir}/softscripts/${LOGGER_SERVICE} ]] && \
910 list="${list} ${LOGGER_SERVICE}"
911
912 for x in $(dolisting "${svcdir}/softscripts/") ; do
913 list="${list} ${x##*/}"
914 done
915
916 trace_dependencies ${list}
917 }
918
919 [[ -e "${svcdir}/interactive" ]] \
920 && interactive="$(<"${svcdir}/interactive")"
921
922 # Start scripts
923 for i in $(get_start_services) ; do
924 if service_stopped "${i}" ; then
925 user_want_interactive && interactive="yes"
926 if [[ ${interactive} == "yes" ]]; then
927 do_interactive "${i}" start_service "${i}"
928 else
929 start_service "${i}"
930 fi
931 fi
932 done
933
934 # Wait for any services that may still be running ...
935 [ "${RC_PARALLEL_STARTUP}" = "yes" ] && wait
936
937 # Clean the old runlevel
938 rm -rf "${svcdir}/softscripts.old" &>/dev/null
939
940 # Depends gets nuked, so update them
941 # (this problem should be solved now, but i think it will be a good idea
942 # to recreate the deps after a change in runlevel)
943
944 #/sbin/depscan.sh &>/dev/null
945
946 # We want devfsd running after a change of runlevel (this is mostly if we return
947 # from runlevel 'single')
948 if [ -z "`ps --no-heading -C 'devfsd'`" -a \
949 -n "`gawk '/\/dev devfs/ { print }' /proc/mounts 2>/dev/null`" ]
950 then
951 if [ "${RC_DEVFSD_STARTUP}" != "no" ]
952 then
953 /sbin/devfsd /dev &>/dev/null
954 fi
955 fi
956
957 # Runlevel end, so clear stale fail list
958 rm -rf "${svcdir}/failed" &>/dev/null
959
960 # If we were in the boot runlevel, it is done now ...
961 if [[ -n ${BOOT} ]]; then
962 unset BOOT
963 # Save our interactive mode into the default runlevel
964 echo "${interactive}" > "${svcdir}/interactive"
965 else
966 # As we're not boot, we remove the interactive file
967 [[ -e "${svcdir}/interactive" ]] && rm -f "${svcdir}/interactive"
968 fi
969
970 # Remove the cached CONSOLETYPE
971 unset CONSOLETYPE
972
973 splash "rc_exit"
974
975 # 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