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