]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
- use blkid optionally (but preferred) to resolve UUID= and LABEL= at initrd generati...
[projects/geninitrd.git] / geninitrd
1 #!/bin/sh
2
3 # geninitrd
4 #
5 #       by PLD Linux Team
6 #
7 # based on mkinitrd from RedHat
8 #
9 # TODO:
10 # - make udev start before insomds
11 # - make proper use of USE_UDEV - don't copy fules if USE_UDEV is off no!
12 # - sanitize - one mounting of /proc and /sys at the begining and one umount at the end!
13 # - chekup and test and ready to go!
14 #
15
16 RCSID='$Id$'
17 PATH=/sbin:$PATH
18 export PATH
19
20 VERSION="`echo "$RCSID"|awk '{print $3}'`"
21
22 . /etc/rc.d/init.d/functions
23
24 COMPRESS="yes"
25 # INITRDFS is set later (catch obsoleted FS option)
26 #INITRDFS="rom"
27 USERAIDSTART="yes"
28 USEMDADMSTATIC="no"
29 USEINSMODSTATIC="no"
30 USE_SUSPEND="yes"
31 USE_SUSPEND2="yes"
32 uselvm="no"
33 usenfs="no"
34 # it should be safe to remove scsi_mod from here, but I'm not sure...
35 PRESCSIMODS="-scsi_mod unknown -sd_mod"
36 PREIDEMODS="-ide-core unknown -ide-detect -ide-disk"
37 PREIDEMODSOLD="-ide-probe -ide-probe-mod -ide-disk"
38 target=""
39 kernel=""
40 force=""
41 verbose=""
42 MODULES=""
43 img_vers=""
44 modulefile=""
45 fstab="/etc/fstab"
46 insmod="insmod"
47 modext=".o"
48 rootdev_nr=0
49 # default bootsplash is off, if it have to be on, install bootsplash package
50 BOOT_SPLASH=no
51 # default same as bootsplash, if on install splashutils and some splashutils theme
52 FB_SPLASH=no
53 # defualt we don't use udev to make nodes for static modules, as per default
54 # PLD loads the modules needed to mount and boot
55 PROBESTATICMODULES=no
56
57 # is /dev on tmpfs. internal variable
58 tmpfs_dev=
59
60 if [ -f /etc/udev/udev.conf -a -x /sbin/initrd-udevd ]; then
61         USE_UDEV="yes"
62         . /etc/udev/udev.conf
63 fi
64
65 if [ -x /sbin/dmraid-initrd ]; then
66         USE_DMRAID="yes"
67 fi
68
69 usage () {
70         echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
71         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
72         echo "       [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]"
73         echo "       [--with-raidstart] [--without-raidstart] [--with-insmod-static]"
74         echo "       [--without-bootsplash] [--without-fbsplash]"
75         echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
76         echo "       [--without-suspend] [--without-suspend2] [--without-dmraid]"
77         echo "       <initrd-image> <kernel-version>"
78         echo "       (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)"
79         exit 1
80 }
81
82 debug() {
83         [ -n "$verbose" ] && echo "$*"
84 }
85
86 find_depmod () {
87         typeset mods module f level depfile first
88
89         depfile=/lib/modules/$kernel/modules.dep
90
91         if [ -f $depfile ] ; then
92                 : ok
93         else
94                 echo >&2 "Error: no $depfile ! Run depmod and rerun geninitrd."
95                 exit 1
96         fi
97
98         # prepend / if no path given, append $modext.gz if not given,
99         # quote /
100         origmodule="$2"
101         module=$(echo "$2" | \
102                 awk '/\// {print;next} {print "/" $0}' | \
103                 awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
104                 awk '{gsub("/","\\/");print}')
105         mods=$(awk '
106 BEGIN { here = 0 }
107 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
108 /:/ { here = 0 }
109 /(.*)/ { gsub(/\\/," "); if (here) print }
110 ' $depfile | xargs)
111
112         # fallback to $modext
113         if [ "$mods" = "" ] ; then
114                 module=$(echo "$module" | \
115                 awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
116         fi
117         mods=$(awk '
118 BEGIN { here = 0 }
119 /'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
120 /:/ { here = 0 }
121 /(.*)/ { gsub(/\\/," "); if (here) print }
122 ' $depfile | xargs)
123
124         if [ "$mods" = "" ] ; then
125                 if [ "$1" != silent ] ; then
126                         echo >&2 "$origmodule: module not found in $depfile"
127                 fi
128                 if ! is_no "$EXIT_IF_MISSING" ; then
129                         exit 1
130                 else
131                         echo >&2 "If $origmodule isn't compiled in kernel then this initrd may not start your system."
132                 fi
133         fi
134
135         level=$3
136         if [ "$level" = "" ] ; then
137                 level=0
138         fi
139         level=$((level + 1))
140         if [ $level -gt 20 ] ; then
141                 echo >&2 "$origmodule: cycle in $depfile"
142                 exit 1
143         fi
144
145         first=
146         for f in $mods ; do
147                 if [ "$first" = "" ] ; then
148                         first=$f
149                 else
150                         find_depmod $1 $f $level
151                 fi
152         done
153
154         echo $first
155 }
156
157 addmodule() {
158         fmPath=$1
159         skiperrors=$2
160
161         if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
162                 if [ -n "$skiperrors" ]; then
163                         return
164                 fi
165
166                 echo >&2 "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)"
167                 exit 1
168         fi
169
170         # only need to add each module once
171         # quote /
172         tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
173         if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
174                 MODULES="$MODULES $fmPath"
175         fi
176 }
177
178 findmodule() {
179         skiperrors=""
180         modName=$1
181
182         if [ ${modName#-} != ${modName} ]; then
183                 skiperrors=1
184                 modName=${modName#-}
185         fi
186
187         # what's that?
188         if [ "$modName" = "pluto" ]; then
189                 findmodule fc4
190                 findmodule soc
191         fi
192         if [ "$modName" = "fcal" ]; then
193                 findmodule fc4
194                 findmodule socal
195         fi
196
197         if [ -n "$skiperrors" ]; then
198                 allModulesToFind=$(find_depmod silent $modName)
199         else
200                 allModulesToFind=$(find_depmod normal $modName)
201                 if [ $? != 0 ]; then
202                         exit 1
203                 fi
204         fi
205
206         for mod in $allModulesToFind; do
207                 mod=$(echo $mod | awk '{sub(/^\/lib\/modules\/[^\/]*\//, ""); print}')
208                 addmodule $mod "$skiperrors"
209         done
210 }
211
212 inst() {
213         if [ "$#" != "2" ];then
214                 echo "usage: inst <file> <destination>"
215                 return
216         fi
217         debug "$1 -> $2"
218         cp "$1" "$2"
219 }
220
221 get_label_ext2 () {
222         /sbin/e2label $1 2> /dev/null
223 }
224
225 get_uuid_ext2 () {
226         /sbin/tune2fs -l $1 2> /dev/null | awk -F: '/UUID:/ {gsub(" ",""); print $2}'
227 }
228
229 get_label_xfs () {
230         /usr/sbin/xfs_admin -l "$1"  2>/dev/null | awk -F'"' '/label =/{print $2}'
231 }
232
233 get_uuid_xfs () {
234         /usr/sbin/xfs_admin -u "$1" 2>/dev/null | awk -F= '{print $2}' | xargs
235 }
236
237 find_root() {
238         eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
239         case $rootdev in
240         LABEL=*)
241                 # new way, using blkid
242                 if [ -x /sbin/blkid ]; then
243                         label=${rootdev#"LABEL="}
244                         dev=$(/sbin/blkid -t LABEL="$label" -o device)
245
246                         if [ "$dev" -a -r "$dev" ]; then
247                                 debug "Using $dev as device for rootfs"
248                                 rootdev=$dev
249                                 rootdev_found=1
250                                 rootdev1=${rootdev} # XXX neccessary?
251                                 return
252                         fi
253                         echo >&2 "geninitrd can't find real device for LABEL=$label"
254                         exit 1
255                 fi
256
257                 # old way, using various tools
258                 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
259                         rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
260                         if [ -n "$rootdev2" ] ; then
261                                 rootdev=$rootdev2
262                                 rootdev_found=1
263                         fi
264                 fi
265                 if [ "$rootdev_found." != "1." ] ; then
266                         case $rootFs in
267                         ext2|ext3)
268                                 if [ ! -x /sbin/e2label ] ; then
269                                         echo >&2 "/sbin/e2label is missing"
270                                         exit 1
271                                 fi
272                                 get_label="get_label_ext2"
273                                 ;;
274                         xfs)
275                                 if [ ! -x /usr/sbin/xfs_db ] ; then
276                                         echo >&2 "/usr/sbin/xfs_db is missing"
277                                         exit 1
278                                 fi
279                                 get_label="get_label_xfs"
280                                 ;;
281                         *)
282                                 echo >&2 "LABEL on $rootFs in not supported by geninitrd"
283                                 exit 1
284                                 ;;
285                         esac
286                         if [ ! -r /proc/partitions ] ; then
287                                 echo >&2 '/proc/partitions is not readable'
288                                 exit 1
289                         fi
290                         label=${rootdev#"LABEL="}
291                         for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
292                                 if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
293                                         debug "Using $dev as device for rootfs"
294                                         rootdev=$dev
295                                         rootdev_found=1
296                                         break
297                                 fi
298                         done
299                         if [ "$rootdev_found." != "1." ] ; then
300                                 echo >&2 "geninitrd can't find real device for LABEL=$label"
301                                 exit 1
302                         fi
303                 fi
304                 ;;
305         UUID=*)
306                 # new way, using blkid
307                 if [ -x /sbin/blkid ]; then
308                         uuid=${rootdev#"UUID="}
309                         dev=$(/sbin/blkid -t UUID="$uuid" -o device)
310
311                         if [ "$dev" -a -r "$dev" ]; then
312                                 debug "Using $dev as device for rootfs"
313                                 rootdev=$dev
314                                 rootdev_found=1
315                                 rootdev1=${rootdev} # XXX neccessary?
316                                 return
317                         fi
318                         echo >&2 "geninitrd can't find real device for UUID=$uuid"
319                         exit 1
320                 fi
321
322                 # old way, using various tools
323                 if [ -x /sbin/findfs -a \( "$rootFs." = "ext2." -o "$rootFs." = "ext3." \) ] ; then
324                         rootdev2="`/sbin/findfs $rootdev 2>/dev/null`"
325                         if [ -n "$rootdev2" ] ; then
326                                 rootdev=$rootdev2
327                                 rootdev_found=1
328                         fi
329                 fi
330                 if [ "$rootdev_found." != "1." ] ; then
331                         case $rootFs in
332                         ext2|ext3)
333                                 if [ ! -x /sbin/tune2fs ] ; then
334                                         echo >&2 "/sbin/tune2fs is missing"
335                                         exit 1
336                                 fi
337                                 get_uuid="get_uuid_ext2"
338                                 ;;
339                         xfs)
340                                 if [ ! -x /usr/sbin/xfs_admin ] ; then
341                                         echo >&2 "/usr/sbin/xfs_admin is missing"
342                                         exit 1
343                                 fi
344                                 get_uuid="get_uuid_xfs"
345                                 ;;
346                         *)
347                                 echo >&2 "UUID on $rootFs in not supported by geninitrd"
348                                 exit 1
349                                 ;;
350                         esac
351                         if [ ! -r /proc/partitions ] ; then
352                                 echo >&2 '/proc/partitions is not readable'
353                                 exit 1
354                         fi
355                         uuid=${rootdev#"UUID="}
356                         for dev in $(awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions); do
357                                 if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
358                                         debug "Using $dev as device for rootfs"
359                                         rootdev=$dev
360                                         rootdev_found=1
361                                         break
362                                 fi
363                         done
364                         if [ "$rootdev_found" != 1 ] ; then
365                                 echo >&2 "geninitrd can't find real device for UUID=$uuid"
366                                 exit 1
367                         fi
368                 fi
369                 ;;
370         esac
371         rootdev1=${rootdev}
372 }
373
374 find_modules_softraid() {
375         if [ -f /etc/mdadm.conf ]; then
376                 debug "Finding RAID details using mdadm for rootdev=$1"
377                 eval `/sbin/mdadm -v --examine --scan --config=/etc/mdadm.conf | awk -v rootdev="$1" '
378                 BEGIN {
379                         found = "no";
380                         dev_list = "";
381                         raidlevel = ""
382                         rootdev_devfs = rootdev;
383                         if (rootdev ~ /\/dev\/md\/[0-9]/) {
384                                 gsub(/\/dev\/md\//,"/dev/md",rootdev_devfs);
385                         }
386                 }
387
388                 /^ARRAY/ {
389                         if (($2 == rootdev) || ($2 == rootdev_devfs)) {
390                                 raidlevel=$3;
391                                 gsub(/level=/,NUL,raidlevel);
392                                 if (raidlevel ~ /^raid([0-6]|10)/) {
393                                         gsub(/raid/,NUL,raidlevel);
394                                 };
395                                 found="yes";
396                                 getline x;
397                                 if (x ~ /devices=/) {
398                                         dev_list = x;
399                                         gsub(".*devices=", NUL, dev_list);
400                                         gsub(",", " ", dev_list);
401                                 }
402                         }
403                 }
404
405                 END {
406                         print "raidfound=" found;
407                         print "raidlevel=" raidlevel;
408                         print "dev_list=\"" dev_list "\"";
409                 }'`
410         fi
411
412         if [ "$raidfound" != "yes" -a -f /etc/raidtab ]; then
413                 echo >&2 "ERROR: raidtools are not longer supported. Please migrate to mdadm setup!"
414                 exit 1
415         fi
416
417         if is_yes "$raidfound" ; then
418                 case "$raidlevel" in
419                 [01456]|10)
420                         findmodule "raid$raidlevel"
421                         ;;
422                 linear)
423                         findmodule "linear"
424                         ;;
425                 *)
426                         echo >&2 "raid level $number (in mdadm config) not recognized"
427                         ;;
428                 esac
429         else
430                 echo >&2 "ERROR: RAID devices not found for \"$1\", check your configuration!"
431                 exit 1
432         fi
433
434         rootdev_nr=$(( $rootdev_nr + 1 ))
435         eval "rootdev${rootdev_nr}=\"$1\""
436         eval "dev_list${rootdev_nr}=\"${dev_list}\""
437
438         for device in $dev_list; do
439                 find_modules_for $device
440         done
441 }
442
443 find_modules_scsi() {
444         for n in $PRESCSIMODS; do
445                 if [ "X$n" = "Xunknown" ] ; then
446                         if [ -f "$modulefile" ]; then
447                                 scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
448                                 for n in $scsimodules; do
449                         # for now allow scsi modules to come from anywhere. There are some
450                         # RAID controllers with drivers in block
451                                         findmodule "$n"
452                                 done
453                         fi
454                 else
455                         findmodule "$n"
456                 fi
457         done
458 }
459
460 find_modules_ide() {
461         typeset rootdev
462
463         rootdev="$(echo "$1" | awk ' { gsub(/\/dev\//,NUL); gsub(/[0-9].*/, NUL); print $0 } ')"
464         if [ "$pack_version_long" -lt "002004021" ]; then
465                 debug "Finding IDE modules for kernels <= 2.4.20"
466                 for n in $PREIDEMODSOLD; do
467                         findmodule "$n"
468                 done
469         else
470                 tryauto=1
471                 for n in $PREIDEMODS; do
472                         if [ "X$n" = "Xunknown" ] ; then
473                                 if [ -f "$modulefile" ]; then
474                                         debug "Finding IDE modules using ide_hostadapter"
475                                         idemodules="`awk '/ide_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
476                                         for na in $idemodules; do
477                                                 tryauto=0;
478                                                 findmodule "$na"
479                                         done
480                                 fi
481
482                                 if [ "$tryauto" -eq 1 ]; then
483                                         # If tryauto {{{
484                                         if [ -r /usr/share/pci-database/ide.pci -a -r /proc/bus/pci/devices ]; then
485                                                 debug "Finding IDE modules using PCI ID database"
486                                                 # Finding IDE modules using PCI ID database {{{
487                                                 if is_yes "${ide_only_root}"; then
488                                                         if [ -f /sys/block/${rootdev}/device/../../vendor -a -f /sys/block/${rootdev}/device/../../device ]; then
489                                                                 vendorid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootdev}/device/../../vendor)"
490                                                                 deviceid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootdev}/device/../../device)"
491                                                                 searchpciid="${vendorid}${deviceid}"
492                                                         elif [ -f /proc/ide/${rootdev}/../config ]; then
493                                                                 searchpciid="$(awk ' /pci bus/ { print $7$9 } ' /proc/ide/${rootdev}/../config)"
494                                                         fi
495                                                 fi
496
497                                                 if [ -z "${searchpciid}" ]; then
498                                                         searchpciid="$(awk ' { print $2 } ' /proc/bus/pci/devices)"
499                                                 fi
500
501                                                 idemodules=""
502
503                                                 for nb in $searchpciid; do
504                                                         eval `awk -v pciid="$nb" '{
505                                                                 gsub("\t"," ");
506                                                                 gsub("  +", " ");
507                                                                 gsub("^ ","");
508                                                                 if (/^[\t ]*#/)
509                                                                         next;
510                                                                 compmod = $1 "";        # make sure comparison type will be string
511                                                                                         # cause pci IDs are hexadecimal numeric
512                                                                 if (compmod == pciid) {
513                                                                         module=$2;
514                                                         #               min_kernel=$3;  # now in ide.pci $3,$4 = vendor and device name
515                                                         #               max_kernel=$4;  #
516                                                                         exit 0;
517                                                                 }
518                                                         }
519
520                                                         END {
521                                                                 print "module=" module "\nmin_kernel=" min_kernel "\nmax_kernel=\"" max_kernel "\"\n";
522                                                         }' /usr/share/pci-database/ide.pci`
523                                                         [ -n "$module" ] && idemodules="$idemodules $module"
524                                                 done
525                                                 if is_yes "$(awk ' /ide=reverse/ { print "yes" } ' /proc/cmdline)"; then
526                                                         new_idemodules=""
527                                                         for nc in idemodules; do
528                                                                 new_idemodules="$nc $new_idemodules"
529                                                         done
530                                                         idemodules="${new_idemodules}"
531                                                 fi
532
533                                                 if [ -z "$idemodules" ]; then
534                                                         echo "WARNING: rootfs on IDE device but no related modules found, loading ide-generic."
535                                                         idemodules="ide-generic"
536                                                 fi
537
538                                                 # }}}
539                                                 for nd in $idemodules; do
540                                                         findmodule "-$nd"
541                                                 done
542                                         # }}}
543                                         # else tryauto {{{
544                                         else
545                                                 [ -r /usr/share/pci-database/ide.pci ] || echo "WARNING: /usr/share/pci-database/ide.pci missing."
546                                                 [ -r /proc/bus/pci/devices ] || echo "WARNING: /proc/bus/pci/devices missing."
547                                                 echo "Automatic IDE modules finding not available."
548                                         fi
549                                         # }}}
550                                 fi
551                         else
552                                 findmodule "$n"
553                         fi
554                 done
555         fi
556 }
557
558 # resolve /dev/dm-0 to lvm2 node
559 # which they got from /proc/partitions when rootfs is UUID=
560 _lvm2_node_resolve() {
561         local node="$1"
562
563         # redirect output to tmpfile so we won't get subshell
564         local tmp ret
565         tmp=$(mktemp) || exit 1
566
567         lvdisplay -c 2>/dev/null|awk -F: '{print $1}' > $tmp
568         while read dev; do
569                 count=$(ls -Ll $dev $node | awk '{print $5, $6}' | sort -u | wc -l)
570                 if [ "$count" = 1 ]; then
571                         ret="$dev"
572                         break
573                 fi
574         done < $tmp
575         rm -f $tmp
576
577         if [ -z "$ret" ]; then
578                 ret=$node
579         fi
580         echo "$ret"
581 }
582
583 # return true if node is lvm node
584 _check_lvm() {
585         local node="$1"
586         if [ ! -e "$node" ]; then
587                 echo >&2 "WARNING: check_lvm(): node $node doesn't exist!"
588                 return 1
589         fi
590
591         # block-major-58 is lvm1
592         ls -lL "$node" 2> /dev/null | awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'
593         rc=$?
594
595         if [ $rc = 0 ]; then
596                 debug "$node is LVM1 node"
597                 # is lvm1
598                 return 0
599         fi
600
601         node=$(_lvm2_node_resolve $node)
602         /sbin/lvm lvdisplay "$node" > /dev/null 2>&1
603         rc=$?
604         if [ $rc -gt 127 ]; then
605                 # lvdisplay terminated by signal! most likely it segfaulted.
606                 echo >&2 "ERROR: Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
607                 exit 1
608         fi
609
610         if [ $rc = 0 ]; then
611                 debug "$node is lvm2 node"
612         else
613                 debug "$node is not any lvm node"
614         fi
615         return $rc
616 }
617
618 find_modules_for() {
619         if [ -z "$1" ]; then
620                 echo "ERROR: no argument passed to find_modules_for() - is your /etc/fstab correct?" >&2
621                 exit
622         fi
623
624         if is_yes "`echo "$1" | awk '/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:|\/dev\/nfs)/ { print "yes"; }'`"; then
625                 if [ ! -x /usr/bin/pcidev -a -z "$NFS_ETH_MODULES" ] ; then
626                         echo "ERROR: root on NFS but /usr/bin/pcidev not found." >&2
627                         echo "Please install correct pci-database package and rerun $0." >&2
628                         exit 1
629                 fi
630                 [ -z "$NFS_ETH_MODULES" ] && NFS_ETH_MODULES=$(/usr/bin/pcidev /m net | xargs)
631                 for m in $NFS_ETH_MODULES; do
632                         findmodule "$m"
633                 done
634                 findmodule "-ipv4"
635                 findmodule "nfs"
636                 usenfs="yes"
637                 echo "Remember to use \`root=/dev/ram0 init=/linuxrc' when starting kernel" >&2
638                 echo "or you will have problems like init(xx) being child process of swapper(1)." >&2
639         elif is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
640                 find_modules_softraid "$1"
641         elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
642                 find_modules_scsi
643         elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }'`" ; then
644                 find_modules_ide "$1"
645         elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
646                 findmodule "DAC960"
647         elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
648                 findmodule "cpqarray"
649         elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
650                 findmodule "cciss"
651         elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
652                 find_modules_ide
653                 findmodule "ataraid"
654                 ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
655                 if -n "$ataraidmodules" ; then
656                         # FIXME: think about modules compiled in kernel
657                         echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
658                         echo "Please set it and run $0 again."
659                         exit 1
660                 fi
661                 for n in $ataraidmodules; do
662                         findmodule "$n"
663                 done
664         # check to see if we need to set up a loopback filesystem
665         elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
666                 echo >&2 "Sorry, root on loop device isn't supported."
667                 exit 1
668                 # TODO: rewrite for bsp and make nfs ready
669                 if [ ! -x /sbin/losetup ]; then
670                         echo "losetup is missing"
671                         exit 1
672                 fi
673                 key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
674                 if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
675                         echo >&2 "The root filesystem is on a $1, but there is no magic entry in $fstab"
676                         echo >&2 "for this device. Consult the geninitrd man page for more information"
677                         exit 1
678                 fi
679
680                 line="`awk '/'$key'/ { print $0; }' $fstab`"
681                 loopDev="$(echo $line | awk '{print $3}')"
682                 loopFs="$(echo $line | awk '{print $4}')"
683                 loopFile="$(echo $line | awk '{print $5}')"
684
685                 BASICMODULES="$BASICMODULES -loop"
686                 findmodule "-$loopFs"
687                 BASICMODULES="$BASICMODULES -${loopFs}"
688         elif _check_lvm "$1"; then
689                 node=$(_lvm2_node_resolve "$1")
690
691                 if [ ! -f /sbin/initrd-lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ] ; then
692                         echo "ERROR: root on LVM but /sbin/initrd-lvm, /sbin/lvdisplay and /sbin/pvdisplay not found." >&2
693                         echo "Please install lvm(2) and lvm(2)-initrd package and rerun $0." >&2
694                         exit 1
695                 fi
696                 if [ -z "$LVMTOOLSVERSION" ] ; then
697                         LVMTOOLSVERSION=$(/sbin/initrd-lvm vgchange --version 2>/dev/null|head -n 1|awk '{gsub("vgchange: Logical Volume Manager ",NIL); gsub("LVM version:     ",NIL); gsub(/\..*/,NIL); print $1}')
698                         if [ -z "$LVMTOOLSVERSION" ] ; then
699                                 echo "ERROR: Can't determine LVM tools version. Please set LVMTOOLSVERSION" >&2
700                                 echo "and rerun $0." >&2
701                                 exit 1
702                         fi
703                 fi
704                 if [ -z "$PVDEVICES" ] ; then
705                         VGVOLUME=$(/sbin/lvdisplay -c "$node" 2> /dev/null | awk -F":" ' { print $2 } ')
706                         PVDEVICES=$(/sbin/pvdisplay -c | awk -F":" -v vg="$VGVOLUME" ' BEGIN { devices="" } { if ($2 == vg) { devices = devices " " $1 } } END { print devices } ')
707                 fi
708                 if [ -n "$PVDEVICES" ] ; then
709                         for device in $PVDEVICES; do
710                                 find_modules_for $device
711                         done
712                 else
713                         echo "ERROR: I wasn't able to find PV (via lvdisplay and pvdisplay)." >&2
714                         echo "You can try to set PVDEVICES in /etc/sysconfig/geninitrd." >&2
715                         exit 1
716                 fi
717                 if [ "$LVMTOOLSVERSION" = "2" ]; then
718                         findmodule "-dm-mod"
719                 elif [ "$LVMTOOLSVERSION" = "1" ]; then
720                         findmodule "-lvm"
721                         findmodule "-lvm-mod"
722                 else
723                         echo "ERROR: LVM version $LVMTOOLSVERSION is not supported yet." >&2
724                         exit 1
725                 fi
726                 debug "LVM $LVMTOOLSVERSION enabled"
727                 uselvm="yes"
728         fi
729 }
730
731 firmware_install_module_pre() {
732         module="$1"
733         linuxrc="$2"
734         firmware_files="$3"
735
736         debug "Adding Firmwares ($firmware_files) to initrd for module $module"
737         mkdir -p $MNTIMAGE/proc
738         mkdir -p $MNTIMAGE/sys
739         # firmware not yet installed
740         if [ ! -f "$MNTIMAGE/lib/firmware/firmware.sh" ]; then
741                 mkdir -p $MNTIMAGE/lib/firmware
742 cat << 'EOF' >> "$MNTIMAGE/lib/firmware/firmware.sh"
743 #!/bin/sh -e
744 echo 1 > /sys$DEVPATH/loading
745 cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
746 echo 0 > /sys$DEVPATH/loading
747 exit 0
748 EOF
749                 chmod 755 "$MNTIMAGE/lib/firmware/firmware.sh"
750         fi
751
752         for firmware in $firmware_files; do
753                 inst "/lib/firmware/$firmware" "$MNTIMAGE/lib/firmware/$firmware"
754         done
755
756         echo "mount -t proc none /proc" >> "$linuxrc"
757         echo "mount -t sysfs none /sys" >> "$linuxrc"
758         echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" >> "$linuxrc"
759 }
760
761 firmware_install_module_post() {
762         module="$1"
763         linuxrc="$2"
764         firmware_files="$3"
765         echo "umount /sys" >> "$linuxrc"
766         echo "umount /proc" >> "$linuxrc"
767 }
768
769 modules_install() {
770         modules="$1"
771
772         for mod in $modules; do
773                 MODULEDIR="`dirname "$mod"`"
774                 mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
775                 cp -a "/lib/modules/$kernel/$mod" "$MNTIMAGE/lib/modules/$kernel/$mod"
776                 gunzip "$MNTIMAGE/lib/modules/$kernel/$mod" 2> /dev/null
777         done
778 }
779
780 modules_add_linuxrc() {
781         modules="$1"
782         linuxrc="$2"
783
784         for mod in $modules; do
785                 MODULE2="`dirname "$mod"`"
786                 NAME2=`basename "$mod" .gz`
787                 MODULE2=$MODULE2/$NAME2
788                 module="`echo $mod | awk -F/ '{ $0=$NF } /'$modext'.*$/ { gsub(/'$modext'.*/, NIL, $0); } { print $0; }'`"
789                 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
790
791                 generic_module=$(echo "${module}" | awk ' { gsub("-", "_", $0) } { print $0; } ')
792                 sleep_var="$(eval echo \$MODULE_${generic_module}_USLEEP)"
793                 firmware_var="$(eval echo \$MODULE_${generic_module}_FIRMWARE)"
794
795                 if [ -n "$verbose" ]; then
796                         echo -n "Loading module [$module] "
797                         if [ -n "$options" ] ; then
798                                 echo -n "with options [$options]"
799                         else
800                                 echo -n "without options"
801                         fi
802                         if [ -n "$sleep_var" ]; then
803                                 echo " and $sleep_var usleep."
804                         else
805                                 echo "."
806                         fi
807                 fi
808
809                 if [ -n "$firmware_var" ]; then
810                         firmware_install_module_pre "$module" "$linuxrc" "$firmware_var"
811                 fi
812                 echo "$insmod /lib/modules/$kernel/$MODULE2 $options" >> "$linuxrc"
813                 if [ -n "${sleep_var}" ]; then
814                         echo "usleep $sleep_var" >> "$linuxrc"
815                 fi
816                 if [ -n "$firmware_var" ]; then
817                         firmware_install_module_post "$module" "$linuxrc" "$firmware_var"
818                 fi
819         done
820 }
821
822 if [ -r /etc/sysconfig/geninitrd ] ; then
823         . /etc/sysconfig/geninitrd
824 fi
825
826 if [ -r /etc/sysconfig/bootsplash ] ; then
827         . /etc/sysconfig/bootsplash
828 fi
829
830 if [ -r /etc/sysconfig/fbsplash ] ; then
831         . /etc/sysconfig/fbsplash
832 fi
833
834 if [ ! -x /bin/initrd-busybox ] ; then
835         echo "/bin/initrd-busybox is missing !"
836         exit 1
837 fi
838
839 while [ $# -gt 0 ]; do
840         case $1 in
841         --fstab=*)
842                 fstab="`echo $1 | awk -F= '{print $2;}'`"
843                 ;;
844         --fstab)
845                 fstab="$2"
846                 shift
847                 ;;
848         --modules-conf=*)
849                 modulefile="`echo $1 | awk -F= '{print $2;}'`"
850                 ;;
851         --modules-conf)
852                 modulefile="$2"
853                 shift
854                 ;;
855         --use-raidstart|--with-raidstart)
856                 USERAIDSTART="yes"
857                 ;;
858         --without-raidstart)
859                 USERAIDSTART="no"
860                 ;;
861         --use-insmod-static|--with-insmod-static)
862                 USEINSMODSTATIC="yes"
863                 ;;
864         --without-insmod-static)
865                 USEINSMODSTATIC="no"
866                 ;;
867         --without-bootsplash)
868                 BOOT_SPLASH="no"
869                 ;;
870         --without-fbsplash)
871                 FB_SPLASH="no"
872                 ;;
873         --without-suspend)
874                 USE_SUSPEND="no";
875                 ;;
876         --without-suspend2)
877                 USE_SUSPEND2="no";
878                 ;;
879         --lvmtoolsversion=|--lvmversion=)
880                 LVMTOOLSVERSION="`echo $1 | awk -F= '{print $2;}'`"
881                 ;;
882         --lvmtoolsversion|--lvmversion)
883                 LVMTOOLSVERSION="$2"
884                 shift
885                 ;;
886         --without-udev)
887                 USE_UDEV=
888                 ;;
889         --with-udev)
890                 USE_UDEV="yes"
891                 ;;
892         --without-dmraid)
893                 USE_DMRAID=
894                 ;;
895         --with=*)
896                 BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
897                 ;;
898         --with)
899                 BASICMODULES="$BASICMODULES $2"
900                 shift
901                 ;;
902         --version)
903                 echo "geninitrd: version $VERSION"
904                 exit 0
905                 ;;
906         -v)
907                 verbose=-v
908                 ;;
909         --nocompress)
910                 COMPRESS="no"
911                 ;;
912         --ifneeded)
913                 ifneeded=1
914                 ;;
915         -f)
916                 force=1
917                 ;;
918         --preload=*)
919                 PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
920                 ;;
921         --preload)
922                 PREMODS="$PREMODS $2"
923                 shift
924                 ;;
925         --fs=*)
926                 echo >&2 "Warning: --fs option is obsoleted. Use --initrdfs instead"
927                 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
928                 ;;
929         --fs)
930                 echo >&2 "Warning: --fs option is obsoleted. Use --initrdfs instead"
931                 INITRDFS="$2"
932                 shift
933                 ;;
934         --initrdfs=*)
935                 INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
936                 ;;
937         --initrdfs)
938                 INITRDFS="$2"
939                 shift
940                 ;;
941         --image-version)
942                 img_vers=yes
943                 ;;
944         --ide-only-root)
945                 ide_only_root="yes"
946                 ;;
947         *)
948                 if [ -z "$target" ]; then
949                         target="$1"
950                 elif [ -z "$kernel" ]; then
951                         kernel="$1"
952                 else
953                         usage
954                 fi
955                 ;;
956         esac
957
958         shift
959 done
960
961 if [ -z "$target" -o -z "$kernel" ]; then
962         usage
963 fi
964
965 pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
966 pack_version_long="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}'`"
967
968 if [ "x" = "x$INITRDFS" ] ; then
969         if [ "x" = "x$FS" ] ; then
970                 # default value
971                 if [ "$pack_version" -ge "002005" ] ; then
972                         INITRDFS="initramfs"
973                 else
974                         INITRDFS="rom"
975                 fi
976         else
977                 echo >&2 "Warning: FS configuration options is obsoleted. Use INITRDFS instead"
978                 INITRDFS="$FS"
979         fi
980 fi
981
982 if [ "$pack_version" -lt "002006" ] ; then
983         USE_UDEV=
984         USE_DMRAID=
985 fi
986
987 if [ "$pack_version" -ge "002005" ] ; then
988         modext=".ko"
989         insmod="insmod"
990 fi
991
992 if is_yes "$USEINSMODSTATIC" ; then
993         insmod="insmod.static"
994         INSMOD="/sbin/insmod.static"
995         if [ "$pack_version" -lt "002005" -a -f /sbin/insmod.static.modutils ] ; then
996                 INSMOD="/sbin/insmod.static.modutils"
997         fi
998         if [ ! -f "$INSMOD" ] ; then
999                 echo "insmod.static requested but /sbin/insmod.static not found !" >&2
1000                 exit 1
1001         fi
1002 fi
1003
1004 case "$INITRDFS" in
1005         ext2)
1006                 if [ ! -x /sbin/mke2fs ]; then
1007                         echo >&2 "/sbin/mke2fs is missing"
1008                         exit 1
1009                 fi
1010                 ;;
1011         rom)
1012                 if [ ! -x /sbin/genromfs ]; then
1013                         echo >&2 "/sbin/genromfs is missing"
1014                         exit 1
1015                 fi
1016                 ;;
1017         cram)
1018                 if [ ! -x /sbin/mkcramfs ]; then
1019                         echo >&2 "/sbin/mkcramfs is missing"
1020                         exit 1
1021                 fi
1022                 ;;
1023         initramfs)
1024                 if [ ! -x /bin/cpio ]; then
1025                         echo >&2 "/bin/cpio is missing"
1026                         exit 1
1027                 fi
1028                 if [ ! -x /usr/bin/find ]; then
1029                         echo >&2 "/usr/bin/find is missing"
1030                         exit 1
1031                 fi
1032                 ;;
1033         *)
1034                 echo >&2 "Filesystem $INITRDFS on initrd is not supported"
1035                 exit 1
1036                 ;;
1037 esac
1038
1039 if [ -n "$img_vers" ]; then
1040         target="$target-$kernel"
1041 fi
1042
1043 if [ -z "$force" -a -f "$target" ]; then
1044         echo >&2 "$target already exists."
1045         exit 1
1046 fi
1047
1048 if [ ! -d "/lib/modules/$kernel" ]; then
1049         echo >&2 "/lib/modules/$kernel is not a directory."
1050         exit 1
1051 fi
1052
1053 if is_yes "$USE_SUSPEND"; then
1054         if is_yes "$USE_SUSPEND2"; then
1055                 echo >&2 "Suspend2 shouldn't be used in parallel with mainline suspend!."
1056                 exit 1
1057         fi
1058 fi
1059
1060 if is_yes "$FB_SPLASH"; then
1061         if is_yes "$BOOT_SPLASH"; then
1062                 echo >&2 "You can't use both bootsplash and fbsplash! Please choose one."
1063                 exit 1
1064         elif [ "$INITRDFS" != "initramfs" ]; then
1065                 echo >&2 "FB_SPLASH works only if INITRDFS is initramfs!."
1066                 exit 1
1067         fi
1068 fi
1069
1070 if [ ! -f /proc/mounts ]; then
1071         echo >&2 "WARNING: /proc filesystem not mounted, may cause wrong results or failure."
1072 fi
1073
1074 if [ "$pack_version" -lt "002005" ]; then
1075         modulefile=/etc/modules.conf
1076         if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
1077                 modulefile=/etc/conf.modules
1078         fi
1079 else
1080         modulefile=/etc/modprobe.conf
1081 fi
1082
1083 for n in $PREMODS; do
1084         findmodule "$n"
1085 done
1086
1087 # allow forcing loading SCSI and/or IDE modules
1088 if is_yes "$ADDSCSI" ; then
1089         find_modules_scsi
1090 fi
1091
1092 if is_yes "$ADDIDE" ; then
1093         find_modules_ide
1094 fi
1095
1096 find_root
1097
1098 org_rootdev="$rootdev1"
1099
1100 find_modules_for "$rootdev1"
1101
1102 findmodule "-$rootFs"
1103
1104 for n in $BASICMODULES; do
1105         findmodule "$n"
1106 done
1107
1108 if is_yes "$USE_SUSPEND2"; then
1109         findmodule "-lzf"
1110 fi
1111
1112 if is_yes "$FB_SPLASH"; then
1113         findmodule "-evdev"
1114 fi
1115 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
1116         debug "No modules are needed -- not building initrd image."
1117         exit 0
1118 fi
1119
1120 debug "Using modules: $MODULES"
1121
1122 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
1123 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
1124 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
1125 RCFILE="$MNTIMAGE/linuxrc"
1126
1127 if [ -f "$MNTIMAGE" ]; then
1128         echo >&2 "$MNTIMAGE already exists. Remove it and try again"
1129         exit 1
1130 fi
1131
1132 if [ -f "$IMAGE" ]; then
1133         echo >&2 "$IMAGE already exists. Remove it and try again"
1134         exit 1
1135 fi
1136
1137 mkdir -p "$MNTPOINT"
1138
1139
1140 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs,var}
1141
1142
1143 # We don't need this directory, so let's save space
1144 rm -rf "$MNTPOINT"/lost+found
1145
1146 modules_install "$MODULES"
1147
1148 # mknod'ing the devices instead of copying them works both with and
1149 # without devfs...
1150 mknod "$MNTIMAGE/dev/console" c 5 1
1151 mknod "$MNTIMAGE/dev/null" c 1 3
1152 mknod "$MNTIMAGE/dev/zero" c 1 5
1153
1154 s="$RCFILE"
1155 ln -s /linuxrc $MNTIMAGE/init
1156
1157 inst /bin/initrd-busybox "$MNTIMAGE/bin/initrd-busybox"
1158 ln -s initrd-busybox "$MNTIMAGE/bin/sh"
1159 ln -s initrd-busybox "$MNTIMAGE/bin/busybox" # for older busyboxes who had /bin/busybox as EXEPATH
1160
1161 if is_yes "$USEINSMODSTATIC" ; then
1162         inst "$INSMOD" $MNTIMAGE/bin/insmod.static
1163 fi
1164
1165 cat > "$s" <<EOF
1166 #! /bin/sh
1167
1168 set -x
1169 EOF
1170 chmod 755 "$s"
1171
1172 modules_add_linuxrc "$MODULES" "$s"
1173
1174 # TODO: rewrite for busybox
1175 #if [ -n "$loopDev" ]; then
1176 #       if [ ! -d /initrd ]; then
1177 #               mkdir /initrd
1178 #       fi
1179 #
1180 #       cp -a "$loopDev" "$MNTIMAGE/dev"
1181 #       cp -a "$rootdev1" "$MNTIMAGE/dev"
1182 #       echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
1183 #       echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
1184 #       echo "echo Setting up loopback device $rootdev1" >> $RCFILE
1185 #       echo "losetup $rootdev1 /loopfs$loopFile" >> "$RCFILE"
1186 #fi
1187
1188 initrd_gen_suspend() {
1189         if [ ! -x /usr/sbin/resume ]; then
1190                 echo "/usr/sbin/resume is missing !"
1191                 exit 1
1192         fi
1193         mkdir -p $MNTIMAGE/etc
1194         mkdir -p $MNTIMAGE/dev
1195         resume_dev="$(awk '/^resume device =/ { print $4 } ' /etc/suspend.conf)"
1196         cp -HR /dev/snapshot $resume_dev $MNTIMAGE/dev
1197         inst /etc/suspend.conf $MNTIMAGE/etc/suspend.conf
1198         inst /usr/sbin/resume "$MNTIMAGE/bin/resume"
1199         echo "resume" >> "$s"
1200 }
1201
1202 initrd_gen_suspend2() {
1203         mkdir -p $MNTIMAGE/sys
1204         mkdir -p $MNTIMAGE/proc
1205 cat << 'EOF' >> "$s"
1206 mount -t proc none /proc
1207 mount -t sysfs none /sys
1208 if [ "$(awk ' /resume2=/  { print "yes"; } ' /proc/cmdline)" = "yes" ]; then
1209 EOF
1210 cat << EOF >> "$s"
1211                 [ -e /proc/suspend2/do_resume ] && echo > /proc/suspend2/do_resume
1212                 [ -e /sys/power/suspend2/do_resume ] && echo > /sys/power/suspend2/do_resume
1213 fi
1214 umount /sys
1215 umount /proc
1216 EOF
1217 }
1218
1219 initrd_gen_tmpfs_dev() {
1220         tmpfs_dev=yes
1221         cat <<-EOF
1222 : 'Creating /dev'
1223 mount -o mode=0755 -t tmpfs none /dev
1224 mknod /dev/console c 5 1
1225 mknod /dev/null c 1 3
1226 mknod /dev/zero c 1 5
1227 mkdir /dev/pts
1228 mkdir /dev/shm
1229 EOF
1230 }
1231
1232 initrd_gen_udev() {
1233         debug "Setting up udev..."
1234         mkdir -p $MNTIMAGE/sbin
1235         mkdir -p $MNTIMAGE/proc
1236         mkdir -p $MNTIMAGE/etc/udev
1237         mkdir -p $MNTIMAGE/sys
1238
1239         inst /sbin/initrd-udevd $MNTIMAGE/sbin/udevd
1240         inst /etc/udev/udev.conf $MNTIMAGE/etc/udev/udev.conf
1241
1242         if is_yes "$USE_UDEV"; then
1243                 initrd_gen_tmpfs_dev >> "$s"
1244                 cat >> "$s" <<- 'EOF'
1245                         mount -t proc none /proc
1246                         mount -t sysfs none /sys
1247                         : 'Starting udev'
1248                         /sbin/udevd --daemon
1249                         EOF
1250                 if is_yes "$PROBESTATICMODS"; then
1251                         inst /sbin/initrd-udevtrigger $MNTIMAGE/sbin/udevtrigger
1252                         inst /sbin/initrd-udevsettle $MNTIMAGE/sbin/udevsettle
1253                         cat >> "$s" <<- 'EOF'
1254                                 /sbin/udevtrigger
1255                                 /sbin/udevsettle
1256                                 EOF
1257                 fi
1258                 cat >> "$s" <<- 'EOF'
1259                         kill udevd
1260                         umount /proc
1261                         umount /sys
1262                         EOF
1263         fi
1264 }
1265
1266 initrd_gen_dmraid() {
1267         if [ ! -x /sbin/dmraid-initrd ] ; then
1268                 echo "/sbin/dmraid-initrd is missing missing !"
1269                 exit 1
1270         fi
1271
1272         # AFAIR it just needs tmpfs on /dev.
1273         if [ ! -x $MNTIMAGE/sbin/udevd ]; then
1274                 echo "udev is needed on target initrd for dmraid to work!"
1275                 exit 1
1276         fi
1277
1278         mkdir -p "$MNTIMAGE/sbin"
1279         inst /sbin/dmraid-initrd $MNTIMAGE/sbin/dmraid
1280         cat <<-EOF >> "$s"
1281         mount -t proc none /proc
1282         mount -t sysfs none /sys
1283         # 2 secs was enough for my system to initialize. but really this is udev issue?
1284         usleep 2000000
1285         : 'Activating Device-Mapper RAID(s)'
1286         /sbin/dmraid -ay -i
1287         umount /sys
1288         umount /proc
1289 EOF
1290 }
1291
1292
1293 initrd_gen_softraid() {
1294         debug "Setting up mdadm..."
1295
1296         if [ ! -x /sbin/mdadm -o ! -x /sbin/initrd-mdassemble ] ; then
1297                 echo "/sbin/mdadm or /sbin/initrd-mdassemble is missing !"
1298                 exit 1
1299         fi
1300
1301         inst /sbin/initrd-mdassemble "$MNTIMAGE/bin/mdassemble"
1302
1303         # LVM on RAID case
1304         dev_list_extra=$(awk '/^DEVICE / { for (i=2; i<=NF; i++) { printf "%s ", $i; }; } ' /etc/mdadm.conf)
1305         for ex_dev in $dev_list_extra; do
1306                 echo "DEVICE $ex_dev" >> "$MNTIMAGE/etc/mdadm.conf"
1307         done
1308         do_md0=1
1309         for nr in `seq 1 $rootdev_nr`; do
1310                 eval cr_rootdev="\$rootdev${nr}"
1311                 eval cr_dev_list="\$dev_list${nr}"
1312                 debug echo "Setting up array ($cr_rootdev = $cr_dev_list)"
1313
1314                 [ "$cr_rootdev" = "/dev/md0" ] && do_md0=0
1315
1316                 echo "DEVICE $cr_dev_list" >> "$MNTIMAGE/etc/mdadm.conf"
1317                 cr_dev_list_md="$(echo "$cr_dev_list" | xargs | awk ' { gsub(/ +/,",",$0); print $0; }')"
1318                 cr_md_conf=$(/sbin/mdadm --detail --brief --config=/etc/mdadm.conf $cr_rootdev | awk ' { gsub(/spares=[0-9]+/, "", $0); print $0; }')
1319                 if [ -n "$cr_md_conf" ]; then
1320                         echo "$cr_md_conf" >> "$MNTIMAGE/etc/mdadm.conf"
1321                 else
1322                         echo "ARRAY $cr_rootdev devices=$cr_dev_list_md" >> "$MNTIMAGE/etc/mdadm.conf"
1323                 fi
1324
1325                 for f in $cr_dev_list $cr_rootdev $dev_list_extra; do
1326                         # mkdir in case of devfs name
1327                         mkdir -p $MNTIMAGE/`dirname $f`
1328                         [ -e "$MNTIMAGE/$f" ] && continue
1329                         debug echo "copying $f"
1330                         # this works fine with and without devfs
1331                         cp -HR $f $MNTIMAGE/$f
1332                 done
1333         done
1334
1335         echo "mdassemble" >> "$s"
1336
1337         # needed to determine md-version
1338         if [ "$do_md0" -eq 1 ] ; then
1339                 mknod $MNTIMAGE/dev/md0 b 9 0
1340         fi
1341 }
1342
1343 initrd_gen_nfs() {
1344         # use root=/dev/ram0 init=/linuxrc when starting kernel or you will
1345         # have problems like init(XX) being child process of swapper(1).
1346         debug "Adding rootfs on NFS support to initrd (dhcp)"
1347         mknod "$MNTIMAGE/dev/urandom" c 1 8
1348         mkdir "$MNTIMAGE/newroot"
1349         mkdir "$MNTIMAGE/proc"
1350         echo "ifconfig lo 127.0.0.1 up" >> "$s"
1351         echo "route add -net 127.0.0.0 netmask 255.0.0.0 lo" >> "$s"
1352         echo "ifconfig eth0 0.0.0.0 up" >> "$s"
1353         echo "udhcpc -i eth0 -f -q -s /bin/setdhcp" >> "$s"
1354         cat << 'EOF' > "$MNTIMAGE/bin/setdhcp"
1355 #!/bin/sh
1356 [ "$1" != "bound" ] && exit
1357 [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
1358 [ -n "$subnet" ] && NETMASK="netmask $subnet"
1359 set -x
1360 ifconfig $interface $ip $BROADCAST $NETMASK up
1361 set +x
1362 if [ -n "$router" ]; then
1363         for r in $router; do
1364                 set -x
1365                 route add default gw $r dev $interface
1366                 set +x
1367         done
1368 fi
1369
1370 mount -t proc none /proc
1371 for o in $(cat /proc/cmdline); do
1372         case $o in
1373         nfsroot=*)
1374                 rootpath=${o#nfsroot=}
1375                 ;;
1376         esac
1377 done
1378 umount /proc
1379
1380 if [ -n "$rootpath" ]; then
1381         set -x
1382         mount -n -t nfs -o ro,nolock,posix,tcp,wsize=8192,rsize=8192 $rootpath /newroot
1383         set +x
1384 else
1385         set +x
1386         echo "Missing rootpath in what DHCP server sent to us. Failing..."
1387         echo "All seen variables are listed below:"
1388         set
1389         set -x
1390 fi
1391 EOF
1392         chmod 755 "$MNTIMAGE/bin/setdhcp"
1393         echo "cd /newroot" >> "$s"
1394         echo "pivot_root . initrd" >> "$s"
1395         echo "[ -x /sbin/chroot ] && exec /sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1" >> "$s"
1396         echo "exec /usr/sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1" >> "$s"
1397 }
1398
1399 initrd_gen_lvm() {
1400         debug "Adding LVM support to initrd"
1401         inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
1402         mkdir -p $MNTIMAGE/etc
1403         mkdir -p $MNTIMAGE/tmp
1404         mkdir -p $MNTIMAGE/proc
1405         mkdir -p $MNTIMAGE/newroot
1406
1407         # always make /dev on tmpfs for LVM2
1408         if [ "$LVMTOOLSVERSION" = "2" ] && ! is_yes "$tmpfs_dev"; then
1409                 initrd_gen_tmpfs_dev >> "$s"
1410         fi
1411
1412         if ! is_yes "$tmpfs_dev"; then
1413                 mkdir -p $MNTIMAGE/dev/mapper
1414                 mknod $MNTIMAGE/dev/mapper/control c 10 63
1415                 for device in $PVDEVICES; do
1416                         # if LVM on RAID then device might be copied already in gen_softraid
1417                         [ -e "$MNTIMAGE/dev/$(basename $device)" ] && continue
1418                         cp -HR $device $MNTIMAGE/dev/
1419                 done
1420         fi
1421         echo "mount -t proc none /proc" >> "$s"
1422         echo "mount -t tmpfs none /tmp" >> "$s"
1423         if [ "$LVMTOOLSVERSION" = "1" ] ; then
1424                 echo "lvm vgscan -T" >> "$s"
1425                 echo "lvm vgchange -T -a y $VGVOLUME" >> "$s"
1426                 echo "umount /tmp" >> "$s"
1427                 # fail to umount
1428                 echo "umount /dev" >> "$s"
1429                 echo "umount /proc" >> "$s"
1430         else
1431                 org_rootdev=$(_lvm2_node_resolve "$org_rootdev")
1432                 echo "cat /etc/lvm.conf > /tmp/lvm.conf" >> "$s"
1433                 echo "global {" > "$MNTIMAGE/etc/lvm.conf"
1434                 echo "  locking_type = 0" >> "$MNTIMAGE/etc/lvm.conf"
1435                 echo "  locking_dir = \"/tmp\"" >> "$MNTIMAGE/etc/lvm.conf"
1436                 echo "}" >> "$MNTIMAGE/etc/lvm.conf"
1437                 echo "devices {" >> "$MNTIMAGE/etc/lvm.conf"
1438                 echo "  sysfs_scan=0" >> "$MNTIMAGE/etc/lvm.conf"
1439                 if is_yes "$raidfound"; then
1440                         echo "  md_component_detection = 1" >> "$MNTIMAGE/etc/lvm.conf"
1441                 fi
1442                 lvm dumpconfig | awk '/filter=/' >> "$MNTIMAGE/etc/lvm.conf"
1443                 echo "}" >> "$MNTIMAGE/etc/lvm.conf"
1444
1445                 cat <<-EOF >> "$s"
1446                 : 'Making device nodes'
1447                 set +x
1448                 (
1449                 # ignore first two lines, header and empty line
1450                 read a
1451                 read a
1452                 while read major minor blocks dev; do
1453                         mknod /dev/\$dev b \$major \$minor
1454                 done
1455                 ) < /proc/partitions
1456
1457                 # disable noise from lvm accessing devices that aren't ready.
1458                 printk=\$(cat /proc/sys/kernel/printk)
1459                 echo 0 > /proc/sys/kernel/printk
1460                 set -x
1461
1462                 : 'Scanning for Volume Groups'
1463                 LVM_SYSTEM_DIR=/tmp lvm vgscan --ignorelockingfailure 2>/dev/null
1464
1465                 : 'Activating Volume Groups'
1466                 LVM_SYSTEM_DIR=/tmp lvm vgchange --ignorelockingfailure -a y $VGVOLUME 2>/dev/null
1467
1468                 echo "\$printk" > /proc/sys/kernel/printk
1469
1470                 # Find out major/minor
1471                 majmin="\$(LVM_SYSTEM_DIR=/tmp lvm lvdisplay --ignorelockingfailure -c $org_rootdev 2>/dev/null)"
1472                 majmin="\${majmin#*/}"
1473                 majmin="\${majmin#*:*:*:*:*:*:*:*:*:*:*:*}"
1474                 major="\${majmin%:*}"
1475                 minor="\${majmin#*:}"
1476                 # Pass it to kernel
1477                 val=\$((256 * \$major + \$minor))
1478                 echo \$val > /proc/sys/kernel/real-root-dev
1479                 umount /tmp
1480                 umount /dev
1481                 umount /proc
1482 EOF
1483         fi
1484 }
1485
1486 initrd_gen_procdata() {
1487         debug "Adding rootfs finding based on root= option support."
1488         mkdir -p $MNTIMAGE/proc
1489 cat << 'EOF' >> "$s"
1490 set +x
1491 mount -t proc none /proc
1492 root="$(busybox awk ' /root=\/dev\// { gsub(/.*root=\/dev\//,NIL,$0); gsub(/ .*/,NIL,$0); print $0; } ' /proc/cmdline)"
1493 if [ -n "$root" ]; then
1494         rootnr="$(busybox awk -v root="$root" ' { if ($4 == root) { print 256*$1+$2; } } ' /proc/partitions)"
1495         if [ -n "$rootnr" ]; then
1496                 echo "$rootnr" > /proc/sys/kernel/real-root-dev
1497         fi
1498 fi
1499 umount /proc
1500 set -x
1501 EOF
1502 }
1503
1504 # main generation
1505
1506 if is_yes "$USE_UDEV"; then
1507         initrd_gen_udev
1508 fi
1509
1510 if is_yes "$USE_SUSPEND"; then
1511         initrd_gen_suspend
1512 fi
1513
1514 if is_yes "$USE_SUSPEND2"; then
1515         initrd_gen_suspend2
1516 fi
1517
1518 if is_yes "$USE_DMRAID"; then
1519         initrd_gen_dmraid
1520 fi
1521
1522 if is_yes "$usenfs" ; then
1523         initrd_gen_nfs
1524 elif is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
1525         initrd_gen_softraid
1526         if is_yes "$uselvm" ; then
1527                 initrd_gen_lvm
1528         else
1529                 initrd_gen_procdata
1530         fi
1531 elif is_yes "$uselvm" ; then
1532         initrd_gen_lvm
1533 else
1534         initrd_gen_procdata
1535 fi
1536
1537 if [ "$INITRDFS" = "initramfs" ]; then
1538         mkdir -p $MNTIMAGE/newroot
1539         [ ! -e "$MNTIMAGE/$org_rootdev" ] && cp -HR $org_rootdev $MNTIMAGE/dev
1540         # Parsing root parameter
1541         # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
1542         cat << 'EOF' >> "$s"
1543 set +x
1544 mount -t proc none /proc
1545
1546 CMDLINE="$(busybox cat /proc/cmdline)"
1547 eval "$(busybox awk -v c="$CMDLINE" '
1548 BEGIN {
1549         num_pattern_short = "[0-9][0-9][0-9]";
1550         num_pattern = "[0-9]" num_pattern_short;
1551         dev_pattern = "[hms][a-z][a-z]([0-9])+";
1552         partition = "no_partition_found";
1553         min = -1; maj = -1;
1554
1555         gsub(/.*root=/,NIL,c);
1556         gsub(/ .*/,NIL,c);
1557
1558         sub("^0x", "", c);
1559         if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
1560         if (c ~ "^" num_pattern  "$") {
1561                 maj = sprintf("%d",substr(c,1,2));
1562                 min = sprintf("%d",substr(c,3));
1563         }
1564         if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
1565         if (c ~ "^" dev_pattern "$") partition = c;
1566 }
1567
1568 $4 ~ partition { maj = $1; min = $2; }
1569 $1 ~ maj && $2 ~ min { partition = $4; }
1570
1571 END {
1572         print sprintf("device=/dev/%s\nmaj=%d\nmin=%d",
1573                 partition, maj, min);
1574 }
1575 ' /proc/partitions)"
1576 set -x
1577 if [ ! -b $device ]; then
1578         mknod $device b $maj $min
1579 fi
1580 EOF
1581         cat << EOF >> "$s"
1582 mount -t $rootFs -r \$device /newroot
1583 init="\$(busybox awk ' /init=\// { gsub(/.*init=/,NIL,\$0); gsub(/ .*/,NIL,\$0); print \$0; }  ' /proc/cmdline )"
1584 if [ -z "\$init" -o ! -x "/newroot\$init" ]; then
1585         init=/sbin/init
1586 fi
1587 umount /proc
1588 exec switch_root /newroot \$init
1589
1590 echo "Error ! initramfs should not reach this place."
1591 echo "It probably means you've got old version of busybox, with broken"
1592 echo "initramfs support. Trying to boot anyway, but won't promise anything."
1593
1594 exec chroot /newroot \$init
1595
1596 echo "Failed to chroot !"
1597 EOF
1598         # we need real file, not symlink
1599         rm -f $MNTIMAGE/init
1600         cp -a $MNTIMAGE/linuxrc $MNTIMAGE/init
1601 fi
1602
1603 chmod +x "$RCFILE"
1604
1605 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
1606
1607 case "$INITRDFS" in
1608         ext2)
1609                 IMAGESIZE=$(du -ks $MNTPOINT | awk '{print int(($1+1023+512)/1024)*1024}')
1610                 debug   "ext2 image size: $IMAGESIZE ($MNTPOINT)"
1611                 if [ "$IMAGESIZE" -gt 4096 ]; then
1612                         echo >&2 "$0: Your image size is larger than 4096, You should add ramdisk_size=$IMAGESIZE to your kernel commandline!"
1613                 fi
1614
1615                 dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
1616                 mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
1617                 tune2fs -i 0 "$IMAGE" >/dev/null 2>&1
1618
1619                 tmpmnt="`mktemp -d /tmp/initrd.mnte2-XXXXXX`"
1620                 mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
1621
1622                 (cd "$MNTPOINT"; tar cf - .) | (cd "$tmpmnt"; tar xf -)
1623
1624                 umount "$IMAGE"
1625                 ;;
1626         rom)
1627                 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
1628                 ;;
1629         cram)
1630                 mkcramfs "$MNTPOINT" "$IMAGE"
1631                 ;;
1632         initramfs)
1633                 (cd $MNTPOINT ; find . | cpio -H newc -o > "$IMAGE")
1634                 ;;
1635         *)
1636                 echo "Filesystem $INITRDFS not supported by $0";
1637 esac
1638
1639 if is_yes "$COMPRESS" ; then
1640         gzip -9 < "$IMAGE" > "$target"
1641 else
1642         cp -a "$IMAGE" "$target"
1643 fi
1644
1645 if is_yes "$BOOT_SPLASH"; then
1646         if [ ! -x /bin/splash.bin ]; then
1647                 echo >&2 "Failed to execute /bin/splash.bin. Is bootsplash package installed?"
1648         elif [ -z "$THEME" ]; then
1649                 echo >&2 "Please configure your /etc/sysconfig/bootsplash first."
1650                 echo >&2 "Generating bootsplashes skipped."
1651         else
1652                 if [ -n "$BOOT_SPLASH_RESOLUTIONS" ]; then
1653                         for res in $BOOT_SPLASH_RESOLUTIONS; do
1654                                 if [ -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" ]; then
1655                                         /bin/splash.bin -s -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" >> "$target" && \
1656                                         debug "Added $res $THEME theme to initrd."
1657                                 else
1658                                         echo >&2 "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg doesn't exist, skipped"
1659                                 fi
1660                         done
1661                 else
1662                         echo >&2 "No BOOT_SPLASH_RESOLUTIONS specified in /etc/sysconfig/bootsplash."
1663                         echo >&2 "Not adding bootsplash to initrd."
1664                 fi
1665         fi
1666 fi
1667
1668 if is_yes "$FB_SPLASH"; then
1669         if [ ! -x /usr/bin/splash_geninitramfs ]; then
1670                 echo >&2 "Failed to execute /usr/bin/splash_geninitramfs. Is splashutils package installed?"
1671         elif [ -z "$SPLASH_THEME" ]; then
1672                 echo >&2 "Please configure your /etc/sysconfig/fbsplash first."
1673                 echo >&2 "Generating fbsplashes skipped."
1674         else
1675                 if [ -n "$FB_SPLASH_RESOLUTIONS" ]; then
1676                         for res in $FB_SPLASH_RESOLUTIONS; do
1677                                 if [ -f "/etc/splash/$SPLASH_THEME/$res.cfg" ]; then
1678                                         /usr/bin/splash_geninitramfs -a $target -r $res $SPLASH_THEME && \
1679                                         debug "Added $res $SPLASH_THEME theme to initramfs."
1680                                 else
1681                                         echo >&2 "/etc/splash/$SPLASH_THEME/$res.cfg doesn't exist, skipped"
1682                                 fi
1683                         done
1684                 else
1685                         echo >&2 "No FB_SPLASH_RESOLUTIONS specified in /etc/sysconfig/fbsplash."
1686                         echo >&2 "Not adding fbsplash to initramfs."
1687                 fi
1688         fi
1689 fi
1690
1691 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"
1692
1693 # vim:ts=4:sw=4:noet:fdm=marker
This page took 0.153255 seconds and 3 git commands to generate.