Merge tag 'upstream/24.2'
[rrq/maintain_lilo.git] / scripts / liloconfig
index 02219a5134cfba38a20574ea02e7cc79d62ae478..55bc593691dc6a326a01bf85cd0a6db1ac7e24d9 100644 (file)
@@ -2,7 +2,8 @@
 
 #       liloconfig -  creating a new lilo.conf file
 #       
-#       Copyright 2011-2013 Joachim Wiedorn <ad_debian@joonet.de>
+#       
+#       Copyright 2011-2015 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
@@ -30,14 +31,15 @@ use File::Copy;
 #---- global variables
 my $prog = $0;
 $prog =~ s#.*/##;
-my $version = "0.2";
+my $version = "0.5";
 
 #---- 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;
 
@@ -71,12 +73,13 @@ sub main {
                $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;
 }
@@ -84,33 +87,59 @@ sub main {
 #-------------------- subroutines --------------------
 
 sub create_lilo_conf {
-       
-       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(); }
+       my $exit = 1;
+       my $found1 = 0;
+       my $found2 = 0;
+       my $found3 = 0;
+
+       # read fstab and search for root device
+       $found1 = read_fstab();
+
+       ## STEP 1 ##
+       if ($found1 == 0)
+               # nothing found, exit by error
+               { $found2 = 0;}
+       elsif ($found1 == 1)
+               # identify root device: root_dev and root_id
+               { $found2 = convert_root_device(); }
+       elsif ($found1 == 2)
+               # nothing found, but exit successfully
+               { $exit = 0; $found2 = 0;}
+
+       ## STEP 2 ##
+       if ($found2 == 0)
+               # nothing found, exit by error
+               { $found3 = 0;}
+       elsif ($found2 == 1)
+               # convert root device to boot device
+               { $found3 = convert_boot_device(); }
+       elsif ($found2 == 2)
+               # nothing found, but exit successfully
+               { $exit = 0; $found2 = 3;}
+
+       ## STEP 3 ##
+       if ($found3 == 0)
+               # nothing found, exit by error
+               { $exit = 1;}
+       elsif ($found3 == 1) {
+               if ((-f $liloconf) and not (-w $liloconf)) {
+                       print "E: Have no write permissions to $liloconf !\n";
+                       $exit = 1;
+               }
+               else {
+                       # finally write new/updated lilo.conf file
+                       if ($opt_u) { $exit = update_lilo_conf(); }
+                       else        { $exit = write_lilo_conf(); }
+               }
+       }
+       elsif ($found3 == 2)
+               # nothing found, but exit successfully
+               { $exit = 0;}
 
        return $exit;
 }
 
-sub detect_root_device {
-       
-       # read fstab and find root device; 
-       my $found = read_fstab();
-
-       # identify root device: root_dev and root_id
-       if ($found) { $found = convert_root_device(); }
-       
-       return $found;
-}
-
 sub read_fstab {
        
        my $root_part;
@@ -146,7 +175,7 @@ sub read_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;
+               $found = 2;
        }
        if ($broken_fstab) {
                print "E: It seems the file /etc/fstab is not properly \n" .
@@ -176,8 +205,7 @@ sub convert_root_device {
 
                        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;
+                               # than we will use root_dev in lilo.conf
                        }
                        else {
                                # finally add uuid label
@@ -262,7 +290,7 @@ sub convert_boot_device {
        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
@@ -287,18 +315,17 @@ sub convert_boot_device {
                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);
 
                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;
+                       # not so important. Then using boot_dev in lilo.conf
                }
        }
-
+       
        return $found;
 }
 
@@ -308,7 +335,7 @@ sub check_raid {
        my $mdname;
        my $md;
        my @devices;
-
+       
        # check if the found partition is a raid volume
        if($part =~ /\/dev\/md/)
        {
@@ -321,8 +348,8 @@ sub check_raid {
                @devices = sort(@devices[4..$#devices]);
                $part = "/dev/" . $devices[0];
                $part =~ s/\[.*$//;
-
        }
+       
        return $part;
 }
 
@@ -333,8 +360,13 @@ sub write_lilo_conf {
 
        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) {
@@ -393,6 +425,7 @@ sub copy_template {
 #large-memory
 lba32
 boot = /dev/sda
+root = /dev/sda1
 map = /boot/map
 install = menu
 menu-scheme = Wb:Yr:Wb:Wb
@@ -410,7 +443,43 @@ vga = normal
        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 = '';
@@ -423,27 +492,109 @@ sub write_boot_option {
                # 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;
                }
        }
+
        close(MYFH_TMP);
        close(MYFH_NEW);
 }
@@ -452,16 +603,93 @@ sub write_image_config {
 
        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>/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
@@ -502,12 +730,12 @@ sub write_image_config {
                print MYFH_NEW     "#\t" . 'optional' . "\n";
                if($opt_v) { print "#\t" . 'optional' . "\n"; }
 
-               if (-f $initrd) {
+               if (-e $initrd) {
                        print MYFH_NEW     "\t"  . 'initrd = ' . $initrd . "\n";
                        if($opt_v) { print "\t"  . 'initrd = ' . $initrd . "\n"; }
                }
                else {
-                       if($opt_v) { print "initrd $initrd could not be found!\n" }
+                       if($opt_v) { print "W: initrd $initrd could not be found!\n" }
                }
 
                print MYFH_NEW     "\n";
@@ -518,9 +746,17 @@ sub write_image_config {
        }
 
        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__
@@ -532,7 +768,7 @@ liloconfig - create new lilo.conf file (with diskid and uuid)
 
 =head1 SYNOPSIS
 
-liloconfig [-h] [-v] [-f] [lilo.conf]
+B<liloconfig> [B<-h>] [B<-v>] [B<-f>] [B<-u>] [B<lilo.conf>]
 
 =head1 DESCRIPTION
 
@@ -542,6 +778,34 @@ 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.
 
+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:
@@ -550,60 +814,58 @@ Lines in the configuration file /etc/lilo.conf:
 
   #large-memory
   lba32
-  boot = /dev/sda
+  #boot = /dev/sda
+  boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999
+  #root = /dev/sda1
+  root = "UUID=18843936-00f9-4df0-a373-000d05a5dd44"
   map = /boot/map
   install = menu
   menu-scheme = Wb:Yr:Wb:Wb
   prompt
   timeout = 100
   vga = normal
+  #password = 
   #default = Linux
 
   ### LILO per-image section ###
 
-  #boot = /dev/sda
-  boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999
-
-  image = /boot/vmlinuz-3.5.0-trunk-686
+  image = /boot/vmlinuz-3.17-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-3.5.0-trunk-686
+      initrd = /boot/initrd.img-3.17-trunk-686
 
-  image = /boot/vmlinuz-3.2.0-4-686
+  image = /boot/vmlinuz-3.14-trunk-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-3.2.0-4-686
+      initrd = /boot/initrd.img-3.14-trunk-686
 
-=head1 OPTIONS
+=head1 COPYRIGHT and LICENSE
 
-=over 4
+Copyright (C) 2011-2015 Joachim Wiedorn
 
-=item B<-h>
+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.
 
-Print a brief help.
-
-=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