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