/[baselayout]/trunk/sbin/rc
Gentoo

Contents of /trunk/sbin/rc

Parent Directory Parent Directory | Revision Log Revision Log


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