]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
Preload crct10dif module when crc-t10dif is going to be loaded (uses its symbols...
[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"
400                                         ;;
401                                 libcrc32c)
402                                         find_depmod "-crc32c-intel"
403                                         find_depmod "-crc32c"
404                                         ;;
405                                 virtio_blk|virtio_scsi)
406                                         find_depmod "-virtio_pci"
407                                         find_depmod "-virtio_mmio"
408                                         ;;
409                         esac
410
411                         echo $modpath
412                 fi
413         done
414         return 0
415 }
416
417 find_firmware() {
418         local module="$1"
419
420         # no firmware support in 2.4 kernels
421         if [ "$kernel_version_long" -lt "002005048" ]; then
422                 return
423         fi
424         echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
425 }
426
427 # @param        $module
428 find_module() {
429         local mod depmod module=$1
430
431         depmod=$(find_depmod $module) || exit 1
432         for mod in $depmod; do
433                 mod=${mod#/lib/modules/$kernel/}
434
435                 # add each module only once
436                 local m have=0
437                 for m in $MODULES; do
438                         [ $m = $mod ] && have=1
439                 done
440                 if [ $have = 0 ]; then
441                         MODULES="$MODULES $mod"
442                 fi
443         done
444 }
445
446 # install a file to temporary mount image.
447 # it will operate recursively (copying directories)
448 # and will symlink destinations if source is symlink.
449 inst() {
450         if [ $# -lt 2 ]; then
451                 die 'Usage: inst <file> [<file>] <destination>'
452         fi
453
454         local src i=0 c=$(($# - 1))
455         while [ $i -lt $c ]; do
456                 src="$src $1"
457                 i=$((i + 1))
458                 shift
459         done
460         local dest=$1
461         set -- $src
462         local parentDir=$(dirname $DESTDIR$dest)
463         if [ ! -d "$parentDir" ]; then
464                 verbose "+ mkdir -p $parentDir"
465                 mkdir -p $parentDir
466         fi
467         verbose "+ cp $* $DESTDIR$dest"
468         cp -HR "$@" "$DESTDIR$dest"
469 }
470
471 inst_d() {
472         if [ $# = 0 ]; then
473                 die 'Usage: inst_d <destination> <destination>'
474         fi
475         for dir in "$@"; do
476                 install -d "$DESTDIR$dir"
477         done
478 }
479
480 # install executable and it's shared libraries
481 inst_exec() {
482         if [ $# -lt 2 ]; then
483                 die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
484         fi
485         local src i=0 c=$(($# - 1))
486         while [ $i -lt $c ]; do
487                 src="$src $1"
488                 i=$((i + 1))
489                 shift
490         done
491         local dest=$1
492         set -- $src
493
494         inst "$@" $dest
495
496         local obj lib libs
497         for obj in "$@"; do
498                 case "$obj" in
499                         /lib/ld-linux.so.2 | /lib64/ld-linux-x86-64.so.2)
500                         continue
501                 esac
502
503                 libs=$(ldd "$obj" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
504                 for lib in $libs; do
505                         if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
506                                 inst_d /$_lib
507                                 inst_exec $lib /$_lib
508                         fi
509                 done
510         done
511
512         # hack for uclibc linked binaries requiring this fixed path
513         # XXX: shouldn't rpath be used here instead so th
514         if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
515                 local lib=$DESTDIR/$_lib/libc.so.0
516                 lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
517                 local libdir=$(cd $(dirname "$lib"); pwd)
518                 if [ ! -e $DESTDIR$libdir ]; then
519                         libdir=$(dirname "$libdir")
520                         inst_d $libdir
521                         verbose "+ ln -s /$_lib $DESTDIR$libdir"
522                         ln -s /$_lib $DESTDIR$libdir
523                 fi
524         fi
525 }
526
527 # output modules.conf / modprobe.conf
528 modprobe_conf() {
529         echo "$modprobe_conf_cache"
530 }
531
532 # return options for MODULE
533 # @param $1 module name
534 modprobe_options() {
535         local module=$1
536         local options=$(modprobe_conf | awk -vmodule="$module" '{ if ($1 == "options" && $2 == module) { for(i=3;i<=NF;i++) printf("%s ",$i); }}')
537         echo ${options# }
538 }
539
540 #
541 # defaults to modprobe -c if not told otherwise, this means include statements
542 # work from there.
543 cache_modprobe_conf() {
544         if [ "$kernel_version" -lt "002005" ]; then
545                 modulefile=/etc/modules.conf
546                 if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
547                         modulefile=/etc/conf.modules
548                 fi
549         fi
550
551         if [ -n "$modulefile" ]; then
552                 debug "Using $modulefile for modules config"
553                 modprobe_conf_cache=$(cat $modulefile | awk '!/^[\t ]*#/ { print }')
554
555         else
556                 debug "Using modprobe -c to get modules config"
557                 modprobe_conf_cache=$(modprobe -c --set-version $kernel | awk '!/^[\t ]*#/ { print }')
558         fi
559 }
560
561 # find modules for $devpath
562 find_modules_for_devpath() {
563         local devpath="$1"
564         if [ -z "$devpath" ]; then
565                 die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
566         fi
567
568         if [[ "$devpath" = /dev/dm-* ]]; then
569                 # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
570                 devpath=$(dm_node "$devpath")
571         fi
572
573         if [ -L "$devpath" ] && ! is_lvm "$devpath" && ! is_luks "$devpath"; then
574                 # sanitize things like:
575                 # /dev/block/104:2 -> /dev/cciss/c0d0p2
576                 devpath=$(readlink -f "$devpath")
577         fi
578
579         verbose "Finding modules for device path $devpath"
580
581         if is_luks "$devpath"; then
582                 find_modules_luks "$devpath"
583                 return
584         fi
585
586         if is_nfs "$devpath"; then
587                 find_modules_nfs "$devpath"
588                 return
589         fi
590
591         if is_md "$devpath"; then
592                 find_modules_md "$devpath"
593                 return
594         fi
595
596         if is_multipath "$devpath"; then
597                 if find_modules_multipath "$devpath"; then
598                         return
599                 fi
600
601                 # fallback
602         fi
603
604         if is_dmraid "$devpath"; then
605                 if find_modules_dmraid "$devpath"; then
606                         return
607                 fi
608                 # fallback
609         fi
610
611         if is_scsi "$devpath"; then
612                 find_modules_scsi "$devpath"
613                 return
614         fi
615
616         if is_ide "$devpath"; then
617                 find_modules_ide "$devpath"
618                 return
619         fi
620
621         if [[ "$devpath" == /dev/rd/* ]]; then
622                 find_module "DAC960"
623                 rootdev_add=/dev/rd/
624                 return
625         fi
626
627         if [[ "$devpath" == /dev/ida/* ]]; then
628                 find_module "cpqarray"
629                 rootdev_add=/dev/ida/
630                 return
631         fi
632
633         if [[ "$devpath" == /dev/cciss/* ]]; then
634                 rootdev_add=/dev/cciss/
635
636                 # load hpsa for future kernels, cciss for backwards compat
637                 if [ "$kernel_version_long" -ge "003000000" ]; then
638                         find_module "hpsa" "-cciss"
639                         find_modules_scsi "$devpath"
640                 else
641                         find_module "cciss"
642                 fi
643
644                 return
645         fi
646
647         if [[ "$devpath" == /dev/ataraid/* ]]; then
648                 find_modules_ide
649                 find_module "ataraid"
650                 ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ { print $3 }')
651                 if [ -n "$ataraidmodules" ]; then
652                         # FIXME: think about modules compiled in kernel
653                         die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
654                 fi
655                 for n in $ataraidmodules; do
656                         find_module "$n"
657                 done
658                 rootdev_add=/dev/ataraid/
659                 return
660         fi
661
662         # check to see if we need to set up a loopback filesystem
663         if [[ "$devpath" == /dev/loop*  ]]; then
664                 die "Sorry, root on loop device isn't supported."
665                 # TODO: rewrite for bsp and make nfs ready
666                 if [ ! -x /sbin/losetup ]; then
667                         die "losetup is missing"
668                 fi
669                 key="^# $(echo $devpath | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
670                 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`"; then
671                         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"
672                 fi
673
674                 line="`awk '/'$key'/ { print $0; }' $fstab`"
675                 loopDev="$(echo $line | awk '{print $3}')"
676                 loopFs="$(echo $line | awk '{print $4}')"
677                 loopFile="$(echo $line | awk '{print $5}')"
678
679                 BASICMODULES="$BASICMODULES -loop"
680                 find_module "-$loopFs"
681                 BASICMODULES="$BASICMODULES -${loopFs}"
682                 return
683         fi
684
685         if is_lvm "$devpath"; then
686                 find_modules_lvm "$devpath"
687                 return
688         fi
689 }
690
691 firmware_install_module() {
692         local module="$1"
693         local firmware_files="$2"
694
695         verbose "Adding Firmwares ($firmware_files) to initrd for module $module"
696         # firmware not yet installed
697         if [ ! -f "$DESTDIR/lib/firmware/firmware.sh" ]; then
698                 inst_d /lib/firmware
699 cat << 'EOF' >> "$DESTDIR/lib/firmware/firmware.sh"
700 #!/bin/sh -e
701 echo 1 > /sys$DEVPATH/loading
702 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
703 echo 0 > /sys$DEVPATH/loading
704 exit 0
705 EOF
706                 chmod 755 "$DESTDIR/lib/firmware/firmware.sh"
707
708                 # setup firmware loader agent
709                 echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" | add_linuxrc
710         fi
711
712         for firmware in $firmware_files; do
713                 if [ -f "/lib/firmware/$kernel/$firmware" ]; then
714                         FIRMWAREDIR=${firmware%/*}
715                         [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
716                         inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
717                 elif [ -f "/lib/firmware/$firmware" ]; then
718                         FIRMWAREDIR=${firmware%/*}
719                         [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
720                         inst /lib/firmware/$firmware /lib/firmware/$firmware
721                 else
722                         warn "Possible missing firmware file /lib/firmware/$firmware or /lib/firmware/$kernel/$firmware for module $module."
723                 fi
724         done
725
726         mount_sys
727 }
728
729 modules_install() {
730         local modules="$1"
731         local mod
732
733         for mod in $modules; do
734                 MODULEDIR=${mod%/*}
735                 inst_d "/lib/modules/$kernel/$MODULEDIR"
736                 cp -a "/lib/modules/$kernel/$mod" "$DESTDIR/lib/modules/$kernel/$mod"
737                 gunzip "$DESTDIR/lib/modules/$kernel/$mod" 2> /dev/null
738                 if [ "$STRIP" ] && [ -x "$STRIP" ]; then
739                         $STRIP -g --remove-section=.comment "$DESTDIR/lib/modules/$kernel/${mod%.gz}"
740                 fi
741         done
742 }
743
744 modules_add_linuxrc() {
745         local mod modpath
746
747         for mod in "$@"; do
748                 # module path without optional compression
749                 modpath=${mod%.gz}
750
751                 # name of the module
752                 local module=${modpath##*/}; module=${module%$modext}
753                 local options=$(modprobe_options "$module")
754                 local genericname=$(echo $module | tr - _)
755                 local usleep=$(eval echo \$MODULE_${genericname}_USLEEP)
756                 local firmware=$(eval echo \$MODULE_${genericname}_FIRMWARE)
757
758                 if [ "$module" = "scsi_mod" -a "$kernel_version_long" -ge "002006030" ]; then
759                         options="scan=sync $options"
760                 fi
761
762                 if [ x"$verbose" = x"-v" ]; then
763                         s=""
764                         if [ "$options" ]; then
765                                 s="$s with options [$options]"
766                         fi
767                         if [ "$usleep" ]; then
768                                 s="$s and $usleep usleep"
769                         fi
770                         verbose "Loading module [$module]$s"
771                 fi
772
773                 if [ -n "$firmware" ]; then
774                         firmware_install_module "$module" "$firmware"
775                 else
776                         for file in $(find_firmware "$module"); do
777                                 firmware_install_module "$module" "$file"
778                         done
779                 fi
780
781                 echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
782                 if [ -n "$usleep" ]; then
783                         echo "usleep $usleep" | add_linuxrc
784                 fi
785                 if [ "$module" = "scsi_wait_scan" ]; then
786                         if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
787                                 echo "rmmod scsi_wait_scan" | add_linuxrc
788                         fi
789                 fi
790
791         done
792 }
793
794 # Generates /dev nodes based on /proc/partitions information.
795 # Needs /proc mounted.
796 # Can be called multiple times.
797 initrd_gen_devices() {
798         if is_yes "$proc_partitions"; then
799                 return
800         fi
801         proc_partitions=yes
802
803         mount_dev
804         add_linuxrc <<-'EOF'
805                 : 'Making device nodes'
806                 cat /proc/partitions | (
807                         # ignore first two lines: header, empty line
808                         read b; read b
809
810                         while read major minor blocks dev rest; do
811                                 node=/dev/$dev
812                                 mkdir -p ${node%/*}
813                                 [ -e $node ] || mknod -m 660 $node b $major $minor
814                         done
815                 )
816         EOF
817 }
818
819
820 initrd_gen_setrootdev() {
821         verbose "Adding rootfs finding based on kernel cmdline root= option support."
822         busybox_applet ls
823         debug "Current /proc/partitions:\n$(sed -e 's,^,> ,' /proc/partitions)"
824         add_linuxrc <<-'EOF'
825                 if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
826                         rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
827                         # fallback to ls
828                         if [ -z "$rootnr" ]; then
829                                 rootnr="$(busybox ls -lL ${ROOT} | busybox awk '{if (/^b/) { print 256 * $3 + $4; }}')"
830                         fi
831                         if [ -n "$rootnr" ]; then
832                                 echo "$rootnr" > /proc/sys/kernel/real-root-dev
833                         fi
834                 fi
835         EOF
836 }
837
838 initrd_gen_initramfs_switchroot() {
839         inst_d /newroot
840         if [ "$rootdev" = "/dev/nfs" ]; then
841                 echo "rootfs on NFS root=/dev/nfs"
842         else
843                 [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
844         fi
845
846         # parse 'root=xxx' kernel commandline
847         # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
848
849         # from lilo-23.2/readme/README:
850         # root=<device> changes the root device. This overrides settings that may
851         # have been made in the boot image and on the LILO command line. <device> is
852         # either the hexadecimal device number or the full path name of the device,
853         # e.g. /dev/hda3 [*]
854         #
855         #  *  The device names are hard-coded in the kernel. Therefore, only the
856         #         "standard" names are supported and some less common devices may not be
857         #         recognized. In those cases, only numbers can be used.
858         busybox_applet cat
859         add_linuxrc <<-'EOF'
860                 device=
861                 eval "$(busybox awk -v root="$ROOT" '
862                         # http://9fans.net/archive/2006/09/261
863                         function h2d(str, hstr, res, num, n, digit, i) {
864                                 hstr = "0123456789abdcef";
865                                 res = 0;
866                                 n = split(tolower(str), digit, "");
867
868                                 for (i = 1; i <= n; i++) {
869                                         num = index(hstr, digit[i]) - 1;
870                                         res = res + (num * 16 ^ (n - i));
871                                 }
872
873                                 return res;
874                         }
875                         BEGIN {
876
877                                 num_pattern_short = "[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]";
878                                 num_pattern = "[0-9a-fA-F]" num_pattern_short;
879                                 dev_pattern = "[hms][a-z][a-z]([0-9])+";
880                                 partition = "";
881                                 min = -1; maj = -1;
882
883                                 # see if we have /dev/hdX or hdX, we can just take partition name
884                                 if (root ~ "^\/dev\/" dev_pattern "$" || root ~ "^" dev_pattern "$") {
885                                         partition = root
886                                         sub("^/dev/", "", partition);
887
888                                 } else {
889                                         # unify values first
890                                         if (root ~ "^" num_pattern_short "$")  {
891                                                 # change "303" => "0x0303"
892                                                 root = "0x0" root
893                                         } else if (root ~ "^" num_pattern "$")  {
894                                                 # change "0303" => "0x0303"
895                                                 root = "0x" root
896                                         }
897
898                                         maj = h2d(substr(root, 3, 2));
899                                         min = h2d(substr(root, 5, 2));
900                                 }
901                         }
902
903                         partition && $4 == partition { maj = $1; min = $2; }
904                         $1 == maj && $2 == min { partition = $4; }
905
906                         END {
907                                 if (maj >= 0 && min >= 0) {
908                                         printf("maj=%s; min=%s;\n", maj, min);
909                                 }
910                                 if (partition) {
911                                         printf("device=/dev/%s;\n", partition);
912                                 }
913                         }
914                         ' /proc/partitions)"
915
916                 if [ -z "$device" ]; then
917                         if [ "$DEBUGINITRD" ]; then
918                                 cat /proc/partitions
919                         fi
920                         device=$ROOT
921                 fi
922
923                 if [ "$device" -a ! -b $device ]; then
924                         mknod -m 660 $device b $maj $min
925                 fi
926
927                 [ -n "$ROOTFSFLAGS" ] && ROOTFSFLAGS="-o $ROOTFSFLAGS"
928
929                 mount -t $ROOTFS -r $device $ROOTFSFLAGS /newroot || echo "Mount of rootfs failed."
930                 init=$INIT
931                 if [ -z "$init" -o ! -x "/newroot$init" ]; then
932                         init=/sbin/init
933                 fi
934         EOF
935
936         busybox_applet dmesg
937         busybox_applet tail
938         add_linuxrc <<-'EOF'
939                 if [ "$DEBUGINITRD" ]; then
940                         echo "Last 20 lines of dmesg:"
941                         dmesg | tail -n 20
942                 fi
943         EOF
944
945         umount_all
946         busybox_applet switch_root
947         add_linuxrc <<-'EOF'
948                 [ ! -e /newroot/dev/console ] && mknod -m 660 /newroot/dev/console c 5 1
949                 exec switch_root /newroot $init ${1:+"$@"}
950
951                 echo "Error! initramfs should not reach this place."
952                 echo "It probably means you've got old version of busybox, with broken"
953                 echo "initramfs support. Trying to boot anyway, but won't promise anything."
954
955                 exec chroot /newroot $init ${1:+"$@"}
956
957                 echo "Failed to chroot!"
958                 debugshell
959         EOF
960         # we need /init being real file, not symlink, otherwise the initramfs will
961         # not be ran by pid 1 which is required for switch_root
962         mv $DESTDIR/linuxrc $DESTDIR/init
963         ln -s init $DESTDIR/linuxrc
964 }
965
966 # find if $symbol exists in System.map $mapfile
967 sym_exists() {
968         local mapfile="$1"
969         local symbol="$2"
970         if [ ! -f $mapfile ]; then
971                 # missing mapfile (not a pld kernel?)
972                 return 1
973         fi
974
975         awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
976 }
977
978 # find best compressor (or forced one) for initrd
979 find_compressor() {
980         local mode="$1"
981         # fastest initrd decompression speed is first
982         local compressors='lzo gzip xz lzma bzip2'
983
984         # a specified one, take it
985         if ! is_yes "$mode"; then
986                 compressors="$mode"
987         fi
988
989         verbose "finding compressor: $compressors (via $mode)"
990         # check for compressor validity
991         local c prog map=/boot/System.map-$kernel
992         for c in $compressors; do
993                 case $c in
994                 xz)
995                         sym=unxz
996                         prog=/usr/bin/xz
997                         ;;
998                 lzma)
999                         sym=unlzma
1000                         prog=/usr/bin/xz
1001                         ;;
1002                 bzip2)
1003                         sym=bzip2
1004                         prog=/usr/bin/bzip2
1005                         ;;
1006                 gzip)
1007                         sym=gunzip
1008                         prog=/bin/gzip
1009                         ;;
1010                 lzo)
1011                         sym=unlzo
1012                         prog=/usr/bin/lzop
1013                         ;;
1014                 none|no)
1015                         # any existing sym will work
1016                         sym=initrd_load
1017                         prog=/bin/cat
1018                         ;;
1019                 *)
1020                         die "Unknown compressor $c"
1021                         ;;
1022                 esac
1023                 if sym_exists $map $sym && [ -x $prog ]; then
1024                         echo $c
1025                         return
1026                 fi
1027         done
1028
1029         verbose "using gzip for compressor (fallback)"
1030         echo gzip
1031 }
1032
1033 # compresses kernel image image
1034 # in function so we could retry with other compressor on failure
1035 compress_image() {
1036         local compressor="$1" IMAGE="$2" target="$3" tmp
1037         tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
1038
1039         case "$compressor" in
1040         xz)
1041                 # don't use -9 here since kernel won't understand it
1042                 xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp" || return $?
1043                 ;;
1044         lzma)
1045                 xz --format=lzma -9 < "$IMAGE" > "$tmp" || return $?
1046                 ;;
1047         bzip2)
1048                 bzip2 -9 < "$IMAGE" > "$tmp" || return $?
1049                 ;;
1050         gzip)
1051                 gzip -9 < "$IMAGE" > "$tmp" || return $?
1052                 ;;
1053         lzo)
1054                 lzop -9 < "$IMAGE" > "$tmp" || return $?
1055                 ;;
1056         none|no)
1057                 cat < "$IMAGE" > "$tmp" || return $?
1058                 ;;
1059         esac
1060
1061         mv -f "$tmp" "$target"
1062 }
1063
1064 if [ -r /etc/sysconfig/geninitrd ]; then
1065         . /etc/sysconfig/geninitrd
1066 fi
1067
1068 if [ ! -f /proc/mounts ]; then
1069         warn "/proc filesystem not mounted, may cause wrong results or failure."
1070 fi
1071
1072 geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs sata scsi usbkbd
1073
1074 while [ $# -gt 0 ]; do
1075         case $1 in
1076         --fstab=*)
1077                 fstab=${1#--fstab=}
1078                 ;;
1079         --fstab)
1080                 fstab=$2
1081                 shift
1082                 ;;
1083         --modules-conf=*)
1084                 modulefile=${1#--modules-conf=}
1085                 ;;
1086         --modules-conf)
1087                 modulefile=$2
1088                 shift
1089                 ;;
1090         --with-bootsplash)
1091                 BOOT_SPLASH=yes
1092                 ;;
1093         --without-bootsplash)
1094                 BOOT_SPLASH=no
1095                 ;;
1096         --with-fbsplash)
1097                 FB_SPLASH=yes
1098                 ;;
1099         --without-fbsplash)
1100                 FB_SPLASH=no
1101                 ;;
1102         --with-fbcondecor)
1103                 FB_CON_DECOR=yes
1104                 ;;
1105         --without-fbcondecor)
1106                 FB_CON_DECOR=no
1107                 ;;
1108         --with-suspend)
1109                 USE_SUSPEND=yes
1110                 ;;
1111         --without-suspend)
1112                 USE_SUSPEND=no
1113                 ;;
1114         --with-suspend2 | --with-tuxonice)
1115                 USE_TUXONICE=yes
1116                 ;;
1117         --without-suspend2 | --without-tuxonice)
1118                 USE_TUXONICE=no
1119                 ;;
1120         --lvmversion=*)
1121                 LVMTOOLSVERSION=${1#--lvmversion=}
1122                 ;;
1123         --lvmtoolsversion=*)
1124                 LVMTOOLSVERSION=${1#--lvmtoolsversion=}
1125                 ;;
1126         --lvmtoolsversion|--lvmversion)
1127                 LVMTOOLSVERSION=$2
1128                 shift
1129                 ;;
1130         --without-udev)
1131                 USE_UDEV=no
1132                 ;;
1133         --with-udev)
1134                 USE_UDEV=yes
1135                 ;;
1136         --without-dmraid)
1137                 USE_DMRAID=no
1138                 ;;
1139         --without-multipath)
1140                 USE_MULTIPATH=no
1141                 ;;
1142         --with-multipath=*)
1143                 USE_MULTIPATH=${1#--with-multipath=}
1144                 ;;
1145         --without-blkid)
1146                 USE_BLKID=no
1147                 ;;
1148         --without-luks)
1149                 USE_LUKS=no
1150                 ;;
1151         --with=*)
1152                 BASICMODULES="$BASICMODULES ${1#--with=}"
1153                 ;;
1154         --with)
1155                 BASICMODULES="$BASICMODULES $2"
1156                 shift
1157                 ;;
1158         --version)
1159                 echo "$PROGRAM: version $VERSION"
1160                 exit 0
1161                 ;;
1162         -v)
1163                 if [ x"$verbose" = x"-v" ]; then
1164                         verbose="-v -v"
1165                 else
1166                         verbose="-v"
1167                 fi
1168                 exec 3>&1
1169                 ;;
1170         --compress)
1171                 COMPRESS=$2
1172                 ;;
1173         --compress=*)
1174                 COMPRESS="${1#--compress=}"
1175                 ;;
1176         --nocompress)
1177                 COMPRESS=no
1178                 ;;
1179         --nostrip)
1180                 STRIP=
1181                 ;;
1182         --strip=*)
1183                 STRIP="${1#--strip=}"
1184                 ;;
1185         --strip)
1186                 STRIP=$2
1187                 shift
1188                 ;;
1189         --ifneeded)
1190                 ifneeded=1
1191                 ;;
1192         -f)
1193                 force=1
1194                 ;;
1195         --preload=*)
1196                 PREMODS="$PREMODS ${1#--preload=}"
1197                 ;;
1198         --preload)
1199                 PREMODS="$PREMODS $2"
1200                 shift
1201                 ;;
1202         --fs=* | --fs)
1203                 die "--fs option is obsoleted. Use --initrdfs instead"
1204                 ;;
1205         --initrdfs=*)
1206                 INITRDFS=${1#--initrdfs=}
1207                 ;;
1208         --initrdfs)
1209                 INITRDFS=$2
1210                 shift
1211                 ;;
1212         --image-version)
1213                 img_vers=yes
1214                 ;;
1215         --ide-only-root)
1216                 ide_only_root="yes"
1217                 ;;
1218         *)
1219                 if [ -z "$target" ]; then
1220                         target="$1"
1221                 elif [ -z "$kernel" ]; then
1222                         kernel="$1"
1223                 else
1224                         usage
1225                         exit 1
1226                 fi
1227                 ;;
1228         esac
1229
1230         shift
1231 done
1232
1233 if [ -z "$target" -o -z "$kernel" ]; then
1234         usage
1235         exit 1
1236 fi
1237
1238 # main()
1239 if [ "$(id -u)" != 0 ]; then
1240         die "You need to be root to generate initrd"
1241 fi
1242
1243 if [ -d /lib64 -a -d /usr/lib64 ]; then
1244         _lib=lib64
1245 else
1246         _lib=lib
1247 fi
1248
1249 initrd_dir=/usr/$_lib/initrd
1250 kernel_version=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d",$1,$2)}')
1251 kernel_version_long=$(echo "$kernel" | awk -F. '{gsub(/[_-].*/, "", $0); print sprintf("%03d%03d%03d",$1,$2,$3)}')
1252
1253 verbose "# $GENINITRD_RCSID (geninitrd)"
1254 debug "Using _lib: $_lib"
1255 debug "Using initrd_dir: $initrd_dir"
1256
1257 busybox=$(find_tool $initrd_dir/busybox $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
1258
1259 # we setup mods after parsing command line args
1260 geninitrd_setup_mods
1261
1262 if [ ! -f /boot/vmlinuz-"$kernel" ]; then
1263         warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
1264 fi
1265
1266 if [ -z "$INITRDFS" ]; then
1267         if [ -n "$FS" ]; then
1268                 # FS= can came only via /etc/sysconfig/geninitrd likely?
1269                 die "FS configuration option is obsoleted. Use INITRDFS instead"
1270         fi
1271
1272         # default value
1273         if [ "$kernel_version" -ge "002005" ]; then
1274                 INITRDFS="initramfs"
1275         else
1276                 INITRDFS="rom"
1277         fi
1278 fi
1279
1280 case "$INITRDFS" in
1281   ext2)
1282         [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
1283         ;;
1284   rom|romfs)
1285         [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
1286         ;;
1287   cram|cramfs)
1288         [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
1289         ;;
1290   initramfs)
1291         [ -x /bin/cpio ] || die "/bin/cpio is missing"
1292         [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
1293         ;;
1294   *)
1295         die "Filesystem $INITRDFS on initrd is not supported"
1296         ;;
1297 esac
1298
1299 if [ -L "$target" ]; then
1300         target=$(readlink -f "$target")
1301 fi
1302
1303 if [ -n "$img_vers" ]; then
1304         target="$target-$kernel"
1305 fi
1306
1307 if [ -z "$force" -a -f "$target" ]; then
1308         die "$target already exists."
1309 fi
1310
1311 if [ ! -d "/lib/modules/$kernel" ]; then
1312         die "/lib/modules/$kernel is not a directory."
1313 fi
1314
1315 if [ "$kernel_version" -ge "002005" ]; then
1316         modext=".ko"
1317 fi
1318
1319 cache_modprobe_conf
1320
1321 for n in $PREMODS; do
1322         find_module "$n"
1323 done
1324
1325 if [ "$FBMODULE" ]; then
1326         find_module "$FBMODULE"
1327 fi
1328
1329 # autodetect USB keyboards
1330 find_modules_usbkbd
1331
1332 # allow forcing loading SCSI and/or IDE modules
1333 # XXX: where ADDSCSI cames from? drop?
1334 if is_yes "$ADDSCSI"; then
1335         find_modules_scsi
1336 fi
1337
1338 # autodetect SATA modules
1339 find_modules_sata
1340
1341 # XXX: where ADDIDE cames from? drop?
1342 if is_yes "$ADDIDE"; then
1343         find_modules_ide
1344 fi
1345
1346 if is_yes "$USE_SUSPEND"; then
1347         find_modules_suspend
1348 fi
1349
1350 find_root "$fstab" || exit
1351 verbose "Using $rootdev as device for rootfs"
1352
1353 find_modules_for_devpath "$rootdev"
1354
1355 # if USE_MULTIPATH is path to device, scan that too
1356 # this is to bootstrap multipath setup into initrd.
1357 if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
1358         find_modules_multipath $USE_MULTIPATH
1359 fi
1360
1361 find_module "-$rootFs"
1362
1363 for n in $BASICMODULES; do
1364         find_module "$n"
1365 done
1366
1367 if is_yes "$USE_TUXONICE"; then
1368         find_module "-lzf"
1369 fi
1370
1371 find_modules_fbsplash
1372
1373 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1374         verbose "No modules are needed -- not building initrd image."
1375         exit 0
1376 fi
1377
1378 verbose "Building initrd..."
1379 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
1380 RCFILE="$DESTDIR/linuxrc"
1381 > "$RCFILE"
1382 chmod a+rx "$RCFILE"
1383 ln -s linuxrc $DESTDIR/init
1384
1385 # create dirs that we really need
1386 inst_d /{lib,bin,etc,dev{,/pts,/shm},loopfs,var,proc,run,sys}
1387
1388 modules_install "$MODULES"
1389
1390 # mknod'ing the devices instead of copying them works both with and
1391 # without devfs...
1392 mknod -m 600 "$DESTDIR/dev/console" c 5 1
1393 mknod -m 666 "$DESTDIR/dev/null" c 1 3
1394 mknod -m 666 "$DESTDIR/dev/zero" c 1 5
1395 mknod -m 666 "$DESTDIR/dev/random" c 1 8
1396 mknod -m 666 "$DESTDIR/dev/urandom" c 1 9
1397
1398 inst_exec $busybox /bin/busybox
1399 ln -s busybox $DESTDIR/bin/sh
1400 # for older busyboxes who had /bin/initrd-busybox as EXEPATH
1401 ln -s busybox $DESTDIR/bin/initrd-busybox
1402
1403 add_linuxrc <<EOF
1404 #!/bin/sh
1405 # initrd generated by:
1406 # $GENINITRD_RCSID
1407
1408 EOF
1409 mount_proc
1410 add_linuxrc <<-EOF
1411         # builtin defaults from geninitrd
1412         ROOT=$rootdev
1413         ROOTFS=$rootFs
1414 EOF
1415 add_linuxrc <<-'EOF'
1416         read CMDLINE < /proc/cmdline
1417
1418         for arg in $CMDLINE; do
1419                 if [ "${arg}" = "debuginitrd" ] || [ "${arg}" = "debugrd" ]; then
1420                         DEBUGINITRD=yes
1421                 fi
1422                 if [ "${arg##debuginitrd=}" != "${arg}" ] || [ "${arg##debugrd=}" != "${arg}" ]; then
1423                         DEBUGINITRD=${arg##debug*rd=}
1424                 fi
1425                 if [ "${arg##root=}" != "${arg}" ]; then
1426                         ROOT=${arg##root=}
1427                 fi
1428                 if [ "${arg##rootfsflags=}" != "${arg}" ]; then
1429                         ROOTFSFLAGS=${arg##rootfsflags=}
1430                 fi
1431                 if [ "${arg##init=}" != "${arg}" ]; then
1432                         INIT=${arg##init=}
1433                 fi
1434         done
1435
1436         if [ "$DEBUGINITRD" = "sh" ]; then
1437                 # export some vars for subshell debug to work
1438                 export CMDLINE ROOT ROOTFS ROOTDEV ROOTFSFLAGS DEBUGINITRD INIT
1439                 export LVM_ROOTVG LVM_SUSPENDVG LVM_VGVOLUMES
1440                 export rootnr attrs majmin major minor device
1441
1442                 # make debugshell() invoke subshell if $DEBUGINITRD=sh
1443                 debugshell() {
1444 EOF
1445 if is_yes "$RUN_SULOGIN_ON_ERR"; then
1446 add_linuxrc <<-'EOF'
1447         echo "debug shell disabled by /etc/sysconfig/system: RUN_SULOGIN_ON_ERR setting"
1448 EOF
1449 else
1450 add_linuxrc <<-'EOF'
1451         sh
1452 EOF
1453 fi
1454 add_linuxrc <<-'EOF'
1455                 }
1456         else
1457                 debugshell() {
1458                         :
1459                 }
1460         fi
1461
1462         if [ "$DEBUGINITRD" ]; then
1463                 set -x
1464         fi
1465 EOF
1466
1467 modules_add_linuxrc $MODULES
1468
1469 # TODO: rewrite for busybox
1470 #if [ -n "$loopDev" ]; then
1471 #       if [ ! -d /initrd ]; then
1472 #               mkdir /initrd
1473 #       fi
1474 #
1475 #       cp -a "$loopDev" "$DESTDIR/dev"
1476 #       cp -a "$rootdev" "$DESTDIR/dev"
1477 #       echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1478 #       echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1479 #       echo "echo Setting up loopback device $rootdev" >> $RCFILE
1480 #       echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
1481 #fi
1482
1483 if is_yes "$USE_UDEV"; then
1484         initrd_gen_udev
1485 else
1486         initrd_gen_mdev
1487 fi
1488
1489 find_modules_uvesafb
1490 initrd_gen_uvesafb
1491
1492 initrd_gen_luks
1493 initrd_gen_dmraid
1494 initrd_gen_multipath
1495 initrd_gen_blkid
1496
1497 if is_yes "$have_nfs"; then
1498         initrd_gen_nfs
1499 else
1500         initrd_gen_md
1501         initrd_gen_lvm
1502         initrd_gen_blkid
1503         initrd_gen_luks
1504         initrd_gen_setrootdev
1505 fi
1506
1507 # additional devs always needed
1508 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
1509
1510 initrd_gen_stop_udevd
1511 initrd_gen_stop_mdev
1512 initrd_gen_stop_uvesafb
1513
1514 # resume after killing local processes
1515 initrd_gen_tuxonice
1516 initrd_gen_suspend
1517
1518 # clean up env
1519 add_linuxrc <<-'EOF'
1520 if [ ! "$DEBUGINITRD" ]; then
1521         ifs=$IFS
1522         IFS="
1523         "
1524         for i in $(export -p); do
1525                 i=${i#declare -x } # ksh/bash
1526                 i=${i#export } # busybox
1527
1528                 case "$i" in
1529                 *=*)
1530                         : ;;
1531                 *)
1532                         continue ;;
1533                 esac
1534
1535                 i=${i%%=*}
1536
1537                 [ -z "$i" ] && continue
1538
1539                 case "$i" in
1540                         ROOT|PATH|HOME|TERM)
1541                                 :
1542                                 ;;
1543                         *)
1544                                 unset $i
1545                                 ;;
1546                 esac
1547         done
1548         IFS=$ifs
1549 fi
1550 EOF
1551
1552 if [ "$INITRDFS" = "initramfs" ]; then
1553         initrd_gen_initramfs_switchroot
1554 else
1555         umount_all
1556 fi
1557
1558 initrd_gen_fbsplash
1559 initrd_gen_fbcondecor
1560
1561 debug "Current /linuxrc:\n$(sed -e 's,^,> ,' $DESTDIR/linuxrc)"
1562
1563 IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
1564
1565 IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
1566 verbose "image size: $IMAGESIZE KiB ($DESTDIR)"
1567
1568 verbose "Creating $INITRDFS image $IMAGE"
1569 case "$INITRDFS" in
1570   ext2)
1571         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1572         # NOTE: ext2 label is max 16 chars
1573         mke2fs -q -F -b 1024 -m 0 -L "PLD/$kernel" "$IMAGE" 2>/dev/null 1>&2
1574         tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1575
1576         local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
1577         debug "Mounting ext2 image $IMAGE to $tmpmnt"
1578         mount -o loop -t ext2 "$IMAGE" "$tmpmnt" || die "mount failed, check dmesg(1)"
1579         # We don't need this directory, so let's save space
1580         rm -rf "$tmpmnt"/lost+found
1581
1582         debug "Copy recursively $DESTDIR -> $tmpmnt"
1583         cp -a $DESTDIR/* $tmpmnt
1584         umount "$IMAGE"
1585         rmdir "$tmpmnt"
1586
1587         ;;
1588   rom|romfs)
1589         genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD Linux/$kernel (geninitrd/$VERSION)"
1590         ;;
1591   cram|cramfs)
1592         mkcramfs "$DESTDIR" "$IMAGE"
1593         ;;
1594   initramfs)
1595         (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
1596         ;;
1597   *)
1598         die "Filesystem $INITRDFS not supported by $PROGRAM"
1599 esac
1600
1601 CONFIG_BLK_DEV_RAM_SIZE=$(ikconfig | awk -F= '/^CONFIG_BLK_DEV_RAM_SIZE/{print $2}')
1602 if [ -z "$CONFIG_BLK_DEV_RAM_SIZE" ]; then
1603         CONFIG_BLK_DEV_RAM_SIZE=4096
1604         warn "No CONFIG_BLK_DEV_RAM_SIZE detected, fallback to $CONFIG_BLK_DEV_RAM_SIZE"
1605 fi
1606
1607 if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
1608         warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
1609 fi
1610
1611 if ! is_no "$COMPRESS"; then
1612         compressor=$(find_compressor "$COMPRESS")
1613         verbose "Compressing $target with $compressor"
1614
1615         # TODO: the image name (specified from kernel.spec) already contains
1616         # extension, which is .gz most of the time.
1617         compress_image "$compressor" "$IMAGE" "$target" || {
1618                 if [ $compressor != gzip ]; then
1619                         warn "Could not compress with $compressor, retrying with gzip"
1620                         compress_image gzip "$IMAGE" "$target" || die "compress failed with gzip" $?
1621                 else
1622                         die "Could not compress image with $compressor"
1623                 fi
1624         }
1625 else
1626         cp -a "$IMAGE" "$target"
1627 fi
1628
1629 # XXX. check if bootsplash can output data to tmp dir not directly to initramfs image.
1630 initrd_gen_bootsplash "$target"
1631
1632 rm -rf "$DESTDIR" "$IMAGE"
1633
1634 # vim:ts=4:sw=4:noet:fdm=marker
This page took 0.185286 seconds and 4 git commands to generate.