mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			765 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			765 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl -w
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| #####################################################
 | |
| #
 | |
| #  xCAT plugin package to handle kernel modules
 | |
| #
 | |
| #####################################################
 | |
| 
 | |
| package xCAT_plugin::kmodules;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| 
 | |
| require xCAT::Table;
 | |
| require xCAT::Utils;
 | |
| require xCAT::TableUtils;
 | |
| require Data::Dumper;
 | |
| require Getopt::Long;
 | |
| require xCAT::MsgUtils;
 | |
| use File::Path qw(mkpath rmtree);
 | |
| use File::Basename qw(basename);
 | |
| use Text::Balanced qw(extract_bracketed);
 | |
| use Safe;
 | |
| my $evalcpt = new Safe;
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| #
 | |
| # Globals
 | |
| #
 | |
| 
 | |
| #------------------------------------------------------------------------------
 | |
| 
 | |
| =head1    kmodules
 | |
| 
 | |
| This program module file performs kernel module functions
 | |
| 
 | |
| Supported commands:
 | |
|    lskmodules -- List the kernel modules in one or more:
 | |
|                     osimage.driverupdatesrc (duds or rpms)
 | |
|                     kitcomponent.driverpacks (rpms in repodir)
 | |
|                     osdistro (kernel-<kernvers> rpms)
 | |
|                     osdistroupdate (kernel-<kernvers> rpms)
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #------------------------------------------------------------------------------
 | |
| 
 | |
| =head2    Kernel Modules Support
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #------------------------------------------------------------------------------
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  handled_commands
 | |
| 
 | |
|         Return a list of commands handled by this plugin
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub handled_commands {
 | |
|     return {
 | |
|         lskmodules => "kmodules"
 | |
|     };
 | |
| }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3   preprocess_request
 | |
| 
 | |
| 
 | |
|         Arguments:
 | |
| 
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| # sub preprocess_request {
 | |
| #
 | |
| # NOT REQUIRED -- no hierarchy for this command
 | |
| #    my $req = shift;
 | |
| #    return [$req];
 | |
| # }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3   process_request
 | |
| 
 | |
|         Process the kernel modules commands
 | |
| 
 | |
|         Arguments:
 | |
| 
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub process_request {
 | |
|     $::request  = shift;
 | |
|     $::CALLBACK = shift;
 | |
|     $::SUBREQ   = shift;
 | |
|     my $ret;
 | |
| 
 | |
|     # globals used by all subroutines.
 | |
|     $::command   = $::request->{command}->[0];
 | |
|     $::args      = $::request->{arg};
 | |
|     $::stdindata = $::request->{stdin}->[0];
 | |
| 
 | |
|     # figure out which cmd and call the subroutine to process
 | |
|     if ($::command eq "lskmodules") {
 | |
|         $ret = &lskmodules($::request);
 | |
|     }
 | |
| 
 | |
|     return $ret;
 | |
| }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  lskmodules_usage
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| # display the usage
 | |
