X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;ds=sidebyside;f=debian%2Fscripts%2Fliloconfig;h=46a83f512d0ad44e55f8e29cf0b1f46a67cd1a3c;hb=9650ecddd0276a177310655d8424473cbd3a955e;hp=1916ece4e1ec32ff0705f72744676061fc1d981e;hpb=bdad01eb872bff65c1932c1b91e892b5b05f54ef;p=rrq%2Fmaintain_lilo.git diff --git a/debian/scripts/liloconfig b/debian/scripts/liloconfig index 1916ece..46a83f5 100644 --- a/debian/scripts/liloconfig +++ b/debian/scripts/liloconfig @@ -1,699 +1,601 @@ -#!/usr/bin/perl -# -# /usr/sbin/liloconfig -- configure lilo automatically using debconf -# -# Author: Bruce Perens -# Bernd Eckenfels -# Vincent Renardias -# Peter Maydell -# Russell Coker -# Andrés Roldán -# William Pitcock -# -# Maintainer: William Pitcock - -# Updated on 2008/07/26 -- William Pitcock -# - Use large-memory by default, hoping that BIOSes now days aren't -# so broken. -# -# Updated on 2008/06/16 -- William Pitcock -# - Warn about images larger than 6.5MiB because some chipsets -# cannot load them in real mode. -# -# Updated on 2006/08/27 -- Artur R. Czechowski -# - Communication with user is handled via debconf -# -# Updated on 2004/07/31 -- Andrés Roldán -# - Added get_bitmap() to allow one choose the bitmap to use. -# -# Updated on 2003/12/20 -- Andrés Roldán -# - Modified get_images() to insert initrd= field when necessary. -# See Bug#224368. -# -# Updated on 2003/10/24 -- Andrés Roldán -# - Now liloconfig will smartly get the installed kernel images -# and put them in the configuration file. -# -# Updated on 2003/10/05 -- Andrés Roldán -# - Updated install= comments . See Bug#183471. -# - Not using depecrated install=/boot/*b options. -# -# Updated on 2003/08/07 -- Andrés Roldán -# - bitmap= field will search bitmaps on /boot -# -# Updated on 2003/04/23 -- Andrés Roldán -# - added menu entry for sid and sarge from debian-bootscreen. -# -# Updated on 1999/01/24 -- Vincent Renardias -# - never return 0 on error. -# - updated the template to produce a more helpfull (commentwise) -# resulting lilo.conf -# -# Updated on 1999/11/24 -- Peter Maydell -# - added error checking of various system calls -# - added $DEBUG switch and pulled lilo.conf and fstab filenames -# out into config variables. -# - turned on Perl's -w switch and use strict subs/refs -# - now does examination of current situation up front, separated -# from the logic of what we do in various situations. - # - added check for special marker in /etc/fstab that indicates that we - # are configuring the base filesystem and shouldn't actually do anything. - # - # Updated on 2000-01-23 -- Peter Maydell - # - fixed a (harmless) warning produced if /etc/fstab had a blank line in it - # - fixed a bug where partition number was not being pulled out of the - # /dev/hda4 string correctly. - # - added a paranoia check that the disk/device we get from fstab actually - # exist in the filesystem. - # - fixed flow-of-control problem where we simply weren't ever installing - # MBR and making partition active. - # - added & to some function calls, for consistency. - # - changed all references to /usr/doc/lilo/ to /usr/share/doc/lilo/. - # - added warning that the lilo.conf we produce does not suffice for - # complicated situations. - # - expanded some of the other prompts and explanatory text presented - # to the user. - # - added a 'ruler' to separate out questions - # - questions no longer accept anything except RET as meaning 'go with - # default answer'. [Previously, if the default answer was 'yes', - # anything not beginning with Y or y would be interpreted as 'no'. - # This is IMHO too lenient considering the consequences of getting - # it wrong...] - # - updated Maintainer, Author and Wishlist... - # - # Updated on 2000-01-25 -- Peter Maydell - # - fixed important bug causing lilo not to install on RAID arrays. - # (Bugs #56153,#56183,#56196) - # - minor improvement to a regexp (no actual functional change) (Bug#56127) - # - expanded cryptic 'iff' comment (Bug#56127) - # - # Updates on 2001-05-04 -- Russell Coker - # - more work on devfs root support - - # Wishlist: - # This script is from Bruce's debian.postinst and need to be more - # intelligent. It should be possible to install lilo in the MBR, too. - # Support for systems which dual boot (esp. dual Linux/Windows) would - # also be nice, but could be complicated to get right. - - ###use strict 'subs'; - ###use strict 'refs'; - #### use strict 'vars' falls over on all the global variables :-> -use Debconf::Client::ConfModule qw(:all); -version('2.0'); -$|=1; - - fset("liloconfig/banner","seen","false"); - fset("liloconfig/use_current_lilo","seen","false"); - fset("liloconfig/wipe_old_liloconf","seen","false"); - fset("liloconfig/instruction","seen","false"); - fset("liloconfig/install_from_root_device","seen","false"); - fset("liloconfig/use_lba32","seen","false"); - fset("liloconfig/install_mbr","seen","false"); - fset("liloconfig/make_active_partition","seen","false"); - fset("liloconfig/select_bitmap","seen","false"); - - # Set this to 1 to disable all commands that do things to the - # hard disk (ie actually running lilo). Note that we still write - # to $LILOCONF, so you should also tweak that to get a 'safe' test - # environment. - #$DEBUG=1; - - # Various files we access - $LILOCONF='/etc/lilo.conf'; - $FSTAB='/etc/fstab'; - - subst("liloconfig/liloconf_exists","liloconf",$LILOCONF); - subst("liloconfig/lilo_warning","liloconf",$LILOCONF); - subst("liloconfig/lilo_error","liloconf",$LILOCONF); - subst("liloconfig/odd_fstab","liloconf",$LILOCONF); - subst("liloconfig/instruction","liloconf",$LILOCONF); - - subst("liloconfig/fstab_broken","fstab",$FSTAB); - subst("liloconfig/odd_fstab","fstab",$FSTAB); - - # Print a banner now, to give the user something to look at while - # we ferret around in the fstab... - - settitle("liloconfig/maintitle"); - input("low","liloconfig/banner"); - - # First we analyse the setup and set variables appropriately - $fstab_broken = 1; # is there a valid /etc/fstab? Assume not and prove otherwise. - $liloconf_exists = 0; # is there a preexisting lilo.conf with a non-commented out line? - $liloconf_incompatible = 0; # does lilo.conf use options not valid for this version of lilo? - $configuring_base = 0; # are we configuring the 'base' filesystem (special case) - $odd_fstab = 0; # set if we don't understand the device in the fstab - # We also set $device, $disk, $partition (assuming fstab_broken == 0) - - if (-f $FSTAB) - { - # Parse fstab for the root partition... - open(FSTAB, "<$FSTAB") or die "liloconfig: couldn't open $FSTAB: $!\n"; - while () - { - # Check for a magic string which indicates that we are configuring - # the base filesystem and not a real machine... - $configuring_base = 1 if /^# UNCONFIGURED FSTAB FOR BASE SYSTEM/; - next if /^#/; # ignore comment lines - s/^[ \t]+//; # remove space or tab at begin of the line - ($device,$filesystem) = split(/[ \t]+/); - next unless defined $filesystem; # ignore empty lines too - # Stop if we found the root device... - if ($filesystem eq '/') - { - $fstab_broken = 0; - last; - } - } - close(FSTAB) or die "liloconfig: couldn't close $FSTAB: $!\n"; - } - - if (! $fstab_broken) - { - # Valid device/filesystem pair, parse them - $disk = `/usr/sbin/lilo_find_mbr $device`; - chomp($disk); - $partition = $device; - my $devfs = 0; - - # Paranoia check: there should be valid /dev/ nodes for these. - # We could check for block-special-device-ness, but perhaps - # some people have symlink forests in /dev/ ? - # This check will fail on things like RAID arrays, where the - # devices don't have names like /dev/hda4. In this case we can't - # do simple autoconfiguration, but we still want to be able - # to allow the user to install their own handrolled lilo.conf. - $odd_fstab = 1 unless ($partition =~ /\d+$/ && -e $disk && -e $device); - } - - # Check for an existing lilo.conf with some non-comment lines in it... - system ("grep -qsv '^#' $LILOCONF"); - # Exit status is 0 iff lilo.conf exists and contains at least one non-comment line. - if ($? == 0) - { - $liloconf_exists = 1; - $liloconf_incompatible = &compatibility_check (); - } - - ########################################################## - # Boilerplate arrays used to produce an initial lilo.conf - ########################################################## - - @header = ( - "# Generated by liloconfig\n", - "\n", - ); - - @bootheader = ( - "# Specifies the boot device\n", - ); - - @rootheader = ( - "\n", - "# Specifies the device that should be mounted as root.\n", - "# If the special name CURRENT is used, the root device is set to the\n", - "# device on which the root file system is currently mounted. If the root\n", - "# has been changed with -r , the respective device is used. If the\n", - "# variable ROOT is omitted, the root device setting contained in the\n", - "# kernel image is used. It can be changed with the rdev program.\n" - ); - - @boilerplate1 = ( - "\n", - "# Enables map compaction:\n", - "# Tries to merge read requests for adjacent sectors into a single\n", - "# read request. This drastically reduces load time and keeps the map\n", - "# smaller. Using COMPACT is especially recommended when booting from a\n", - "# floppy disk.\n", - "# compact\n", - "\n", - "# Install the specified file as the new boot sector.\n", - "# LILO supports built in boot sectory, you only need\n", - "# to specify the type, choose one from 'text', 'menu' or 'bitmap'.\n", - "# new: install=bmp old: install=/boot/boot-bmp.b\n", - "# new: install=text old: install=/boot/boot-text.b\n", - "# new: install=menu old: install=/boot/boot-menu.b or boot.b\n", - "# default: 'menu' is default, unless you have a bitmap= line\n", - "# Note: install=bmp must be used to see the bitmap menu.\n", - "# install=menu\n", - "install=bmp\n", - "\n", - "# Specifies the number of _tenths_ of a second LILO should\n", - "# wait before booting the first image. LILO\n", - "# doesn't wait if DELAY is omitted or if DELAY is set to zero.\n", - "# delay=20\n", - "\n", - "# Prompt to use certaing image. If prompt is specified without timeout,\n", - "# boot will not take place unless you hit RETURN\n", - "prompt\n", - "timeout=50\n", - "\n", - "# Enable large memory mode.\n", - "large-memory\n", - "\n", - "# Specifies the location of the map file. If MAP is\n", - "# omitted, a file /boot/map is used.\n", - "map=/boot/map\n", - "\n", - "# Specifies the VGA text mode that should be selected when\n", - "# booting. The following values are recognized (case is ignored):\n", - "# NORMAL select normal 80x25 text mode.\n", - "# EXTENDED select 80x50 text mode. The word EXTENDED can be\n", - "# abbreviated to EXT.\n", - "# ASK stop and ask for user input (at boot time).\n", - "# use the corresponding text mode. A list of available modes\n", - "# can be obtained by booting with vga=ask and pressing [Enter].\n", - "vga=normal\n", - "\n", - "# Defines non-standard parameters for the specified disk.\n", - "#disk=/dev/sda\n", - "#\tbios=0x80\n", - "\n", - "# If you are using removable USB drivers (with mass-storage)\n", - "# you will need to tell LILO to not use these devices even\n", - "# if defined in /etc/fstab and referenced in /proc/partitions.\n", - "# Adjust these lines to your devices:\n", - "#\n", - "# disk=/dev/sda inaccessible\n", - "# disk=/dev/sdb inaccessible\n", - "\n" - ); - - @boilerplate2 = ( - "# If you have another OS on this machine (say DOS),\n", - "# you can boot if by uncommenting the following lines\n", - "# (Of course, change /dev/hda2 to wherever your DOS partition is.)\n", - "# other=/dev/hda2\n", - "# label=\"MS Windows\"\n", - "\n" - ); - - #################### - # Utility functions - #################### - -sub get_bitmap -{ - input("high","liloconfig/select_bitmap"); - go(); - ($ret,$val) = get("liloconfig/select_bitmap"); - - # each line with: [ filename,bmp-color,bmp-table,bmp-timer ] - @bitmaps = ( - [ "/boot/tuxlogo.bmp","6,9,0;15,9,0","59,5;1,23,","66,28;6,8,0" ], - [ "/boot/inside.bmp","14,11,;15,9,0","21,284p;2,7,175p,4","73,29;12,8,0" ], - [ "/boot/debian.bmp","10,0,;7,0,","16,12;1,12,16","34,28;13,0," ], - [ "/boot/debian-de.bmp","10,0,;7,0,","16,12;1,12,16","34,28;13,0," ], - [ "/boot/debianlilo.bmp","1,,0;9,,0","106p,144p;2,9,144p","514p,144p;6,8,0" ], - [ "/boot/coffee.bmp","12,,11;15,,8","385p,100p;1,10","38,2;13,1" ], - [ "/boot/onlyblue.bmp","7,,0;15,,0","3,4;4,26,19,1","37,2;7,4,0" ] - ); - - $counter = 0; - - for $ref (@bitmaps) - { - last if ($val eq @$ref[0]); - $counter++; - } - - $ans = $counter; - - push (@bitmapconf, "\n# Bitmap configuration for $bitmaps[$ans][0]\n"); - push (@bitmapconf, "bitmap=$bitmaps[$ans][0]\n"); - push (@bitmapconf, "bmp-colors=$bitmaps[$ans][1]\n"); - push (@bitmapconf, "bmp-table=$bitmaps[$ans][2]\n"); - push (@bitmapconf, "bmp-timer=$bitmaps[$ans][3]\n"); - - return @bitmapconf; -} - -sub get_images -{ - my @images = (); - - $count = 0; - - print STDERR "Searching for installed kernels and updating image entries ...\n"; - - push (@images, "# These images were automagically added. You may need to edit something.\n\n"); - - # Ignore that /vmlinuz link since it can surely be poiting to - # some /boot/vmlinuz* file - if (-e "/vmlinuz" && ! -l "/vmlinuz") - { - push (@images, "image=/vmlinuz\n"); - push (@images, "\tlabel=\"Linux\"\n"); - if (-e "/initrd.img") - { - push (@images, "\tinitrd=/initrd.img\n"); +#!/usr/bin/perl -w + +# liloconfig - creating a new lilo.conf file +# +# Copyright 2011 Joachim Wiedorn +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +#---- some modules +use strict; +use warnings; +use Getopt::Std; +use Pod::Usage; +use File::Copy; + + +#---- global variables +my $prog = $0; +$prog =~ s#.*/##; +my $version = "0.1"; + +#---- parameter check +# h: help, v: verbose, f: force +our $opt_h = 0; +our $opt_v = 0; +our $opt_f = 0; +getopts('hvf'); +# define perldoc usage +pod2usage(1) if $opt_h; + +#---- other variables +our $liloconf = "/etc/lilo.conf"; +our $conftmp_1 = "/tmp/lilotmp1"; +our $conftmp_2 = "/tmp/lilotmp2"; +our $liloconfold = $liloconf . ".old"; +our $liloconfnew = $liloconf . ".new"; +our $fstabconf = "/etc/fstab"; + +our $idpath = "/dev/disk/by-id"; +our $uuidpath = "/dev/disk/by-uuid"; +our $lblpath = "/dev/disk/by-label"; +our $template = "/usr/share/doc/lilo/examples/lilo.example.conf.gz"; + +our $rootpart; # found root part +our $root_dev; # /dev/hdX9, /dev/sdX9, /dev/md/* +our $root_id; # UUID, LABEL, ID +our $boot_dev; # /dev/hdX, /dev/sdX, /dev/md +our $boot_id; # DISK-ID + +#-------------------- main program -------------------- + +sub main { + + my $exit = 0; + + if (@ARGV == 1) { + $liloconf = "$ARGV[0]"; + $liloconfold = $liloconf . ".old"; + $liloconfnew = $liloconf . ".new"; } - push (@images, "\tread-only\n"); - push (@images, "\n"); - } - - # Ignore that /boot/vmlinuz link as well since it can surely be - # poiting to some /boot/vmlinuz* file - if (-e "/boot/vmlinuz" && ! -l "/boot/vmlinuz") - { - push (@images, "image=/boot/vmlinuz\n"); - push (@images, "\tlabel=\"Linux 1\"\n"); - if (-e "/boot/initrd.img") - { - push (@images, "\tinitrd=/boot/initrd.img\n"); - } - push (@images, "\tread-only\n"); - push (@images, "\n"); - } - - foreach $image (`/bin/ls /boot/vmlinuz*`) - { - chomp $image; - - my $version = ""; - my $complement = ""; - - if ($image =~ /vmlinuz-(\d+\.\d+\.\d+)-(.+)/) - { - $version = $1; - $complement = $2; - - $label = "Lin " . $version . "img" . $count; - } - elsif ($image =~ /vmlinuz-(\d+\.\d+\.\d+)$/) - { - $version = $1; - - $label = "Lin " . $version . "img" . $count; + if (-f $liloconf and not $opt_f) { + print "$prog: $liloconf already exist! Please use '-f' for overwriting.\n"; + $exit = 1; } - else - { - $label = "Lin " . "img" . $count; - } + else { + $exit = create_lilo_conf() + } + return $exit; +} + +#-------------------- subroutines -------------------- + +sub create_lilo_conf { - push (@images, "image=$image\n"); - push (@images, "\tlabel=\"$label\"\n"); + my $found = 0; + my $exit = 1; + + # search for root device in fstab and convert it + $found = detect_root_device(); + + # convert root device to boot device + if ($found) { $found = convert_boot_device(); } + + # finally write new lilo.conf file + if ($found) { $exit = write_lilo_conf(); } + + return $exit; +} + +sub detect_root_device { - if (-e "/boot/initrd.img-$version-$complement") - { - push (@images, "\tinitrd=/boot/initrd.img-$version-$complement\n"); - } - elsif (-e "/boot/initrd.img-$version") - { - push (@images, "\tinitrd=/boot/initrd.img-$version\n"); - } + # read fstab and find root device; + my $found = read_fstab(); - push (@images, "\tread-only\n"); - push (@images, "\n"); + # identify root device: root_dev and root_id + if ($found) { $found = convert_root_device(); } - $count++; - } - - if (-e "/boot/memtest86.bin") - { - push (@images, "image=/boot/memtest86.bin\n"); - push (@images, "\tlabel=\"Memory Test\"\n"); - push (@images, "\tread-only\n"); - push (@images, "\n"); - } - - if (-e "/boot/memtest86+.bin") - { - push (@images, "image=/boot/memtest86+.bin\n"); - push (@images, "\tlabel=\"Memory Test+\"\n"); - push (@images, "\tread-only\n"); - push (@images, "\n"); - } - - return @images; + return $found; } -sub asky -{ - do - { - print STDERR @_,"? [Yes] "; - $answer=; - } - while ($answer ne "\n" && !($answer =~ /^[YyNn].*/)); - &ruler (); - return ( !($answer =~ /^[nN].*/) ); -} +sub read_fstab { + + my $root_part; + my $mountpoint; + my $broken_fstab = 1; + my $base_fstab = 0; + my $found = 1; + + # check fstab for root device + if (-f $fstabconf) { + # Parsing fstab for the root partition + open(FSTAB, "<$fstabconf") or die "$prog: couldn't open $fstabconf: $!\n"; + + while () { + # Search magic string which indicates a base filesystem + $base_fstab = 1 if /^# UNCONFIGURED FSTAB FOR BASE SYSTEM/; + next if /^#/; # ignore comment lines + + s/^[ \t]+//; # remove space or tab at begin of the line + ($root_part,$mountpoint) = split(/[ \t]+/); + next unless defined $mountpoint; # ignore empty lines too + + # stop if we found the root device... + if ($mountpoint eq '/') { + $broken_fstab = 0; + last; + } + } + close(FSTAB) or die "$prog: couldn't close $fstabconf: $!\n"; + } -sub askn -{ - do - { - print STDERR @_,"? [No] "; - $answer=; - } - while ($answer ne "\n" && !($answer =~ /^[YyNn].*/)); - &ruler (); - return ( $answer =~ /^[yY].*/ ); -} + if ($base_fstab) { + print "E: It seems you want configure the base filesystem \n" . + "and I'm therefore simply going to exit successfully \n" . + "without trying to actually configure LILO properly. \n"; + $found = 0; + } + if ($broken_fstab) { + print "E: It seems the file /etc/fstab is not properly \n" . + "configured: no root partition '/' found! \n"; + $found = 0; + } + # save the found root device + $rootpart = $root_part; -sub compatibility_check -{ - # Check a lilo.conf for options which are not compatible - # with the current version of lilo, and return 1 if any - # incompatible usages are found. - # This currently just checks for use of the any_* loaders. - system ("egrep '^[^#]*any_' $LILOCONF"); - return 1 if ($? == 0); - return 0; + return $found; } -sub safe_system($) -{ - # Works like system(), but just echoes the command that would - # be run if $DEBUG is 1. - if ($DEBUG) { - print STDERR "[Would have run: ", join(' ', @_), "]\n"; - $? = 0; - } - else - { - system($_[0].">&2"); - } +sub convert_root_device { + + my $found = 1; + my $root_disk = ''; + my $root_link; + # global variables: $root_dev, $root_id + + if ($rootpart =~ /\/dev\//) { + $root_disk = $rootpart; + + if (-b $root_disk) { + $root_dev = $root_disk; + if($opt_v) { print "Convert root option $root_disk into UUID\n"; } + $root_id = find_id_link($root_disk,$uuidpath); + + if (not -l "$uuidpath/$root_id") { + if($opt_v) { print "W: could not find UUID for $root_disk!\n"; } + ## than we want use root_dev in lilo.conf + #$found = 0; + } + else { + # finally add uuid label + $root_id = "UUID=" . $root_id; + } + } + else { + if($opt_v) { print "E: cannot check $root_disk: device does not exist!\n"; } + $found = 0; + } + } + elsif ($rootpart =~ /^UUID/ or $rootpart =~ /^LABEL/) { + $root_link = $rootpart; + $root_link =~ s{\"}{}g; + $root_link =~ s{^LABEL=}{/dev/disk/by-label/}; + $root_link =~ s{^UUID=}{/dev/disk/by-uuid/}; + + if (-l $root_link) { + $root_id = $rootpart; + $root_disk = readlink($root_link); + $root_disk =~ s{\.\./\.\./}{/dev/}; + + if (-b $root_disk) { $root_dev = $root_disk; } + else { + if($opt_v) { print "E: cannot check $root_link: link does not exist!\n"; } + $found = 0; + } + } + else { + print "E: cannot check $root_link: link does not exist!\n"; + $found = 0; + } + } + else { + print "E: cannot use uncommon $rootpart found as root device!\n"; + $found = 0; + } + + return $found; } -##################################### -# Actual work is done below here... -##################################### - -# Debian's 'base' filesystem is a special case -- it's prebuilt -# by installing and configuring packages into a subdirectory, -# which is then made into a tarball, which is then used to -# make the initial filesystem for a fresh Debian install. -# Thus we can't actually run LILO now, because we know nothing -# of the disk layout. That will be done as part of the install -# process. -if ($configuring_base) -{ - input("high","liloconfig/configuring_base"); - go(); - -exit(0); +sub find_id_link { + + my $olddev = $_[0]; + my $path_id = $_[1]; + my @sellinks; + my $_idlink; + my $_actlink; + my $newdevid = ''; + + opendir(MYDH, "$path_id") or die("cannot open $path_id: $! \n"); + @sellinks = grep(!/\-part\d\d?$/, grep(!/^\.\.?$/, readdir(MYDH))); + @sellinks = sort(@sellinks); + closedir(MYDH); + + foreach $_idlink (@sellinks) { + chomp $_idlink; + if(not $_idlink =~ /^usb/ and length($_idlink) > 10) { + $_actlink = readlink("$path_id/$_idlink"); + $_actlink =~ s{\.\./\.\./}{/dev/}; + if($opt_v) { print "** try: $_actlink => $_idlink \n"; } + + # stop if we find the right link... + if($_actlink eq $olddev) { + $newdevid = $_idlink; + if($opt_v) { print "** convert: $_actlink => $path_id/$_idlink \n\n"; } + last; + } + } + } + + if(not $newdevid) { + if($opt_v) { print "W: $olddev not converted: link not useful\n\n"; } + } + + return ($newdevid); } -if ($liloconf_exists) -{ - # Trust and use the existing lilo.conf. - # FIX: If the current lilo.conf installs a master boot record, ask - # to edit it to a partition boot record and install the master boot - # record to chain to that. - - input("high","liloconfig/liloconf_exists"); - go(); - - if ($liloconf_incompatible) - { - input("high","liloconfig/liloconf_incompatible"); - go(); - exit(1); - } - - set("liloconfig/use_current_lilo","true"); - input("high","liloconfig/use_current_lilo"); - go(); - ($ret,$val)=get("liloconfig/use_current_lilo"); - if ($val eq "true") - { - input("high","liloconfig/lilo_warning"); - go(); - stop(); - &safe_system("/sbin/lilo -v"); - if ( $? == 0 ) - { - exit(0); +sub convert_boot_device { + + my $found = 1; + my $boot_disk = ''; + my $boot_link; + # global variables: $boot_dev, $boot_id + + if (-b $root_dev) { + if ($root_dev =~ /\/dev\/md/) { + # search if the found partition is a raid volume + $boot_disk = check_raid($root_dev); + } + else { + # find the right block device name + $boot_disk = $root_dev; + $boot_disk =~ s/\d+$//; + } + + if (-b $boot_disk) { + # set global variable boot_dev + $boot_dev = $boot_disk; + } + else { + print "E: boot device $boot_disk does not exist! \n"; + $found = 0; + } } - input("high","liloconfig/lilo_error"); - go(); - exit(1); - } - else - { - set("liloconfig/wipe_old_liloconf","false"); - input("high","liloconfig/wipe_old_liloconf"); - go(); - ($ret,$val)=get("liloconfig/wipe_old_liloconf"); - if($val eq "true") - { - rename($LILOCONF, "$LILOCONF.OLD") or die "liloconfig: couldn't save old $LILOCONF as $LILOCONF.OLD: $!\n"; + else { + print "E: could not find root device $root_dev! \n"; + $found = 0; } - else - { - input("high","liloconfig/no_changes"); - go(); - exit(0); + + if ($found) { + if($opt_v) { print "Convert boot option $boot_disk into DISK ID\n"; } + $boot_id = $idpath . "/" . find_id_link($boot_disk,$idpath); + + if(not -l "$boot_id") { + if($opt_v) { print "W: could not find DISK ID for $boot_disk!\n"; } + ## not so important, than using boot_dev in lilo.conf + #$found = 0; + } } - } -} -# ASSERT: that we get here only if there is no lilo.conf or the user -# asked us to wipe out the old one... -# We make checks for broken fstabs and odd devices only if we are -# going to try to write a lilo.conf for the user. -if ($fstab_broken) -{ - input("high","liloconfig/fstab_broken"); - go(); - exit(1); + return $found; } -if ($odd_fstab) -{ - subst("liloconfig/odd_fstab","device",$device); - input("high","liloconfig/odd_fstab"); - go(); - exit(1); -} +sub check_raid { + + my $part = $_[0]; + my $mdname; + my $md; + my @devices; -input("high","liloconfig/instruction"); -go(); - -# Flag so we can print STDERR a warning if we fell out the bottom of the config -# without having run lilo at all. -$lilorun = 0; $madeactive = 0; - - -subst("liloconfig/install_from_root_device","device",$device); -set("liloconfig/install_from_root_device","false"); -input("high","liloconfig/install_from_root_device"); -go(); -($ret,$val)=get("liloconfig/install_from_root_device"); - -if($val eq "true") -{ - umask(077); - open(CONF, ">$LILOCONF") or die "Couldn't open $LILOCONF for writing: $!\n"; - if (!chown(0, 0, "$LILOCONF")) - { - die "Couldn't make $LILOCONF owned by root.root: $!\n" unless $DEBUG; - - # Following message is only shown if $DEBUG is set. So, I do not care - # about templating it. Let it goes into STDERR. YMMV. - print STDERR "Oops, couldn't make $LILOCONF owned by root.root. Since you\n"; - print STDERR "have set the DEBUG flag, I'm going to assume this is because\n"; - print STDERR "you're running liloconfig as a normal user, and continue anyway.\n"; - } - print CONF @header; - input("high","liloconfig/install_from_root_device"); - go(); - ($ret,$val)=get("liloconfig/install_from_root_device"); - if($val eq "true") - { - print CONF "# This allows booting from any partition on disks with more than 1024\n"; - print CONF "# cylinders.\n"; - print CONF "lba32\n"; - print CONF "\n"; - } - @middle_boilerplate = &get_images; - @bmp_boilerplate = &get_bitmap; - - print CONF @bootheader, "boot=".$device, "\n", @rootheader, "root=".$device, "\n", @bmp_boilerplate, @boilerplate1, @middle_boilerplate, @boilerplate2; - - close(CONF) or die "Couldn't close $LILOCONF: $!\n"; - - &safe_system("/sbin/lilo"); - if ($? != 0) - { - input("high","liloconfig/lilo_error"); - go(); - exit(1); - } - $lilorun = 1; + # check if the found partition is a raid volume + if($part =~ /\/dev\/md/) + { + $mdname = $part; + $mdname =~ s/\/dev\///; + $mdname =~ s/\///; + $md = `grep $mdname /proc/mdstat`; + + @devices = split(" ", $md); + @devices = sort(@devices[4..$#devices]); + $part = "/dev/" . $devices[0]; + $part =~ s/\[.*$//; + + } + return $part; } +sub write_lilo_conf { + + my @status; + my $exit = copy_template(); -subst("liloconfig/install_mbr","disk",$disk); -set("liloconfig/install_mbr","false"); -input("high","liloconfig/install_mbr"); -go(); -($ret,$val)=get("liloconfig/install_mbr"); -if($val eq "true") -{ - &safe_system("install-mbr $disk"); - if ($? != 0) - { - input("high","liloconfig/mbr_error"); - go(); - exit(1); - } -} + if (not $exit) { + # create lilo.conf.new + write_boot_option(); + write_image_config(); + } -subst("liloconfig/make_active_partition","device",$device); -input("high","liloconfig/make_active_partition"); -go(); -($ret,$val)=get("liloconfig/install_mbr"); -if($val eq "true") -{ - my $part_num = $partition; - $part_num =~ s/^.*[a-z]//; - print STDERR "Activating Partition $part_num on disk $disk.\n"; - &safe_system("/sbin/activate $disk $part_num"); - if ($? != 0) - { - input("high","liloconfig/activate_error"); - go(); - exit(1); - } - $madeactive = 1; + if (-f $liloconf and not -f $liloconfold) { + # move old lilo.conf to lilo.conf.old + @status = stat($liloconf); + move ($liloconf, $liloconfold) or die "Cannot rename file: $!\n"; + utime ($status[9],$status[9],$liloconfold); + chmod (0600,$liloconfold); + print "Old file moved to: $liloconfold \n"; + } + if (-f $liloconfnew) { + move ($liloconfnew, $liloconf) or die "Cannot move file: $!\n"; + chmod (0600,$liloconf); + print "New file created as: $liloconf \n"; + print "Now you must execute '/sbin/lilo' to " . + "activate this new configuation!\n\n"; + } + else { + print "E: Cannot find temporary file $conftmp_1!\n"; + $exit = 1; + } + + return $exit; } -# Trailer: summarise what we've done -print STDERR "\n"; -if (! $lilorun) -{ - print STDERR "WARNING: you will have to set up LILO manually to ensure that\n"; - print STDERR " your system can be booted successfully!\n"; - print STDERR "You can rerun liloconfig at any time if you change your mind and\n"; - print STDERR "wish to use the default configuration.\n"; -} -elsif ($madeactive) -{ - # LILO was run and Linux partition made active - print STDERR "LILO successfully configured; Linux will be booted by default.\n"; - print STDERR "If you installed the master boot record, you can boot a different\n"; - print STDERR "OS by holding down the shift key as the system boots, and then\n"; - print STDERR "pressing the key corresponding to the partition containing that\n"; - print STDERR "OS when you see the \"1234F:\" prompt.\n"; +sub copy_template { + + my $endreached = 0; + my $exit = 0; + + # copy template config + if (-f $template) { + system("gzip -d -c $template >$conftmp_1") if ($template =~ /\.gz$/); + system("cat $template >$conftmp_1") if ($template =~ /\.conf$/); + + open(CONFTMP1, "<$conftmp_1") or die "$prog: couldn't open $conftmp_1: $!\n"; + open(CONFTMP2, ">$conftmp_2") or die "$prog: couldn't open $conftmp_2: $!\n"; + + while () { + if (/first\ example/) { + $endreached = 1; + } + unless ($endreached) { + print CONFTMP2 $_; + } + } + close(CONFTMP1) or die "$prog: couldn't close $conftmp_1: $!\n";; + close(CONFTMP2) or die "$prog: couldn't close $conftmp_2: $!\n";; + } + else { + open(CONFTMP2, ">$conftmp_2") or die "$prog: couldn't open $conftmp_2: $!\n"; + print CONFTMP2 "# /etc/lilo.conf + +### LILO global section ### + +#large-memory +lba32 +boot = /dev/sda +map = /boot/map +install = menu +menu-scheme = Wb:Yr:Wb:Wb +prompt +timeout = 100 +vga = normal +#default = Linux + +### LILO per-image section ### + +"; + close(CONFTMP2) or die "$prog: couldn't close $conftmp_2: $!\n";; + } + + return $exit; } -else -{ - my $part_num = $partition; - $part_num =~ s/^.*[a-z]//; - # LILO run, but Linux partition not made active - print STDERR "OK. If you installed the master boot record, and the partition\n"; - print STDERR "boot record, you may boot Linux by holding down the shift key\n"; - print STDERR "as the system boots, and then pressing the $part_num key\n"; - print STDERR "when you see the \"1234F:\" prompt.\n"; + +sub write_boot_option { + + my $oldline = ''; + my $newline = ''; + my $ok = 0; + + open(MYFH_NEW, "> $liloconfnew") or die "Cannot open file: $!"; + open(MYFH_TMP, "< $conftmp_2") or die "Cannot read file: $!"; + + while () { + # line read from MYFH_TMP + $oldline = $_; + + if (/^boot/ and $ok == 0) { + if ($boot_id) { + $oldline = "#boot = $boot_dev\n"; + $newline = "boot = $boot_id\n"; + print MYFH_NEW $oldline; + if($opt_v) { print $oldline; } + } + else { + $oldline = "boot = $boot_dev\n"; + } + print MYFH_NEW $newline; + if($opt_v) { print $newline; } + if($opt_v) { print "\n"; } + + # convert only one time + $ok = 1; + } + else { + print MYFH_NEW $oldline; + } + } + close(MYFH_TMP); + close(MYFH_NEW); } -print STDERR "\n"; -print STDERR "For more information about LILO, see the documentation in\n"; -print STDERR "/usr/share/doc/lilo/. For details about the MBR, see also\n"; -print STDERR "/usr/share/doc/mbr/.\n"; +sub write_image_config { + + my $image; + my $initrd; + my $nr; + my $nr2; + + # search for kernel image files + my @vmlinuz = readpipe("/bin/ls -t -1 /boot/vmlinuz-2* 2>/dev/null"); + + # append to new lilo.conf + open(MYFH_NEW, ">> $liloconfnew") or die "Cannot open file: $!"; + + # create some line for each kernel image + $nr = 0; + foreach $image (@vmlinuz) { + # search for kernel initrd file + chomp $image; + $initrd = $image; + $initrd =~ s/vmlinuz/initrd\.img/; + $nr2 = $nr + 1; + + print MYFH_NEW 'image = ' . $image . "\n"; + if($opt_v) { print 'image = ' . $image . "\n"; } + if ($nr == 0) { + print MYFH_NEW "\t" . 'label = "Linux"' . "\n"; + if($opt_v) { print "\t" . 'label = "Linux"' . "\n"; } + } + elsif ($nr == 1) { + print MYFH_NEW "\t" . 'label = "Linux Old"' . "\n"; + if($opt_v) { print "\t" . 'label = "Linux Old"' . "\n"; } + } + if ($root_id) { + print MYFH_NEW "\t" . '#root = ' . $root_dev . "\n"; + if($opt_v) { print "\t" . '#root = ' . $root_dev . "\n"; } + print MYFH_NEW "\t" . 'root = "' . $root_id . '"' . "\n"; + if($opt_v) { print "\t" . 'root = "' . $root_id . '"' . "\n"; } + } + else { + print MYFH_NEW "\t" . 'root = ' . $root_dev . "\n"; + if($opt_v) { print "\t" . 'root = ' . $root_dev . "\n"; } + } + print MYFH_NEW "\t" . 'read-only' . "\n"; + if($opt_v) { print "\t" . 'read-only' . "\n"; } + print MYFH_NEW "#\t" . 'restricted' . "\n"; + if($opt_v) { print "#\t" . 'restricted' . "\n"; } + print MYFH_NEW "#\t" . 'alias = ' . "$nr2" . "\n"; + if($opt_v) { print "#\t" . 'alias = ' . "$nr2" . "\n"; } + print MYFH_NEW "#\t" . 'optional' . "\n"; + if($opt_v) { print "#\t" . 'optional' . "\n"; } + if (-f $initrd) { + print MYFH_NEW "\t" . 'initrd = ' . $initrd . "\n"; + if($opt_v) { print "\t" . 'initrd = ' . $initrd . "\n"; } + } + print MYFH_NEW "\n"; + if($opt_v) { print "\n"; } + + $nr++; + last if ($nr > 1); + } + + close(MYFH_NEW); +} + + +main(); + +__END__ + + +=head1 NAME + +liloconfig - create new lilo.conf file (with diskid and uuid) + +=head1 SYNOPSIS + +liloconfig [-h] [-v] [-f] [lilo.conf] + +=head1 DESCRIPTION + +liloconfig is an simple program for creating a new lilo.conf file. +After creating the new configuration file you must execute '/sbin/lilo'. + +liloconfig use the lilo.example.conf file as template. In the final +lilo.conf file you find many useful comments for custom changes. + +=head1 EXAMPLES + +Lines in the configuration file /etc/lilo.conf: + + ### LILO global section ### + + #large-memory + lba32 + boot = /dev/sda + map = /boot/map + install = menu + menu-scheme = Wb:Yr:Wb:Wb + prompt + timeout = 100 + vga = normal + #default = Linux + + ### LILO per-image section ### + + #boot = /dev/sda + boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999 + + image = /boot/vmlinuz-2.6.32-5book-686 + label = "Linux" + #root = /dev/sda1 + root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44" + read-only + # restricted + # alias = 1 + # optional + initrd = /boot/initrd.img-2.6.32-5book-686 + + image = /boot/vmlinuz-2.6.32-5-686 + label = "Linux Old" + #root = /dev/sda1 + root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44" + read-only + # restricted + # alias = 2 + # optional + initrd = /boot/initrd.img-2.6.32-5-686 + +=head1 OPTIONS + +=over 4 + +=item B<-h> + +Print a brief help. + +=item B<-v> + +Print verbose messages. + +=item B<-f> + +Force overriding existing lilo.conf. + +=back + +=head1 AUTHOR + +B was written by Joachim Wiedorn. -exit(0); +=cut