]> git.pld-linux.org Git - projects/geninitrd.git/blob - geninitrd
better message if modules is loadded without options
[projects/geninitrd.git] / geninitrd
1 #!/bin/sh
2
3 # geninitrd
4 #
5 #       by Jacek Konieczny <jajcus@pld.org.pl>
6 #
7 # based on mkinitrd from RedHat
8 #
9 PATH=/sbin:$PATH
10 export PATH
11
12 VERSION=%VERSIONTAG%
13
14 . /etc/rc.d/init.d/functions
15
16 COMPRESS="yes"
17 FS="rom"
18 PROBESCSI="yes"
19 PROBEIDE="yes"
20 PROBERAID="yes"
21 USEBSP="yes"
22
23 if [ -f /etc/sysconfig/geninitrd ] ; then
24         . /etc/sysconfig/geninitrd
25 fi
26
27 if is_yes $USEBSP ; then
28         [ ! -x /sbin/bsp ] && USEBSP="no"
29 fi
30 target=""
31 kernel=""
32 force=""
33 verbose=""
34 MODULES=""
35 img_vers=""
36 modulefile=/etc/modules.conf
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 "       [--omit-scsi-modules] [--omit-raid-modules] [--omit-ide-modules]" 1>&2
49         echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" 1>&2 
50         echo "       [--fs=rom|ext2|cram] [--no-bsp] [--modules-conf=<modules.conf>" 1>&2
51         echo "       <initrd-image> <kernel-version>" 1>&2
52         echo "       (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)" 1>&2
53         exit 1
54 }
55
56
57 my_find() {
58         for name in `ls`
59         do
60                 if [ -d $name ]; then
61                         if [ "$name" != "build" ]; then
62                                 (cd $name;my_find $1/$name $2)
63                         fi
64                 else
65                         if [ -f $name -a "$name" = "$2" ]; then
66                                 echo $1/$name
67                         fi
68                 fi
69         done
70 }
71
72 my_dirname() {
73         echo $1|awk -F/ '{print substr($0, 0, length($0) - length($NF));}'
74 }
75
76 findmodule() {
77         skiperrors=""
78         modName=$1
79         if [ "$(echo $modName | awk '{print(substr($0,1,1));}')" = "-" ]; then
80                 skiperrors=1
81                 modName="$(echo $modName | awk '{print(substr($0,2));}')"
82         fi
83
84         if [ "$modName" = "pluto" ]; then
85                 findmodule fc4
86                 findmodule soc
87         fi
88         if [ "$modName" = "fcal" ]; then
89                 findmodule fc4
90                 findmodule socal
91         fi
92
93         fmPath="`(cd /lib/modules/$kernel; my_find . "$modName.o")`"
94
95         if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
96                 if [ -n "$skiperrors" ]; then
97                         return
98                 fi
99
100                 # ignore the absence of the scsi modules
101                 for n in $PRESCSIMODS; do
102                         if [ "$n" = "$modName" ]; then
103                                 return;
104                         fi
105                 done;
106
107                 # ignore the absence of the ide modules
108                 for n in $PREIDEMODS; do
109                         if [ "$n" = "$modName" ]; then
110                                 return;
111                         fi
112                 done;
113     
114                 echo "No module $modName found for kernel $kernel" 1>&2
115                 exit 1
116         fi
117
118         # only need to add each module once
119         tmpFmPath="`echo "$fmPath"|awk -F/ '{for(i=1;i<NF;i++) { printf("%s\\\\/",$i); } { print $NF; }}'`"
120         if is_yes "`echo "$MODULES" | awk '/"'$tmpFmPath'"/ { print "yes"; }' `" ; then : ; else
121                 MODULES="$MODULES $fmPath"
122         fi
123 }
124
125 inst() {
126         if [ "$#" != "2" ];then
127                 echo "usage: inst <file> <destination>"
128                 return
129         fi 
130         [ -n "$verbose" ] && echo "$1 -> $2"
131         cp "$1" "$2"
132 }
133
134 get_label_ext2 () {
135         /sbin/e2label $1 2> /dev/null
136 }
137
138 get_uuid_ext2 () {
139         /sbin/tune2fs -l $1 2> /dev/null | awk  -F: '/UUID:/ {gsub(" ",""); print $2}'
140 }
141
142 get_label_xfs () {
143     /sbin/xfs_admin -l $1 2> /dev/null
144 }
145
146 get_uuid_xfs () {
147     /sbin/xfs_admin -u $1 2> /dev/null
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 /sbin/xfs_admin ] ; then
164 #                               echo "/sbin/xfs_admin 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 /sbin/xfs_admin ] ; then
205 #                               echo "/sbin/xfs_admin 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         --with*)
260                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
261                         modname="`echo $1 | awk -F= '{print $2;}'`"
262                 else
263                         modname="$2"
264                         shift
265                 fi                  
266
267                 BASICMODULES="$BASICMODULES $modname"
268                 ;;
269         --version)
270                 echo "geninitrd: version $VERSION"
271                 exit 0
272                 ;;
273         -v)
274                 verbose=-v
275                 ;;
276         --nocompress)
277                 COMPRESS="no"
278                 ;;
279         --ifneeded)
280                 ifneeded=1
281                 ;;
282         -f)
283                 force=1
284                 ;;
285         --preload*)
286                 if is_yes "`echo $1 | awk '/=/ { print "yes"; }'`" ; then
287                         modname="`echo $1 | awk -F= '{print $2;}'`"
288                 else
289                         modname="$2"
290                         shift
291                 fi                  
292                 PREMODS="$PREMODS $modname"
293                 ;;
294         --omit-scsi-modules)
295                 PRESCSIMODS=""
296                 PROBESCSI="no";
297                 ;;
298         --omit-raid-modules)
299                 PROBERAID="no";
300                 ;;
301         --omit-ide-modules)
302                 PROBEIDE="no";
303                 ;;
304         --fs=*)
305                 FS="`echo $1 | awk -F= '{print $2;}'`"
306                 ;;
307         --fs)
308                 FS="$2"
309                 shift
310                 ;;
311         --image-version)
312                 img_vers=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 "$PROBESCSI" && is_yes "$(echo "$rootdev" | awk '/^\/dev\/sd/ { print "yes"; }')" ; then
378
379     for n in $PRESCSIMODS; do
380         if [ "$n" = "unknown" ] ; then
381                 if [ ! -f "$modulefile" ]; then
382                         modulefile=/etc/conf.modules
383                 fi
384                 if [ -f "$modulefile" ]; then
385                         scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile| LC_ALL=C sort -u`"
386                         for n in $scsimodules; do
387                 # for now allow scsi modules to come from anywhere.  There are some
388                 # RAID controllers with drivers in block/
389                                 findmodule "$n"
390                         done
391                 fi
392         else
393                 findmodule "$n"
394         fi
395     done
396
397 fi
398
399 if is_yes "$PROBEIDE" && is_yes "`echo "$rootdev" | awk '/^\/dev\/hd/ { print "yes"; }'`" ; then
400     for n in $PREIDEMODS; do
401             findmodule "$n"
402     done
403 fi
404
405 if is_yes "$PROBERAID" ; then
406     # load appropriate raid devices if necessary
407     if is_yes "`awk '/^\/dev\/md/ && ! /noauto/ { print "yes"; }' "$fstab"`" ; then
408         for number in $(awk '/^[\t ]*raid-level/ { print $2; }' /etc/raidtab | LC_ALL=C sort -u) ; do
409             case "$number" in
410             [0145])
411                 findmodule "raid$number"
412                 ;;
413             *)
414                 echo "raid level $number (in /etc/raidtab) not recognized" 1>&2
415                 ;;
416             esac
417         done
418     fi
419 fi
420
421 if is_yes "`echo "$rootdev" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
422         findmodule "DC960"
423 fi
424
425 if is_yes "`echo "$rootdev" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
426         findmodule "cpqarray"
427 fi
428
429 if is_yes "`echo "$rootdev" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
430         findmodule "cciss"
431 fi
432
433 # check to see if we need to set up a loopback filesystem
434 if is_yes "`echo "$rootdev" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
435         if [ ! -x /sbin/losetup ]; then
436                 echo "losetup is missing"
437                 exit 1
438         fi
439         key="^# $(echo $rootdev | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
440         if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
441                 echo "The root filesystem is on a $rootdev, but there is no magic entry in $fstab" 1>&2
442                 echo "for this device. Consult the geninitrd man page for more information" 1>&2
443                 exit 1
444         fi
445
446         line="`awk '/'$key'/ { print $0; }' $fstab`"
447         loopDev="$(echo $line | awk '{print $3}')"
448         loopFs="$(echo $line | awk '{print $4}')"
449         loopFile="$(echo $line | awk '{print $5}')"
450
451         BASICMODULES="$BASICMODULES -loop"
452         findmodule "-$loopFs"
453         BASICMODULES="$BASICMODULES -${loopFs}"
454         # don't have any clue, how is this supposed to work,
455         # anyway no bsp
456         USEBSP="no"
457 else # Check for other filesystems
458         findmodule "-$rootFs"
459 fi
460
461 for n in $BASICMODULES; do 
462         findmodule "$n"
463 done
464
465 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
466         if [ -n "$verbose" ]; then
467                 echo "No modules are needed -- not building initrd image."
468         fi
469         exit 0
470 fi
471
472 if [ -n "$verbose" ]; then
473         echo "Using modules: $MODULES"
474 fi
475
476 MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
477 IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
478 MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
479 RCFILE="$MNTIMAGE/linuxrc"
480
481 if [ -f "$MNTIMAGE" ]; then
482         echo "$MNTIMAGE already exists.  Remove it and try again" 1>&2
483         exit 1
484 fi
485
486 if [ -f "$IMAGE" ]; then
487         echo "$IMAGE already exists. Remove it and try again" 1>&2
488         exit 1
489 fi
490
491 if [ "$FS" = "ext2" ] ; then
492         dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
493
494         # We have to "echo y |" so that it doesn't complain about $IMAGE not
495         # being a block device
496         echo y | mke2fs -F "$IMAGE" "$IMAGESIZE" >/dev/null 2>/dev/null
497
498         mkdir -p "$MNTPOINT"
499         mount -o loop -t ext2 "$IMAGE" "$MNTPOINT"
500 else
501         mkdir -p "$MNTPOINT"
502 fi
503
504
505 mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs}
506
507
508 # We don't need this directory, so let's save space
509 rm -rf "$MNTPOINT"/lost+found
510
511 for MODULE in $MODULES; do
512         MODULEDIR="`my_dirname "$MODULE"`"
513         mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
514         cp $verbose -a "/lib/modules/$kernel/$MODULE" "$MNTIMAGE/lib/modules/$kernel/$MODULE"
515 done
516
517 # mknod'ing the devices instead of copying them works both with and
518 # without devfs...
519 mknod "$MNTIMAGE/dev/console" c 5 1
520
521 if is_yes "$USEBSP" ; then
522         s="$MNTIMAGE/etc/startup"
523         inst /sbin/bsp "$RCFILE"
524         echo "# autogenerated startup" > "$s"
525         echo "" >> "$s"
526     
527         for MODULE in $MODULES; do
528                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
529                 options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
530     
531                 if [ -n "$verbose" ]; then
532                         /bin/echo -n "Loading module $module "
533                         if [ -n "$options"]
534                                 echo "with options $options"
535                         else
536                                 echo "without options"
537                         fi
538                 fi
539                 echo "insmod /lib/modules/$kernel/$MODULE $options" >> "$s"
540         done
541 else
542         inst /bin/trash "$MNTIMAGE/bin/sh"
543         inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
544     
545         mknod "$MNTIMAGE/dev/null" c 1 3
546         mknod "$MNTIMAGE/dev/ram" b 1 1
547         mknod "$MNTIMAGE/dev/systty" c 4 0
548         for i in 1 2 3 4; do
549                 mknod "$MNTIMAGE/dev/tty$i" c 4 1
550         done
551         mknod "$MNTIMAGE/dev/zero" c 1 5
552     
553         echo "#!/bin/sh" > "$RCFILE"
554         echo "" >> "$RCFILE"
555     
556         for MODULE in $MODULES; do
557                 module="`echo $MODULE | awk -F/ '{ $0=$NF } /.o$/ { $0=substr($0,1,length($0)-2); } { print $0; }'`"
558                 if [ -f "$modulefile" ] ; then
559                         options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"
560                 else
561                         options=
562                 fi
563
564                 if [ -n "$verbose" ]; then
565                         echo "Loading module $module with options $options"
566                 fi
567                 echo "Add module $module to initrd."
568                 echo "echo \"Loading $module module\"" >> "$RCFILE"
569                 echo "insmod -k /lib/modules/$kernel/$MODULE $options" >> "$RCFILE"
570         done
571
572         if [ -n "$loopDev" ]; then
573                 if [ ! -d /initrd ]; then
574                         mkdir /initrd
575                 fi
576     
577                 cp -a "$loopDev" "$MNTIMAGE/dev"
578                 cp -a "$rootdev" "$MNTIMAGE/dev"
579                 echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
580                 echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
581                 echo "echo Setting up loopback device $rootdev" >> $RCFILE
582                 echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
583         fi
584 fi
585
586 chmod +x "$RCFILE"
587
588 (cd "$MNTIMAGE"; tar cf - .) | (cd "$MNTPOINT"; tar xf -)
589
590 case "$FS" in
591         ext2)
592                 umount "$IMAGE"
593                 ;;
594         rom)
595                 genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
596                 ;;
597         cram)
598                 mkcramfs "$MNTPOINT" "$IMAGE"
599                 ;;
600         *)
601                 echo "Filesystem $FS not supported by $0";
602 esac            
603
604 if is_yes "$COMPRESS" ; then
605         gzip -9 < "$IMAGE" > "$target"
606 else
607         cp -a "$IMAGE" "$target"
608 fi
609 rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"
This page took 0.070339 seconds and 4 git commands to generate.