| sub lskmodules_usage {
 | |
|     my $rsp;
 | |
|     push @{ $rsp->{data} },
 | |
|       "\nUsage: lskmodules - List kernel modules in specified input \n";
 | |
|     push @{ $rsp->{data} },
 | |
| "  lskmodules [-V|--verbose] [-x|--xml|--XML] [-c|--kitcomponent kit_comp1,kit_comp2,...] [-o|--osdistro os_distro] [-u|--osdistroupdate os_distro_update] [-i|--osimage osimage]  \n ";
 | |
|     push @{ $rsp->{data} }, "  lskmodules [-h|--help|-?] \n";
 | |
|     push @{ $rsp->{data} },
 | |
|       "  lskmodules [-v|--version]  \n ";
 | |
|     xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3   processArgs
 | |
| 
 | |
|         Process the command line
 | |
| 
 | |
|         Arguments:
 | |
| 
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - just print usage
 | |
|                 2 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub processArgs {
 | |
| 
 | |
|     if (defined($::args) && @{$::args}) {
 | |
|         @ARGV = @{$::args};
 | |
|     }
 | |
| 
 | |
|     # parse the options
 | |
|     # options can be bundled up like -vV, flag unsupported options
 | |
|     Getopt::Long::Configure("bundling", "no_ignore_case", "no_pass_through");
 | |
|     Getopt::Long::GetOptions(
 | |
|         'help|h|?'           => \$::opt_h,
 | |
|         'kitcomponent|c=s'   => \$::opt_c,
 | |
|         'osimage|i=s'        => \$::opt_i,
 | |
|         'osdistro|o=s'       => \$::opt_o,
 | |
|         'osdistroupdate|u=s' => \$::opt_u,
 | |
|         'verbose|V'          => \$::opt_V,
 | |
|         'version|v'          => \$::opt_v,
 | |
|         'xml|XML|x'          => \$::opt_x,
 | |
|     );
 | |
| 
 | |
|     # Option -h for Help
 | |
|     if (defined($::opt_h)) {
 | |
|         return 2;
 | |
|     }
 | |
| 
 | |
|     # Option -v for version
 | |
|     if (defined($::opt_v)) {
 | |
|         my $rsp;
 | |
|         my $version = xCAT::Utils->Version();
 | |
|         push @{ $rsp->{data} }, "$::command - $version\n";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         return 1;    # no usage - just exit
 | |
|     }
 | |
| 
 | |
|     # Option -V for verbose output
 | |
|     if (defined($::opt_V)) {
 | |
|         $::verbose = 1;
 | |
|         $::VERBOSE = 1;
 | |
|     }
 | |
| 
 | |
|     if (!defined($::opt_c) &&
 | |
|         !defined($::opt_i) &&
 | |
|         !defined($::opt_o) &&
 | |
|         !defined($::opt_u)) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Specify a search location \n";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         return 2;
 | |
|     }
 | |
| 
 | |
|     my $more_input = shift(@ARGV);
 | |
|     if (defined($more_input)) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Invalid input: $more_input \n";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|         return 2;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  lskmodules
 | |
| 
 | |
|         Support for listing kernel modules
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub lskmodules {
 | |
| 
 | |
|     my $rc = 0;
 | |
| 
 | |
|     # process the command line
 | |
|     $rc = &processArgs;
 | |
|     if ($rc != 0) {
 | |
| 
 | |
|         # rc: 0 - ok, 1 - return, 2 - help, 3 - error
 | |
|         if ($rc != 1) {
 | |
|             &lskmodules_usage;
 | |
|         }
 | |
|         return ($rc - 1);
 | |
|     }
 | |
| 
 | |
|     if ($::VERBOSE) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Running lskmodules command... ";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|     }
 | |
| 
 | |
|     # Get all the rpms and img files to search based on command input
 | |
|     my @sources = &set_sources;
 | |
|     if (!(@sources)) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "No input search source found.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # Get the list of kernel modules in each rpm/img file
 | |
|     my @modlist;
 | |
|     foreach my $source (@sources) {
 | |
|         if ($source =~ /^dud:/) {
 | |
|             $source =~ s/^dud://;
 | |
|             push(@modlist, &mods_in_img($source));
 | |
|         } else {
 | |
|             my $osver = xCAT::Utils->osver();
 | |
|             if ($osver =~ /ubuntu/) {
 | |
|                 $source =~ s/^deb://;
 | |
|             } else {
 | |
|                 $source =~ s/^rpm://;
 | |
|             }
 | |
|             push(@modlist, &mods_in_rpm($source));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     @modlist = &remove_duplicate_mods(\@modlist);
 | |
| 
 | |
|     # Return the module list for this rpm/img file
 | |
|     my $rsp;
 | |
|     foreach my $mn (@modlist) {
 | |
|         if ($::opt_x) {
 | |
|             my %data_entry;
 | |
|             $data_entry{module}->{name}        = $mn->{name};
 | |
|             $data_entry{module}->{description} = $mn->{description};
 | |
|             push @{ $rsp->{data} }, \%data_entry;
 | |
|         } else {
 | |
|             push @{ $rsp->{data} }, $mn->{name} . ': ' . $mn->{description};
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ($rsp) {
 | |
|         $::CALLBACK->($rsp);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return $rc;
 | |
| }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  set_sources
 | |
| 
 | |
|         return array of input kernel module sources
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub set_sources {
 | |
| 
 | |
|     my $installdir = xCAT::TableUtils->getInstallDir;
 | |
|     my @sources;
 | |
|     my %src_data;
 | |
|     my $order = 1;
 | |
| 
 | |
| 
 | |
|     # OS images (osimage.driverupdatesrc)
 | |
|     if (defined($::opt_i)) {
 | |
|         my $litab = xCAT::Table->new('linuximage');
 | |
|         foreach my $li (split(',', $::opt_i)) {
 | |
|             my ($li_entry) = $litab->getAttribs({ 'imagename' => $li }, ('driverupdatesrc'));
 | |
|             if (!($li_entry)) {
 | |
|                 if ($::VERBOSE) {
 | |
|                     my $rsp;
 | |
|                     push @{ $rsp->{data} }, "No driverupdatesrc attribute for osimage $li found.  Skipping. ";
 | |
|                     xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                 }
 | |
|                 next;
 | |
|             }
 | |
|             foreach my $dus (split(',', $li_entry->{'driverupdatesrc'})) {
 | |
|                 my $base_dus = basename($dus);
 | |
|                 if (defined($src_data{$base_dus})) {
 | |
|                     if ($::VERBOSE) {
 | |
|                         my $rsp;
 | |
|                         push @{ $rsp->{data} }, "Duplicate source $base_dus found in input.  Skipping $dus entry in osimage &li driverupdatesrc.  Using from $src_data{$base_dus}{'sourcemsg'} instead.";
 | |
|                         xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                     }
 | |
|                     next;
 | |
|                 } else {
 | |
|                     $src_data{$base_dus}{'sourcemsg'} = "osimage $li driverupdatesrc entry $dus";
 | |
|                     $src_data{$base_dus}{'source'} = $dus;
 | |
|                     $src_data{$base_dus}{'order'}  = $order++;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         $litab->close;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     # Kit Components (kitcomp.driverpacks)
 | |
|     if (defined($::opt_c)) {
 | |
|         my $kctab = xCAT::Table->new('kitcomponent');
 | |
|         my $krtab = xCAT::Table->new('kitrepo');
 | |
|         foreach my $kc (split(',', $::opt_c)) {
 | |
|             my ($kc_entry) = $kctab->getAttribs({ 'kitcompname' => $kc }, ('kitreponame', 'driverpacks'));
 | |
|             if (!($kc_entry)) {
 | |
|                 if ($::VERBOSE) {
 | |
|                     my $rsp;
 | |
|                     push @{ $rsp->{data} }, "No driverpacks attribute for kitcomponent $kc found.  Skipping.";
 | |
|                     xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                 }
 | |
|                 next;
 | |
|             }
 | |
|             my ($kr_entry) = $krtab->getAttribs({ 'kitreponame' => $kc_entry->{'kitreponame'} }, ('kitrepodir'));
 | |
|             if (!($kr_entry)) {
 | |
|                 if ($::VERBOSE) {
 | |
|                     my $rsp;
 | |
|                     push @{ $rsp->{data} }, "Kitrepo $kc_entry->{'kitreponame'} not found in database.  Error in kitcomponent definition for $kc.  Skipping.";
 | |
|                     xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                 }
 | |
|                 next;
 | |
|             }
 | |
|             foreach my $dp (split(',', $kc_entry->{'driverpacks'})) {
 | |
|                 if (defined($src_data{$dp})) {
 | |
|                     if ($::VERBOSE) {
 | |
|                         my $rsp;
 | |
|                         push @{ $rsp->{data} }, "Duplicate source $dp found in input.  Skipping kitcomponent $kc driverpack entry $dp.  Using from $src_data{$dp}{'sourcemsg'} instead.";
 | |
|                         xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                     }
 | |
|                     next;
 | |
|                 } else {
 | |
|                     $src_data{$dp}{'sourcemsg'} = "kitcomponent $kc, kitrepo $kc_entry->{'kitreponame'}";
 | |
|                     $src_data{$dp}{'source'} = $kr_entry->{'kitrepodir'} . '/' . $dp;
 | |
|                     $src_data{$dp}{'order'} = $order++;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         $kctab->close;
 | |
|     }
 | |
| 
 | |
|     # OS distro update
 | |
|     if (defined($::opt_u)) {
 | |
|         my $outab = xCAT::Table->new('osdistroupdate');
 | |
|         foreach my $ou (split(',', $::opt_u)) {
 | |
|             my ($ou_entry) = $outab->getAttribs({ 'osupdatename' => $ou }, ('dirpath', 'basename'));
 | |
|             if (!($ou_entry) || !(defined($ou_entry->{'dirpath'}))) {
 | |
|                 if ($::VERBOSE) {
 | |
|                     my $rsp;
 | |
|                     push @{ $rsp->{data} }, "No dirpath attribute for osdistroupdate $ou found.  Skipping.";
 | |
|                     xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                 }
 | |
|                 next;
 | |
|             }
 | |
|             my $dirpath     = $ou_entry->{'dirpath'};
 | |
|             my @kernel_rpms = ();
 | |
|             if ($ou_entry->{'basename'} =~ /^ubuntu/)
 | |
|             {
 | |
|                 @kernel_rpms = `find $dirpath/pool/main/l/linux/ -name *deb`;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 @kernel_rpms = `find $dirpath -name kernel-*.rpm`;
 | |
|             }
 | |
| 
 | |
|             foreach my $krpm (@kernel_rpms) {
 | |
|                 chomp($krpm);
 | |
|                 my $base_krpm = basename($krpm);
 | |
|                 if (defined($src_data{$base_krpm})) {
 | |
|                     if ($::VERBOSE) {
 | |
|                         my $rsp;
 | |
|                         push @{ $rsp->{data} }, "Duplicate source $base_krpm found in input.  Skipping $krpm in osdistroupdate $ou.  Using from $src_data{$base_krpm}{'sourcemsg'} instead.";
 | |
|                         xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                     }
 | |
|                     next;
 | |
|                 }
 | |
|                 $src_data{$base_krpm}{'sourcemsg'} = "osdistroupdate $ou rpm $krpm";
 | |
|                 $src_data{$base_krpm}{'source'} = $krpm;
 | |
|                 $src_data{$base_krpm}{'order'}  = $order++;
 | |
|             }
 | |
|         }
 | |
|         $outab->close;
 | |
|     }
 | |
| 
 | |
|     # OS distro
 | |
|     if (defined($::opt_o)) {
 | |
|         my $odtab = xCAT::Table->new('osdistro');
 | |
|         foreach my $od (split(',', $::opt_o)) {
 | |
|             my ($od_entry) = $odtab->getAttribs({ 'osdistroname' => $od }, ('dirpaths', 'basename'));
 | |
|             if (!($od_entry)) {
 | |
| 
 | |
|                 # try building dirpath from distro_name/local_arch
 | |
|                 my $arch = `uname -m`;
 | |
|                 chomp($arch);
 | |
|                 $arch = "x86" if ($arch =~ /i.86$/);
 | |
|                 my $dirpath = $installdir . '/' . $od . '/' . $arch;
 | |
|                 if (!(-e $dirpath)) {
 | |
|                     if ($::VERBOSE) {
 | |
|                         my $rsp;
 | |
|                         push @{ $rsp->{data} }, "No dirpaths attribute for osdistro $od found.  Skipping. ";
 | |
|                         xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                     }
 | |
|                     next;
 | |
|                 }
 | |
| 
 | |
|                 my @kernel_rpms = ();
 | |
|                 if ($od_entry->{'basename'} =~ /ubuntu/)
 | |
|                 {
 | |
|                     @kernel_rpms = `find $dirpath/pool/main/l/linux/ -name *deb`;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     @kernel_rpms = `find $dirpath -name kernel-*.rpm`;
 | |
|                 }
 | |
| 
 | |
|                 foreach my $krpm (@kernel_rpms) {
 | |
|                     chomp($krpm);
 | |
|                     my $base_krpm = basename($krpm);
 | |
|                     if (!defined($src_data{$base_krpm})) {
 | |
|                         $src_data{$base_krpm}{'sourcemsg'} = "osdistro $od default rpm $krpm";
 | |
|                         $src_data{$base_krpm}{'source'} = $krpm;
 | |
|                         $src_data{$base_krpm}{'order'}  = $order++;
 | |
|                     }
 | |
|                 }
 | |
|             } else {
 | |
|                 foreach my $dirpath (split(',', $od_entry->{'dirpaths'})) {
 | |
|                     my @kernel_rpms = ();
 | |
|                     if ($od_entry->{'basename'} =~ /ubuntu/)
 | |
|                     {
 | |
|                         @kernel_rpms = `find $dirpath/pool/main/l/linux/ -name *deb`;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         @kernel_rpms = `find $dirpath -name kernel-*.rpm`;
 | |
|                     }
 | |
| 
 | |
|                     #my @kernel_rpms = `find $dirpath -name kernel-*.rpm`;
 | |
|                     foreach my $krpm (@kernel_rpms) {
 | |
|                         chomp($krpm);
 | |
|                         my $base_krpm = basename($krpm);
 | |
|                         if (defined($src_data{$base_krpm})) {
 | |
|                             if ($::VERBOSE) {
 | |
|                                 my $rsp;
 | |
|                                 push @{ $rsp->{data} }, "Duplicate source $base_krpm found in input.  Skipping $krpm in osdistro $od.  Using from $src_data{$base_krpm}{'sourcemsg'} instead.";
 | |
|                                 xCAT::MsgUtils->message("W", $rsp, $::CALLBACK);
 | |
|                             }
 | |
|                             next;
 | |
|                         }
 | |
|                         $src_data{$base_krpm}{'sourcemsg'} = "osdistro $od rpm $krpm";
 | |
|                         $src_data{$base_krpm}{'source'} = $krpm;
 | |
|                         $src_data{$base_krpm}{'order'}  = $order++;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         $odtab->close;
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
|     foreach my $base_source (sort { $src_data{$a}{'order'} <=> $src_data{$b}{'order'} } keys %src_data) {
 | |
|         push @sources, $src_data{$base_source}{'source'};
 | |
|     }
 | |
| 
 | |
|     if ($::VERBOSE && @sources) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Searching the following locations for kernel modules: ";
 | |
|         push @{ $rsp->{data} }, @sources;
 | |
|         xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return @sources;
 | |
| }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  mods_in_rpm
 | |
| 
 | |
|         return hash of module names/descriptions found in rpm
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub mods_in_rpm {
 | |
| 
 | |
|     my $krpm = shift;
 | |
|     my @modlist;
 | |
| 
 | |
| 
 | |
|     my $tmp_path = "/tmp/lskmodules_expanded_rpm";
 | |
|     mkpath($tmp_path);
 | |
|     if (-r $krpm) {
 | |
|         my $osver = xCAT::Utils->osver();
 | |
|         if ($osver =~ /ubuntu/) {
 | |
|             if (system("cd $tmp_path; dpkg -X $krpm $tmp_path > /dev/null 2>&1 ; cd - > /dev/null 2>&1")) {
 | |
|                 my $rsp;
 | |
|                 push @{ $rsp->{data} }, "Unable to extract files from the deb package $krpm.";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|                 rmtree($tmp_path);
 | |
|                 return; }
 | |
|         } else {
 | |
|             if (system("cd $tmp_path; rpm2cpio $krpm | cpio -idum  > /dev/null 2>&1 ; cd - > /dev/null 2>&1")) {
 | |
|                 my $rsp;
 | |
|                 push @{ $rsp->{data} }, "Unable to extract files from the rpm $krpm.";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|                 rmtree($tmp_path);
 | |
|                 return;
 | |
|             }
 | |
|         }
 | |
|     } else {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Unable to read rpm $krpm.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         rmtree($tmp_path);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     my @ko_files = `find $tmp_path -regextype posix-egrep  -regex ".*/*\.ko(\.xz)?"`;
 | |
|     foreach my $ko (@ko_files) {
 | |
|         my %mod;
 | |
|         chomp($ko);
 | |
|         my $name = basename($ko);
 | |
|         my $desc = `modinfo -d $ko`;
 | |
|         chomp($desc);
 | |
|         if ($desc =~ /^\s*$/) {
 | |
|             $desc = "  ";
 | |
|         }
 | |
|         $mod{name}        = $name;
 | |
|         $mod{description} = $desc;
 | |
|         push(@modlist, \%mod);
 | |
|     }
 | |
|     rmtree($tmp_path);
 | |
| 
 | |
|     return @modlist;
 | |
| 
 | |
| }
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  mods_in_img
 | |
| 
 | |
|         return hash of module names/descriptions found in
 | |
|            driver update image
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub mods_in_img {
 | |
| 
 | |
|     my $img_file = shift;
 | |
|     my @modlist;
 | |
| 
 | |
|     my $mnt_path = "/tmp/lskmodules_mnt";
 | |
|     mkpath($mnt_path);
 | |
| 
 | |
|     my $rc = system("mount -o loop $img_file $mnt_path");
 | |
|     if ($rc) {
 | |
|         my $rsp;
 | |
|         push @{ $rsp->{data} }, "Mount of driver disk image $img_file failed";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
 | |
|         rmtree($mnt_path);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     my @ko_files = `find $mnt_path -name *.ko`;
 | |
|     foreach my $ko (@ko_files) {
 | |
|         my %mod;
 | |
|         chomp($ko);
 | |
|         my $name = basename($ko);
 | |
|         my $desc = `modinfo -d $ko`;
 | |
|         chomp($desc);
 | |
|         if ($desc =~ /^\w*$/) {
 | |
|             $desc = "  ";
 | |
|         }
 | |
|         $mod{name}        = $name;
 | |
|         $mod{description} = $desc;
 | |
|         push(@modlist, \%mod);
 | |
|     }
 | |
| 
 | |
|     $rc = system("umount $mnt_path");
 | |
|     rmtree($mnt_path);
 | |
| 
 | |
|     return @modlist;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| =head3  remove_duplicate_mods
 | |
| 
 | |
|         return array of unique module names/descriptions hashes from input array
 | |
| 
 | |
|         Arguments:
 | |
|         Returns:
 | |
|                 0 - OK
 | |
|                 1 - error
 | |
|         Globals:
 | |
| 
 | |
|         Error:
 | |
| 
 | |
|         Example:
 | |
| 
 | |
|         Comments:
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub remove_duplicate_mods {
 | |
| 
 | |
|     my $modlist = shift;
 | |
| 
 | |
|     my %unique_names;
 | |
|     my @return_list;
 | |
| 
 | |
|     foreach my $mn (@$modlist) {
 | |
|         if (defined($unique_names{ $mn->{name} })) { next; }
 | |
|         $unique_names{ $mn->{name} } = $mn->{description};
 | |
|     }
 | |
| 
 | |
|     foreach my $un (sort keys(%unique_names)) {
 | |
|         my %mod;
 | |
|         $mod{name}        = $un;
 | |
|         $mod{description} = $unique_names{$un};
 | |
|         push(@return_list, \%mod);
 | |
|     }
 | |
| 
 | |
|     return @return_list;
 | |
| }
 | |
| 
 | |
| 1;
 |