Add lilo-uuid-diskid script with manpage
authorJoachim Wiedorn <ad_debian@joonet.de>
Thu, 18 Nov 2010 21:41:42 +0000 (22:41 +0100)
committerJoachim Wiedorn <ad_debian@joonet.de>
Thu, 18 Nov 2010 21:41:42 +0000 (22:41 +0100)
debian/changelog
debian/manpages/lilo-uuid-diskid.8 [new file with mode: 0644]
debian/manpages/lilo-uuid-diskid.pod [new file with mode: 0644]
debian/scripts/lilo-uuid-diskid [new file with mode: 0644]

index 6aaed9f70fdde0f29f50fd2e92f09552def7f347..ff0ebb02addedf3c86914fb102b7872ecf8d49dc 100644 (file)
@@ -29,6 +29,7 @@ lilo (1:23.1-1) unstable; urgency=low
   * Remove some obsolete manpages.
   * Move script liloconfig into directory debian/scripts.
   * Add new script update-lilo and its manual page.
+  * Add new script lilo-uuid-diskid for ID conversion and its manual page.
 
  -- Joachim Wiedorn <ad_debian@joonet.de>  Thu, 18 Nov 2010 20:32:02 +0100
 
diff --git a/debian/manpages/lilo-uuid-diskid.8 b/debian/manpages/lilo-uuid-diskid.8
new file mode 100644 (file)
index 0000000..d601435
--- /dev/null
@@ -0,0 +1,122 @@
+.\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.07)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.el \{\
+.    de IX
+..
+.\}
+.\" ========================================================================
+.\"
+.IX Title "LILO-UUID-DISKID 8"
+.TH LILO-UUID-DISKID 8 "2010-07-24" "23.0" "lilo documentation"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+lilo\-uuid\-diskid \- convert boot / root options to diskid and uuid in lilo.conf.
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+lilo-uuid-diskid [\-h] [\-v] [lilo.conf]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This script looks for the boot block device or boot partition and create the
+right diskid or uuid as boot option. Then it looks for all root partitions
+and create the right uuids as root options.
+.PP
+These conversions are necessary for use with newer kernel (>= 2.6.26) if it
+use the libata module for parallel and serial \s-1ATA\s0 interfaces of block devices
+(i. e. hard disks with \s-1IDE\s0 or \s-1SATA\s0 interface, usbsticks).
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-h\fR" 4
+.IX Item "-h"
+Print a brief help.
+.IP "\fB\-v\fR" 4
+.IX Item "-v"
+Print verbose messages.
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+Lines in the configuration file /etc/lilo.conf:
+.PP
+.Vb 2
+\&  #boot = /dev/sda
+\&  boot = /dev/disk/by\-id/ata\-SAMSUNG_SV1604N_S01FJ10X999999
+\&
+\&  #root = /dev/sda1
+\&  root = "UUID=/dev/disk/by\-uuid/18843936\-00f9\-4df0\-a373\-000d05a5dd44"
+.Ve
+.SH "COPYRIGHT and LICENSE"
+.IX Header "COPYRIGHT and LICENSE"
+Copyright (C) 2010 Joachim Wiedorn
+.PP
+This script is free software; you can redistribute it and/or modify
+it under the terms of the \s-1GNU\s0 General Public License as published by 
+the Free Software Foundation; either version 2 of the License, or 
+(at your option) any later version.
+.PP
+On Debian systems, the complete text of the \s-1GNU\s0 General Public
+License version 2 can be found in `/usr/share/common\-licenses/GPL\-2'.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+\&\fBlilo-uuid-diskid\fR was written by Joachim Wiedorn.
+.PP
+This manual page was written by Joachim Wiedorn <ad_debian at joonet.de>
+for the Debian project (and may be used by others).
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBlilo\fR(8), \fBupdate-lilo\fR(8)
diff --git a/debian/manpages/lilo-uuid-diskid.pod b/debian/manpages/lilo-uuid-diskid.pod
new file mode 100644 (file)
index 0000000..a741bfe
--- /dev/null
@@ -0,0 +1,75 @@
+=for header
+manpage:  LILO-UUID-DISKID
+section:  8
+title:    lilo documentation
+version:  23.0
+datum:    2010-07-24
+
+=encoding utf8
+
+=head1 NAME
+
+lilo-uuid-diskid - convert boot / root options to diskid and uuid in lilo.conf.
+
+=head1 SYNOPSIS
+
+lilo-uuid-diskid [-h] [-v] [lilo.conf]
+
+=head1 DESCRIPTION
+
+This script looks for the boot block device or boot partition and create the
+right diskid or uuid as boot option. Then it looks for all root partitions
+and create the right uuids as root options.
+
+These conversions are necessary for use with newer kernel (>= 2.6.26) if it
+use the libata module for parallel and serial ATA interfaces of block devices
+(i. e. hard disks with IDE or SATA interface, usbsticks).
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h>
+
+Print a brief help.
+
+=item B<-v>
+
+Print verbose messages.
+
+=back
+
+=head1 EXAMPLES
+
+Lines in the configuration file /etc/lilo.conf:
+
+  #boot = /dev/sda
+  boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999
+
+  #root = /dev/sda1
+  root = "UUID=/dev/disk/by-uuid/18843936-00f9-4df0-a373-000d05a5dd44"
+
+=head1 COPYRIGHT and LICENSE
+
+Copyright (C) 2010 Joachim Wiedorn
+
+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.
+
+On Debian systems, the complete text of the GNU General Public
+License version 2 can be found in `/usr/share/common-licenses/GPL-2'.
+
+=head1 AUTHOR
+
+B<lilo-uuid-diskid> was written by Joachim Wiedorn.
+
+This manual page was written by Joachim Wiedorn <ad_debian at joonet.de>
+for the Debian project (and may be used by others).
+
+=head1 SEE ALSO
+
+B<lilo>(8), B<update-lilo>(8)
+
+=cut
diff --git a/debian/scripts/lilo-uuid-diskid b/debian/scripts/lilo-uuid-diskid
new file mode 100644 (file)
index 0000000..5b79f9f
--- /dev/null
@@ -0,0 +1,463 @@
+#!/usr/bin/perl -w
+
+#       lilo-uuid-diskid - convert boot / root options to diskid and 
+#                          uuid in lilo.conf
+#
+#       Copyright 2010 Joachim Wiedorn <ad_debian 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
+#       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
+our $opt_h = 0;
+our $opt_v = 0;
+getopts('hv');
+# define perldoc usage
+pod2usage(1) if $opt_h;
+
+#---- other variables
+our $liloconf = "/etc/lilo.conf";
+our $liloconfold = '';
+our $fstabconf = "/etc/fstab";
+our $idpath = "/dev/disk/by-id";
+our $uuidpath = "/dev/disk/by-uuid";
+
+our $bootready = 0;
+our $boot_id = '';
+our $root_id = '';
+our $optboot = 0;     #  -1 = only ^#boot,  0 = nothing,  1 = ^boot  exist
+
+#-------------------- main program --------------------
+
+sub main {
+       
+       my $exit = 0;
+
+       if (@ARGV == 1) {
+               $liloconf = "$ARGV[0]";
+       }
+
+       if (-f $liloconf) {
+               $liloconfold = $liloconf . "_old";
+               $exit = convert_lilo_conf();
+       }
+       else {
+               print "cannot open $liloconf: file not found!\n";
+               $exit = 1;
+       }
+       return $exit;
+}
+
+#-------------------- subroutines --------------------
+
+sub convert_lilo_conf {
+       
+       my @sellines;
+       my $exit = 0;
+       my $line = '';
+       my $bootline = '';
+
+       # at first read lilo.conf and search for 'boot'
+       my $ok = 0;
+       open(MYFH, "<$liloconf") or die ("cannot open $liloconf: $!");
+       @sellines = grep(/^#?boot/, readline(MYFH));
+       close(MYFH);
+
+       # analyse the boot option in config file
+       foreach $line (@sellines) {
+               if ($line =~ /^boot/) {
+                       # activated boot option found
+                       $bootline = $line;
+                       chomp $bootline;
+                       $optboot = 1;
+               }
+               if ($optboot == 0) {
+                       # commented boot option found
+                       if ($line =~ /^#boot/) { $optboot = -1; }
+               }
+       }
+
+       if ($optboot != 0) {
+
+               if($opt_v) { print "++++++++++ write options into $liloconf ++++++++++\n\n"; }
+
+               if ( detect_boot_device($bootline) == 0) {
+                       # found diskid or uuid for boot device: $boot_id
+                       if (-l $boot_id) {
+                               write_boot_option();
+                       }
+                       else {
+                               if($opt_v) { print "cannot open $boot_id: link does not exist!\n"; }
+                               $exit = 1;
+                       }
+               }
+               else {
+                       if($opt_v) { print "\n"; }
+               }
+       }
+       else {
+               print "cannot use $liloconf: uncomplete configuration!\n";
+               $exit = 1;
+       }
+
+       return $exit;
+}
+
+
+sub detect_boot_device {
+       
+       my $boot_line = $_[0];
+       my $boot_disk = '';
+       my $searchpath;
+       my $_part;
+       my $exit = 0;
+
+       if ($optboot == 1) {
+               # the usual case: found ^boot in lilo.conf
+               $boot_disk = ($boot_line =~ /^boot *= *(\/dev\/.*)/) ? ($1) : ();
+
+               # check if the found partition is a raid volume
+               if($boot_disk =~ /\/dev\/md/) {
+                       $boot_disk = check_raid($boot_disk);
+               }
+       }
+       elsif ($optboot == -1) {
+               # found only ^#boot in lilo.conf, then /etc/fstab is needed
+               if (-f $fstabconf) {
+                       if($opt_v) {
+                               print "no boot option in $liloconf: selecting from $fstabconf\n";
+                       }
+                       $boot_disk = read_fstab($fstabconf);
+               }
+               else {
+                       print "no boot option in $liloconf and no file $fstabconf found!\n";
+                       $exit = 1;
+               }
+       }
+
+       if (-b $boot_disk) {
+               if($boot_disk =~ /$idpath/ or $boot_disk =~ /$uuidpath/) {
+                       print "boot option is already updated to $boot_disk\n";
+                       $bootready = 1; $exit = 1;
+               }
+               else {
+                       if($opt_v) { print "convert boot option $boot_disk into new ID\n"; }
+
+                       # is it a block device name ?
+                       $_part = $boot_disk;
+                       $_part =~ s/\d+$//;
+                       $searchpath = ($_part eq $boot_disk) ? $idpath : $uuidpath;
+
+                       $boot_id = $searchpath . "/" . find_id_link($boot_disk,$searchpath);
+                       if(not -l "$boot_id") { $exit = 1; }
+               }
+       }
+       else {
+               if($opt_v) { print "cannot read $boot_disk: link does not exist!\n"; }
+               $exit = 1;
+       }
+       return $exit;
+}
+
+
+sub read_fstab {
+       
+       my $ffile = $_[0];
+       my $root_line;
+       my $root_part;
+       my $_item;
+
+       $root_line = `awk '{ if (\$2=="/") print \$1}' <$ffile`;
+
+       # search for the last valid entry in /etc/fstab about root partition
+       foreach $_item (split("\n", $root_line)) {
+               if(not $_item =~ /#/) {
+                       $root_part = $_item;
+               }
+       }
+       # check if the found partition is a raid volume
+       if($root_part =~ /\/dev\/md/) {
+               $root_part = check_raid($root_part);
+       }
+       # now find the right block device name
+       $root_part =~ s/\d+$//;
+       $root_part =~ s/part$/disc/;
+
+       return $root_part;
+}
+
+sub check_raid {
+       
+       my $part = $_[0];
+
+       # check if the found partition is a raid volume
+       if($part =~ /\/dev\/md/)
+       {
+               my $mdname;
+               my $md;
+               my @devices;
+       
+               $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 detect_root_device {
+       
+       my $root_line = $_[0];
+       my $root_disk = '';
+       my $exit = 0;
+
+       if (not $exit) {
+               # extract the root device name
+               $root_disk = ($root_line =~ /^\t?root *= *(\/dev\/.*)/) ? ($1) : ();
+               chomp $root_disk;
+
+               # check if the found partition is a raid volume
+               if($root_disk =~ /\/dev\/md/) {
+                       $root_disk = check_raid($root_disk);
+               }
+       }
+       
+       if (-b $root_disk) {
+
+               if($root_disk =~ /$uuidpath/) {
+                       print "$root_disk is already updated - nothing to do\n";
+               }
+               else {
+                       if($opt_v) { print "convert root option $root_disk into new UUID\n"; }
+
+                       $root_id = find_id_link($root_disk,$uuidpath);
+                       if (not -l "$uuidpath/$root_id") { $exit = 1; }
+               }
+       }
+       else {
+               if($opt_v) { print "cannot read $root_disk: link does not exist!\n"; }
+               $exit = 1;
+       }
+       return $exit;
+}
+
+sub find_id_link {
+       
+       my $olddev = $_[0];
+       my $path_id = $_[1];
+       my @sellinks;
+       my $_idlink;
+       my $_actlink;
+       my $newdevid = '';
+       my $ok = 0;
+
+       opendir(MYDH, "$path_id") or die("cannot open $path_id: $! \n");
+
+       @sellinks = grep(!/\-part\d\d?$/, grep(!/^\.\.?$/, readdir(MYDH)));
+       foreach $_idlink (@sellinks) {
+               
+               if(not $_idlink =~ /^usb/ and not $_idlink =~ /^scsi/
+                               and length($_idlink) > 10 and $ok == 0) {
+
+                       $_actlink = readlink("$path_id/$_idlink");
+                       $_actlink =~ s/^\.\.\/\.\.\//\/dev\//;
+                       if($opt_v) { print "** try: $_actlink => $_idlink \n"; }
+                       
+                       if($_actlink eq $olddev) {
+                               $newdevid = $_idlink;
+                               if($opt_v) { print "** convert: $_actlink => $path_id/$_idlink \n"; }
+                               # run only one time
+                               $ok = 1;
+                       }
+               }
+       }
+       closedir(MYDH);
+
+       if($opt_v and not $ok) { print "$olddev not converted: link not useful\n\n"; }
+       
+       return ($newdevid);
+}
+
+sub write_boot_option {
+       
+       my $oldline = '';
+       my $comline = '';
+       my $newline = '';
+       my @status;
+       my $_preold;
+       my $_prenew;
+
+       if (-f $liloconf) {
+               # move old lilo.conf to lilo.conf_old
+               @status = stat($liloconf);
+               move ($liloconf, $liloconfold);
+               utime ($status[9],$status[9],$liloconfold);
+
+               # copy all lines from lilo.conf_old into
+               # new lilo.conf and add 'boot=' line
+               my $ok = 0;
+               open(MYFH_NEW, "> $liloconf") or die("cannot open $liloconf: $!");
+               open(MYFH_OLD, "< $liloconfold") or die ("cannot open $liloconfold: $!");
+
+               while (<MYFH_OLD>) {
+                       # line read from MYFH_OLD
+                       $oldline = $_;
+
+                       if (/^boot/ and $ok == 0) {
+                               $newline = "boot = $boot_id\n";
+                               print MYFH_NEW "#" . $oldline;
+                               print MYFH_NEW $newline;
+                               if($opt_v) { print "+  #" . $oldline; }
+                               print "+  " . $newline;
+                               if($opt_v) { print "\n"; }
+                               # convert only one time
+                               $ok = 1;
+                       }
+                       elsif (/^#boot/ and $optboot == -1 and $ok == 0) {
+                               # found a line with boot option commented out
+                               $newline = "boot = $boot_id\n";
+                               print MYFH_NEW $oldline;
+                               print MYFH_NEW $newline;
+                               if($opt_v) { print "+  " . $oldline; }
+                               print "+  " . $newline;
+                               if($opt_v) { print "\n"; }
+                               # convert only one time
+                               $ok = 1;
+                       }
+                       elsif (/^root/ or /^\troot/) {
+                               # found a line with root option
+                               if (detect_root_device($oldline) == 0) {
+                                       $comline = comment_root_line($oldline);
+                                       $newline = modern_root_line($oldline,$root_id);
+                                       print MYFH_NEW $comline;
+                                       print MYFH_NEW $newline;
+                                       if($opt_v) { print '+  ' . $comline; }
+                                       print '+  ' . $newline;
+                                       if($opt_v) { print "\n"; }
+                               }
+                               else {
+                                       print MYFH_NEW $oldline;
+                               }
+                       }
+                       else {
+                               print MYFH_NEW $oldline;
+                       }
+               }
+               close(MYFH_OLD);
+               close(MYFH_NEW);
+       }
+       else {
+               print "file $liloconf does not exist: nothing changed\n";
+       }
+}
+
+sub comment_root_line {
+
+       my $rootline = $_[0];
+
+       if( $rootline =~ /root/) {
+               $rootline =~ s/root/#root/;
+       }
+       return $rootline;
+}
+
+sub modern_root_line {
+       
+       my $oldline = $_[0];
+       my $newline = $_[0];
+       my $rootid  = $_[1];
+       my $indent  = '';
+
+       if($oldline =~ /root/) {
+               $indent = $oldline;
+               chomp $indent;
+               $indent =~ s/^(\t?)root.*/$1/;
+               $newline = $indent . "root = \"UUID=$rootid\"\n";
+       }
+       return $newline;
+}
+
+
+main();
+
+
+__END__
+
+
+=head1 NAME
+
+lilo-uuid-diskid - convert boot / root options to diskid and uuid in lilo.conf
+
+=head1 SYNOPSIS
+
+lilo-uuid-diskid [-h] [-v] [lilo.conf]
+
+=head1 DESCRIPTION
+
+This script looks for the boot block device or boot partition and create the
+right diskid or uuid as boot option. Then it looks for all root partitions
+and create the right uuids as root options.
+
+These conversions are necessary for use with newer kernel (>= 2.6.26) if it
+use the libata module for parallel and serial ATA interfaces of block devices
+(i. e. hard disks with IDE or SATA interface, usbsticks).
+
+=head1 EXAMPLES
+
+Lines in the configuration file /etc/lilo.conf:
+
+  #boot = /dev/sda
+  boot = /dev/disk/by-id/ata-SAMSUNG_SV1604N_S01FJ10X999999
+
+  #root = /dev/sda1
+  root = "UUID=/dev/disk/by-uuid/18843936-00f9-4df0-a373-000d05a5dd44"
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h>
+
+Print a brief help.
+
+=item B<-v>
+
+Print verbose messages.
+
+=back
+
+=head1 AUTHOR
+
+B<lilo-uuid-diskid> was written by Joachim Wiedorn.
+
+=cut