1 | #!/usr/bin/perl -w
|
---|
2 | #
|
---|
3 | # Subroutines related to Kernel brought by the MondoRescue project
|
---|
4 | #
|
---|
5 | # $Id$
|
---|
6 | #
|
---|
7 | # Copyright B. Cornec 2008-2015
|
---|
8 | # Provided under the GPL v2
|
---|
9 |
|
---|
10 | package MondoRescue::Kernel;
|
---|
11 |
|
---|
12 | use strict 'vars';
|
---|
13 | use Data::Dumper;
|
---|
14 | use File::Basename;
|
---|
15 | use POSIX "uname";
|
---|
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);
|
---|
30 | our @EXPORT = qw(mr_kernel_get_version mr_kernel_get_modules);
|
---|
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 |
|
---|
59 | my ($sysname, $nodename, $release, $version, $machine ) = uname();
|
---|
60 | $kernelver = $release if (defined $release);
|
---|
61 |
|
---|
62 | return($kernelver);
|
---|
63 | }
|
---|
64 |
|
---|
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 |
|
---|
79 | my @allmodules = @_;
|
---|
80 | my $ver = shift @allmodules;
|
---|
81 | $ver = mr_kernel_get_version() if (not defined ($ver));
|
---|
82 |
|
---|
83 | my $module = "";
|
---|
84 | my %modlist;
|
---|
85 | my %modpath;
|
---|
86 | my $void = "";
|
---|
87 | my @alllivemodules;
|
---|
88 | my @allmodpaths;
|
---|
89 | my $modulepath = "";
|
---|
90 |
|
---|
91 | #print Dumper(@allmodules);
|
---|
92 |
|
---|
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(/ /);
|
---|
98 | pb_log(2,"***$module***|***$void***\n");
|
---|
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
|
---|
104 | if (not defined $allmodules[0]) {
|
---|
105 | @allmodules = @alllivemodules;
|
---|
106 | }
|
---|
107 | #print Dumper(@allmodules);
|
---|
108 |
|
---|
109 | # Now computes the dependencies of each module and store them in %modlist
|
---|
110 | # # Some depmods gives a full path, others a relative path to /lib/modules/$ver
|
---|
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);
|
---|
116 | $void =~ s/\s+//;
|
---|
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
|
---|
121 | $modlist{$module} = $void;
|
---|
122 | my $m = basename($module,".ko",".o",".ko.gz",".ko.bz",".ko.xz",".o.gz",".o.bz",".o.xz");
|
---|
123 | $modpath{$m} = $module;
|
---|
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 |
|
---|
135 | # Analyze each module to find its full path name
|
---|
136 | foreach my $m (@allmodules) {
|
---|
137 | pb_log(1,"Analyzing $m\n");
|
---|
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";
|
---|
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);
|
---|
153 | if (not defined $modlist{$module}) {
|
---|
154 | pb_log(0,"No modlist found for $module\n");
|
---|
155 | next;
|
---|
156 | }
|
---|
157 | pb_log(2,"modpath: $module\n");
|
---|
158 | push @allmodpaths,$module,split(/ /,$modlist{$module});
|
---|
159 | }
|
---|
160 | pb_log(1,"all modpaths: ".join(' ',@allmodpaths)."\n");
|
---|
161 | # From List::More
|
---|
162 | my %seen = ();
|
---|
163 | return(grep { not $seen{$_}++ } @allmodpaths);
|
---|
164 | }
|
---|
165 |
|
---|
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 |
|
---|