# liloconfig - creating a new lilo.conf file
#
-# Copyright 2011 Joachim Wiedorn <ad_debian@joonet.de>
+#
+# Copyright 2011-2014 Joachim Wiedorn <joodevel at joonet.de>
#
# 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
#---- global variables
my $prog = $0;
$prog =~ s#.*/##;
-my $version = "0.1";
+my $version = "0.4";
#---- parameter check
# h: help, v: verbose, f: force
our $opt_h = 0;
our $opt_v = 0;
our $opt_f = 0;
-getopts('hvf');
+our $opt_u = 0;
+getopts('hvfu');
# define perldoc usage
pod2usage(1) if $opt_h;
our $idpath = "/dev/disk/by-id";
our $uuidpath = "/dev/disk/by-uuid";
our $lblpath = "/dev/disk/by-label";
-our $template = "/etc/lilo.conf_example";
+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/*
$liloconfold = $liloconf . ".old";
$liloconfnew = $liloconf . ".new";
}
- if (-f $liloconf and not $opt_f) {
- print "$prog: $liloconf already exist! Please use '-f' for overwriting.\n";
+ if (-f $liloconf and not $opt_f and not $opt_u) {
+ print $prog .": " . $liloconf .
+ " already exist! Please force overwriting with '-f' or '-u'.\n";
$exit = 1;
}
else {
- $exit = create_lilo_conf()
+ $exit = create_lilo_conf();
}
return $exit;
}
if ($found) { $found = convert_boot_device(); }
# finally write new lilo.conf file
- if ($found) { $exit = write_lilo_conf(); }
+ if ($found) {
+ if ($opt_u) { $exit = update_lilo_conf(); }
+ else { $exit = write_lilo_conf(); }
+ }
return $exit;
}
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
print "E: could not find root device $root_dev! \n";
$found = 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);
#$found = 0;
}
}
-
+
return $found;
}
my $mdname;
my $md;
my @devices;
-
+
# check if the found partition is a raid volume
if($part =~ /\/dev\/md/)
{
@devices = sort(@devices[4..$#devices]);
$part = "/dev/" . $devices[0];
$part =~ s/\[.*$//;
-
}
+
return $part;
}
if (not $exit) {
# create lilo.conf.new
- write_boot_option();
- write_image_config();
+ write_bootroot_option();
+ if ( not write_image_config() ) {
+ if ( not write_imagelinks_config() ) {
+ print "E: Cannot find any images or image symlinks!\n";
+ $exit = 1;
+ }
+ }
}
if (-f $liloconf and not -f $liloconfold) {
#large-memory
lba32
boot = /dev/sda
+root = /dev/sda1
map = /boot/map
install = menu
menu-scheme = Wb:Yr:Wb:Wb
return $exit;
}
-sub write_boot_option {
+sub update_lilo_conf {
+
+ my @status;
+ my $exit = 0;
+
+ if (-f $liloconf) {
+ # copy old config
+ system("cat $liloconf >$conftmp_2");
+
+ # create lilo.conf.new
+ update_bootroot_option();
+ }
+
+ 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;
+}
+
+sub write_bootroot_option {
my $oldline = '';
my $newline = '';
# line read from MYFH_TMP
$oldline = $_;
+ # lines beginning direct with boot option
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; }
+ $newline = "#boot = " . $boot_dev . "\n";
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; }
+ $newline = "boot = " . $boot_id . "\n";
+ }
+ else {
+ $newline = "boot = " . $boot_dev . "\n";
+ }
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; print "\n";}
+ # convert only one time
+ $ok = 1;
+ }
+ # lines beginning direct with root option
+ elsif (/^root\ =/) {
+ if ($root_id) {
+ $newline = '#root = ' . $root_dev . "\n";
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; }
+ $newline = 'root = "' . $root_id . '"' . "\n";
}
else {
- $oldline = "boot = $boot_dev\n";
+ $newline = 'root = ' . $root_dev . "\n";
}
print MYFH_NEW $newline;
- if($opt_v) { print $newline; }
- if($opt_v) { print "\n"; }
+ if($opt_v) { print $newline; print "\n";}
+ }
+ # print the rest into file, but not old commented root lines
+ elsif ( not (/^\#boot\ =/ or /^\#root\ =/) ) {
+ print MYFH_NEW $oldline;
+ }
+ }
+ close(MYFH_TMP);
+ close(MYFH_NEW);
+}
+
+sub update_bootroot_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 (<MYFH_TMP>) {
+ # read (old) line from MYFH_TMP
+ $oldline = $_;
+ # lines beginning direct with boot option
+ if (/^boot/ and $ok == 0) {
+ if ($boot_id) {
+ $newline = "#boot = " . $boot_dev . "\n";
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; }
+ $newline = "boot = " . $boot_id . "\n";
+ }
+ else {
+ $newline = "boot = " . $boot_dev . "\n";
+ }
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; print "\n";}
# convert only one time
$ok = 1;
}
- else {
+ # lines beginning direct with root option
+ elsif (/^root\ =/) {
+ if ($root_id) {
+ $newline = '#root = ' . $root_dev . "\n";
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; }
+ $newline = 'root = "' . $root_id . '"' . "\n";
+ }
+ else {
+ $newline = 'root = ' . $root_dev . "\n";
+ }
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; print "\n";}
+ }
+ # lines beginning with one tabulator or with two - eight spaces
+ elsif (/^\troot\ =/ or /^\ {2,8}root\ =/) {
+ if ($root_id) {
+ $newline = "\t" . '#root = ' . $root_dev . "\n";
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; }
+ $newline = "\t" . 'root = "' . $root_id . '"' . "\n";
+ }
+ else {
+ $newline = "\t" . 'root = ' . $root_dev . "\n";
+ }
+ print MYFH_NEW $newline;
+ if($opt_v) { print $newline; print "\n";}
+ }
+ # print the rest into file, but not old commented root lines
+ elsif ( not (/^\#boot\ =/ or /^\#root\ =/ or /^\t\#root\ =/ or /^\ {2,8}\#root\ =/) ) {
print MYFH_NEW $oldline;
}
}
my $image;
my $initrd;
+ my $initrd2;
my $nr;
my $nr2;
+ # append to new lilo.conf
+ open(MYFH_NEW, ">> $liloconfnew") or die "Cannot open file: $!";
+
# search for kernel image files
- my @vmlinuz = readpipe("/bin/ls -t -1 /boot/vmlinuz-2* 2>/dev/null");
+ my @vmlinuz = readpipe("/bin/ls -t -1 /boot/vmlinuz* 2>/dev/null");
+
+ # create some lines for each kernel image
+ $nr = 0;
+ foreach $image (@vmlinuz) {
+ # search for kernel initrd file
+ chomp $image;
+ $initrd = $image;
+ $initrd =~ s/vmlinuz/initrd\.img/;
+ $initrd2 = $initrd;
+ $initrd2 =~ s/\.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"; }
+ }
+
+ 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 (-e $initrd) {
+ print MYFH_NEW "\t" . 'initrd = ' . $initrd . "\n";
+ if($opt_v) { print "\t" . 'initrd = ' . $initrd . "\n"; }
+ }
+ elsif (-e $initrd2) {
+ print MYFH_NEW "\t" . 'initrd = ' . $initrd2 . "\n";
+ if($opt_v) { print "\t" . 'initrd = ' . $initrd2 . "\n"; }
+ }
+ else {
+ if($opt_v) { print "W: initrd $initrd could not be found!\n" }
+ }
+
+ print MYFH_NEW "\n";
+ if($opt_v) { print "\n"; }
+
+ $nr++;
+ last if ($nr > 1);
+ }
+
+ close(MYFH_NEW);
+
+ if ($nr == 0) {
+ print "No images '/boot/vmlinuz*' found!\n";
+ if($opt_v) { print "\n"; }
+ }
+ elsif( not $opt_v ) {
+ print "$nr images '/boot/vmlinuz*' found.\n";
+ }
+ return ($nr > 0); # if =0 this is an error
+}
+
+sub write_imagelinks_config {
+
+ my $image;
+ my $initrd;
+ my $nr;
+ my $nr2;
# append to new lilo.conf
open(MYFH_NEW, ">> $liloconfnew") or die "Cannot open file: $!";
- # create some line for each kernel image
+ # search for kernel image files
+ my @vmlinuz = readpipe("/bin/ls -t -1 /vmlinuz /vmlinuz.old 2>/dev/null");
+
+ # create some lines for each kernel image
$nr = 0;
foreach $image (@vmlinuz) {
# search for kernel initrd file
$initrd =~ s/vmlinuz/initrd\.img/;
$nr2 = $nr + 1;
- print MYFH_NEW 'image = ' . $image . "\n";
- if($opt_v) { print 'image = ' . $image . "\n"; }
+ 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"; }
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_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" . '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 (-e $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"; }
+ else {
+ if($opt_v) { print "W: initrd $initrd could not be found!\n" }
+ }
+
+ print MYFH_NEW "\n";
+ if($opt_v) { print "\n"; }
$nr++;
last if ($nr > 1);
}
close(MYFH_NEW);
-}
-
-
+
+ if ($nr == 0) {
+ print "No image symlinks '/vmlinuz*' found!\n";
+ if($opt_v) { print "\n"; }
+ }
+ elsif( not $opt_v ) {
+ print "$nr image symlinks '/vmlinuz*' found.\n";
+ }
+ return ($nr > 0); # if =0 this is an error
+}
+
main();
__END__
=head1 SYNOPSIS
-liloconfig [-h] [-v] [-f] [lilo.conf]
+B<liloconfig> [B<-h>] [B<-v>] [B<-f>] [B<-u>] [B<lilo.conf>]
=head1 DESCRIPTION
liloconfig use the lilo.example.conf file as template. In the final
lilo.conf file you find many useful comments for custom changes.
+Please pay attention about error messages if liloconfig cannot find
+any images (/boot/vmlinuz*) oder image symlinks (/vmlinuz, /vmlinu.old).
+Then you need to search for images by ourself and make some changes
+in the '/etc/lilo.conf' file. Otherwise no bootloader can be installed
+with '/sbin/lilo'.
+
+=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.
+
+=item B<-u>
+
+Force overriding/update of boot line in lilo.conf.
+
+=back
+
=head1 EXAMPLES
Lines in the configuration file /etc/lilo.conf:
#large-memory
lba32
boot = /dev/sda
+ #root = /dev/sda1
+ root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
map = /boot/map
install = menu
menu-scheme = Wb:Yr:Wb:Wb
#boot = /dev/sda
boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999
- image = /boot/vmlinuz-2.6.32-5book-686
+ image = /boot/vmlinuz-3.5.0-trunk-686
label = "Linux"
#root = /dev/sda1
- root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
+ #root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
read-only
# restricted
# alias = 1
# optional
- initrd = /boot/initrd.img-2.6.32-5book-686
+ initrd = /boot/initrd.img-3.5.0-trunk-686
- image = /boot/vmlinuz-2.6.32-5-686
+ image = /boot/vmlinuz-3.2.0-4-686
label = "Linux Old"
#root = /dev/sda1
- root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
+ #root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
read-only
# restricted
# alias = 2
# optional
- initrd = /boot/initrd.img-2.6.32-5-686
-
-=head1 OPTIONS
+ initrd = /boot/initrd.img-3.2.0-4-686
-=over 4
+=head1 COPYRIGHT and LICENSE
-=item B<-h>
+Copyright (C) 2011-2014 Joachim Wiedorn
-Print a brief help.
+This script 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.
-=item B<-v>
-
-Print verbose messages.
-
-=item B<-f>
+=head1 AUTHOR
-Force overriding existing lilo.conf.
+B<liloconfig> was written by Joachim Wiedorn.
-=back
+This manual page was written by Joachim Wiedorn <joodevel at joonet.de>.
-=head1 AUTHOR
+=head1 SEE ALSO
-B<liloconfig> was written by Joachim Wiedorn.
+B<lilo>(8), B<update-lilo>(8), B<lilo-uuid-diskid>(8)
=cut