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