/[baselayout]/trunk/sbin/rc
Gentoo

Contents of /trunk/sbin/rc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 346 - (show annotations) (download)
Mon Apr 7 02:49:43 2003 UTC (16 years, 1 month ago) by azarah
File size: 11913 byte(s)
new release

1 #!/bin/bash
2 # Copyright 1999-2003 Gentoo Technologies, Inc.
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header$
5
6
7 trap ":" INT QUIT TSTP
8 source /sbin/functions.sh
9 umask 022
10
11 try() {
12 local retval=0
13 # This works fine in test, but real life booting, fails for mounting /proc
14 # if we only check $? for instance ... We thus need to [ -n "${errstr}" ]
15 # as well.
16 local errstr
17 errstr="`(eval $*) 2>&1 >/dev/null`"
18 retval=$?
19 if [ "${retval}" -ne 0 ] || \
20 ([ -n "`echo "$*" | gawk '/mount/ { print "yes" }'`" -a -n "${errstr}" ])
21 then
22 echo -e "${ENDCOL}${NORMAL}[${BAD} oops ${NORMAL}]"
23 echo
24 eerror "The \"${1}\" command failed with error:"
25 echo
26 echo "${errstr#*: }"
27 echo
28 eerror "Since this is a critical task, startup cannot continue."
29 echo
30 /sbin/sulogin ${CONSOLE}
31 einfo "Unmounting filesystems"
32 /bin/mount -a -o remount,ro & >/dev/null
33 einfo "Rebooting"
34 /sbin/reboot -f
35 fi
36 return ${retval}
37 }
38
39 # Check that $svcdir exists ...
40 check_statedir() {
41 if [ ! -d "${svcdir}" ]
42 then
43 if ! mkdir -p "${svcdir}" &> /dev/null
44 then
45 echo
46 eerror "For Gentoo Linux to function properly, \"${svcdir}\" need to exist."
47 eerror "Please mount your root partition read/write, and execute:"
48 echo
49 eerror " # mkdir -p ${svcdir}"
50 echo; echo
51 /sbin/sulogin ${CONSOLE}
52 einfo "Unmounting filesystems"
53 /bin/mount -a -o remount,ro & >/dev/null
54 einfo "Rebooting"
55 /sbin/reboot -f
56 fi
57 fi
58 }
59
60 # Save $1
61 argv1="$1"
62
63 # First time boot stuff goes here. Note that 'sysinit' is an internal runlevel
64 # used to bring up local filesystems, and should not be started with /sbin/rc
65 # directly ...
66 if [ "${RUNLEVEL}" = "S" -a "${argv1}" = "sysinit" ]
67 then
68 # Setup initial $PATH just in case
69 PATH="/bin:/sbin:/usr/bin:/usr/sbin:${PATH}"
70
71 echo
72 echo -e "${GOOD}Gentoo Linux${GENTOO_VERS}; \e[34;01mhttp://www.gentoo.org/${NORMAL}"
73 echo -e " Copyright 2001-2003 Gentoo Technologies, Inc.; Distributed under the GPL"
74 echo
75
76 ebegin "Mounting /proc"; \
77 try mount -n /proc; \
78 eend $?
79
80 if [ "$(get_KV)" -ge "$(KV_to_int '2.5.0')" -a -d /sys ]
81 then
82 ebegin "Mounting /sys"
83 mount -t sysfs none /sys
84 eend $?
85 fi
86
87 # Check if the user disabled devfs
88 devfs="yes"
89 get_bootparam "nodevfs"
90 if [ "$?" -eq 0 ]
91 then
92 devfs="no"
93 fi
94
95 # Fix weird bug where there is a /dev/.devfsd in a unmounted /dev
96 mymounts="`awk '($3 == "devfs") { print "yes"; exit 0 }' /proc/mounts`"
97 if [ -e "/dev/.devfsd" -a "${mymounts}" != "yes" ]
98 then
99 rm -f /dev/.devfsd
100 fi
101
102 # With the new way, /dev can be mounted by the kernel ...
103 if [ "${devfs}" = "yes" -a ! -e "/dev/.devfsd" ]
104 then
105 mymounts="`awk '($2 == "devfs") { print "yes"; exit 0 }' /proc/filesystems`"
106 # Is devfs support compiled in?
107 if [ "${mymounts}" = "yes" ]
108 then
109 ebegin "Mounting devfs at /dev"; \
110 try mount -n -t devfs none /dev; \
111 eend $?
112 else
113 clear
114 echo
115 einfo "The Gentoo Linux system initialization scripts have detected that your"
116 einfo "kernel has been compiled without DEVFS support. Because Gentoo Linux"
117 einfo "has been designed to work with DEVFS, it is required that you compile"
118 einfo "support for it into your kernel. Please read the 'Gentoo Linux from"
119 einfo "source (build) CD Installation Guide' at:"
120 echo
121 einfo " http://www.gentoo.org/doc/build.html"
122 echo
123 einfo "for more information on how to do this."
124 echo
125 read -t 15 -p "(hit Enter to continue or wait 15 seconds...)"
126 fi
127 fi
128
129 # Need devfsd running now so that /dev/ram0 exists if we need it
130 mymounts="`awk '($3 == "devfs") { print "yes"; exit 0 }' /proc/mounts`"
131 if [ "${devfs}" = "yes" -a -e "/dev/.devfsd" -a \
132 "${mymounts}" = "yes" ]
133 then
134 ebegin "Starting devfsd"
135 /sbin/devfsd /dev > /dev/null
136 eend $?
137 fi
138
139 # Mount either a ramdisk or tmpfs if requested.
140 # we do this to temp mount, until we can get /var mounted ...
141 tsvcdir="/mnt/.init.d"
142
143 # Should we use tmpfs or a ramdisk for caching dependency and
144 # general initscript data? Note that the 'gentoo=tmpfs' kernel
145 # option should override most settings ...
146 if get_bootparam "tmpfs" || \
147 [ "${svcmount}" = "yes" -a "${svcfstype}" = "tmpfs" ]
148 then
149 mkdir -p "${tsvcdir}"
150
151 ebegin "Mounting tmpfs at ${tsvcdir}"
152 try mount -n -t tmpfs tmpfs "${tsvcdir}" \
153 -o rw,mode=0644,size="${svcsize}"k
154 eend 0
155
156 elif get_bootparam "ramfs" || \
157 [ "${svcmount}" = "yes" -a "${svcfstype}" = "ramfs" ]
158 then
159 mkdir -p "${tsvcdir}"
160
161 ebegin "Mounting ramdisk 0 at ${tsvcdir}"
162 try dd if=/dev/zero of=/dev/ram0 bs=1k count="${svcsize}"
163 try /sbin/mke2fs -i 1024 -vm0 /dev/ram0 "${svcsize}"
164 try mount -n -t ext2 /dev/ram0 "${tsvcdir}" -o rw
165 eend 0
166 fi
167
168 if get_bootparam "adelie"
169 then
170 einfo "Server/Node low-level initialisation..."
171
172 # Saving the kernel attributed hostname to a file for future
173 # initialisation selection: see /etc/init.d/switch.
174 cat /proc/sys/kernel/hostname > "${svcdir}/hostname"
175
176 if checkserver
177 then
178 # For server we do pretty much a standard boot ...
179 einfo "Server detected."
180 else
181 #
182 # Low-level Node Initialisation
183 #
184 einfo "Node detected."
185
186 init_node
187 fi
188 fi
189
190 # If a Adelie server, or normal Gentoo box, init swap ...
191 if checkserver
192 then
193 # Swap needs to be activated *after* devfs has been mounted and *after*
194 # devfsd has been started, so that the fstab can be properly parsed
195 # and only if the server/Gentoo box is initialized ...
196 ebegin "Activating swap"
197 /sbin/swapon -a &> /dev/null
198 eend 0
199 fi
200
201 # Set the console loglevel to 1 for a cleaner boot
202 # the logger should anyhow dump the ring-0 buffer at start to the
203 # logs, and that with dmesg can be used to check for problems
204 /bin/dmesg -n 1
205
206 # $BOOT can be used by rc-scripts to test if it is the first time
207 # the 'boot' runlevel is executed. Now also needed by some stuff in
208 # the 'sysinit' runlevel ...
209 export BOOT="yes"
210
211 # We do not want to break compadibility, so we do not fully integrate
212 # these into /sbin/rc, but rather start them by hand ...
213 for x in checkroot hostname modules checkfs localmount
214 do
215 source "/etc/init.d/${x}" || error "Failed to source /etc/init.d/${x}"
216 start || eerror "Failed to start /etc/init.d/${x}"
217
218 if [ "$?" -ne 0 ]
219 then
220 echo
221 eerror "One of more critical startup scripts failed to start!"
222 eerror "Please correct this, and reboot ..."
223 echo; echo
224 /sbin/sulogin ${CONSOLE}
225 einfo "Unmounting filesystems"
226 /bin/mount -a -o remount,ro & >/dev/null
227 einfo "Rebooting"
228 /sbin/reboot -f
229 fi
230 done
231
232 # Check that $svcdir exists ...
233 check_statedir
234
235 # Since we are using tmpfs or ramfs, just bin to $tsvcdir to $svcdir
236 if get_bootparam "tmpfs" || get_bootparam "ramfs" || [ "${svcmount}" = "yes" ]
237 then
238 mount --bind "${tsvcdir}" "${svcdir}"
239 fi
240
241 # Clear $svcdir from stale entries
242 rm -rf "${svcdir}"/*
243
244 # Update the dependency cache
245 /sbin/depscan.sh
246
247 # Now that the dependency cache are up to date, make sure these
248 # are marked as started ...
249 for x in checkroot hostname modules checkfs localmount
250 do
251 ln -snf "/etc/init.d/${x}" "${svcdir}/started/${x}"
252 done
253
254 fi # Sysinit ends here
255
256 if [ "${RUNLEVEL}" = "S" -a "${argv1}" = "boot" ]
257 then
258 # $BOOT can be used by rc-scripts to test if it is the first time
259 # the 'boot' runlevel is executed
260 export BOOT="yes"
261 fi
262
263 if [ "${argv1}" = "sysinit" ]
264 then
265 exit 0
266 fi
267
268 if [ -z "${argv1}" ]
269 then
270 if [ -f "${svcdir}/softlevel" ]
271 then
272 export SOFTLEVEL="`cat ${svcdir}/softlevel`"
273 else
274 export SOFTLEVEL="boot"
275 fi
276 else
277 export SOFTLEVEL="${argv1}"
278 fi
279
280 if [ ! -f "${svcdir}/softlevel" ]
281 then
282 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
283 fi
284
285 # For keeping a list of services that fails during boot/halt
286 if [ ! -d "${svcdir}/failed" ]
287 then
288 install -d -m0755 "${svcdir}/failed"
289 else
290 rm -rf "${svcdir}"/failed/*
291 fi
292
293 if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
294 then
295 myscripts=""
296
297 export HALT="${SOFTLEVEL}"
298
299 elif [ ! -d "/etc/runlevels/${SOFTLEVEL}" ]
300 then
301 eerror "ERROR: runlevel ${SOFTLEVEL} does not exist; exiting..."
302 exit 1
303 else
304 myscripts=""
305 if [ "${SOFTLEVEL}" != "boot" ]
306 then
307 # Normal runlevels *include* boot scripts
308 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
309 mylevels="${mylevels} $(dolisting /etc/runlevels/boot/)"
310 else
311 # Non-normal runlevels don't include boot scripts as default
312 mylevels="$(dolisting "/etc/runlevels/${SOFTLEVEL}/")"
313 fi
314 for x in ${mylevels}
315 do
316 if [ -L "${x}" ]
317 then
318 myscripts="${myscripts} ${x##*/}"
319 fi
320 done
321 fi
322
323 # The softscripts dir contains all scripts that belong to the
324 # runlevel specified in ${svcdir}/softlevel
325 # It needs to be a new directory, else when stopping the services
326 # and the old directory is not intact, things get broken
327
328 install -d -m0755 "${svcdir}/softscripts.new"
329
330 for x in ${myscripts}
331 do
332 if [ ! -e "/etc/init.d/${x}" ]
333 then
334 ewarn "WARNING: /etc/init.d/${x} missing; skipping..."
335 continue
336 fi
337 # The -f eliminates a warning if the symlink already exists,
338 # which can happen if a service is in both the boot level and
339 # the current "normal" runlevel
340 ln -snf "/etc/init.d/${x}" "${svcdir}/softscripts.new/${x}"
341 done
342
343 dep_stop() {
344 local x=""
345 local needsme=""
346 local myservice=""
347 local depservice=""
348
349 [ ! -L "$1" ] && continue
350 if [ ! -e "$1" ]
351 then
352 # Remove dud symlinks
353 rm -f "$1"
354 continue
355 fi
356 myservice="${1##*/}"
357
358 if [ ! -L "${svcdir}/softscripts.new/${myservice}" ]
359 then
360 # Candidate for zapping
361
362 # Should not work for 'use'
363 if [ ! -d "${svcdir}/need/${myservice}" ]
364 then
365 # Nothing depends on me
366 if [ -L "${svcdir}/started/${myservice}" ]
367 then
368 "$1" stop
369 fi
370 else
371 # Something may depend on me
372 needsme=0
373 for dep in $(dolisting "${svcdir}/need/${myservice}/")
374 do
375 if [ -L "${svcdir}/softscripts.new/${dep##*/}" -a -e "${dep}" ]
376 then
377 # This dep is valid
378 needsme=1
379 break
380 fi
381 done
382 if [ "${needsme}" -eq 0 ]
383 then
384 if [ -L "${svcdir}/started/${myservice}" ]
385 then
386 "$1" stop
387 fi
388 fi
389 fi
390 fi
391 }
392
393 # Stop services
394 for i in $(dolisting "${svcdir}/started/")
395 do
396 dep_stop "${i}"
397 done
398
399 # Only change softlevel AFTER all the services have been stopped,
400 # else they will not get the depend's right (wrong SOFTLEVEL)
401
402 echo "${SOFTLEVEL}" > "${svcdir}/softlevel"
403
404 if [ "${SOFTLEVEL}" = "reboot" -o "${SOFTLEVEL}" = "shutdown" ]
405 then
406 source /sbin/functions.sh
407
408 # Make sure that our $svcdir are clean for next reboot ...
409 rm -rf "${svcdir}"/*
410
411 source /etc/init.d/halt.sh
412
413 if [ "${SOFTLEVEL}" = "reboot" ]
414 then
415 source /etc/init.d/reboot.sh
416 else
417 source /etc/init.d/shutdown.sh
418 fi
419 # Should never get here
420 exit 0
421 fi
422
423 # Move the old softscritps directory to a different one
424 # and make the new softscripts directory the current
425
426 mv -f "${svcdir}/softscripts" "${svcdir}/softscripts.old"
427 mv -f "${svcdir}/softscripts.new" "${svcdir}/softscripts"
428
429 dep_start() {
430 local x=""
431 local myservice=""
432 local depservice=""
433
434 if [ ! -L "$1" ]
435 then
436 continue
437 fi
438 # Only start a script if it isn't already running
439 myservice="${1##*/}"
440 if [ ! -L "${svcdir}/started/${myservice}" ]
441 then
442 "$1" start
443 fi
444 }
445
446 # Start scripts
447 for i in $(dolisting "${svcdir}/softscripts/")
448 do
449 dep_start "${i}"
450 done
451
452 # Clean the old runlevel
453 rm -rf "${svcdir}/softscripts.old" &> /dev/null
454
455 # Depends gets nuked, so update them
456 # (this problem should be solved now, but i think it will be a good idea
457 # to recreate the deps after a change in runlevel)
458
459 #/sbin/depscan.sh &>/dev/null
460
461 # We want devfsd running after a change of runlevel (this is mostly if we return
462 # from runlevel 'single')
463 if [ -z "`ps --no-heading -C 'devfsd'`" -a \
464 -n "`gawk '/\/dev devfs/ { print }' /proc/mounts 2> /dev/null`" ]
465 then
466 /sbin/devfsd /dev &> /dev/null
467 fi
468
469 # Runlevel end, so clear stale fail list
470 rm -rf "${svcdir}/failed" &> /dev/null
471
472 # If we were in the boot runlevel, it is done now ...
473 [ -n "${BOOT}" ] && unset BOOT
474
475
476 # 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