[3219] | 1 | #!/usr/bin/perl -w
|
---|
| 2 | #
|
---|
| 3 | # Subroutines related to Kernel brought by the MondoRescue project
|
---|
| 4 | #
|
---|
| 5 | # $Id$
|
---|
| 6 | #
|
---|
[3354] | 7 | # Copyright B. Cornec 2008-2015
|
---|
[3219] | 8 | # Provided under the GPL v2
|
---|
| 9 |
|
---|
| 10 | package MondoRescue::Kernel;
|
---|
| 11 |
|
---|
| 12 | use strict 'vars';
|
---|
| 13 | use Data::Dumper;
|
---|
[3354] | 14 | use File::Basename;
|
---|
[3249] | 15 | use POSIX "uname";
|
---|
[3219] | 16 | use lib qw (lib);
|
---|
| 17 | use ProjectBuilder::Base;
|
---|
| 18 | use ProjectBuilder::Conf;
|
---|
| 19 | use MondoRescue::Base;
|
---|
| 20 | use MondoRescue::Inventory;
|
---|
| 21 |
|
---|
| 22 | # Inherit from the "Exporter" module which handles exporting functions.
|
---|
| 23 |
|
---|
| 24 | use Exporter;
|
---|
| 25 |
|
---|
| 26 | # Export, by default, all the functions into the namespace of
|
---|
| 27 | # any code which uses this module.
|
---|
| 28 |
|
---|
| 29 | our @ISA = qw(Exporter);
|
---|
[3249] | 30 | our @EXPORT = qw(mr_kernel_get_version mr_kernel_get_modules);
|
---|
[3219] | 31 |
|
---|
| 32 | =pod
|
---|
| 33 |
|
---|
| 34 | =head1 NAME
|
---|
| 35 |
|
---|
| 36 | MondoRescue::Kernel, part of the mondorescue.org
|
---|
| 37 |
|
---|
| 38 | =head1 DESCRIPTION
|
---|
| 39 |
|
---|
| 40 | This modules provides low level functions for Kernel support in the Mondorescue project
|
---|
| 41 |
|
---|
| 42 | =head1 USAGE
|
---|
| 43 |
|
---|
| 44 | =over 4
|
---|
| 45 |
|
---|
| 46 | =item B<mr_kernel_get_version>
|
---|
| 47 |
|
---|
| 48 | This function checks the kernel and returns back its version
|
---|
| 49 |
|
---|
| 50 | =cut
|
---|
| 51 |
|
---|
| 52 | sub mr_kernel_get_version {
|
---|
| 53 |
|
---|
| 54 | my ($os,$ver,$kernelver,$rest);
|
---|
| 55 |
|
---|
| 56 | # By default we don't know how it works for other OSes
|
---|
| 57 | $kernelver = "unknown";
|
---|
| 58 |
|
---|
[3249] | 59 | my ($sysname, $nodename, $release, $version, $machine ) = uname();
|
---|
| 60 | $kernelver = $release if (defined $release);
|
---|
[3219] | 61 |
|
---|
| 62 | return($kernelver);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
[3249] | 65 |
|
---|
| 66 | =item B<mr_kernel_get_modules>
|
---|
| 67 |
|
---|
| 68 | Tis function takes as input the kernel version to examined (can be undef in which case the running kernel is used) and a list of modules names to examined as well (can be undef in which case all modules ar taken)
|
---|
| 69 | This function returns back the modules path as a first argument and the list of relative modules path for the modules names passed.
|
---|
| 70 |
|
---|
| 71 | Example:
|
---|
| 72 | mr_kernel_get_modules("3.8.13.4-desktop-1.mga3","ext3") returns
|
---|
| 73 | ("/lib/modules/3.8.13.4-desktop-1.mga3", "kernel/fs/ext3/ext3.ko.xz","kernel/fs/jbd/jbd.ko.xz")
|
---|
| 74 |
|
---|
| 75 | =cut
|
---|
| 76 |
|
---|
| 77 | sub mr_kernel_get_modules {
|
---|
| 78 |
|
---|
[3250] | 79 | my @allmodules = @_;
|
---|
| 80 | my $ver = shift @allmodules;
|
---|
[3249] | 81 | $ver = mr_kernel_get_version() if (not defined ($ver));
|
---|
| 82 |
|
---|
| 83 | my $module = "";
|
---|
| 84 | my %modlist;
|
---|
[3354] | 85 | my %modpath;
|
---|
[3249] | 86 | my $void = "";
|
---|
[3254] | 87 | my @alllivemodules;
|
---|
[3249] | 88 | my @allmodpaths;
|
---|
| 89 | my $modulepath = "";
|
---|
| 90 |
|
---|
[3250] | 91 | #print Dumper(@allmodules);
|
---|
| 92 |
|
---|
[3254] | 93 | # First compute the list of "live" modules - run on the system
|
---|
| 94 | open(LSMOD, "cat /proc/modules |") or die "Unable to launch lsmod";
|
---|
| 95 | while (<LSMOD>) {
|
---|
| 96 | next if (/^Module/);
|
---|
| 97 | ($module, $void) = split(/ /);
|
---|
[3257] | 98 | pb_log(2,"***$module***|***$void***\n");
|
---|
[3254] | 99 | push @alllivemodules,$module;
|
---|
| 100 | }
|
---|
| 101 | close(LSMOD);
|
---|
| 102 |
|
---|
| 103 | # If no module name list passed as parameter, then work on all modules of the system
|
---|
[3249] | 104 | if (not defined $allmodules[0]) {
|
---|
[3254] | 105 | @allmodules = @alllivemodules;
|
---|
[3249] | 106 | }
|
---|
[3250] | 107 | #print Dumper(@allmodules);
|
---|
[3249] | 108 |
|
---|
[3254] | 109 | # Now computes the dependencies of each module and store them in %modlist
|
---|
[3354] | 110 | # # Some depmods gives a full path, others a relative path to /lib/modules/$ver
|
---|
[3249] | 111 | open(DEPMOD, "/sbin/depmod -n $ver |") or die "Unable to launch depmod";
|
---|
| 112 | while (<DEPMOD>) {
|
---|
| 113 | ($module, $void) = split(/:/);
|
---|
| 114 | last if ($module =~ /^#/);
|
---|
| 115 | chomp($void);
|
---|
[3250] | 116 | $void =~ s/\s+//;
|
---|
[3354] | 117 | $module = "/lib/modules/$ver/$module" if ($module !~ /^\/lib\/modules/);
|
---|
| 118 | # Now module is a full path whatever depmod version
|
---|
| 119 | $void = join(' ',map { "/lib/modules/$ver/".$_ } split(/ /,$void)) if ($void !~ /^\/lib\/modules/);
|
---|
| 120 | # Now void is a full path of modules whatever depmod version
|
---|
[3249] | 121 | $modlist{$module} = $void;
|
---|
[3354] | 122 | my $m = basename($module,".ko",".o",".ko.gz",".ko.bz",".ko.xz",".o.gz",".o.bz",".o.xz");
|
---|
| 123 | $modpath{$m} = $module;
|
---|
[3249] | 124 | pb_log(2,"Depmod on $module gives $void\n");
|
---|
| 125 | }
|
---|
| 126 | close(DEPMOD);
|
---|
| 127 |
|
---|
| 128 | #print Dumper(%modlist)."\n";
|
---|
| 129 |
|
---|
| 130 | my $lib;
|
---|
| 131 | my $modulep;
|
---|
| 132 | my $kernelv;
|
---|
| 133 | my $modpath;
|
---|
| 134 |
|
---|
[3254] | 135 | # Analyze each module to find its full path name
|
---|
[3249] | 136 | foreach my $m (@allmodules) {
|
---|
| 137 | pb_log(1,"Analyzing $m\n");
|
---|
[3354] | 138 | if (not defined $modpath{$m}) {
|
---|
| 139 | pb_log(1,"WARNING: No modpath for module $m\n");
|
---|
| 140 | next;
|
---|
| 141 | }
|
---|
| 142 | pb_log(2,"$m has a modpath of $modpath{$m}\n");
|
---|
| 143 | open(MODINFO, "/sbin/modinfo -n $modpath{$m} 2>/dev/null |") or die "Unable to launch modinfo";
|
---|
[3249] | 144 | $module = <MODINFO>;
|
---|
| 145 | close(MODINFO);
|
---|
| 146 | if ((not defined $module) || ($module =~ '^$')) {
|
---|
| 147 | pb_log(1,"WARNING: No modinfo for module $m\n");
|
---|
| 148 | next;
|
---|
| 149 | }
|
---|
| 150 | chomp($module);
|
---|
| 151 | ($void,$lib,$modulep,$kernelv,$modpath) = split(/\//,$module,5);
|
---|
| 152 | next if (not defined $modpath);
|
---|
[3354] | 153 | if (not defined $modlist{$module}) {
|
---|
| 154 | pb_log(0,"No modlist found for $module\n");
|
---|
[3313] | 155 | next;
|
---|
| 156 | }
|
---|
[3354] | 157 | pb_log(2,"modpath: $module\n");
|
---|
| 158 | push @allmodpaths,$module,split(/ /,$modlist{$module});
|
---|
[3249] | 159 | }
|
---|
| 160 | pb_log(1,"all modpaths: ".join(' ',@allmodpaths)."\n");
|
---|
[3250] | 161 | # From List::More
|
---|
| 162 | my %seen = ();
|
---|
| 163 | return(grep { not $seen{$_}++ } @allmodpaths);
|
---|
[3249] | 164 | }
|
---|
| 165 |
|
---|
[3219] | 166 | =back
|
---|
| 167 |
|
---|
| 168 | =head1 WEB SITES
|
---|
| 169 |
|
---|
| 170 | The main Web site of the project is available at L<http://www.mondorescue.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.mondorescue.org/>.
|
---|
| 171 |
|
---|
| 172 | =head1 USER MAILING LIST
|
---|
| 173 |
|
---|
| 174 | The mailing list of the project is available at L<mailto:mondo@lists.sf.net>
|
---|
| 175 |
|
---|
| 176 | =head1 AUTHORS
|
---|
| 177 |
|
---|
| 178 | The Mondorescue.org team L<http://www.mondorescue.org/> lead by Bruno Cornec L<mailto:bruno@mondorescue.org>.
|
---|
| 179 |
|
---|
| 180 | =head1 COPYRIGHT
|
---|
| 181 |
|
---|
| 182 | This module is distributed under the GPL v2.0 license
|
---|
| 183 | described in the file C<COPYING> included with the distribution.
|
---|
| 184 |
|
---|
| 185 | =cut
|
---|
| 186 |
|
---|
| 187 | 1;
|
---|
| 188 |
|
---|