3 # /usr/sbin/liloconfig -- configure lilo automatically using debconf
5 # Author: Bruce Perens <bruce@Pixar.com>
6 # Bernd Eckenfels <ecki@debian.org>
7 # Vincent Renardias <vincent@ldsol.com>
8 # Peter Maydell <pmaydell@chiark.greenend.org.uk>
9 # Russell Coker <russell@coker.com.au>
10 # Andrés Roldán <aroldan@debian.org>
11 # William Pitcock <nenolod@dereferenced.org>
13 # Maintainer: William Pitcock <nenolod@dereferenced.org>
15 # Updated on 2008/07/26 -- William Pitcock <nenolod@dereferenced.org>
16 # - Use large-memory by default, hoping that BIOSes now days aren't
19 # Updated on 2008/06/16 -- William Pitcock <nenolod@sacredspiral.co.uk>
20 # - Warn about images larger than 6.5MiB because some chipsets
21 # cannot load them in real mode.
23 # Updated on 2006/08/27 -- Artur R. Czechowski <arturcz@hell.pl>
24 # - Communication with user is handled via debconf
26 # Updated on 2004/07/31 -- Andrés Roldán <aroldan@debian.org>
27 # - Added get_bitmap() to allow one choose the bitmap to use.
29 # Updated on 2003/12/20 -- Andrés Roldán <aroldan@debian.org>
30 # - Modified get_images() to insert initrd= field when necessary.
33 # Updated on 2003/10/24 -- Andrés Roldán <aroldan@debian.org>
34 # - Now liloconfig will smartly get the installed kernel images
35 # and put them in the configuration file.
37 # Updated on 2003/10/05 -- Andrés Roldán <aroldan@debian.org>
38 # - Updated install= comments . See Bug#183471.
39 # - Not using depecrated install=/boot/*b options.
41 # Updated on 2003/08/07 -- Andrés Roldán <aroldan@fluidsignal.com>
42 # - bitmap= field will search bitmaps on /boot
44 # Updated on 2003/04/23 -- Andrés Roldán <aroldan@fluidsignal.com>
45 # - added menu entry for sid and sarge from debian-bootscreen.
47 # Updated on 1999/01/24 -- Vincent Renardias <vincent@ldsol.com>
48 # - never return 0 on error.
49 # - updated the template to produce a more helpfull (commentwise)
52 # Updated on 1999/11/24 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
53 # - added error checking of various system calls
54 # - added $DEBUG switch and pulled lilo.conf and fstab filenames
55 # out into config variables.
56 # - turned on Perl's -w switch and use strict subs/refs
57 # - now does examination of current situation up front, separated
58 # from the logic of what we do in various situations.
59 # - added check for special marker in /etc/fstab that indicates that we
60 # are configuring the base filesystem and shouldn't actually do anything.
62 # Updated on 2000-01-23 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
63 # - fixed a (harmless) warning produced if /etc/fstab had a blank line in it
64 # - fixed a bug where partition number was not being pulled out of the
65 # /dev/hda4 string correctly.
66 # - added a paranoia check that the disk/device we get from fstab actually
67 # exist in the filesystem.
68 # - fixed flow-of-control problem where we simply weren't ever installing
69 # MBR and making partition active.
70 # - added & to some function calls, for consistency.
71 # - changed all references to /usr/doc/lilo/ to /usr/share/doc/lilo/.
72 # - added warning that the lilo.conf we produce does not suffice for
73 # complicated situations.
74 # - expanded some of the other prompts and explanatory text presented
76 # - added a 'ruler' to separate out questions
77 # - questions no longer accept anything except RET as meaning 'go with
78 # default answer'. [Previously, if the default answer was 'yes',
79 # anything not beginning with Y or y would be interpreted as 'no'.
80 # This is IMHO too lenient considering the consequences of getting
82 # - updated Maintainer, Author and Wishlist...
84 # Updated on 2000-01-25 -- Peter Maydell <pmaydell@chiark.greenend.org.uk>
85 # - fixed important bug causing lilo not to install on RAID arrays.
86 # (Bugs #56153,#56183,#56196)
87 # - minor improvement to a regexp (no actual functional change) (Bug#56127)
88 # - expanded cryptic 'iff' comment (Bug#56127)
90 # Updates on 2001-05-04 -- Russell Coker <russell@coker.com.au>
91 # - more work on devfs root support
94 # This script is from Bruce's debian.postinst and need to be more
95 # intelligent. It should be possible to install lilo in the MBR, too.
96 # Support for systems which dual boot (esp. dual Linux/Windows) would
97 # also be nice, but could be complicated to get right.
100 ###use strict 'refs';
101 #### use strict 'vars' falls over on all the global variables :->
102 use Debconf::Client::ConfModule qw(:all);
106 fset("liloconfig/banner","seen","false");
107 fset("liloconfig/use_current_lilo","seen","false");
108 fset("liloconfig/wipe_old_liloconf","seen","false");
109 fset("liloconfig/instruction","seen","false");
110 fset("liloconfig/install_from_root_device","seen","false");
111 fset("liloconfig/use_lba32","seen","false");
112 fset("liloconfig/install_mbr","seen","false");
113 fset("liloconfig/make_active_partition","seen","false");
114 fset("liloconfig/select_bitmap","seen","false");
116 # Set this to 1 to disable all commands that do things to the
117 # hard disk (ie actually running lilo). Note that we still write
118 # to $LILOCONF, so you should also tweak that to get a 'safe' test
122 # Various files we access
123 $LILOCONF='/etc/lilo.conf';
126 subst("liloconfig/liloconf_exists","liloconf",$LILOCONF);
127 subst("liloconfig/lilo_warning","liloconf",$LILOCONF);
128 subst("liloconfig/lilo_error","liloconf",$LILOCONF);
129 subst("liloconfig/odd_fstab","liloconf",$LILOCONF);
130 subst("liloconfig/instruction","liloconf",$LILOCONF);
132 subst("liloconfig/fstab_broken","fstab",$FSTAB);
133 subst("liloconfig/odd_fstab","fstab",$FSTAB);
135 # Print a banner now, to give the user something to look at while
136 # we ferret around in the fstab...
138 settitle("liloconfig/maintitle");
139 input("low","liloconfig/banner");
141 # First we analyse the setup and set variables appropriately
142 $fstab_broken = 1; # is there a valid /etc/fstab? Assume not and prove otherwise.
143 $liloconf_exists = 0; # is there a preexisting lilo.conf with a non-commented out line?
144 $liloconf_incompatible = 0; # does lilo.conf use options not valid for this version of lilo?
145 $configuring_base = 0; # are we configuring the 'base' filesystem (special case)
146 $odd_fstab = 0; # set if we don't understand the device in the fstab
147 # We also set $device, $disk, $partition (assuming fstab_broken == 0)
151 # Parse fstab for the root partition...
152 open(FSTAB, "<$FSTAB") or die "liloconfig: couldn't open $FSTAB: $!\n";
155 # Check for a magic string which indicates that we are configuring
156 # the base filesystem and not a real machine...
157 $configuring_base = 1 if /^# UNCONFIGURED FSTAB FOR BASE SYSTEM/;
158 next if /^#/; # ignore comment lines
159 s/^[ \t]+//; # remove space or tab at begin of the line
160 ($device,$filesystem) = split(/[ \t]+/);
161 next unless defined $filesystem; # ignore empty lines too
162 # Stop if we found the root device...
163 if ($filesystem eq '/')
169 close(FSTAB) or die "liloconfig: couldn't close $FSTAB: $!\n";
174 # Valid device/filesystem pair, parse them
175 $disk = `/usr/sbin/lilo_find_mbr $device`;
177 $partition = $device;
180 # Paranoia check: there should be valid /dev/ nodes for these.
181 # We could check for block-special-device-ness, but perhaps
182 # some people have symlink forests in /dev/ ?
183 # This check will fail on things like RAID arrays, where the
184 # devices don't have names like /dev/hda4. In this case we can't
185 # do simple autoconfiguration, but we still want to be able
186 # to allow the user to install their own handrolled lilo.conf.
187 $odd_fstab = 1 unless ($partition =~ /\d+$/ && -e $disk && -e $device);
190 # Check for an existing lilo.conf with some non-comment lines in it...
191 system ("grep -qsv '^#' $LILOCONF");
192 # Exit status is 0 iff lilo.conf exists and contains at least one non-comment line.
195 $liloconf_exists = 1;
196 $liloconf_incompatible = &compatibility_check ();
199 ##########################################################
200 # Boilerplate arrays used to produce an initial lilo.conf
201 ##########################################################
204 "# Generated by liloconfig\n",
209 "# Specifies the boot device\n",
214 "# Specifies the device that should be mounted as root.\n",
215 "# If the special name CURRENT is used, the root device is set to the\n",
216 "# device on which the root file system is currently mounted. If the root\n",
217 "# has been changed with -r , the respective device is used. If the\n",
218 "# variable ROOT is omitted, the root device setting contained in the\n",
219 "# kernel image is used. It can be changed with the rdev program.\n"
224 "# Enables map compaction:\n",
225 "# Tries to merge read requests for adjacent sectors into a single\n",
226 "# read request. This drastically reduces load time and keeps the map\n",
227 "# smaller. Using COMPACT is especially recommended when booting from a\n",
231 "# Install the specified file as the new boot sector.\n",
232 "# LILO supports built in boot sectory, you only need\n",
233 "# to specify the type, choose one from 'text', 'menu' or 'bitmap'.\n",
234 "# new: install=bmp old: install=/boot/boot-bmp.b\n",
235 "# new: install=text old: install=/boot/boot-text.b\n",
236 "# new: install=menu old: install=/boot/boot-menu.b or boot.b\n",
237 "# default: 'menu' is default, unless you have a bitmap= line\n",
238 "# Note: install=bmp must be used to see the bitmap menu.\n",
242 "# Specifies the number of _tenths_ of a second LILO should\n",
243 "# wait before booting the first image. LILO\n",
244 "# doesn't wait if DELAY is omitted or if DELAY is set to zero.\n",
247 "# Prompt to use certaing image. If prompt is specified without timeout,\n",
248 "# boot will not take place unless you hit RETURN\n",
252 "# Enable large memory mode.\n",
255 "# Specifies the location of the map file. If MAP is\n",
256 "# omitted, a file /boot/map is used.\n",
259 "# Specifies the VGA text mode that should be selected when\n",
260 "# booting. The following values are recognized (case is ignored):\n",
261 "# NORMAL select normal 80x25 text mode.\n",
262 "# EXTENDED select 80x50 text mode. The word EXTENDED can be\n",
263 "# abbreviated to EXT.\n",
264 "# ASK stop and ask for user input (at boot time).\n",
265 "# <number> use the corresponding text mode. A list of available modes\n",
266 "# can be obtained by booting with vga=ask and pressing [Enter].\n",
269 "# Defines non-standard parameters for the specified disk.\n",
273 "# If you are using removable USB drivers (with mass-storage)\n",
274 "# you will need to tell LILO to not use these devices even\n",
275 "# if defined in /etc/fstab and referenced in /proc/partitions.\n",
276 "# Adjust these lines to your devices:\n",
278 "# disk=/dev/sda inaccessible\n",
279 "# disk=/dev/sdb inaccessible\n",
284 "# If you have another OS on this machine (say DOS),\n",
285 "# you can boot if by uncommenting the following lines\n",
286 "# (Of course, change /dev/hda2 to wherever your DOS partition is.)\n",
287 "# other=/dev/hda2\n",
288 "# label=\"MS Windows\"\n",
298 input("high","liloconfig/select_bitmap");
300 ($ret,$val) = get("liloconfig/select_bitmap");
302 # each line with: [ filename,bmp-color,bmp-table,bmp-timer ]
304 [ "/boot/tuxlogo.bmp","6,9,0;15,9,0","59,5;1,23,","66,28;6,8,0" ],
305 [ "/boot/inside.bmp","14,11,,15,9,0","21,284p,2,7,175p,4","73,29,12,8,0" ],
306 [ "/boot/debian.bmp","10,0,,7,0,","16,12,1,12,16","34,28,13,0," ],
307 [ "/boot/debian-de.bmp","10,0,,7,0,","16,12,1,12,16","34,28,13,0," ],
308 [ "/boot/debianlilo.bmp","1,,0,9,,0","106p,144p,2,9,144p","514p,144p,6,8,0" ]
309 [ "/boot/coffee.bmp","12,,11,15,,8","385p,100p,1,10","38,2,13,1" ],
310 [ "/boot/onlyblue.bmp","7,,0,15,,0","3,4,4,26,19,1","37,2,7,4,0" ],
317 last if ($val eq @$ref[0]);
323 push (@bitmapconf, "\n# Bitmap configuration for $bitmaps[$ans][0]\n");
324 push (@bitmapconf, "bitmap=$bitmaps[$ans][0]\n");
325 push (@bitmapconf, "bmp-colors=$bitmaps[$ans][1]\n");
326 push (@bitmapconf, "bmp-table=$bitmaps[$ans][2]\n");
327 push (@bitmapconf, "bmp-timer=$bitmaps[$ans][3]\n");
338 print STDERR "Searching for installed kernels and updating image entries ...\n";
340 push (@images, "# These images were automagically added. You may need to edit something.\n\n");
342 # Ignore that /vmlinuz link since it can surely be poiting to
343 # some /boot/vmlinuz* file
344 if (-e "/vmlinuz" && ! -l "/vmlinuz")
346 push (@images, "image=/vmlinuz\n");
347 push (@images, "\tlabel=\"Linux\"\n");
348 if (-e "/initrd.img")
350 push (@images, "\tinitrd=/initrd.img\n");
352 push (@images, "\tread-only\n");
353 push (@images, "\n");
356 # Ignore that /boot/vmlinuz link as well since it can surely be
357 # poiting to some /boot/vmlinuz* file
358 if (-e "/boot/vmlinuz" && ! -l "/boot/vmlinuz")
360 push (@images, "image=/boot/vmlinuz\n");
361 push (@images, "\tlabel=\"Linux 1\"\n");
362 if (-e "/boot/initrd.img")
364 push (@images, "\tinitrd=/boot/initrd.img\n");
366 push (@images, "\tread-only\n");
367 push (@images, "\n");
370 foreach $image (`/bin/ls /boot/vmlinuz*`)
377 if ($image =~ /vmlinuz-(\d+\.\d+\.\d+)-(.+)/)
382 $label = "Lin " . $version . "img" . $count;
384 elsif ($image =~ /vmlinuz-(\d+\.\d+\.\d+)$/)
388 $label = "Lin " . $version . "img" . $count;
392 $label = "Lin " . "img" . $count;
395 push (@images, "image=$image\n");
396 push (@images, "\tlabel=\"$label\"\n");
398 if (-e "/boot/initrd.img-$version-$complement")
400 push (@images, "\tinitrd=/boot/initrd.img-$version-$complement\n");
402 elsif (-e "/boot/initrd.img-$version")
404 push (@images, "\tinitrd=/boot/initrd.img-$version\n");
407 push (@images, "\tread-only\n");
408 push (@images, "\n");
413 if (-e "/boot/memtest86.bin")
415 push (@images, "image=/boot/memtest86.bin\n");
416 push (@images, "\tlabel=\"Memory Test\"\n");
417 push (@images, "\tread-only\n");
418 push (@images, "\n");
421 if (-e "/boot/memtest86+.bin")
423 push (@images, "image=/boot/memtest86+.bin\n");
424 push (@images, "\tlabel=\"Memory Test+\"\n");
425 push (@images, "\tread-only\n");
426 push (@images, "\n");
436 print STDERR @_,"? [Yes] ";
439 while ($answer ne "\n" && !($answer =~ /^[YyNn].*/));
441 return ( !($answer =~ /^[nN].*/) );
448 print STDERR @_,"? [No] ";
451 while ($answer ne "\n" && !($answer =~ /^[YyNn].*/));
453 return ( $answer =~ /^[yY].*/ );
456 sub compatibility_check
458 # Check a lilo.conf for options which are not compatible
459 # with the current version of lilo, and return 1 if any
460 # incompatible usages are found.
461 # This currently just checks for use of the any_* loaders.
462 system ("egrep '^[^#]*any_' $LILOCONF");
463 return 1 if ($? == 0);
469 # Works like system(), but just echoes the command that would
470 # be run if $DEBUG is 1.
472 print STDERR "[Would have run: ", join(' ', @_), "]\n";
481 #####################################
482 # Actual work is done below here...
483 #####################################
485 # Debian's 'base' filesystem is a special case -- it's prebuilt
486 # by installing and configuring packages into a subdirectory,
487 # which is then made into a tarball, which is then used to
488 # make the initial filesystem for a fresh Debian install.
489 # Thus we can't actually run LILO now, because we know nothing
490 # of the disk layout. That will be done as part of the install
492 if ($configuring_base)
494 input("high","liloconfig/configuring_base");
500 if ($liloconf_exists)
502 # Trust and use the existing lilo.conf.
503 # FIX: If the current lilo.conf installs a master boot record, ask
504 # to edit it to a partition boot record and install the master boot
505 # record to chain to that.
507 input("high","liloconfig/liloconf_exists");
510 if ($liloconf_incompatible)
512 input("high","liloconfig/liloconf_incompatible");
517 set("liloconfig/use_current_lilo","true");
518 input("high","liloconfig/use_current_lilo");
520 ($ret,$val)=get("liloconfig/use_current_lilo");
523 input("high","liloconfig/lilo_warning");
526 &safe_system("/sbin/lilo -v");
531 input("high","liloconfig/lilo_error");
537 set("liloconfig/wipe_old_liloconf","false");
538 input("high","liloconfig/wipe_old_liloconf");
540 ($ret,$val)=get("liloconfig/wipe_old_liloconf");
543 rename($LILOCONF, "$LILOCONF.OLD") or die "liloconfig: couldn't save old $LILOCONF as $LILOCONF.OLD: $!\n";
547 input("high","liloconfig/no_changes");
554 # ASSERT: that we get here only if there is no lilo.conf or the user
555 # asked us to wipe out the old one...
556 # We make checks for broken fstabs and odd devices only if we are
557 # going to try to write a lilo.conf for the user.
560 input("high","liloconfig/fstab_broken");
567 subst("liloconfig/odd_fstab","device",$device);
568 input("high","liloconfig/odd_fstab");
573 input("high","liloconfig/instruction");
576 # Flag so we can print STDERR a warning if we fell out the bottom of the config
577 # without having run lilo at all.
578 $lilorun = 0; $madeactive = 0;
581 subst("liloconfig/install_from_root_device","device",$device);
582 set("liloconfig/install_from_root_device","false");
583 input("high","liloconfig/install_from_root_device");
585 ($ret,$val)=get("liloconfig/install_from_root_device");
590 open(CONF, ">$LILOCONF") or die "Couldn't open $LILOCONF for writing: $!\n";
591 if (!chown(0, 0, "$LILOCONF"))
593 die "Couldn't make $LILOCONF owned by root.root: $!\n" unless $DEBUG;
595 # Following message is only shown if $DEBUG is set. So, I do not care
596 # about templating it. Let it goes into STDERR. YMMV. <arturcz@hell.pl>
597 print STDERR "Oops, couldn't make $LILOCONF owned by root.root. Since you\n";
598 print STDERR "have set the DEBUG flag, I'm going to assume this is because\n";
599 print STDERR "you're running liloconfig as a normal user, and continue anyway.\n";
602 input("high","liloconfig/install_from_root_device");
604 ($ret,$val)=get("liloconfig/install_from_root_device");
607 print CONF "# This allows booting from any partition on disks with more than 1024\n";
608 print CONF "# cylinders.\n";
609 print CONF "lba32\n";
612 @middle_boilerplate = &get_images;
613 @bmp_boilerplate = &get_bitmap;
615 print CONF @bootheader, "boot=".$device, "\n", @rootheader, "root=".$device, "\n", @bmp_boilerplate, @boilerplate1, @middle_boilerplate, @boilerplate2;
617 close(CONF) or die "Couldn't close $LILOCONF: $!\n";
619 &safe_system("/sbin/lilo");
622 input("high","liloconfig/lilo_error");
630 subst("liloconfig/install_mbr","disk",$disk);
631 set("liloconfig/install_mbr","false");
632 input("high","liloconfig/install_mbr");
634 ($ret,$val)=get("liloconfig/install_mbr");
637 &safe_system("install-mbr $disk");
640 input("high","liloconfig/mbr_error");
646 subst("liloconfig/make_active_partition","device",$device);
647 input("high","liloconfig/make_active_partition");
649 ($ret,$val)=get("liloconfig/install_mbr");
652 my $part_num = $partition;
653 $part_num =~ s/^.*[a-z]//;
654 print STDERR "Activating Partition $part_num on disk $disk.\n";
655 &safe_system("/sbin/activate $disk $part_num");
658 input("high","liloconfig/activate_error");
665 # Trailer: summarise what we've done
669 print STDERR "WARNING: you will have to set up LILO manually to ensure that\n";
670 print STDERR " your system can be booted successfully!\n";
671 print STDERR "You can rerun liloconfig at any time if you change your mind and\n";
672 print STDERR "wish to use the default configuration.\n";
676 # LILO was run and Linux partition made active
677 print STDERR "LILO successfully configured; Linux will be booted by default.\n";
678 print STDERR "If you installed the master boot record, you can boot a different\n";
679 print STDERR "OS by holding down the shift key as the system boots, and then\n";
680 print STDERR "pressing the key corresponding to the partition containing that\n";
681 print STDERR "OS when you see the \"1234F:\" prompt.\n";
685 my $part_num = $partition;
686 $part_num =~ s/^.*[a-z]//;
687 # LILO run, but Linux partition not made active
688 print STDERR "OK. If you installed the master boot record, and the partition\n";
689 print STDERR "boot record, you may boot Linux by holding down the shift key\n";
690 print STDERR "as the system boots, and then pressing the $part_num key\n";
691 print STDERR "when you see the \"1234F:\" prompt.\n";
695 print STDERR "For more information about LILO, see the documentation in\n";
696 print STDERR "/usr/share/doc/lilo/. For details about the MBR, see also\n";
697 print STDERR "/usr/share/doc/mbr/.\n";