ACC SHELL
Path : /sbin/ |
|
Current File : //sbin/mkinitrd_setup |
#!/usr/bin/perl
#
# Install initrd scripts
#
use strict;
use Getopt::Long;
my @scripts_boot = ();
my @scripts_setup = ();
my %level_boot = ();
my %level_setup = ();
my %depends_boot = ();
my %depends_setup = ();
my %providedby_boot = ();
my %providedby_setup = ();
my $debug = 0;
my $offset = 0;
my $installdir = "/lib/mkinitrd";
my $scriptdir = "$installdir/scripts";
my $dohelp = 0;
my %stages = (
setup => 0,
filesystem => 1,
crypto => 2,
volumemanager => 3,
softraid => 4,
partitions => 5,
devicemapper => 6,
block => 7,
device => 8,
boot => 9,
);
sub dprintf
{
if ($debug > 0) {
printf @_;
}
}
sub resolve_dependency
{
my $section = shift(@_);
my $name = shift(@_);
my $oldlevel;
my $level;
my $depends;
my $providedby;
if ( $section eq "setup" ) {
$level = \%level_setup;
$depends = \%depends_setup;
$providedby= \%providedby_setup;
} else {
$level = \%level_boot;
$depends = \%depends_boot;
$providedby= \%providedby_boot;
}
$oldlevel = $$level{$name};
foreach my $elem (split(' ',$$depends{$name})) {
my $newlevel = -1;
foreach my $n (split(' ',$$providedby{$elem})) {
$newlevel = resolve_dependency($section, $n);
if ( $oldlevel <= $newlevel) {
$oldlevel = $newlevel + 1;
}
}
if ($newlevel == -1) {
dprintf "Unresolved dependency \"%s\" ", $elem;
}
}
dprintf "%s/%s (%s) ", $section, $name, $oldlevel;
$$level{$name} = $oldlevel;
return $oldlevel;
}
sub scan_section
{
my @scripts = @_;
my @scrlist = ();
my $depends;
my $level;
my $providedby;
SCAN: foreach $_ (@scripts) {
my $provides;
my $section;
my $scriptname;
my $level;
my $depends;
my $providedby;
my $scrlist;
if (/(.*)-(.*)\.sh$/) {
if (($1 ne "setup" ) && ($1 ne "boot")) {
next SCAN;
}
$section = $1;
$scriptname = $2;
} else {
next SCAN;
}
if ( $section eq "setup" ) {
$level = \%level_setup;
$depends = \%depends_setup;
$providedby= \%providedby_setup;
$scrlist = \@scripts_setup;
} else {
$level = \%level_boot;
$depends = \%depends_boot;
$providedby= \%providedby_boot;
$scrlist = \@scripts_boot;
}
dprintf "scanning script %s (name %s)\n", $_, $scriptname;
dprintf "\tsection: %s\n", $section;
$provides = $scriptname;
open(SCR, "$scriptdir/$_");
while (<SCR>) {
chomp;
if ( /^\#%stage: (.*)/ ) {
if (! defined $stages{$1}) {
dprintf "%s: Invalid stage \"%s\"\n", $scriptname, $1;
close(SCR);
next SCAN;
}
if ($section eq "setup") {
$$level{$scriptname} = ($stages{$1} * 10) + 1;
} else {
$$level{$scriptname} = 91 - ($stages{$1} * 10);
}
dprintf "\tstage %s: %d\n", $1, $$level{$scriptname};
}
if ( /^\#%depends: (.*)/ ) {
dprintf "\tdepends on %s\n", $1;
$$depends{$scriptname} = $1;
}
if ( /\#%provides: (.*)/ ) {
$provides = join(' ',$provides,$1);
}
}
close SCR;
@$scrlist = (@$scrlist,$scriptname);
dprintf "\tprovides %s\n", $provides;
foreach my $elem (split(' ',$provides)) {
$$providedby{$elem} = join(' ', $$providedby{$elem},$scriptname);
}
}
}
sub usage {
print <<EOF;
usage:
mkinitrd_setup [-s|--scriptdir <scriptdir>]
[-i|--installdir <installdir>]
[-d|--debug] [-o|--offset <offset>] [-h|--help]
Install mkinitrd scripts. Options are:
-s|--scriptdir Install initrd scripts from dir <scriptdir>
-i|--installdir Install initrd scripts in dir <installdir>
-d|--debug Enable debug output
-o|--offset Use <offset> between script numbers.
EOF
}
Getopt::Long::Configure('no_ignore_case');
if (!GetOptions('scriptdir|s=s' => \$scriptdir,
'installdir|i=s' => \$installdir,
'debug|d' => \$debug,
'offset|o' => \$offset,
'help|h' => \$dohelp
)) {
usage();
exit 1;
}
if ( ! -d $installdir ) {
print "Installation directory $installdir does not exist!\n";
$dohelp++;
}
if ( $dohelp == 0 && ! -d "$installdir/setup" ) {
print "Installation directory $installdir/setup does not exist!\n";
$dohelp++;
}
if ( $dohelp == 0 && ! -d "$installdir/boot" ) {
print "Installation directory $installdir/boot does not exist!\n";
$dohelp++;
}
if ( $dohelp == 0 && ! -d $scriptdir ) {
print "Script directory $scriptdir does not exist!\n";
$dohelp++;
}
if ($dohelp > 0) {
usage();
exit 0;
}
print "Scanning scripts ...\n";
opendir(DIR, $scriptdir);
my @scripts = grep { /.*\.sh$/ && -f "$scriptdir/$_" } readdir(DIR);
closedir DIR;
# Scan scripts
scan_section(@scripts);
print "Resolve dependencies ...\n";
# Resolve dependencies
foreach my $scr (@scripts_setup) {
resolve_dependency("setup", $scr);
dprintf "\n";
}
foreach my $scr (@scripts_boot) {
resolve_dependency("boot", $scr);
dprintf "\n";
}
print "Install symlinks in $installdir/setup ...\n";
chdir "$installdir/setup" || die "Can't chdir to $installdir/setup : $!";
opendir(DIR, ".");
my @links = grep { -l "$_" } readdir(DIR);
closedir DIR;
foreach $_ (@links) {
unlink || printf "Can't unlink %s: %s\n", $_, $!;
}
foreach (@scripts_setup) {
my $level = \%level_setup;
my $lvl = $$level{$_};
my $linkname;
my $target;
my $ret;
$linkname = sprintf "%02d-%s.sh", $lvl, $_;
$target = sprintf "../scripts/setup-%s.sh", $_;
# Strictly speaking not required, but ...
next if -l $linkname;
dprintf "Linking %s to %s\n", $target, $linkname;
$ret = symlink($target, $linkname);
if ( $ret < 1 ) {
printf "Failed to create symlink %s: %s\n", $linkname, $!;
}
}
print "Install symlinks in $installdir/boot ...\n";
chdir "../boot" || die "Can't chdir to $installdir/boot: $!";
opendir(DIR, ".");
@links = grep { -l "$_" } readdir(DIR);
closedir DIR;
foreach $_ (@links) {
unlink || printf "Can't unlink %s: %s\n", $_, $!;
}
foreach (@scripts_boot) {
my $level = \%level_boot;
my $lvl = $$level{$_};
my $linkname;
my $target;
my $ret;
$linkname = sprintf "%02d-%s.sh", $lvl, $_;
$target = sprintf "../scripts/boot-%s.sh", $_;
# Strictly speaking not required, but ...
next if -l $linkname;
dprintf "Linking %s to %s\n", $target, $linkname;
$ret = symlink($target, $linkname);
if ( $ret < 1 ) {
printf "Failed to create symlink %s: %s\n", $linkname, $!;
}
}
ACC SHELL 2018