]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
- s/DC960/DAC960/
[projects/geninitrd.git] / geninitrd
1 #!/bin/sh
2
3 # geninitrd
4 # $Id: geninitrd,v 1.38 2001/08/22 15:04:52 areq Exp $
5 #
6 #       by Jacek Konieczny <jajcus@pld.org.pl>
7 #
8 # based on mkinitrd from RedHat
9 #
10 PATH=/sbin:$PATH
11 export PATH
12
13 VERSION=%VERSIONTAG%
14
15 . /etc/rc.d/init.d/functions
16
17 COMPRESS="yes"
18 FS="rom"
19 USEBSP="yes"
20 USERAIDSTART="no"
21
22 if [ -f /etc/sysconfig/geninitrd ] ; then
23         . /etc/sysconfig/geninitrd
24 fi
25
26 if is_yes $USEBSP ; then
27         [ ! -x /sbin/bsp ] && USEBSP="no"
28 fi
29 target=""
30 kernel=""
31 force=""
32 verbose=""
33 MODULES=""
34 img_vers=""
35 modulefile=/etc/modules.conf
36 raidtab=/etc/raidtab
37 if [ "`uname -m`" = "ia64" ]; then
38         IMAGESIZE=3000
39 else
40         IMAGESIZE=1500
41 fi
42 PRESCSIMODS="scsi_mod unknown sd_mod"
43 PREIDEMODS="ide-mod ide-probe ide-probe-mod ide-disk"
44 fstab="/etc/fstab"
45
46 usage () {
47         echo "usage: `basename $0` [--version] [-v] [-f] [--ifneeded] [--preload <module>]" 1>&2
48         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2 
49         echo "       [--fs=rom|ext2|cram] [--no-bsp] [--modules-conf=<modules.conf>" 1>&2
50         echo "       <initrd-image> <kernel-version>" 1>&2
51         echo "       (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
52         exit 1
53 }
54
55
56 my_find() {
57         for name in `ls`
58         do
59                 if [ -d $name ]; then
60                         if [ "$name" != "build" ]; then
61                                 (cd $name;my_find $1/$name $2)
62                         fi
63                 else
64                         if [ -f $name -a "$name" = "$2" ]; then
65                                 echo $1/$name
66                         fi
67                 fi
68         done
69 }
70
71 my_dirname() {
72         echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
73 }
74
75 findmodule() {
76         skiperrors=""
77         modName=$1
78         if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
79                 skiperrors=1
80                 modName="$(echo $modName | awk '{print(substr($0,2));}')"
81         fi
82
83         if [ "$modName" = "pluto" ]; then
84                 findmodule fc4
85                 findmodule soc
86         fi
87         if [ "$modName" = "fcal" ]; then
88                 findmodule fc4
89                 findmodule socal
90         fi
91
92         fmPath="`(cd /lib/modules/$kernel; my_find . "$modName.o")`"
93
94         if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
95                 if [ -n "$skiperrors" ]; then
96                         return
97                 fi
98
99                 # ignore the absence of the scsi modules
100                 for n in $PRESCSIMODS; do
101                         if [ "$n" = "$modName" ]; then
102                                 return;
103                         fi
104                 done;
105
106                 # ignore the absence of the ide modules
107                 for n in $PREIDEMODS; do
108                         if [ "$n" = "$modName" ]; then
109                                 return;
110                         fi
111                 done;
112     
113                 echo "No module $modName found for kernel $kernel" 1>&2
114                 exit 1
115         fi
116
117         # only need to add each module once
118         tmpFmPath="`echo "$fmPath"|awk -F/ '{for(i=1;i<NF;i++) { printf("%s\\\\/",$i); } { print $NF; }}'`"
119         if is_yes "`echo "$MODULES" | awk '/"'$tmpFmPath'"/ { print "yes"; }' `" ; then : ; else
120                 MODULES="$MODULES $fmPath"
121         fi
122 }
123
124 inst() {
125         if [ "$#" != "2" ];then
126                 echo "usage: inst <file> <destination>"
127                 return
128         fi 
129         [ -n "$verbose" ] && echo "$1 -> $2"
130         cp "$1" "$2"
131 }
132
133 get_label_ext2 () {
134         /sbin/e2label $1 2> /dev/null
135 }
136
137 get_uuid_ext2 () {
138         /sbin/tune2fs -l $1 2> /dev/null | awk  -F: '/UUID:/ {gsub(" ",""); print $2}'
139 }
140
141 get_label_xfs () {
142         /usr/sbin/xfs_db -x -p xfs_admin -c label -r "$1"|awk -F= '{sub("^\"","", $2); sub("\"$", "", $2); print $2}'
143         
144 }
145
146 get_uuid_xfs () {
147         /usr/sbin/xfs_db -x -p xfs_admin -c uuid -r "$1"|awk -F= '{print $2}'
148 }
149
150 find_root() { 
151         eval `awk '/^[\t ]*#/ {next} {if ( $2 == "/" ) {print "rootdev=\"" $1 "\"\nrootFs=\"" $3 "\""}}' $fstab`
152         case $rootdev in
153         LABEL=*)
154                 case $rootFs in
155                 ext2) 
156                         if [ ! -x /sbin/e2label ] ; then
157                                 echo "/sbin/e2label is missing" 1>&2
158                                 exit 1
159                         fi
160                         get_label="get_label_ext2"
161                         ;;
162                 xfs)
163                         if [ ! -x /usr/sbin/xfs_db ] ; then
164                                 echo "/usr/sbin/xfs_db is missing" 1>&2
165                                 exit 1
166                         fi
167                         get_label="get_label_xfs"
168                         ;;
169                 *)
170                         echo "LABEL on $rootFs in not supported by geninitrd" 1>&2
171                         exit 1
172                         ;;
173                 esac
174                 if [ ! -r /proc/partitions ] ; then
175                         echo '/proc/partitions is not readable'; 1>&2
176                         exit 1
177                 fi
178                 label=${rootdev#"LABEL="}
179                 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
180                         if [ -r $dev ] && [ "$label" = "`$get_label $dev`" ] ; then
181                                 if [ -n "$verbose" ] ; then
182                                         echo "Using $dev as device for rootfs"
183                                 fi
184                             rootdev=$dev
185                             rootdev_found=1
186                             break
187                         fi
188                 done
189                 if [ "$rootdev_found" != 1 ] ; then
190                     echo "geninitrd can't find real device for LABEL=$label" 1>&2
191                     exit 1
192                 fi
193                 ;;
194         UUID=*)
195                 case $rootFs in
196                 ext2) 
197                         if [ ! -x /sbin/tune2fs ] ; then
198                                 echo "/sbin/tune2fs is missing" 1>&2
199                                 exit 1
200                         fi
201                         get_uuid="get_uuid_ext2"
202                         ;;
203                 xfs)
204                         if [ ! -x /usr/sbin/xfs_db ] ; then
205                                 echo "/usr/sbin/xfs_db is missing" 1>&2
206                                 exit 1
207                         fi
208                         get_label="get_uuid_xfs"
209                         ;;
210                 *)
211                         echo "UUID on $rootFs in not supported by geninitrd" 1>&2
212                         exit 1
213                         ;;
214                 esac
215                 if [ ! -r /proc/partitions ] ; then
216                         echo '/proc/partitions is not readable'; 1>&2
217                         exit 1
218                 fi
219                 uuid=${rootdev#"UUID="}
220                 for dev in `awk 'BEGIN {getline;getline} {print "/dev/" $4}' /proc/partitions` ; do
221                         if [ -r $dev ] && [ "$uuid" = "`$get_uuid $dev`" ] ; then
222                                 if [ -n "$verbose" ] ; then
223                                         echo "Using $dev as device for rootfs"
224                                 fi
225                             rootdev=$dev
226                             rootdev_found=1
227                             break
228                         fi
229                 done
230                 if [ "$rootdev_found" != 1 ] ; then
231                     echo "geninitrd can't find real device for UUID=$uuid" 1>&2
232                     exit 1
233                 fi
234                 ;;
235         esac
236
237 }
238
239 while [ $# -gt 0 ]; do
240         case $1 in
241         --no-bsp)
242                 USEBSP="no"
243                 ;;
244         --fstab*)
245                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
246                         fstab="`echo $1 | awk -F= '{print $2;}'`"
247                 else
248                         fstab="$2"
249                         shift
250                 fi                  
251                 ;;
252         --modules-conf=*)
253                 modulefile="`echo $1 | awk -F= '{print $2;}'`"
254                 ;;
255         --modukes-conf)
256                 modulefile="$2"
257                 shift
258                 ;;
259         --raidtab=*)
260                 raidtab="`echo $1 | awk -F= '{print $2;}'`"
261                 ;;
262         --raidtab)
263                 raidtab="$2"
264                 shift
265                 ;;
266         --with*)
267                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
268                         modname="`echo $1 | awk -F= '{print $2;}'`"
269                 else
270                         modname="$2"
271                         shift
272                 fi                  
273
274                 BASICMODULES="$BASICMODULES $modname"
275                 ;;
276         --version)
277                 echo "geninitrd: version $VERSION"
278                 exit 0
279                 ;;
280         -v)
281                 verbose=-v
282                 ;;
283         --nocompress)
284                 COMPRESS="no"
285                 ;;
286         --ifneeded)
287                 ifneeded=1
288                 ;;
289         -f)
290                 force=1
291                 ;;
292         --preload*)
293                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
294                         modname="`echo $1 | awk -F= '{print $2;}'`"
295                 else
296                         modname="$2"
297                         shift
298                 fi                  
299                 PREMODS="$PREMODS $modname"
300                 ;;
301         --fs=*)
302                 FS="`echo $1 | awk -F= '{print $2;}'`"
303                 ;;
304         --fs)
305                 FS="$2"
306                 shift
307                 ;;
308         --image-version)
309                 img_vers=yes
310                 ;;
311         --use-raidstart)
312                 USERAIDSTART=yes
313                 ;;
314         *)
315                 if [ -z "$target" ]; then
316                         target="$1"
317                 elif [ -z "$kernel" ]; then
318                         kernel="$1"
319                 else
320                         usage
321                 fi
322                 ;;
323         esac
324
325         shift
326 done
327
328 if [ -z "$target" -o -z "$kernel" ]; then
329         usage
330 fi
331
332 case "$FS" in
333         ext2)
334                 if [ ! -x /sbin/mke2fs ]; then
335                         echo "/sbin/mke2fs is missing" 1>&2
336                         exit 1
337                 fi
338                 ;;
339         rom)
340                 if [ ! -x /sbin/genromfs ]; then
341                         echo "/sbin/genromfs is missing" 1>&2
342                         exit 1
343                 fi
344                 ;;
345         cram)
346                 if [ ! -x /sbin/mkcramfs ]; then
347                         echo "/sbin/mkcramfs is missing" 1>&2
348                         exit 1
349                 fi
350                  ;;
351         *)
352                 echo "Filesystem $FS on initrd is not supported" 1>&2
353                 exit 1
354                 ;;
355 esac
356
357 if [ -n "$img_vers" ]; then
358         target="$target-$kernel"
359 fi
360
361 if [ -z "$force" -a -f "$target" ]; then
362         echo "$target already exists." 1>&2
363         exit 1
364 fi
365
366 if [ ! -d "/lib/modules/$kernel" ]; then
367         echo "/lib/modules/$kernel is not a directory." 1>&2
368         exit 1
369 fi
370
371 for n in $PREMODS; do
372         findmodule "$n"
373 done
374
375 find_root
376
377 if is_yes "`echo "$rootdev" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
378         eval `awk -v rootdev=$rootdev 'BEGIN {
379         addide="no"; 
380         addscsi="no";
381         found="no";
382
383
384
385         gsub("\t"," "); 
386         gsub("  +", " "); 
387         gsub("^ ",""); 
388         if (/^[\t ]*#/) 
389                 next; 
390         if (/^raiddev/) { 
391                 if ($2 == rootdev) {
392                         found="yes";
393                 } else {
394                         if (found == "yes") {
395                                 exit 0;
396                         };
397                 }; 
398         }; 
399         if (found == "yes") {
400                 if ($1 == "device") {
401                         if ($2 ~ /\/dev\/(sd|scsi)/) {
402                                 addscsi="yes";
403                         };
404                         if ($2 ~ /\/dev\/(hd|ide)/) {
405                                 addide="yes";
406                         };
407                 };
408                 if ($1 == "raid-level") {
409                         raidlevel=$2;
410                 }
411         };
412 }
413
414 END {
415         print "raidfound=" found "\nADDSCSI=" addscsi "\nADDIDE=" addide "\nraidlevel=" raidlevel "\n";
416 }' $raidtab `
417     if is_yes "$raidfound" ; then
418             case "$raidlevel" in
419             [0145])
420                         findmodule "raid$raidlevel"
421                         ;;
422                 linear)
423                         findmodule "linear"
424                         ;;
425             *)
426                         echo "raid level $number (in $raidtab) not recognized" 1>&2
427                         ;;
428             esac
429     fi
430
431 else
432         USERAIDSTART="no"
433 fi
434
435 if is_yes "$ADDSCSI" || is_yes "$(echo "$rootdev" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
436
437     for n in $PRESCSIMODS; do
438         if [ "$n" = "unknown" ] ; then
439                 if [ ! -f "$modulefile" ]; then
440                         modulefile=/etc/conf.modules
441                 fi
442                 if [ -f "$modulefile" ]; then
443                         scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
444                         for n in $scsimodules; do
445                 # for now allow scsi modules to come from anywhere.  There are some
446                 # RAID controllers with drivers in block/
447                                 findmodule "$n"
448                         done
449                 fi
450         else
451                 findmodule "$n"
452         fi
453     done
454
455 fi
456
457 if is_yes "$ADDIDE" || is_yes "`echo "$rootdev" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }'`" ; then
458     for n in $PREIDEMODS; do
459             findmodule "$n"
460     done
461 fi
462
463 if is_yes "`echo "$rootdev" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
464         findmodule "DAC960"
465 fi
466
467 if is_yes "`echo "$rootdev" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
468         findmodule "cpqarray"
469 fi
470
471 if is_yes "`echo "$rootdev" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
472         findmodule "cciss"
473 fi
474
475 # check to see if we need to set up a loopback filesystem
476 if is_yes "`echo "$rootdev" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
477         if [ ! -x /sbin/losetup ]; then
478                 echo "losetup is missing"
479                 exit 1
480         fi
481         key="^# $(echo $rootdev | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
482         if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
483                 echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
484                 echo "for this device. Consult the geninitrd man page for more information" 1>&2
485                 exit 1
486         fi
487
488         line="`awk '/'$key'/ { print $0; }' $fstab`"
489         loopDev="$(echo $line | awk '{print $3}')"
490         loopFs="$(echo $line | awk '{print $4}')"
491         loopFile="$(echo $line | awk '{print $5}')"
492
493         BASICMODULES="$BASICMODULES -loop"
494         findmodule "-$loopFs"
495         BASICMODULES="$BASICMODULES -${loopFs}"
496         # don't have any clue, how is this supposed to work,
497         # anyway no bsp
498         USEBSP="no"
499 else # Check for other filesystems
500         findmodule "-$rootFs"
501 fi
502
503 for n in $BASICMODULES; do 
504         findmodule "$n"
505 done
506
507 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
508         if [ -n "$verbose" ]; then
509                 echo "No modules are needed -- not building initrd image."
510         fi
511         exit 0
512 fi
513
514 if [ -n "$verbose" ]; then
515         echo "Using modules: $MODULES"
516 fi
517
518 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
519 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
520 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
521 RCFILE="$MNTIMAGE/linuxrc"
522
523 if [ -f "$MNTIMAGE" ]; then
524         echo "$MNTIMAGE already exists.  Remove it and try again" 1>&2
525         exit 1
526 fi
527
528 if [ -f "$IMAGE" ]; then
529         echo "$IMAGE already exists. Remove it and try again" 1>&2
530         exit 1
531 fi
532
533 if [ "$FS" = "ext2" ] ; then
534         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
535
536         # We have to "echo y |" so that it doesn't complain about $IMAGE not
537         # being a block device
538         echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
539
540         mkdir -p "$MNTPOINT"
541         mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
542 else
543         mkdir -p "$MNTPOINT"
544 fi
545
546
547 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
548
549
550 # We don't need this directory, so let's save space
551 rm -rf "$MNTPOINT"/lost+found
552
553 for MODULE in $MODULES; do
554         MODULEDIR="`my_dirname "$MODULE"`"
555         mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
556         cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
557 done
558
559 # mknod'ing the devices instead of copying them works both with and
560 # without devfs...
561 mknod "$MNTIMAGE/dev/console" c 5 1
562
563 if is_yes "$USEBSP" ; then
564         s="$MNTIMAGE/etc/startup"
565         inst /sbin/bsp "$RCFILE"
566         echo "# autogenerated startup" > "$s"
567         echo "" >> "$s"
568     
569         for MODULE in $MODULES; do
570                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
571                 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
572     
573                 if [ -n "$verbose" ]; then
574                         /bin/echo -n "Loading module $module "
575                         if [ -n "$options" ] ; then
576                                 echo "with options $options."
577                         else
578                                 echo "without options."
579                         fi
580                 fi
581                 echo "insmod /lib/modules/$kernel/$MODULE $options" >> "$s"
582         done
583 else
584         inst /bin/trash "$MNTIMAGE/bin/sh"
585         inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
586     
587         mknod "$MNTIMAGE/dev/null" c 1 3
588         mknod "$MNTIMAGE/dev/ram" b 1 1
589         mknod "$MNTIMAGE/dev/systty" c 4 0
590         for i in 1 2 3 4; do
591                 mknod "$MNTIMAGE/dev/tty$i" c 4 1
592         done
593         mknod "$MNTIMAGE/dev/zero" c 1 5
594     
595         echo "#!/bin/sh" > "$RCFILE"
596         echo "" >> "$RCFILE"
597     
598         for MODULE in $MODULES; do
599                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
600                 if [ -f "$modulefile" ] ; then
601                         options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
602                 else
603                         options=
604                 fi
605
606                 if [ -n "$verbose" ]; then
607                         echo "Loading module $module with options $options"
608                 fi
609                 echo "Add module $module to initrd."
610                 echo "echo \"Loading $module module\"" >> "$RCFILE"
611                 echo "insmod -k /lib/modules/$kernel/$MODULE $options" >> "$RCFILE"
612         done
613
614
615         if [ -n "$loopDev" ]; then
616                 if [ ! -d /initrd ]; then
617                         mkdir /initrd
618                 fi
619     
620                 cp -a "$loopDev" "$MNTIMAGE/dev"
621                 cp -a "$rootdev" "$MNTIMAGE/dev"
622                 echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
623                 echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
624                 echo "echo Setting up loopback device $rootdev" >> $RCFILE
625                 echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
626         fi
627 fi
628
629 if is_yes "$USERAIDSTART" ; then 
630         if [ -x /sbin/raidstart.static ] ; then
631                 [ -n "$verbose" ] && echo "Add raidstart to initrd"
632                 mkdir -p "$MNTIMAGE/etc" || true
633                 inst /sbin/raidstart.static "$MNTIMAGE/bin/raidstart"
634                 inst "$raidtab" "$MNTIMAGE/etc/raidtab"
635                 echo "echo \"Starting RAID\"" >> "$RCFILE"
636                 echo "/bin/raidstart $rootdev" >> "$RCFILE"
637         else
638                 echo "/sbin/raidstart.static is missing" 1>&2
639                 exit 1
640         fi
641 fi
642
643 chmod +x "$RCFILE"
644
645 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
646
647 case "$FS" in
648         ext2)
649                 umount "$IMAGE"
650                 ;;
651         rom)
652                 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
653                 ;;
654         cram)
655                 mkcramfs "$MNTPOINT" "$IMAGE"
656                 ;;
657         *)
658                 echo "Filesystem $FS not supported by $0";
659 esac            
660
661 if is_yes "$COMPRESS" ; then
662         gzip -9 < "$IMAGE" > "$target"
663 else
664         cp -a "$IMAGE" "$target"
665 fi
666 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"
This page took 0.106459 seconds and 4 git commands to generate.