#!/usr/bin/perl # デバイスモジュール挿入マネージャ # insdev (-m ooo or --mode=mode) module.o /dev/dev1 /dev/dev2 /dev/devx=x ... if($#ARGV<0) { print STDERR "insdev: insmod+device management\n\n"; print STDERR "usage:\n"; print STDERR " insdev (option) modulename device_file_list\n"; print STDERR " option: -m ooo, --mode=mode default:666(all rw)\n"; print STDERR " -b blockdevice default:char_device\n"; print STDERR " --major=major default:autoselect\n"; print STDERR " +var=value parameter to module\n"; print STDERR " d_f_list: list of device file of minor=0,1,2...\n"; print STDERR " df=%d : assign minor %d file df\n"; exit(1); } $module=''; $devmode='666'; $devtype='c'; $devminor=0; while($arg = shift){ # argv 順番に if($arg eq '-m') { $devmode=shift; next; } if($arg=~/--mode=(\d+)/) { $devmode=$1; next; } if($arg=~/--major=(\d+)/) { $devmajor=$1; next; } if($arg eq '-b') { $devtype='b'; next; } if($arg=~/\+(.+=.+)/) { $modparam[$#modparam+1]=' '.$1; next; } if($module eq '') { $module=$arg; next; } if($arg=~/(.+)=(\d+)/){ $devminor=$2; $arg=$1; } $nodlist[$devminor]=$arg; $devminor++; } if($#modparam>=0) { print STDERR "arguments to module '$module': @modparam\n"; } if($devmajor eq ''){ # リザーブドをうめる /usr/src/linux/Documentation/devices.txt(2.2.13) for($i=0;$i<256;$i++) { $cdev[$i]='r'; $bdev[$i]='r'; } for($i=60;$i<64;$i++) { $cdev[$i]=''; $bdev[$i]=''; } # experimental用 for($i=120;$i<128;$i++) { $cdev[$i]=''; $bdev[$i]=''; } # experimental用 for($i=240;$i<255;$i++) { $cdev[$i]=''; $bdev[$i]=''; } # experimental用 # すでに使用しているデバイスを探す open(F,"/proc/devices"); $mode='C'; while(){ if(/Character/){ $mode='C'; }; if(/Block/) { $mode='B'; }; if(/(\d+)\s+(.+)/){ if($mode eq 'C') { $cdev[$1]=$2; } if($mode eq 'B') { $bdev[$1]=$2; } } } close(F); if($devtype eq 'b') { for($i=0;$i<256;$i++){ if($bdev[$i] eq '') { $devmajor=$i; last; } } } else { for($i=0;$i<256;$i++){ if($cdev[$i] eq '') { $devmajor=$i; last; } } } if($devmajor eq ''){ print STDERR "device major auto-selector failed\n"; exit(1); } print STDERR "auto-selected "; } print STDERR "devcie major($devtype)=$devmajor\n"; # モジュールインストール system("insmod $module devmajor=$devmajor@modparam"); if($? != 0){ print STDERR "insmod failed\n"; exit(1); } # デバイスファイル管理テーブル open(F,"/tmp/insdev.tab"); @devtab=; close(F); # ノード作成 for($i=0;$i<256;$i++){ $nod=$nodlist[$i]; if($nod eq '') { next; } print "device $devmajor:$i: $nod\n"; if(-e $nod) { print STDERR "device file '$nod' already exists. delete?"; $ans=; if($ans=~/[yY]/) { unlink($nod); if(-e $nod) { print STDERR "cannot remove '$nod'\n"; next; } } else {next; } } system("mknod -m $devmode $nod $devtype $devmajor $i"); if($? ne '0'){ print STDERR "error occured in making device file '$nod'\n"; next; } # 登録 for($j=0;$j<$#devtab+1;$j++){ if($devtab[$j]=~/(\S+) (\S+)/){ if($2 eq $nod) { $devtab[$j]="$module $nod\n"; last; } } } if($j == $#devtab+1){ $devtab[$j]="$module $nod\n"; } } open(F,"> /tmp/insdev.tab"); print F @devtab; close(F); #print STDERR @devtab;