1# 2# (c) Jan Gehring <jan.gehring@gmail.com> 3# 4# vim: set ts=2 sw=2 tw=0: 5# vim: set expandtab: 6 7=head1 NAME 8 9Rex::Commands::Kernel - Load/Unload Kernel Modules 10 11=head1 DESCRIPTION 12 13With this module you can load and unload kernel modules. 14 15Version <= 1.0: All these functions will not be reported. 16 17All these functions are not idempotent. 18 19=head1 SYNOPSIS 20 21 kmod load => "ipmi_si"; 22 23 kmod unload => "ipmi_si"; 24 25=head1 EXPORTED FUNCTIONS 26 27=cut 28 29package Rex::Commands::Kernel; 30 31use 5.010001; 32use strict; 33use warnings; 34 35our $VERSION = '1.13.4'; # VERSION 36 37use Rex::Logger; 38use Rex::Helper::Run; 39use Rex::Commands::Gather; 40 41use Data::Dumper; 42 43require Rex::Exporter; 44 45use base qw(Rex::Exporter); 46use vars qw(@EXPORT); 47 48@EXPORT = qw(kmod); 49 50=head2 kmod($action => $module) 51 52This function loads or unloads a kernel module. 53 54 task "load", sub { 55 kmod load => "ipmi_si"; 56 }; 57 58 task "unload", sub { 59 kmod unload => "ipmi_si"; 60 }; 61 62If you're using NetBSD or OpenBSD you have to specify the complete path and, if needed the entry function. 63 64 task "load", sub { 65 kmod load => "/usr/lkm/ntfs.o"; 66 kmod load => "/path/to/module.o", entry => "entry_function"; 67 }; 68 69=cut 70 71sub kmod { 72 my ( $action, $module, @rest ) = @_; 73 74 my $options = {@_}; 75 76 my $os = get_operating_system(); 77 78 my $load_command = "modprobe"; 79 my $unload_command = "rmmod"; 80 81 if ( $os eq "FreeBSD" ) { 82 $load_command = "kldload"; 83 $unload_command = "kldunload"; 84 } 85 elsif ( $os eq "NetBSD" || $os eq "OpenBSD" ) { 86 $load_command = "modload"; 87 $unload_command = "modunload"; 88 89 if ( $options->{"entry"} ) { 90 $load_command .= " -e " . $options->{"entry"}; 91 } 92 } 93 elsif ( $os eq "SunOS" ) { 94 $load_command = "modload -p "; 95 96 if ( $options->{"exec_file"} ) { 97 $load_command .= " -e " . $options->{"exec_file"} . " "; 98 } 99 100 $unload_command = sub { 101 my @mod_split = split( /\//, $module ); 102 my $mod = $mod_split[-1]; 103 104 my ($mod_id) = map { /^\s*(\d+)\s+.*$mod/ } i_run "modinfo"; 105 my $cmd = "modunload -i $mod_id"; 106 107 if ( $options->{"exec_file"} ) { 108 $cmd .= " -e " . $options->{"exec_file"}; 109 } 110 111 return $cmd; 112 }; 113 } 114 elsif ( $os eq "OpenWrt" ) { 115 $load_command = "insmod"; 116 } 117 118 if ( $action eq "load" ) { 119 Rex::Logger::debug("Loading Kernel Module: $module"); 120 i_run "$load_command $module", fail_ok => 1; 121 unless ( $? == 0 ) { 122 Rex::Logger::info( "Error loading Kernel Module: $module", "warn" ); 123 die("Error loading Kernel Module: $module"); 124 } 125 else { 126 Rex::Logger::debug("Kernel Module $module loaded."); 127 } 128 } 129 elsif ( $action eq "unload" ) { 130 Rex::Logger::debug("Unloading Kernel Module: $module"); 131 my $unload_command_str = $unload_command; 132 if ( ref($unload_command) eq "CODE" ) { 133 $unload_command_str = &$unload_command(); 134 } 135 136 i_run "$unload_command_str $module", fail_ok => 1; 137 unless ( $? == 0 ) { 138 Rex::Logger::info( "Error unloading Kernel Module: $module", "warn" ); 139 die("Error unloading Kernel Module: $module"); 140 } 141 else { 142 Rex::Logger::debug("Kernel Module $module unloaded."); 143 } 144 } 145 else { 146 Rex::Logger::info("Unknown action $action"); 147 die("Unknown action $action"); 148 } 149} 150 1511; 152