]> git.pld-linux.org Git - projects/geninitrd.git/blame - geninitrd
Prefer suspend/resume binary over initrd/resume. Install previously found binary...
[projects/geninitrd.git] / geninitrd
CommitLineData
bb529f94
JK
1#!/bin/sh
2
3# geninitrd
4#
45d4d8cb 5# by PLD Linux Team
bb529f94 6#
9e1ceabe 7# based on mkinitrd from RedHat Linux
e4b07ddc 8#
c31050f3 9
b7114dde 10VERSION='devel'
ca2c2012 11PROGRAM=${0##*/}
bb529f94
JK
12
13. /etc/rc.d/init.d/functions
ded87775 14. /lib/geninitrd/functions
e2405b29 15. /etc/sysconfig/system
bb529f94 16
c124d0cf
ER
17# list of geninitrd modules which need setup routine after commandline args parsing
18GENINITRD_MODS=""
c3667d07 19COMPRESS=yes
897d14b7 20STRIP=/usr/bin/strip
bb529f94
JK
21target=""
22kernel=""
23force=""
24verbose=""
25MODULES=""
26img_vers=""
c3667d07 27fstab=/etc/fstab
c3667d07 28modext=.o
4e9eb79c 29rootdev_nr=0
738c05d8
ER
30# device node for rootfs from fstab
31rootdev=""
bb529f94 32
8bd582f1
ER
33# internal variables
34# is /dev on tmpfs
b64f015b
ER
35dev_mounted=no
36# is /proc mounted
37proc_mounted=no
38# is /sys mounted
39sys_mounted=no
40# is /tmp mounted on tmpfs
41tmp_mounted=no
42
43# are /dev nodes already created from /proc/devices info?
8bd582f1 44proc_partitions=no
6b013929 45
b64f015b 46usage() {
46768f45 47 echo "Usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
ac085800 48 echo " [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
8a6f083b 49 echo " [--compress=yes|xz|lzma|bzip2|gzip|lzo]"
76a48507 50 echo " [--nostrip ] [--strip PATH/strip] [--strip=PATH/strip]"
92ed99b6 51 echo " [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
ba5d09f0 52 echo " [--with-bootsplash] [--without-bootsplash]"
6c69a2d4
ER
53 echo " [--with-fbsplash] [--without-fbsplash]"
54 echo " [--with-fbcondecor] [--without-fbcondecor]"
e4b07ddc 55 echo " [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
ba5d09f0 56 echo " [--with-suspend] [--without-suspend]"
1cd2aabd 57 echo " [--with-tuxonice] [--without-tuxonice]"
ecd7bf46
ER
58 echo " [--without-dmraid]"
59 echo " [--with-multipath=DEVPATH] [--without-multipath]"
3ef3d717 60 echo " [--without-blkid] [--without-luks]"
ac085800 61 echo " <initrd-image> <kernel-version>"
553786c4 62 echo ""
46768f45
ER
63 echo "Example:"
64
0ad676eb 65 local kdir kver dir=${target:-/boot}
46768f45
ER
66 for kdir in /lib/modules/*; do
67 [ -d $kdir ] || continue
68 kver=${kdir##*/}
dfe1a27c 69 echo " $0 -f --initrdfs=initramfs $dir/initrd-$kver.gz $kver $verbose"
63514069 70 done | sort -V
bb529f94
JK
71}
72
779a218a 73msg() {
f4010f7f
AM
74 echo "$PROGRAM: $*"
75}
76
77warn() {
4a60c01f 78 msg "WARNING: $*" >&2
779a218a
AM
79}
80
02ba8ab7 81verbose() {
34f3f0e9 82 [ -n "$verbose" ] && msg "$*" >&3
02ba8ab7
ER
83}
84
94769f11 85debug() {
02ba8ab7 86 [ x"$verbose" = x"-v -v" ] && msg "$*" >&3
94769f11 87}
aa69da6e 88
2b945b6b
ER
89# add initrd code to print to kmsg
90# @param string message
91# @param int loglevel. defaults to "6" (info)
92# Log levels can be:
93# Name String Meaning
94# KERN_EMERG "0" Emergency messages, system is about to crash or is unstable
95# KERN_ALERT "1" Something bad happened and action must be taken immediately
96# KERN_CRIT "2" A critical condition occurred like a serious hardware/software failure
97# KERN_ERR "3" An error condition, often used by drivers to indicate difficulties with the hardware
98# KERN_WARNING "4" A warning, meaning nothing serious by itself but might indicate problems
99# KERN_NOTICE "5" Nothing serious, but notably nevertheless. Often used to report security events.
100# KERN_INFO "6" Informational message e.g. startup information at driver initialization
101# KERN_DEBUG "7" Debug messages
102# KERN_CONT "c" "continued" line of log printout (only done after a line that had no enclosing \n)
103kmsg() {
104 local msg="$1" level=${2:-6}
105 echo "echo '<$level>$msg' > /dev/kmsg" | add_linuxrc
106}
107
bf6c3fcb
ER
108# aborts program abnormally
109die() {
b5f5c089 110 local rc=${2:-1}
046c68c9 111 msg "ERROR: $1" >&2
bf6c3fcb
ER
112 exit $rc
113}
114
684d5d2a
ER
115# find program from specified paths
116find_tool() {
27442691 117 local x p b n
c45a111c 118 local paths="$initrd_dirs /bin /sbin /usr/bin /usr/sbin"
684d5d2a 119 for x in "$@"; do
5493388d 120 debug "find_tool: checking $x"
684d5d2a
ER
121 if [ -x "$x" ]; then
122 echo $x
02ba8ab7 123 verbose "find_tool: found $x"
684d5d2a
ER
124 return 0
125 fi
27442691
JR
126 n="$x"
127 for p in $paths; do
128 b=$(basename $x)
5493388d 129 debug "find_tool: checking $p/$b"
27442691
JR
130 if [ -x "$p/$b" ]; then
131 echo $p/$b
132 verbose "find_tool: found $p/$b"
133 return 0
134 fi
135 n="$n $p/$b"
136 done
684d5d2a 137 done
27442691 138 debug "find_tool: did not find any of: $n"
684d5d2a
ER
139 return 1
140}
141
c124d0cf
ER
142# loads geninitrd modules
143geninitrd_load_mods() {
144 local mod
145 for mod in "$@"; do
146 if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
147 die "$mod geninitrd module can't be loaded"
148 fi
149 . /lib/geninitrd/mod-$mod.sh
150
c34c6a69 151 GENINITRD_MODS="$GENINITRD_MODS $mod"
c124d0cf
ER
152 done
153}
154
155# setup geninitrd modules
156geninitrd_setup_mods() {
b7114dde 157 local mod
c124d0cf
ER
158
159 for mod in $GENINITRD_MODS; do
b7114dde 160 debug "# $mod"
c34c6a69
ER
161
162 # some mods want init
163 if type setup_mod_$mod > /dev/null; then
164 eval setup_mod_$mod
165 fi
c124d0cf
ER
166 done
167}
168
c6c6ce01
ER
169# append text to /linuxrc
170# takes STDIN as input
171add_linuxrc() {
b64f015b 172 cat >> "$RCFILE"
c6c6ce01
ER
173}
174
b64f015b
ER
175# generate code to mount /dev on tmpfs and create initial nodes
176# can be called multiple times. /dev is cleaned up (umounted) automatically at
177# the end of script.
178mount_dev() {
b64f015b
ER
179 # we already generated tmpfs code; return
180 if is_yes "$dev_mounted"; then
181 return
182 fi
183
184 dev_mounted=yes
185
186 busybox_applet mount mknod mkdir
187 add_linuxrc <<-EOF
188 : 'Creating /dev'
621695f6
AF
189 if ! mount -t devtmpfs -o mode=0755,nosuid devtmpfs /dev > /dev/null 2>&1; then
190 mount -o mode=0755,nosuid -t tmpfs tmpfs /dev
13659675
AM
191 mknod -m 600 /dev/console c 5 1
192 mknod -m 666 /dev/null c 1 3
193 mknod -m 666 /dev/zero c 1 5
194 mknod -m 666 /dev/random c 1 8
195 mknod -m 600 /dev/snapshot c 10 231
196 mknod -m 666 /dev/urandom c 1 9
197 mknod -m 666 /dev/ptmx c 5 2
198 mknod -m 644 /dev/kmsg c 1 11
621695f6 199 fi
b64f015b
ER
200 mkdir /dev/pts
201 mkdir /dev/shm
202 EOF
203}
204
ff9aded5
AM
205# load font
206load_font() {
207 local font
208 [ ! -r /etc/sysconfig/console ] && return
209 . /etc/sysconfig/console
210 if [ -n "$CONSOLEFONT" ]; then
211 font=$(ls -1 /lib/kbd/consolefonts/${CONSOLEFONT}*.gz 2> /dev/null)
212 if [ -n "$font" ]; then
213 verbose "Loading font $font"
214 busybox_applet loadfont
215 inst_d "/lib/kbd/consolefonts"
216 cp -a "$font" "$DESTDIR/lib/kbd/consolefonts/"
217 gunzip ${DESTDIR}/lib/kbd/consolefonts/${CONSOLEFONT}*.gz
218 font=${font%.gz}
219 echo "loadfont < $font" | add_linuxrc
220 fi
221 fi
222}
223
b64f015b
ER
224# generate code to mount /proc on initrd
225# can be called multiple times
226mount_proc() {
227 if is_yes "$proc_mounted"; then
228 return
229 fi
230
231 proc_mounted=yes
2bface63
ER
232 if [ "$INITRDFS" = "initramfs" ]; then
233 # /proc is mounted with initramfs 2.6.22.14 kernel
234 # XXX: remove when it is clear why proc was already mounted
235 echo "[ -f /proc/cmdline ] || mount -t proc none /proc" | add_linuxrc
236 else
237 echo "mount -t proc none /proc" | add_linuxrc
238 fi
b64f015b
ER
239}
240
241# generate code to mount /sys on initrd
242# can be called multiple times
243mount_sys() {
244 if is_yes "$sys_mounted"; then
245 return
246 fi
247
248 sys_mounted=yes
249 echo "mount -t sysfs none /sys" | add_linuxrc
250}
251
252# generate code to mount /tmp on initrd
253# can be called multiple times
254mount_tmp() {
255 if [ "$INITRDFS" = "initramfs" ]; then
256 # initramfs is read-write filesystem, no need for tmpfs
257 return
258 fi
259
260 if is_yes "$tmp_mounted"; then
261 return
262 fi
263
264 tmp_mounted=yes
265 echo "mount -t tmpfs none /tmp" | add_linuxrc
266}
267
d63131e0
AF
268# generate code to mount /run on initrd
269# can be called multiple times
270mount_run() {
271 if is_yes "$run_mounted"; then
272 return
273 fi
274
275 run_mounted=yes
276 echo "mount -t tmpfs run /run" | add_linuxrc
277}
278
b64f015b 279# unmount all mountpoints mounted by geninitrd
c6d164fb 280# try to move pseudo filesystems to newroot if possible
b64f015b 281umount_all() {
ec49b7e6
ER
282
283 add_linuxrc <<-'EOF'
903f21ea 284 : Last shell before umounting all and giving control over to real init.
ec49b7e6
ER
285 debugshell
286 EOF
5b70f84d 287
d63131e0 288 if is_yes "$run_mounted"; then
c6d164fb
ER
289 add_linuxrc <<-EOF
290 mount --bind /run /newroot/run
291 umount /run
292 EOF
d63131e0
AF
293 run_mounted=no
294 fi
b64f015b 295 if is_yes "$dev_mounted"; then
c6d164fb
ER
296 add_linuxrc <<-EOF
297 mount --bind /dev /newroot/dev
298 umount /dev
299 EOF
b64f015b
ER
300 dev_mounted=no
301 fi
b64f015b 302 if is_yes "$sys_mounted"; then
c6d164fb
ER
303 add_linuxrc <<-EOF
304 mount --bind /sys /newroot/sys
305 umount /sys
306 EOF
b64f015b
ER
307 sys_mounted=no
308 fi
c6d164fb
ER
309 if is_yes "$proc_mounted"; then
310 add_linuxrc <<-EOF
311 mount --bind /proc /newroot/proc
312 umount /proc
313 EOF
314 proc_mounted=no
315 fi
b64f015b
ER
316 if is_yes "$tmp_mounted"; then
317 echo 'umount /tmp' | add_linuxrc
318 tmp_mounted=no
319 fi
320}
321
9299682f
ER
322# Checks if busybox has support for APPLET(s)
323# Exits from geninitrd if the support is not present.
324#
325# NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
326busybox_applet() {
30495bbf 327 local err=0 applet
9299682f
ER
328
329 if [ -z "$busybox_functions" ]; then
684d5d2a 330 local tmp=$($busybox 2>&1)
9b1373fb
ER
331
332 # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
333 if [[ "$tmp" = *applet\ not\ found* ]]; then
334 local t=$(mktemp -d)
684d5d2a 335 ln -s $busybox $t/busybox
9b1373fb
ER
336 local tmp=$($t/busybox 2>&1)
337 rm -rf $t
338 fi
339
340 busybox_functions=$(echo "$tmp" | \
9299682f
ER
341 sed -ne '/Currently defined functions:/,$p' | \
342 xargs | sed -e 's,.*Currently defined functions: ,,'
343 )
344 fi
345 for applet in $*; do
346 local have
347 # try cache
348 eval have='$'busybox_have_$applet
349 if [ -z "$have" ]; then
e871f497 350 have=$(echo "$busybox_functions" | grep -Ec "( |^)$applet(,|$)")
9299682f 351 if [ "$have" = 0 ]; then
f4010f7f 352 warn "This setup requires busybox-initrd compiled with applet '$applet' support"
9299682f
ER
353 err=1
354 fi
355 eval busybox_have_$applet=$have
356 fi
357 done
358 if [ $err = 1 ]; then
00eaa938 359 die "Aborted"
9299682f
ER
360 fi
361}
362
755e5cdc
ER
363# Extract the .config file from a kernel image
364# uses extract-ikconfig from kernel sources (scripts/extract-ikconfig)
365ikconfig() {
61d20b49 366 local kofile=$(modinfo -k $kernel -n configs 2> /dev/null)
755e5cdc
ER
367 if [ -n "$kofile" ]; then
368 /lib/geninitrd/extract-ikconfig $kofile
7283bf35 369 return
25cb53df 370 fi
7283bf35
ER
371
372 # see if config available as separate file
373 if [ -f /boot/config-$kernel ]; then
374 cat /boot/config-$kernel
375 return
376 fi
377
378 # finally try vmlinuz itself
379 /lib/geninitrd/extract-ikconfig /boot/vmlinuz-$kernel
25cb53df
ER
380}
381
faee129c
AM
382# @param $module
383basename_module() {
384 local module=$1
385
386 module=${module##*/}
387 module=${module%$modext*}
388 echo $module
389}
390
7ffba534
ER
391# Finds module dependencies
392#
7ffba534
ER
393# @param $module
394#
046c68c9 395# Outputs full path to module and it's dependencies
7ffba534 396find_depmod() {
fe280785 397 local module="$1"
046c68c9
ER
398 local skiperrors=0
399
400 # if module is prefixed with dash, we should ignore errors if the module
401 # can't be found.
402 if [ ${module#-} != $module ]; then
403 skiperrors=1
404 module=${module#-}
405 fi
406
046c68c9
ER
407 # This works when user has module-init-tools installed even on 2.4 kernels
408 local modprobe
409 modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
410
411 if [ $? != 0 ]; then
412 if [ $skiperrors = 1 ]; then
0c7e9123 413 return 0
7cac5014 414 fi
046c68c9 415 echo >&2 "$modprobe"
7cac5014 416
7ffba534 417 if ! is_no "$EXIT_IF_MISSING"; then
046c68c9 418 die "$module: module not found for $kernel kernel"
7ffba534 419 fi
046c68c9
ER
420
421 warn "$module: module not found for $kernel kernel"
422 warn "If $module isn't compiled in kernel then this initrd may not start your system."
7ffba534
ER
423 fi
424
faee129c
AM
425 local smodule
426
046c68c9 427 echo "$modprobe" | \
c25765ed 428 while read insmod modpath options; do
faee129c
AM
429 if [ "$insmod" = "insmod" ]; then
430
431 # XXX: find a away to autodetect
432 smodule=$(basename_module $modpath)
433 case "$smodule" in
b771ab7f
AM
434 btrfs)
435 find_depmod "-libcrc32c"
436 ;;
bb0ca032 437 crc-t10dif)
e7d76a06 438 find_depmod "-crct10dif-pclmul"
bb0ca032
AM
439 find_depmod "-crct10dif"
440 ;;
faee129c
AM
441 libcrc32c)
442 find_depmod "-crc32c-intel"
443 find_depmod "-crc32c"
444 ;;
dd1e5379
AM
445 virtio_blk|virtio_scsi)
446 find_depmod "-virtio_pci"
447 find_depmod "-virtio_mmio"
448 ;;
faee129c
AM
449 esac
450
451 echo $modpath
452 fi
7ffba534 453 done
0c7e9123 454 return 0
7ffba534
ER
455}
456
4a60c01f
AM
457find_firmware() {
458 local module="$1"
601127ea
ER
459
460 # no firmware support in 2.4 kernels
461 if [ "$kernel_version_long" -lt "002005048" ]; then
462 return
463 fi
464 echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
4a60c01f
AM
465}
466
046c68c9
ER
467# @param $module
468find_module() {
469 local mod depmod module=$1
ac085800 470
046c68c9 471 depmod=$(find_depmod $module) || exit 1
fe280785 472 for mod in $depmod; do
7ffba534 473 mod=${mod#/lib/modules/$kernel/}
fe280785
ER
474
475 # add each module only once
476 local m have=0
477 for m in $MODULES; do
478 [ $m = $mod ] && have=1
479 done
480 if [ $have = 0 ]; then
c2eb7d4f 481 MODULES="$MODULES $mod"
fe280785 482 fi
10c3df06 483 done
bb529f94
JK
484}
485
034fdd5d
ER
486# install a file to temporary mount image.
487# it will operate recursively (copying directories)
488# and will symlink destinations if source is symlink.
bb529f94 489inst() {
17e97aec 490 if [ $# -lt 2 ]; then
a9ace64a 491 die 'Usage: inst <file> [<file>] <destination>'
c31050f3 492 fi
17e97aec
ER
493
494 local src i=0 c=$(($# - 1))
495 while [ $i -lt $c ]; do
496 src="$src $1"
497 i=$((i + 1))
498 shift
499 done
500 local dest=$1
501 set -- $src
ce40ba21 502 local parentDir=$(dirname $DESTDIR$dest)
02ba8ab7 503 if [ ! -d "$parentDir" ]; then
7f5eccc0 504 verbose "+ mkdir -p DESTDIR${parentDir#$DESTDIR}"
02ba8ab7
ER
505 mkdir -p $parentDir
506 fi
7f5eccc0 507 verbose "+ cp $* DESTDIR$dest"
9b557a09 508 cp -HR "$@" "$DESTDIR$dest"
bb529f94
JK
509}
510
dab92b1d 511inst_d() {
17e97aec 512 if [ $# = 0 ]; then
a9ace64a 513 die 'Usage: inst_d <destination> <destination>'
034fdd5d 514 fi
7c239866 515 local dir
034fdd5d 516 for dir in "$@"; do
9b557a09 517 install -d "$DESTDIR$dir"
034fdd5d
ER
518 done
519}
520
209061e3
ER
521# install executable and it's shared libraries
522inst_exec() {
17e97aec 523 if [ $# -lt 2 ]; then
3601c2fa 524 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
17e97aec 525 fi
209061e3
ER
526 local src i=0 c=$(($# - 1))
527 while [ $i -lt $c ]; do
528 src="$src $1"
529 i=$((i + 1))
530 shift
531 done
9b532fe6 532 local dest=$1
209061e3
ER
533 set -- $src
534
9b532fe6
ER
535 inst "$@" $dest
536
c45a111c 537 local obj lib libs libdir
10e8125f 538 for obj in "$@"; do
66aec48b 539 case "$obj" in
68c2e3b2 540 /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2 | /libx32/ld-linux-x32.so.2)
66aec48b
ER
541 continue
542 esac
543
544 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
545 for lib in $libs; do
1be24d6e
ER
546 libdir=$(cd $(dirname "$lib"); pwd)
547 if [ ! -f "$DESTDIR/$lib" ]; then
548 inst_d $libdir
549 inst_exec $lib $libdir
66aec48b
ER
550 fi
551 done
209061e3 552 done
c7ade647
ER
553
554 # hack for uclibc linked binaries requiring this fixed path
555 # XXX: shouldn't rpath be used here instead so th
556 if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
1be24d6e 557 lib=$DESTDIR/$_lib/libc.so.0
c7ade647 558 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
1be24d6e 559 libdir=$(cd $(dirname "$lib"); pwd)
c7ade647
ER
560 if [ ! -e $DESTDIR$libdir ]; then
561 libdir=$(dirname "$libdir")
562 inst_d $libdir
02ba8ab7 563 verbose "+ ln -s /$_lib $DESTDIR$libdir"
c7ade647
ER
564 ln -s /$_lib $DESTDIR$libdir
565 fi
566 fi
209061e3
ER
567}
568
82474db9
ER
569# output modules.conf / modprobe.conf
570modprobe_conf() {
571 echo "$modprobe_conf_cache"
572}
573
38ac83a5
ER
574# return options for MODULE
575# @param $1 module name
576modprobe_options() {
577 local module=$1
915ff812 578 local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
38ac83a5
ER
579 echo ${options# }
580}
581
82474db9
ER
582#
583# defaults to modprobe -c if not told otherwise, this means include statements
584# work from there.
585cache_modprobe_conf() {
707f5e60 586 if [ "$kernel_version" -lt "002005" ]; then
82474db9
ER
587 modulefile=/etc/modules.conf
588 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
589 modulefile=/etc/conf.modules
590 fi
591 fi
592
593 if [ -n "$modulefile" ]; then
d8056591 594 debug "Using $modulefile for modules config"
99e7251e
ER
595 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
596
82474db9 597 else
d8056591 598 debug "Using modprobe -c to get modules config"
99e7251e 599 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
82474db9
ER
600 fi
601}
602
bc0d6f2d 603# find modules for $devpath
d8056591 604find_modules_for_devpath() {
bc0d6f2d
ER
605 local devpath="$1"
606 if [ -z "$devpath" ]; then
d8056591 607 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
f6536797 608 fi
ac085800 609
c2eb7d4f
ER
610 if [[ "$devpath" = /dev/dm-* ]]; then
611 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
d2cb46cf 612 devpath=$(dm_node "$devpath")
c2eb7d4f
ER
613 fi
614
336018a5 615 if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
c2eb7d4f
ER
616 # sanitize things like:
617 # /dev/block/104:2 -> /dev/cciss/c0d0p2
618 devpath=$(readlink -f "$devpath")
619 fi
620
02ba8ab7 621 verbose "Finding modules for device path $devpath"
bc0d6f2d 622
3ef3d717
ER
623 if is_luks "$devpath"; then
624 find_modules_luks "$devpath"
625 return
626 fi
627
74d45ce1
ER
628 if is_nfs "$devpath"; then
629 find_modules_nfs "$devpath"
d9179777
ER
630 return
631 fi
632
e16414d9 633 if is_md "$devpath"; then
df738638 634 find_modules_md "$devpath"
d9179777
ER
635 return
636 fi
637
c3b54060 638 if is_multipath "$devpath"; then
07137fe3 639 if find_modules_multipath "$devpath"; then
9baf4f3f 640 return
9baf4f3f 641 fi
ecd7bf46 642
9baf4f3f
ER
643 # fallback
644 fi
645
36523626 646 if is_dmraid "$devpath"; then
c083ae23
ER
647 if find_modules_dmraid "$devpath"; then
648 return
649 fi
650 # fallback
651 fi
652
35043b20
ER
653 if is_scsi "$devpath"; then
654 find_modules_scsi "$devpath"
d9179777
ER
655 return
656 fi
657
30ca4815 658 if is_ide "$devpath"; then
bc0d6f2d 659 find_modules_ide "$devpath"
d9179777
ER
660 return
661 fi
662
0bdde1a1
ER
663 if [[ "$devpath" == /dev/bcache* ]]; then
664 find_modules_bcache "$devpath"
665 return
666 fi
667
07b09cf9 668 if [[ "$devpath" == /dev/rd/* ]]; then
046c68c9 669 find_module "DAC960"
c3313cd6 670 rootdev_add=/dev/rd/
d9179777
ER
671 return
672 fi
673
07b09cf9 674 if [[ "$devpath" == /dev/ida/* ]]; then
046c68c9 675 find_module "cpqarray"
c3313cd6 676 rootdev_add=/dev/ida/
d9179777
ER
677 return
678 fi
679
08651ad1 680 if [[ "$devpath" == /dev/cciss/* ]]; then
c3313cd6 681 rootdev_add=/dev/cciss/
df11fbe8
ER
682
683 # load hpsa for future kernels, cciss for backwards compat
684 if [ "$kernel_version_long" -ge "003000000" ]; then
685 find_module "hpsa" "-cciss"
649df3de 686 find_modules_scsi "$devpath"
df11fbe8
ER
687 else
688 find_module "cciss"
689 fi
690
d9179777
ER
691 return
692 fi
693
07b09cf9 694 if [[ "$devpath" == /dev/ataraid/* ]]; then
ac085800 695 find_modules_ide
046c68c9 696 find_module "ataraid"
99e7251e 697 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
9ae446b9 698 if [ -n "$ataraidmodules" ]; then
7c38b114 699 # FIXME: think about modules compiled in kernel
82474db9 700 die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
7c38b114
AF
701 fi
702 for n in $ataraidmodules; do
046c68c9 703 find_module "$n"
7c38b114 704 done
c3313cd6 705 rootdev_add=/dev/ataraid/
d9179777
ER
706 return
707 fi
708
7c38b114 709 # check to see if we need to set up a loopback filesystem
07b09cf9 710 if [[ "$devpath" == /dev/loop* ]]; then
00eaa938 711 die "Sorry, root on loop device isn't supported."
7c38b114
AF
712 # TODO: rewrite for bsp and make nfs ready
713 if [ ! -x /sbin/losetup ]; then
00eaa938 714 die "losetup is missing"
7c38b114 715 fi
bc0d6f2d 716 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
82474db9 717 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
42820142 718 die "The root filesystem is on a $devpath, but there is no magic entry in $fstab for this device. Consult the $PROGRAM man page for more information"
7c38b114
AF
719 fi
720
721 line="`awk '/'$key'/ { print $0; }' $fstab`"
722 loopDev="$(echo $line | awk '{print $3}')"
723 loopFs="$(echo $line | awk '{print $4}')"
724 loopFile="$(echo $line | awk '{print $5}')"
725
726 BASICMODULES="$BASICMODULES -loop"
046c68c9 727 find_module "-$loopFs"
7c38b114 728 BASICMODULES="$BASICMODULES -${loopFs}"
d9179777
ER
729 return
730 fi
731
67aa84bd
ER
732 if is_lvm "$devpath"; then
733 find_modules_lvm "$devpath"
d9179777 734 return
7c38b114
AF
735 fi
736}
737
b64f015b 738firmware_install_module() {
c3667d07 739 local module="$1"
c6c6ce01 740 local firmware_files="$2"
9ed6e1db 741
02ba8ab7 742 verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
9ed6e1db 743 # firmware not yet installed
9b557a09 744 if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
034fdd5d 745 inst_d /lib/firmware
9b557a09 746cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
9ed6e1db 747#!/bin/sh -e
45294dc1
ER
748# handle only firmware add requests
749if [ "$SUBSYSTEM" != "firmware" ]; then
750 exit 0
751fi
752if [ "$ACTION" != "add" ]; then
753 exit 0
754fi
8639f99a
AM
755echo 1 > /sys$DEVPATH/loading
756cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
757echo 0 > /sys$DEVPATH/loading
758exit 0
9ed6e1db 759EOF
9b557a09 760 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
63cb815e
ER
761
762 # setup firmware loader agent
763 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
9ed6e1db
AM
764 fi
765
766 for firmware in $firmware_files; do
80b23733 767 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
486d26a5 768 FIRMWAREDIR=${firmware%/*}
4a9920e7 769 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733
ER
770 inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
771 elif [ -f "/lib/firmware/$firmware" ]; then
c661b23c 772 FIRMWAREDIR=${firmware%/*}
773 [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
80b23733 774 inst /lib/firmware/$firmware /lib/firmware/$firmware
c661b23c 775 else
6652b089 776 warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
4a60c01f 777 fi
9ed6e1db
AM
778 done
779
b64f015b 780 mount_sys
9ed6e1db
AM
781}
782
2a5bcca9 783modules_install() {
c3667d07
ER
784 local modules="$1"
785 local mod
2a5bcca9
AM
786
787 for mod in $modules; do
fe280785 788 MODULEDIR=${mod%/*}
4a9920e7 789 inst_d "/lib/modules/$kernel/$MODULEDIR"
9b557a09 790 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
5d62840e
AM
791 case $mod in
792 *.gz)
b657b865 793 gunzip "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress gz"
5d62840e
AM
794 mod=${mod%.gz}
795 ;;
796 *.xz)
b657b865 797 xz -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress xz"
5d62840e
AM
798 mod=${mod%.xz}
799 ;;
800 *.bz2)
b657b865 801 bzip2 -d "$DESTDIR/lib/modules/$kernel/$mod" || die "Can't uncompress bz2"
5d62840e
AM
802 mod=${mod%.bz2}
803 ;;
804 esac
897d14b7 805 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
5d62840e 806 $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod}"
ccd1f65f 807 fi
2a5bcca9
AM
808 done
809}
810
811modules_add_linuxrc() {
fe280785 812 local mod modpath
ac085800 813
fe280785
ER
814 for mod in "$@"; do
815 # module path without optional compression
816 modpath=${mod%.gz}
5d62840e
AM
817 modpath=${modpath%.xz}
818 modpath=${modpath%.bz2}
fe280785
ER
819
820 # name of the module
8011a76c 821 local module=${modpath##*/}; module=${module%$modext}
38ac83a5 822 local options=$(modprobe_options "$module")
8011a76c
ER
823 local genericname=$(echo $module | tr - _)
824 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
825 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
2a5bcca9 826
3e1d0df9
AM
827 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
828 options="scan=sync $options"
829 fi
830
02ba8ab7 831 if [ x"$verbose" = x"-v" ]; then
8a47b72c
ER
832 s=""
833 if [ "$options" ]; then
834 s="$s with options [$options]"
835 fi
8011a76c
ER
836 if [ "$usleep" ]; then
837 s="$s and $usleep usleep"
8a47b72c 838 fi
02ba8ab7 839 verbose "Loading module [$module]$s"
ac085800
ER
840 fi
841
8011a76c
ER
842 if [ -n "$firmware" ]; then
843 firmware_install_module "$module" "$firmware"
4a60c01f 844 else
06e481d7
ER
845 for file in $(find_firmware "$module"); do
846 firmware_install_module "$module" "$file"
847 done
9ed6e1db 848 fi
4a60c01f 849
18ece493 850 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
8011a76c
ER
851 if [ -n "$usleep" ]; then
852 echo "usleep $usleep" | add_linuxrc
8e598759 853 fi
e00dcfcb 854 if [ "$module" = "scsi_wait_scan" ]; then
d29583e0
ER
855 if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
856 echo "rmmod scsi_wait_scan" | add_linuxrc
857 fi
e00dcfcb
AM
858 fi
859
2a5bcca9
AM
860 done
861}
862
82b2dba2
ER
863# Generates /dev nodes based on /proc/partitions information.
864# Needs /proc mounted.
865# Can be called multiple times.
866initrd_gen_devices() {
867 if is_yes "$proc_partitions"; then
868 return
869 fi
870 proc_partitions=yes
335cd101 871
82b2dba2
ER
872 mount_dev
873 add_linuxrc <<-'EOF'
874 : 'Making device nodes'
875 cat /proc/partitions | (
8d4aba01 876 # ignore first two lines: header, empty line
82b2dba2 877 read b; read b
2cc3ae8b 878
82b2dba2
ER
879 while read major minor blocks dev rest; do
880 node=/dev/$dev
881 mkdir -p ${node%/*}
6b45dd6c 882 [ -e $node ] || mknod -m 660 $node b $major $minor
82b2dba2
ER
883 done
884 )
885 EOF
886}
bb529f94 887
82b2dba2 888
4828c787 889initrd_gen_setrootdev() {
02ba8ab7 890 verbose "Adding rootfs finding based on kernel cmdline root= option support."
71b2d771 891 busybox_applet ls
b7114dde 892 debug "Current /proc/partitions:\n$(sed -e 's,^,| ,' /proc/partitions)"
82b2dba2 893 add_linuxrc <<-'EOF'
dcdf6b49
ER
894 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
895 rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
94da85db
ER
896 # fallback to ls, try two different formats
897 # http://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2014-May/023915.html
898 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
899 # busybox up to 1.22
5efa9a2e 900 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
71b2d771 901 fi
94da85db
ER
902 if [ "${rootnr:-0}" = 0 -a -e "$ROOT" ]; then
903 # busybox 1.22 and upwards
904 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $5 + $6; }}')"
905 fi
906 if [ "${rootnr:-0}" -gt 0 ]; then
82b2dba2
ER
907 echo "$rootnr" > /proc/sys/kernel/real-root-dev
908 fi
909 fi
b64f015b 910 EOF
1606e343
AM
911}
912
4671d086
ER
913initrd_gen_initramfs_switchroot() {
914 inst_d /newroot
915 if [ "$rootdev" = "/dev/nfs" ]; then
916 echo "rootfs on NFS root=/dev/nfs"
917 else
918 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
919 fi
5845b321
ER
920
921 # parse 'root=xxx' kernel commandline
4671d086 922 # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
ec21900e
ER
923
924 # from lilo-23.2/readme/README:
925 # root=<device> changes the root device. This overrides settings that may
926 # have been made in the boot image and on the LILO command line. <device> is
927 # either the hexadecimal device number or the full path name of the device,
928 # e.g. /dev/hda3 [*]
929 #
930 # * The device names are hard-coded in the kernel. Therefore, only the
931 # "standard" names are supported and some less common devices may not be
932 # recognized. In those cases, only numbers can be used.
5436b31f 933 busybox_applet cat
4671d086 934 add_linuxrc <<-'EOF'
7f187a08 935 device=
3564e6b6 936 eval "$(busybox awk -v root="$ROOT" '
f9194b15
ER
937 # http://9fans.net/archive/2006/09/261
938 function h2d(str, hstr, res, num, n, digit, i) {
939 hstr = "0123456789abdcef";
940 res = 0;
941 n = split(tolower(str), digit, "");
942
943 for (i = 1; i <= n; i++) {
944 num = index(hstr, digit[i]) - 1;
945 res = res + (num * 16 ^ (n - i));
946 }
947
948 return res;
949 }
4671d086 950 BEGIN {
f9194b15
ER
951
952 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
953 num_pattern = "[0-9a-fA-F]" num_pattern_short;
4671d086 954 dev_pattern = "[hms][a-z][a-z]([0-9])+";
7f187a08 955 partition = "";
4671d086
ER
956 min = -1; maj = -1;
957
3564e6b6
ER
958 # see if we have /dev/hdX or hdX, we can just take partition name
959 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
960 partition = root
961 sub("^/dev/", "", partition);
962
963 } else {
964 # unify values first
965 if (root ~ "^" num_pattern_short "$") {
966 # change "303" => "0x0303"
967 root = "0x0" root
968 } else if (root ~ "^" num_pattern "$") {
969 # change "0303" => "0x0303"
970 root = "0x" root
971 }
972
f9194b15
ER
973 maj = h2d(substr(root, 3, 2));
974 min = h2d(substr(root, 5, 2));
4671d086 975 }
4671d086
ER
976 }
977
7f187a08 978 partition && $4 == partition { maj = $1; min = $2; }
afa32d0e 979 $1 == maj && $2 == min { partition = $4; }
4671d086
ER
980
981 END {
fa3a5452 982 if (maj >= 0 && min >= 0) {
7f187a08
ER
983 printf("maj=%s; min=%s;\n", maj, min);
984 }
985 if (partition) {
986 printf("device=/dev/%s;\n", partition);
fa3a5452 987 }
4671d086
ER
988 }
989 ' /proc/partitions)"
4671d086 990
7f187a08 991 if [ -z "$device" ]; then
5436b31f
AM
992 if [ "$DEBUGINITRD" ]; then
993 cat /proc/partitions
994 fi
0fb9dda3 995 device=$ROOT
4671d086
ER
996 fi
997
481bdb77 998 if [ "$device" -a ! -b $device -a "$maj$min" ]; then
6b45dd6c 999 mknod -m 660 $device b $maj $min
7f187a08
ER
1000 fi
1001
86aa389f
ER
1002 # XXX hack, if no device, try to parse it from /proc/partitions using /proc/sys/kernel/real-root-dev
1003 if [ ! -e "$device" ]; then
1004 rrd=$(cat /proc/sys/kernel/real-root-dev)
1005 major=$(($rrd / 256))
1006 minor=$(($rrd % 256))
1007
1008 while read pmajor pminor blocks dev rest; do
1009 # skip header and empty line
1010 [ -z "$pmajor" -o "$pmajor" = "major" ] && continue
1011
1012 if [ $pmajor = $major -a $pminor = $minor ]; then
1013 device=/dev/$dev
1014 echo "DEVICE set to $device based on real-root-dev"
1015 fi
1016 done < /proc/partitions
1017 fi
1018
144396dd 1019 [ -n "$ROOTFLAGS" ] && ROOTFLAGS="-o $ROOTFLAGS"
41d3645c 1020
144396dd 1021 mount -t $ROOTFS -r $device $ROOTFLAGS /newroot || echo "Mount of rootfs failed."
0fb9dda3 1022 init=$INIT
4671d086
ER
1023 if [ -z "$init" -o ! -x "/newroot$init" ]; then
1024 init=/sbin/init
1025 fi
1026 EOF
1027
b1ae7c80
AM
1028 busybox_applet dmesg
1029 busybox_applet tail
1030 add_linuxrc <<-'EOF'
1031 if [ "$DEBUGINITRD" ]; then
1032 echo "Last 20 lines of dmesg:"
1033 dmesg | tail -n 20
1034 fi
2b945b6b 1035
b1ae7c80
AM
1036 EOF
1037
2b945b6b
ER
1038 kmsg "geninitrd/$VERSION switching root"
1039
4671d086 1040 umount_all
0273c2c4 1041 busybox_applet switch_root usleep
4671d086 1042 add_linuxrc <<-'EOF'
278e5013 1043 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
0273c2c4
ER
1044
1045 # switch root to empty dir will make kernel panic, so sleep 10s before it
1046 # switch_root needs to be pid 1, so there's no other way to recover from here
1047 # if /dev is missing, switch root will likely fail, give debug shell before that
1048 if [ ! -d /newroot/dev ]; then
1049 echo "/dev is missing, switch_root will likely fail"
1050 echo "if you booted with debugrd=sh, then you be given shell and you might able to recover this situation"
1051 debugshell
1052 [ "$DEBUGINITRD" ] || usleep 10000000
1053 fi
1054
72a1b0ef
ER
1055 # systemd[1]: /usr appears to be on its own filesytem and is not
1056 # already mounted. This is not a supported setup. Some things will
1057 # probably break (sometimes even silently) in mysterious ways. Consult
1058 # http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
1059 # for more information.
1060 echo trying to mount /usr
1061 chroot /newroot mount -n /usr
1062
f8ea6a63 1063 exec switch_root /newroot $init ${1:+"$@"}
4671d086 1064
0273c2c4
ER
1065 # FIXME: this code is never executed, as "exec" does not return!
1066
4671d086
ER
1067 echo "Error! initramfs should not reach this place."
1068 echo "It probably means you've got old version of busybox, with broken"
1069 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1070
f8ea6a63 1071 exec chroot /newroot $init ${1:+"$@"}
4671d086
ER
1072
1073 echo "Failed to chroot!"
b61aa273 1074 debugshell
4671d086
ER
1075 EOF
1076 # we need /init being real file, not symlink, otherwise the initramfs will
1077 # not be ran by pid 1 which is required for switch_root
1078 mv $DESTDIR/linuxrc $DESTDIR/init
1079 ln -s init $DESTDIR/linuxrc
1080}
1081
c552503c
ER
1082# find if $symbol exists in System.map $mapfile
1083sym_exists() {
1084 local mapfile="$1"
1085 local symbol="$2"
1086 if [ ! -f $mapfile ]; then
1087 # missing mapfile (not a pld kernel?)
1088 return 1
1089 fi
1090
1091 awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
1092}
1093
1094# find best compressor (or forced one) for initrd
1095find_compressor() {
1096 local mode="$1"
1b89c904
AM
1097 # fastest initrd decompression speed is first
1098 local compressors='lzo gzip xz lzma bzip2'
c552503c
ER
1099
1100 # a specified one, take it
55aaf2fe
AM
1101 if ! is_yes "$mode"; then
1102 compressors="$mode"
c552503c
ER
1103 fi
1104
02ba8ab7 1105 verbose "finding compressor: $compressors (via $mode)"
c552503c
ER
1106 # check for compressor validity
1107 local c prog map=/boot/System.map-$kernel
1108 for c in $compressors; do
1109 case $c in
66d146a5 1110 xz)
29f7d622
AM
1111 sym=unxz
1112 prog=/usr/bin/xz
1113 ;;
1114 lzma)
c552503c 1115 sym=unlzma
66d146a5 1116 prog=/usr/bin/xz
c552503c
ER
1117 ;;
1118 bzip2)
1119 sym=bzip2
c42692d4 1120 prog=/usr/bin/bzip2
c552503c
ER
1121 ;;
1122 gzip)
1123 sym=gunzip
c42692d4 1124 prog=/bin/gzip
c552503c 1125 ;;
8a6f083b
AM
1126 lzo)
1127 sym=unlzo
1128 prog=/usr/bin/lzop
1129 ;;
5fcc3d04
AM
1130 none|no)
1131 # any existing sym will work
1132 sym=initrd_load
1133 prog=/bin/cat
1134 ;;
c552503c
ER
1135 *)
1136 die "Unknown compressor $c"
1137 ;;
1138 esac
c454c66e 1139 if sym_exists $map $sym && [ -x $prog ]; then
c552503c
ER
1140 echo $c
1141 return
1142 fi
1143 done
1144
02ba8ab7 1145 verbose "using gzip for compressor (fallback)"
c552503c
ER
1146 echo gzip
1147}
1148
97f51b6e
ER
1149# compresses kernel image image
1150# in function so we could retry with other compressor on failure
1151compress_image() {
1152 local compressor="$1" IMAGE="$2" target="$3" tmp
1153 tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1154
1155 case "$compressor" in
1156 xz)
1157 # don't use -9 here since kernel won't understand it
1158 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1159 ;;
1160 lzma)
1161 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1162 ;;
1163 bzip2)
1164 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1165 ;;
1166 gzip)
1167 gzip -9 < "$IMAGE" > "$tmp" || return $?
1168 ;;
8a6f083b
AM
1169 lzo)
1170 lzop -9 < "$IMAGE" > "$tmp" || return $?
1171 ;;
5fcc3d04
AM
1172 none|no)
1173 cat < "$IMAGE" > "$tmp" || return $?
1174 ;;
97f51b6e
ER
1175 esac
1176
1177 mv -f "$tmp" "$target"
1178}
1179
82b2dba2
ER
1180if [ -r /etc/sysconfig/geninitrd ]; then
1181 . /etc/sysconfig/geninitrd
1182fi
2cc3ae8b 1183
c215292c
AG
1184if [ ! -f /proc/mounts ]; then
1185 warn "/proc filesystem not mounted, may cause wrong results or failure."
1186fi
1187
2d769917 1188geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd bcache
c124d0cf 1189
82b2dba2
ER
1190while [ $# -gt 0 ]; do
1191 case $1 in
1192 --fstab=*)
1193 fstab=${1#--fstab=}
1194 ;;
1195 --fstab)
1196 fstab=$2
1197 shift
1198 ;;
1199 --modules-conf=*)
1200 modulefile=${1#--modules-conf=}
1201 ;;
1202 --modules-conf)
1203 modulefile=$2
1204 shift
1205 ;;
82b2dba2
ER
1206 --with-bootsplash)
1207 BOOT_SPLASH=yes
1208 ;;
1209 --without-bootsplash)
1210 BOOT_SPLASH=no
1211 ;;
1212 --with-fbsplash)
1213 FB_SPLASH=yes
1214 ;;
1215 --without-fbsplash)
1216 FB_SPLASH=no
1217 ;;
6c69a2d4
ER
1218 --with-fbcondecor)
1219 FB_CON_DECOR=yes
1220 ;;
1221 --without-fbcondecor)
1222 FB_CON_DECOR=no
1223 ;;
82b2dba2
ER
1224 --with-suspend)
1225 USE_SUSPEND=yes
1226 ;;
1227 --without-suspend)
1228 USE_SUSPEND=no
1229 ;;
1230 --with-suspend2 | --with-tuxonice)
1231 USE_TUXONICE=yes
1232 ;;
1233 --without-suspend2 | --without-tuxonice)
1234 USE_TUXONICE=no
1235 ;;
80b1ed79 1236 --lvmversion=*)
7308edee 1237 LVMTOOLSVERSION=${1#--lvmversion=}
82b2dba2 1238 ;;
80b1ed79 1239 --lvmtoolsversion=*)
1240 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1241 ;;
82b2dba2
ER
1242 --lvmtoolsversion|--lvmversion)
1243 LVMTOOLSVERSION=$2
1244 shift
1245 ;;
1246 --without-udev)
1247 USE_UDEV=no
1248 ;;
1249 --with-udev)
1250 USE_UDEV=yes
1251 ;;
1252 --without-dmraid)
1253 USE_DMRAID=no
1254 ;;
1255 --without-multipath)
ecd7bf46
ER
1256 USE_MULTIPATH=no
1257 ;;
1258 --with-multipath=*)
1259 USE_MULTIPATH=${1#--with-multipath=}
82b2dba2 1260 ;;
af075488 1261 --without-blkid)
1262 USE_BLKID=no
289fbc9b 1263 ;;
3ef3d717
ER
1264 --without-luks)
1265 USE_LUKS=no
1266 ;;
82b2dba2
ER
1267 --with=*)
1268 BASICMODULES="$BASICMODULES ${1#--with=}"
1269 ;;
1270 --with)
1271 BASICMODULES="$BASICMODULES $2"
1272 shift
1273 ;;
1274 --version)
1275 echo "$PROGRAM: version $VERSION"
1276 exit 0
1277 ;;
1278 -v)
02ba8ab7
ER
1279 if [ x"$verbose" = x"-v" ]; then
1280 verbose="-v -v"
1281 else
1282 verbose="-v"
1283 fi
11ab0dea 1284 exec 3>&1
82b2dba2 1285 ;;
c552503c
ER
1286 --compress)
1287 COMPRESS=$2
1288 ;;
1289 --compress=*)
1290 COMPRESS="${1#--compress=}"
1291 ;;
82b2dba2
ER
1292 --nocompress)
1293 COMPRESS=no
1294 ;;
ccd1f65f 1295 --nostrip)
76a48507
ER
1296 STRIP=
1297 ;;
1298 --strip=*)
1299 STRIP="${1#--strip=}"
1300 ;;
1301 --strip)
1302 STRIP=$2
1303 shift
ccd1f65f 1304 ;;
82b2dba2
ER
1305 --ifneeded)
1306 ifneeded=1
1307 ;;
1308 -f)
1309 force=1
1310 ;;
1311 --preload=*)
1312 PREMODS="$PREMODS ${1#--preload=}"
1313 ;;
1314 --preload)
1315 PREMODS="$PREMODS $2"
1316 shift
1317 ;;
2965cab9 1318 --fs=* | --fs)
bbbc32d0 1319 die "--fs option is obsoleted. Use --initrdfs instead"
82b2dba2
ER
1320 ;;
1321 --initrdfs=*)
1322 INITRDFS=${1#--initrdfs=}
1323 ;;
1324 --initrdfs)
1325 INITRDFS=$2
1326 shift
1327 ;;
1328 --image-version)
1329 img_vers=yes
1330 ;;
1331 --ide-only-root)
1332 ide_only_root="yes"
1333 ;;
1334 *)
1335 if [ -z "$target" ]; then
1336 target="$1"
1337 elif [ -z "$kernel" ]; then
1338 kernel="$1"
1339 else
7f6e5359 1340 usage
36523626 1341 exit 1
82b2dba2
ER
1342 fi
1343 ;;
1344 esac
f5db170b 1345
82b2dba2
ER
1346 shift
1347done
1348
1349if [ -z "$target" -o -z "$kernel" ]; then
7f6e5359 1350 usage
36523626 1351 exit 1
82b2dba2
ER
1352fi
1353
93a38d1a
ER
1354# main()
1355if [ "$(id -u)" != 0 ]; then
1356 die "You need to be root to generate initrd"
1357fi
1358
c45a111c
ER
1359for dir in libx32 lib64 lib; do
1360 initrd_dir=/usr/$dir/initrd
1361 if [ -d "$initrd_dir" ]; then
1362 initrd_dirs="$initrd_dirs $initrd_dir"
1363 fi
1364done
1365
1366if [ -d /libx32 -a -d /usr/libx32 ]; then
1367 _lib=libx32
1368elif [ -d /lib64 -a -d /usr/lib64 ]; then
c124d0cf
ER
1369 _lib=lib64
1370else
1371 _lib=lib
130aadc1
ER
1372fi
1373
e4487862
AM
1374kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1375kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
82b2dba2 1376
b7114dde 1377verbose "# geninitrd $VERSION"
c124d0cf
ER
1378debug "Using _lib: $_lib"
1379debug "Using initrd_dir: $initrd_dir"
1380
6ec4aea6 1381busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
c124d0cf
ER
1382
1383# we setup mods after parsing command line args
1384geninitrd_setup_mods
1385
1386if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1387 warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1388fi
1389
82b2dba2 1390if [ -z "$INITRDFS" ]; then
bbbc32d0
ER
1391 if [ -n "$FS" ]; then
1392 # FS= can came only via /etc/sysconfig/geninitrd likely?
1393 die "FS configuration option is obsoleted. Use INITRDFS instead"
f5db170b 1394 fi
f5db170b 1395
bbbc32d0
ER
1396 # default value
1397 if [ "$kernel_version" -ge "002005" ]; then
1398 INITRDFS="initramfs"
1399 else
1400 INITRDFS="rom"
1401 fi
82b2dba2 1402fi
966c32cc 1403
82b2dba2 1404case "$INITRDFS" in
4877276e
ER
1405 ext2)
1406 [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1407 ;;
1408 rom|romfs)
1409 [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1410 ;;
1411 cram|cramfs)
1412 [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1413 ;;
1414 initramfs)
1415 [ -x /bin/cpio ] || die "/bin/cpio is missing"
1416 [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1417 ;;
1418 *)
1419 die "Filesystem $INITRDFS on initrd is not supported"
1420 ;;
82b2dba2 1421esac
f5db170b 1422
9323ada3 1423if [ -L "$target" ]; then
1424 target=$(readlink -f "$target")
1425fi
1426
82b2dba2
ER
1427if [ -n "$img_vers" ]; then
1428 target="$target-$kernel"
1429fi
8bd582f1 1430
82b2dba2
ER
1431if [ -z "$force" -a -f "$target" ]; then
1432 die "$target already exists."
1433fi
c6c6ce01 1434
82b2dba2
ER
1435if [ ! -d "/lib/modules/$kernel" ]; then
1436 die "/lib/modules/$kernel is not a directory."
1437fi
2ffb1734 1438
bbbc32d0
ER
1439if [ "$kernel_version" -ge "002005" ]; then
1440 modext=".ko"
1441fi
1442
82b2dba2
ER
1443cache_modprobe_conf
1444
1445for n in $PREMODS; do
046c68c9 1446 find_module "$n"
82b2dba2
ER
1447done
1448
ed30e3a8 1449if [ "$FBMODULE" ]; then
046c68c9 1450 find_module "$FBMODULE"
ed30e3a8
ER
1451fi
1452
cefcd7bb
AM
1453# autodetect USB keyboards
1454find_modules_usbkbd
1455
82b2dba2 1456# allow forcing loading SCSI and/or IDE modules
35043b20 1457# XXX: where ADDSCSI cames from? drop?
82b2dba2
ER
1458if is_yes "$ADDSCSI"; then
1459 find_modules_scsi
1460fi
1461
3f53322c 1462# autodetect SATA modules
1463find_modules_sata
e2d6ca6c 1464
35043b20 1465# XXX: where ADDIDE cames from? drop?
82b2dba2
ER
1466if is_yes "$ADDIDE"; then
1467 find_modules_ide
1468fi
1469
4c16dac4
ER
1470if is_yes "$USE_SUSPEND"; then
1471 find_modules_suspend
1472fi
1473
82b2dba2 1474find_root "$fstab" || exit
02ba8ab7 1475verbose "Using $rootdev as device for rootfs"
82b2dba2 1476
d8056591 1477find_modules_for_devpath "$rootdev"
ac085800 1478
ecd7bf46
ER
1479# if USE_MULTIPATH is path to device, scan that too
1480# this is to bootstrap multipath setup into initrd.
1481if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1482 find_modules_multipath $USE_MULTIPATH
1483fi
1484
046c68c9 1485find_module "-$rootFs"
ac085800 1486
82b2dba2 1487for n in $BASICMODULES; do
046c68c9 1488 find_module "$n"
82b2dba2 1489done
4e9eb79c 1490
82b2dba2 1491if is_yes "$USE_TUXONICE"; then
046c68c9 1492 find_module "-lzf"
82b2dba2 1493fi
33d24e12 1494
2d769917 1495find_modules_uvesafb
bf6d9c64 1496find_modules_fbsplash
2968c9dd 1497
82b2dba2 1498if [ -n "$ifneeded" -a -z "$MODULES" ]; then
02ba8ab7 1499 verbose "No modules are needed -- not building initrd image."
82b2dba2
ER
1500 exit 0
1501fi
c6c6ce01 1502
02ba8ab7 1503verbose "Building initrd..."
d8056591 1504DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
9b557a09 1505RCFILE="$DESTDIR/linuxrc"
82b2dba2
ER
1506> "$RCFILE"
1507chmod a+rx "$RCFILE"
9b557a09 1508ln -s linuxrc $DESTDIR/init
e8d178ff 1509
82b2dba2 1510# create dirs that we really need
d63131e0 1511inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
e8d178ff 1512
82b2dba2 1513modules_install "$MODULES"
b64f015b 1514
82b2dba2
ER
1515# mknod'ing the devices instead of copying them works both with and
1516# without devfs...
6b45dd6c
AM
1517mknod -m 600 "$DESTDIR/dev/console" c 5 1
1518mknod -m 666 "$DESTDIR/dev/null" c 1 3
1519mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1520mknod -m 666 "$DESTDIR/dev/random" c 1 8
1521mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
2b945b6b 1522mknod -m 644 "$DESTDIR/dev/kmsg" c 1 11
be2f3ecc 1523
6ec4aea6
JR
1524inst_exec $busybox /bin/busybox
1525ln -s busybox $DESTDIR/bin/sh
1526# for older busyboxes who had /bin/initrd-busybox as EXEPATH
1527ln -s busybox $DESTDIR/bin/initrd-busybox
2ffb1734 1528
82b2dba2
ER
1529add_linuxrc <<EOF
1530#!/bin/sh
b7114dde 1531# initrd generated by geninitrd/$VERSION
8938f33d 1532# on $(LC_ALL=C date)
c6c6ce01 1533
82b2dba2 1534EOF
ff9aded5 1535load_font
82b2dba2 1536mount_proc
2b945b6b
ER
1537
1538kmsg "geninitrd/$VERSION starting"
1539
0fb9dda3
ER
1540add_linuxrc <<-EOF
1541 # builtin defaults from geninitrd
1542 ROOT=$rootdev
1543 ROOTFS=$rootFs
1544EOF
82b2dba2 1545add_linuxrc <<-'EOF'
48d98595 1546 read CMDLINE < /proc/cmdline
c6c6ce01 1547
82b2dba2 1548 for arg in $CMDLINE; do
04bffd7a 1549 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
82b2dba2
ER
1550 DEBUGINITRD=yes
1551 fi
04bffd7a
ER
1552 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1553 DEBUGINITRD=${arg##debug*rd=}
82b2dba2 1554 fi
fc787d45 1555 if [ "${arg##root=}" != "${arg}" ]; then
1556 ROOT=${arg##root=}
1557 fi
144396dd
AM
1558 if [ "${arg##rootflags=}" != "${arg}" ]; then
1559 ROOTFLAGS=${arg##rootflags=}
db795d06 1560 fi
41d3645c
AM
1561 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1562 ROOTFSFLAGS=${arg##rootfsflags=}
1563 fi
0fb9dda3
ER
1564 if [ "${arg##init=}" != "${arg}" ]; then
1565 INIT=${arg##init=}
1566 fi
82b2dba2 1567 done
c6c6ce01 1568
144396dd
AM
1569 # handling of invalid, rootfsflags, option
1570 if [ -n "$ROOTFSFLAGS" ]; then
1571 if [ -n "$ROOTFLAGS" ]; then
1572 ROOTFLAGS="$ROOTFLAGS,$ROOTFSFLAGS"
1573 else
1574 ROOTFLAGS="$ROOTFSFLAGS"
1575 fi
1576 fi
1577
82b2dba2 1578 if [ "$DEBUGINITRD" = "sh" ]; then
8938f33d 1579 # export some vars to subshell for debug to work
144396dd 1580 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFLAGS DEBUGINITRD INIT
4569a02c
ER
1581 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1582 export rootnr attrs majmin major minor device
1583
1584 # make debugshell() invoke subshell if $DEBUGINITRD=sh
82b2dba2 1585 debugshell() {
e2405b29
AM
1586EOF
1587if is_yes "$RUN_SULOGIN_ON_ERR"; then
1588add_linuxrc <<-'EOF'
0273c2c4 1589 echo "debug shell disabled by RUN_SULOGIN_ON_ERR=yes from /etc/sysconfig/system during initrd generation time"
e2405b29
AM
1590EOF
1591else
1592add_linuxrc <<-'EOF'
1593 sh
1594EOF
1595fi
1596add_linuxrc <<-'EOF'
82b2dba2
ER
1597 }
1598 else
1599 debugshell() {
1600 :
1601 }
1602 fi
e934d044 1603
82b2dba2
ER
1604 if [ "$DEBUGINITRD" ]; then
1605 set -x
cff3058d 1606 fi
82b2dba2 1607EOF
2df2e995 1608
fe280785 1609modules_add_linuxrc $MODULES
82b2dba2
ER
1610
1611# TODO: rewrite for busybox
1612#if [ -n "$loopDev" ]; then
1613# if [ ! -d /initrd ]; then
1614# mkdir /initrd
1615# fi
1616#
9b557a09
ER
1617# cp -a "$loopDev" "$DESTDIR/dev"
1618# cp -a "$rootdev" "$DESTDIR/dev"
82b2dba2
ER
1619# echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1620# echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1621# echo "echo Setting up loopback device $rootdev" >> $RCFILE
1622# echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1623#fi
2b1a3707 1624
1606e343
AM
1625if is_yes "$USE_UDEV"; then
1626 initrd_gen_udev
382ce856
AM
1627else
1628 initrd_gen_mdev
1606e343
AM
1629fi
1630
3dd50160 1631initrd_gen_uvesafb
1b481849
ER
1632initrd_gen_luks
1633initrd_gen_dmraid
1634initrd_gen_multipath
1635initrd_gen_blkid
289fbc9b 1636
69b1e935 1637if is_yes "$have_nfs"; then
2df2e995 1638 initrd_gen_nfs
1b481849
ER
1639else
1640 initrd_gen_md
1641 initrd_gen_lvm
2d769917 1642 initrd_gen_bcache
d222b474 1643 initrd_gen_blkid
1b481849 1644 initrd_gen_luks
4828c787 1645 initrd_gen_setrootdev
7c38b114
AF
1646fi
1647
5101a385 1648# additional devs always needed
9b557a09 1649[ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
5101a385 1650
1b481849 1651initrd_gen_stop_udevd
382ce856 1652initrd_gen_stop_mdev
6fadace4 1653initrd_gen_stop_uvesafb
82de999f 1654
4a362aea
ER
1655# resume after killing local processes
1656initrd_gen_tuxonice
1657initrd_gen_suspend
1658
52a92a2a
ER
1659# clean up env
1660add_linuxrc <<-'EOF'
4569a02c 1661if [ ! "$DEBUGINITRD" ]; then
52a92a2a
ER
1662 ifs=$IFS
1663 IFS="
1664 "
1665 for i in $(export -p); do
1666 i=${i#declare -x } # ksh/bash
1667 i=${i#export } # busybox
1668
1669 case "$i" in
1670 *=*)
1671 : ;;
1672 *)
1673 continue ;;
1674 esac
1675
1676 i=${i%%=*}
1677
1678 [ -z "$i" ] && continue
1679
1680 case "$i" in
62028605 1681 ROOT|PATH|HOME|TERM)
52a92a2a
ER
1682 :
1683 ;;
1684 *)
62028605 1685 unset $i
52a92a2a
ER
1686 ;;
1687 esac
1688 done
1689 IFS=$ifs
4569a02c 1690fi
52a92a2a
ER
1691EOF
1692
f8f9e56d 1693if [ "$INITRDFS" = "initramfs" ]; then
4671d086 1694 initrd_gen_initramfs_switchroot
b64f015b 1695else
b64f015b 1696 umount_all
f8f9e56d
AM
1697fi
1698
1b481849
ER
1699initrd_gen_fbsplash
1700initrd_gen_fbcondecor
6c69a2d4 1701
b7114dde 1702debug "Current /linuxrc:\n$(sed -e 's,^,| ,' $DESTDIR/linuxrc)"
2990ac33 1703
d8056591 1704IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
51dc1fe6 1705
5c7359e3 1706IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
02ba8ab7 1707verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
5c7359e3 1708
02ba8ab7 1709verbose "Creating $INITRDFS image $IMAGE"
2ad94d8a 1710case "$INITRDFS" in
4877276e 1711 ext2)
4877276e 1712 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
c091a192
ER
1713 # NOTE: ext2 label is max 16 chars
1714 mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
4877276e
ER
1715 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1716
1717 local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1718 debug "Mounting ext2 image $IMAGE to $tmpmnt"
5c7359e3 1719 mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
4877276e
ER
1720 # We don't need this directory, so let's save space
1721 rm -rf "$tmpmnt"/lost+found
1722
1723 debug "Copy recursively $DESTDIR -> $tmpmnt"
1724 cp -a $DESTDIR/* $tmpmnt
1725 umount "$IMAGE"
1726 rmdir "$tmpmnt"
1727
1728 ;;
1729 rom|romfs)
c091a192 1730 genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
4877276e
ER
1731 ;;
1732 cram|cramfs)
1733 mkcramfs "$DESTDIR" "$IMAGE"
1734 ;;
1735 initramfs)
1736 (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1737 ;;
1738 *)
93a38d1a 1739 die "Filesystem $INITRDFS not supported by $PROGRAM"
c31050f3 1740esac
bb529f94 1741
755e5cdc 1742CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
25cb53df
ER
1743if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1744 CONFIG_BLK_DEV_RAM_SIZE=4096
3fbd853a 1745 warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
25cb53df 1746fi
e3bc44e2 1747
e3bc44e2
ER
1748if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1749 warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1750fi
1751
c552503c 1752if ! is_no "$COMPRESS"; then
c552503c 1753 compressor=$(find_compressor "$COMPRESS")
02ba8ab7 1754 verbose "Compressing $target with $compressor"
c552503c
ER
1755
1756 # TODO: the image name (specified from kernel.spec) already contains
1757 # extension, which is .gz most of the time.
97f51b6e
ER
1758 compress_image "$compressor" "$IMAGE" "$target" || {
1759 if [ $compressor != gzip ]; then
1760 warn "Could not compress with $compressor, retrying with gzip"
1761 compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1762 else
1763 die "Could not compress image with $compressor"
1764 fi
1765 }
bb529f94 1766else
7d2fc5eb 1767 cp -a "$IMAGE" "$target"
bb529f94 1768fi
5b71959c 1769
7992356a 1770# XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1b481849 1771initrd_gen_bootsplash "$target"
5b71959c 1772
d8056591 1773rm -rf "$DESTDIR" "$IMAGE"
ac085800
ER
1774
1775# vim:ts=4:sw=4:noet:fdm=marker
This page took 0.537434 seconds and 4 git commands to generate.