Fix support for linux 3.x
[rrq/maintain_lilo.git] / mkrescue
1 #!/bin/bash
2 #
3 # mkrescue
4 #
5 #       30-Oct-2001     original version 1.0
6 #
7 # Revision history:
8 #       09-Apr-2002     John Coffman    modify for lilo 22.3   1.1
9 #       09-Jun-2002     John Coffman    get keyboard translation table 1.2
10 #                                       (suggested by Qing Liu)
11 #       07-May-2003     John Coffman    add nowarn for lilo 22.5.2  1.3
12 #       13-May-2003     John Coffman    use default image, add append=  1.4
13 #       24-May-2003     John Coffman    specify ext2 params for xtra space
14 #       26-May-2003     John Coffman    el-torito-bootable-CD   2.1
15 #       30-May-2003        "            add lilo version check  2.1
16 #       07-Jul-2003        "            determine loopback dynamically 2.3
17 #       29-Aug-2004        "            allow --root LABEL=lblname  2.4
18 #       01-Sep-2004        "            fix check for LILO version  2.4
19 #       03-Oct-2004        "            get root= from /etc/fstab   2.5
20 #       15-Nov-2004        "            support --iso --size HD     3.0
21 #       18-Aug-2005        "            applied temp-file security patch 3.1
22 #       25-Sep-2005        "            log config file on --debug  3.2
23 #       04-Oct-2005        "            new 'master' determination  3.2
24 #       07-Oct-2005        "            add -v0 -w to usages of -I  3.2
25 #
26
27 debug=false
28 #debug=true
29
30 # set the version number on this command
31 version=3.2
32
33 # set the version of LILO required to run
34 major=22
35 minor=6
36 revision=1
37
38 log=$(pwd)/mkrescue.log
39 clog=$(pwd)/mkrescue.conf.log
40
41
42 usage () {
43     cat <<EOF
44
45 usage:  `basename $0` [--help]
46         `basename $0` [--version]
47         `basename $0` [--device <device>] [--fast] [--fs ext2|msdos|minix]
48             [--image <label>] [--install text|menu] [--keymap <keymap.ktl>] 
49             [--initrd <file> --kernel <file>] [--append <string>]
50             [--root <device>] [--nocompact] [--noformat]
51             [--iso] [--size 1440|1200|2880|HD]
52
53   --device  is the floppy drive; e.g.,  /dev/fd0
54   --fast  specifies creation using a loopback device, which may be faster
55   --fs  is the filesystem to make on the device; e.g.,  ext2
56   --help  prints this helpfile
57   --iso  create a bootable ISO image to burn to a CD-R or CD-RW
58   --keymap  is the keyboard translation table; default to same as lilo.conf
59   --noformat  bypasses creation of a new filesystem on device
60   --nocompact  omits lilo map file compaction
61   --size  is assumed to be 1440 (1.44M), unless 1200 or 2880 is specified
62         HD may be specified for ISO images
63   --image  specifies the label of the kernel/initrd if not the default
64   --install  text is the default for floppies, menu for ISO images
65   --initrd and --kernel  are the initial ramdisk & kernel files
66   --append  is a string used to specify kernel options
67   --root  is the root filesystem for the boot floppy; e.g., current
68   --version  prints the version number of `basename $0`
69
70 Used without any arguments, `basename $0` will use the default kernel in
71 /etc/lilo.conf, the companion initrd (if any), and the specified root
72 filesystem to make a bootable rescue floppy.
73
74 EOF
75 #
76 # --install & --debug are undocumented above
77 #
78 #
79     exit $1
80 }
81
82 if [ $debug != false ]; then
83         lilo=$(pwd)/lilo
84         config=$(pwd)/lilo.conf
85 else
86         lilo=/sbin/lilo
87         config=/etc/lilo.conf
88 fi
89
90 if [ ! -r "$config" ] ; then
91        echo "$0: Cannot read the configuration file $config (are you root?)"
92        exit 1
93 fi
94
95
96 compact=-c
97 device=/dev/fd0
98 fs=ext2
99 tmpbase="`mktemp -dt $(basename $0).XXXXXXXXXX`" || exit
100 if [ "$debug" != true ]; then
101         trap 'rm -rf -- "$tmpbase"' EXIT
102         trap 'trap - EXIT; rm -rf -- "$tmpbase"; exit 1' HUP INT QUIT TERM
103 fi
104 mount="$tmpbase/mkrescue-flp"
105 mfile="$tmpbase/mkrescue-emu"
106 mtemp="$tmpbase/mkrescue-tmp"
107 mkdir "$mount"
108 touch "$mfile" "$mtemp"
109
110 loopback=loop0
111 looppart=loop1
112 install=text
113 isoimage=no
114 format=yes
115 image=
116 root=
117 bios=0x00
118 fast=slow
119 size=0
120 heads=2
121 sectors=18
122 cylinders=80
123 hdsize=16384
124 bootcmd=
125 append=
126 initrd=
127 boot=/boot
128 diag=no
129 master=
130
131 VERSION=$($lilo -V | awk '{print $3}' | sed -e "s/[^a-zA-Z0-9.]//g")
132
133 NVERSION=$(echo $VERSION | sed "s/\\./ /g")
134
135 DASH=$(echo $VERSION | sed "/-/s/.*-//" )
136 if [ "$DASH" = "$VERSION" ]; then
137         DASH=0
138 else
139         NVERSION=$(echo $NVERSION | sed "s/-.*//")
140 fi
141 MAJOR=$(echo $NVERSION | sed "s/ .*//")
142 MINOR=$(echo $NVERSION | sed -e "s/$MAJOR //" -e "s/ .*//" )
143 if [ "$MINOR" = "$NVERSION" ]; then
144         MINOR=0
145 fi
146 REVISION=$(echo $NVERSION | sed "s/$MAJOR $MINOR //")
147 if [ "$REVISION" = "$NVERSION" ]; then
148         REVISION=0
149 fi
150 REVISION=$(echo $REVISION | sed "s/ .*//")
151 if [ "$MINOR" -gt 49 ]; then MINOR=$(expr $MINOR % 10); fi
152
153 if [ $debug = true ]; then
154 echo ""
155 echo VERSION $VERSION
156 echo ""
157 echo MAJOR $MAJOR
158 echo MINOR $MINOR
159 echo REVISION $REVISION
160 echo DASH $DASH
161 echo ""
162 fi
163
164 #if [ "$MAJOR" -lt "$major" \
165 #       -o "$MINOR" -lt "$minor" \
166 #               -o $REVISION -lt "$revision" ]
167 skip=false
168 if [ "$REVISION" -lt "$revision" ]
169 then
170 skip=true
171 #echo $REVISION lt $revision
172 fi
173 if [ "$MINOR" -gt "$minor" ]
174 then
175 skip=false
176 #echo $MINOR gt $minor
177 fi
178 if [ "$MAJOR" -gt "$major" ]
179 then
180 skip=false
181 #echo $MAJOR gt $major
182 fi
183 if [ "$skip" = "true" ]
184 then
185     echo `basename $0` version $version
186     echo "LILO version $major.$minor.$revision (or newer) is required."
187     exit 0
188 fi
189
190 umount $mount 2>/dev/null
191 rm -rf $mount/*
192 > $mfile
193
194 mkdir $tmpbase || {
195     echo "Could not create temporary directory."
196     exit 1
197 }
198
199 master=`mount | grep " / " | cut -d " " -f 1`
200 master=`echo $master | sed "s/part[0-9]*$/disc/"`
201 master=`echo $master | sed "s/[0-9]*$//"`
202 if [ ! -b $master ]; then master=`echo $master | sed "s/p$//"`; fi
203 if [ ! -b $master ]; then master=""  ; fi
204
205
206 while [ $# -gt 0 ]; do
207     case $1 in
208         --append)
209             shift
210             append=$1
211             ;;
212         --debug)
213             debug=true
214             ;;
215         --device)
216             shift
217             device=$1
218             ;;
219         --fast)
220             fast=fast
221             ;;
222         --fs)
223             shift
224             fs=$1
225             ;;
226         -h)
227             usage 0
228             ;;
229         --help)
230             usage 0
231             ;;
232         --image)
233             shift
234             image=$1
235             ;;
236         --initrd)
237             shift
238             initrd=$1
239             ;;
240         --install)
241             shift
242             install=$1
243             ;;
244         --iso)
245             isoimage=yes
246             ;;
247         --kernel)
248             shift
249             kernel=$1
250             ;;
251         --keymap)
252             shift
253             keymap=$1
254             ;;
255         --nocompact)
256             compact=
257             ;;
258         --noformat)
259             format=no
260             ;;
261         --root)
262             shift
263             root=$1
264             ;;
265         --size)
266             shift
267             size=$1
268             ;;
269         --version)
270             echo `basename $0` version $version
271             exit 0
272             ;;
273         *)
274             echo "unrecognized argument: " $1
275             usage 1
276             ;;
277     esac
278
279     shift
280 done
281
282 if [ -z "$image" ]; then
283 #       image=`cat /proc/cmdline | sed "s/.*BOOT_IMAGE=//" | sed "s/ .*//"`
284         image=`$lilo -C $config -v0 -w -I " " D`
285 fi
286
287 if [ -z $kernel ]; then
288         kernel=`$lilo -C $config -v0 -w -I "$image" i`
289         if [ "$kernel" = "" ]; then exit 1;
290         elif [ $debug = "true" ]; then echo kernel = "$kernel";
291         fi
292 fi
293
294 if [ -z $root ]; then
295         root=`$lilo -C $config -v0 -w -I "$image" R`
296         if [ "$root" = "No root specified" ]; then
297                 root=`grep </etc/fstab -v "^[ \t]*#" |
298                         grep "[[:space:]]/[[:space:]]" | \
299                                 sed -e "s/^[ \t]*//" -e "s/[ \t].*//"`
300                 if [ -z $root ]; then
301                         root=`mount | grep " on / type" | sed "s/ .*//"`
302                 fi
303                 if [ -z $root ]; then
304                         echo "Cannot find mounted root partition"
305                         echo "Using current root"
306                         root=current
307                 fi
308         fi
309         if [ $debug = true ]; then echo root = "$root";
310         fi
311 fi
312
313 if [ -z $initrd ]; then
314         initrd=`$lilo -C $config -v0 -w -I "$image" r`
315         if [ "$initrd" = "" ]; then exit 1;
316         elif [ $debug = "true" ]; then echo initrd = "$initrd";
317         fi
318 fi
319 if [ "$initrd" = "No initial ramdisk specified" ]; then initrd= ; fi
320
321 if [ -z $append ]; then
322         append=`$lilo -C $config -v0 -w -I "$image" a`
323         if [ "$append" = "" ]; then exit 1;
324         elif [ $debug = "true" ]; then echo append = \"$append\";
325         fi
326 fi
327 if [ "$append" = "No append= was specified" ]; then append= ; fi
328
329 if [ -z $keymap ]; then
330         keymap=`$lilo -C $config -v0 -w -I "$image" k`
331         if [ "$keymap" = "" ]; then exit 1;
332         elif [ $debug = "true" ]; then echo keymap = "$keymap";
333         fi
334 fi
335
336 if [ $isoimage = yes ]; then
337     fast=fast
338     if [ $size = 0 ]; then
339         size=$hdsize
340     elif [ $size = HD -o $size = hd ]; then
341         size=$hdsize
342     fi
343     if [ $device = "/dev/fd0" ]; then
344         device=rescue.iso
345     fi
346 else
347         umount $device 2>/dev/null 1>/dev/null
348 fi
349
350 if [ $size = 0 ]; then
351     size=1440
352 fi
353
354 if [ $size = 1200 ]; then
355     sectors=15
356 elif [ $size = 1440 ]; then
357     sectors=18
358 elif [ $size = 2880 ]; then
359     sectors=36
360     install=menu
361     if [ -f $boot/diag1.img -a -f $boot/diag2.img ]; then
362         diag=yes
363     fi
364 elif [ $size = $hdsize ]; then
365     sectors=32
366     heads=8
367     cylinders=$(($size/$sectors/$heads*2))
368     if [ $size != $(($sectors*$heads*$cylinders/2)) ]; then
369         echo Internal error in HDsize
370         exit 1
371     fi
372     install=menu
373     if [ -f $boot/diag1.img -a -f $boot/diag2.img ]; then
374         diag=yes
375     fi
376 elif [ $size = HD -o $size = hd ]; then
377     echo "--size $size  may only be used with the  --iso  option."
378     exit 1
379 else
380     echo "--size must be 1200 or 1440; --size 1440 assumed."
381     sectors=18
382     size=1440
383 fi
384
385 if [ $fs != msdos -a $fs != ext2 -a $fs != minix ]; then
386     echo "illegal option:  --fs" $fs
387     echo "   must be either  msdos  or  ext2  or  minix"
388     exit 1
389 fi
390
391 if [ $fs = msdos ]; then
392         mountconfig=$mount/lilo.cnf
393 else
394         mountconfig=$mount/lilo.conf
395 fi
396
397 if [ $debug = "true" ]; then
398         umount $mfile
399
400         echo ""
401
402         echo lilo = $lilo
403         echo device = $device
404         echo image = $image
405         echo kernel = $kernel
406         echo initrd = $initrd
407         echo append = \"$append\"
408         echo install = $install
409         echo format = $format
410         echo fs = $fs
411         echo size = $size
412         echo root = $root
413         echo compact = $compact
414         echo keymap = $keymap
415         echo isoimage = $isoimage
416         echo master = $master
417         echo ""
418         echo pause after parameter display
419         read aline
420 fi
421
422 if [ ! -f $kernel ]; then
423         echo "Kernel file " $kernel " does not exist"
424         exit 1
425 fi
426
427 if [ ! -z $initrd ]; then
428         if [ ! -f $initrd ]; then
429                 echo "Initial ramdisk file " $initrd " does not exist"
430                 exit 1
431         fi
432 fi
433
434 if [ $isoimage != yes ]; then
435        # Calculate size
436         if [ -x /usr/bin/du ]; then
437                 totalsize=`/usr/bin/du -Dc $kernel $initrd $keymap |tail -1 | awk '{ print $1 }'`
438                 if [ "$totalsize" -gt "$size" ] ; then
439                         echo "Sorry, the ramdisk, kernel and keymap don't fit in the floppy disk."
440                         exit 1
441                 fi
442         fi
443         echo ""
444         echo "Insert a blank floppy into $device"
445         echo "All information on this floppy will be destroyed"
446         echo "Press [Enter] to proceed, ^C to abort"
447         read aline
448 fi
449
450 if [ "$fast" = fast ]; then
451
452         dd bs=1024 count=$size of=$mfile if=/dev/zero
453         bsize=$size
454         mpart=$mfile
455         if [ $size = $hdsize ]; then
456             bios=0x80
457             bsize=$(($size-$sectors))
458             cat > $mtemp <<EOF
459 n
460 p
461 1
462
463
464 a
465 1
466 w
467 EOF
468             echo Partitioning HD "file   (this will take a minute)"
469             fdisk -b 512 -S $sectors -H $heads -C $cylinders \
470                 $mfile < $mtemp > /dev/null 2> /dev/null
471             rm -f $mtemp
472             echo bsize = $bsize
473 #read aline
474             losetup -d /dev/$loopback 2>/dev/null
475             losetup -d /dev/$looppart 2>/dev/null
476             losetup /dev/$loopback $mfile
477             losetup -o $(($sectors*512)) /dev/$looppart $mfile
478             mpart=/dev/$looppart
479         fi
480         echo Making filesystem
481         if [ "$fs" = ext2 ]; then
482                 echo y | mkfs.$fs -N 24 -b 1024 $mpart $bsize
483         else
484                 echo y | mkfs.$fs $mpart
485         fi
486         echo Mounting filesystem
487 #read aline
488         if [ $size != $hdsize ]; then
489             mount -t $fs -o rw,loop $mfile $mount
490             loopback=`mount | grep $mfile | sed -e "sX.*loop=/dev/XX" -e "s/).*//"`
491         else
492             mount -t $fs -o rw $mpart $mount
493         fi
494         if [ $debug = true ]; then
495                 mount
496         fi
497         disk="/dev/$loopback"
498         if [ $debug = true ]; then
499                 echo "disk=$disk"
500         fi
501
502 else
503
504         if [ "$format" = "yes" ]; then
505                 echo Formatting $device with $fs filesystem...
506                 dd of=$device if=/dev/zero bs=512 count=1
507                 if [ "$fs" = ext2 ]; then
508                         mkfs -t $fs -N 24 -b 1024 $device 1>/dev/null 2>/dev/null
509                 else
510                         mkfs -t $fs $device 1>/dev/null 2>/dev/null
511                 fi
512                 echo done.
513                 echo ""
514         fi
515
516         rm -rf $mount/*
517         mount -t $fs -o rw $device $mount
518
519         rm -rf $mount/*
520         disk=$device
521
522 fi
523
524 cat > $mountconfig <<EOF
525 #  Begin mkrescue $version configuration file
526 install=$install
527 boot=$device
528 map=map
529 backup=/dev/null
530 message=message
531 prompt
532 timeout=150
533 nowarn
534 geometric
535 disk=$disk bios=$bios
536   sectors=$sectors heads=$heads cylinders=$cylinders
537 EOF
538 if [ $size = $hdsize ]; then
539         echo "  max-partitions=7" >>$mountconfig
540         echo "  partition=/dev/$looppart  start=$sectors" >>$mountconfig
541         echo static-bios-codes >>$mountconfig
542         bios=0x81
543 else
544         bios=0x80
545 fi
546
547 if [ "$master" != "" -a $isoimage = yes ]; then
548         echo "disk=$master" >>$mountconfig
549         echo "  bios=$bios" >>$mountconfig
550 elif [ "$master" != "" -a $debug = true ]; then
551         echo "disk=$master" >>$mountconfig
552         echo "  bios=$bios" >>$mountconfig
553 fi
554
555 if [ $keymap != us.ktl ]; then 
556         echo "keytable=lang.ktl" >>$mountconfig
557 fi
558
559 if [ $isoimage = yes ]; then 
560         echo "el-torito-bootable-CD" >>$mountconfig
561 fi
562
563 echo " " >>$mountconfig
564 echo "image=linux" >>$mountconfig
565
566 if [ ! -z $initrd ]; then
567         echo "  initrd=initrd" >>$mountconfig
568 fi
569
570 if [ ! -z "$append" ]; then
571         echo "  append=\"$append\"" >>$mountconfig
572 fi
573
574 cat >> $mountconfig <<EOF
575   root="$root"
576   read-only
577 EOF
578
579 if [ "$master" != "" -a $isoimage = yes ]; then
580 cat >> $mountconfig <<EOF
581 other=$master
582   unsafe
583   label=hard_disk
584 EOF
585 fi
586
587 if [ "$diag" = yes ]; then
588 cp -pv $boot/diag1.img $mount
589 cp -pv $boot/diag2.img $mount
590 cat >> $mountconfig <<EOF
591 image=diag1.img
592   label=diagnostic_1
593 image=diag2.img
594   label=diagnostic_2
595 EOF
596 fi
597 echo >>$mountconfig "#  End of mkrescue-generated configuration file"
598
599 if [ $isoimage = yes ]; then
600         comment="El-Torito bootable-CD will boot at end of timeout"
601 else
602         comment="floppy will boot in 15 seconds"
603 fi
604
605 rm -rf $mount/lost+found
606 cat > $mount/message <<EOF
607
608 MKRESCUE version $version $comment
609 Use  "boot: linux <options>"  to enter kernel options
610 The root device is currently configured as  root="$root"
611
612 EOF
613 echo `uname --sysname` `uname --release` > $mount/$(uname --release)
614
615 sync
616
617 if [ $debug = true ]; then
618         echo root=\"$root\"
619         echo ""
620         echo "pause after writing lilo.conf & message ..."
621         read aline
622 fi
623
624 echo "Copying files..."
625 if [ $keymap != us.ktl ]; then 
626         cp -pv $keymap $mount/lang.ktl
627 fi
628
629 if [ ! -z $initrd ]; then
630         cp -pv $initrd $mount/initrd
631 fi
632
633 cp -pv $kernel $mount/linux
634 sync
635
636 echo "done."
637 echo ""
638
639
640
641 pushd $mount >/dev/null 2>/dev/null
642 if [ "$fast" = fast ]; then
643         bootcmd="-b /dev/$loopback"
644 fi
645
646 echo Running $lilo ...
647 if [ $debug = true ]; then
648
649 cp -pvf $mountconfig $clog
650 if [ -z $log ]; then
651  echo   $lilo -w+ -C $mountconfig $compact $bootcmd -v5
652         $lilo -w+ -C $mountconfig $compact $bootcmd -v5 || fast=error
653 else
654  echo   $lilo -w+ -C $mountconfig $compact $bootcmd -v5 ">$log"
655         $lilo -w+ -C $mountconfig $compact $bootcmd -v5 >$log || fast=error
656 fi
657
658 else
659         $lilo -C $mountconfig $compact $bootcmd || fast=error
660 fi
661 popd >/dev/null 2>/dev/null
662 if [ "$fast" = error ]; then
663         echo -n `$lilo -V`
664         echo " failure."
665 else
666         echo done.
667 fi
668 echo ""
669
670 umount $mount
671
672 if [ $fast = error ]; then
673         exit 1
674 fi
675
676 if [ $isoimage = yes ]; then
677         echo MKISOFS
678         out=$device
679         opt=
680         if [ $size = $hdsize ]; then
681             losetup -d /dev/$looppart
682             losetup -d /dev/$loopback
683             opt=-hard-disk-boot
684         fi
685         mv $mfile $mount/boot.bin
686         mkisofs $opt -J -R -T \
687                 -V LILO_BOOT -A "Linux Boot CD created by LILO mkrescue" \
688                 -b boot.bin -c boot.cat -o $out $mount
689         cat <<EOF
690
691 END MKISOFS:  output is in  '$device'
692
693
694 The bootable CD can be burned with the 'cdrecord' utility
695 using a command of the form:
696
697         cdrecord [<options>] [dev=<device>] $device
698
699 EOF
700 elif [ "$fast" = fast ]; then
701         if [ $debug = true ]; then
702                 echo Pause before transfering to $device
703                 read aline
704         fi
705         dd if=$mfile of=$device bs=1024
706 fi
707
708 echo "All done."
709 echo ""
710 exit 0
711