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