#!/usr/bin/perl use strict; use File::Find; my %depend = (); my %depend2 = (); my %rmlist = (); my @nodep; my @modlist; my @allmodules; my %reqmodules; my %loaded = (); my $i=0; # Device debug parameters # Module name Debug option my %debug = ( "tuner" => "tuner_debug=1", "dvb-core" => "cam_debug=1", "dvb-ttpci" => "debug=247", "b2c2-flexcop" => "debug=0x01", "b2c2-flexcop-usb" => "debug=0x01", "b2c2-flexcop-pci" => "debug=0x01", "dvb-usb" => "debug=0x33", "dvb-usb-gp8psk" => "debug=0x03", "dvb-usb-vp7045" => "debug=0x03", "dvb-usb-dtt200u" => "debug=0x03", "dvb-usb-dibusb-common" => "debug=0x03", ); sub parse_dir { my $file = $File::Find::name; if (!($file =~ /[.]ko$/)) { return; } my $module = $file; $module =~ s|^[./]*(.*)[.]ko|\1|; open IN, "modinfo $file|grep depends|cut -b 17-|"; while () { my $deps = $_; $deps =~ s/\n//; $deps =~ s/[,]/ /g; $deps = " $deps "; $depend{$module} = $deps; push @allmodules, $module; $i++; } close IN; } sub parse_loaded { open IN, "/proc/modules"; while () { m/^([\w\d_-]+)/; $loaded{$1}=1; } close IN; } sub cleandep() { my $dep; while ( my ($k, $v) = each(%depend) ) { my $arg=$v; my $arg2=" "; while (!($arg =~ m/^\s*$/)) { if ($arg =~ m/^ ([^ ]+) /) { my $val=$1; if (exists($depend{$val})) { $arg2="$arg2 $val "; } else { $reqmodules{$val}=1; } } $arg =~ s/^ [^ ]+//; $arg2 =~ s/\s\s+/ /; } $depend2 { $k } = $arg2; } } sub rmdep() { my $dep; while ($dep=pop @nodep) { while ( my ($k, $v) = each(%depend2) ) { if ($v =~ m/\s($dep)\s/) { $v =~ s/\s${dep}\s/ /; $v =~ s/\s${dep}\s/ /; $v =~ s/\s${dep}\s/ /; $depend2 {$k} = $v; } } } } sub orderdep () { my $old; do { $old=$i; while ( my ($key, $value) = each(%depend2) ) { if ($value =~ m/^\s*$/) { push @nodep, $key; push @modlist, $key; $i=$i-1; delete $depend2 {$key}; } } rmdep(); } until ($old==$i); while ( my ($key, $value) = each(%depend2) ) { printf "ERROR: bad dependencies - $key ($value)\n"; } } sub insmod ($) { my $debug=shift; while ( my ($key, $value) = each(%reqmodules) ) { printf ("modprobe $key\n"); system ("modprobe $key"); } foreach my $key (@modlist) { if ($debug) { my $dbg=$debug{$key}; printf "insmod ./$key.ko $dbg\n"; system "insmod ./$key.ko $dbg\n"; } else { printf "insmod ./$key.ko\n"; system "insmod ./$key.ko\n"; } } } sub rmmod () { my $cmd="rmmod"; while (my $key=pop @modlist) { my $dep=$key; $dep=~s/[\-]/_/g; if (exists ($loaded{$dep})) { printf "$cmd ./$key.ko\n"; system "$cmd ./$key.ko\n"; } } } sub prepare_cmd() { find(\&parse_dir, "."); printf "found $i modules\n"; cleandep(); orderdep(); } # main my $mode=shift; if ($mode eq "load") { prepare_cmd; insmod(0); } else { if ($mode eq "unload") { prepare_cmd; parse_loaded; rmmod; } else { if ($mode eq "reload") { prepare_cmd; parse_loaded; my @modlist2=@modlist; rmmod; @modlist=@modlist2; insmod(0); } else { if ($mode eq "debug") { prepare_cmd; parse_loaded; insmod(1); } else { printf "Usage: $0 [load|unload|reload]\n"; } } } }