#!/usr/local//bin/perl -wT use strict; use Getopt::Long; sub give_warning($) { my $ans = shift; if ($ans ) { return; } #--yes option given print <; chop $ans; $ans = lc $ans; if ( $ans ne 'yes' ) { die "Exitting at user request (type 'yes' to not exit)\n"; } print "\n"; } sub usage() { print STDERR < $src already exists\n" if ($verbose); return; } else { if ( ! $force ) { print "$dest is symlink but not to $src\n"; print "$dest points to $src2\n"; print "Replace it[n]?"; my $ans = <>; chop $ans; $ans=lc $ans; if ( $ans !~ /^\s*y(es)?\s*$/ ) { print "Leaving $dest as is\n"; return; } } $forceit=1; } } else { if ( ! $force ) { print "$dest exists, and is not a symlink\n"; print "Replace it[n]?"; my $ans = <>; chop $ans; $ans=lc $ans; if ( $ans !~ /^\s*y(es)?\s*$/ ) { print "Leaving $dest as is\n"; return; } } $forceit = 1; } } if ( $forceit ) { print "Deleting $dest prior to making symlink\n" if ($debug); unlink $dest unless $test; } if (! $test ) { symlink $src,$dest or die "Unable to symlink $src<- $dest"; } print "Made symlink from $src to $dest\n" if ($debug); } my %uid_hash=(); my %gid_hash = (); sub get_uid($) { my $user = shift; if ( exists $uid_hash{$user} ) { return $uid_hash{$user}; }; my $uid = getpwnam $user; if ( ! defined $uid ) { die "Cannot get uid for $user\n"; } $uid_hash{$user} = $uid; return $uid; } sub get_gid($) { my $user = shift; if ( exists $gid_hash{$user} ) { return $gid_hash{$user}; }; my $gid = getgrnam $user; if ( ! defined $gid ) { die "Cannot get gid for $user\n"; } $gid_hash{$user} = $gid; return $gid; } sub get_majorminor($) #Takes filename as argument. If not a block or char device, returns false. #If is, returns (type,major,minor,uid,gid,mode) { my $file = shift; my $type; if ( -b $file ) { $type='b'; } elsif ( -c $file ) { $type='c'; } else { return (); } my ($major, $minor); my @stat = stat $file; my $rdev = $stat[6]; my $uid = $stat[4]; my $gid = $stat[5]; my $mode = $stat[2]; # #Dec Tru64 4.0d specific # $major = ($rdev>>20)&07777; # $minor = ($rdev&03777777); #Sun4u sparc SUNW 5.7 specific $major = ($rdev>>18)&0x3fff; $minor = ($rdev&0x3ffff); return ($type,$major,$minor,$uid,$gid,$mode); } sub make_device($$$$$$$;$$$$) { my $dev = shift; my $type = shift; my $major = shift; my $minor = shift; my $owner = shift; my $group = shift; my $origmode = shift; my $test = shift || 0; my $force = shift || 0; my $verbose = shift || 0; my $debug = shift || 0; #Convert from octal to decimal my $mode = oct $origmode; print < uid $uid\ngroup $group => gid $gid\n" if ( $debug ); my $forceit =0; if ( -e $dev ) { print "$dev exists\n" if ($debug); my @tmp = get_majorminor($dev); if ( @tmp ) { #A device file my ($typ2,$maj2,$min2,$uid2,$gid2,$mod2) = @tmp; $mod2 &=0777; if ( ($type eq $typ2) && ( $major == $maj2 ) && ( $minor == $min2 ) && ( $uid == $uid2 ) && ( $gid == $gid2 ) && ( $mode == $mod2 ) ) { print "$dev already exists as desired\n" if ($verbose); return; } else { if ( ! $force ) { print <; chop $ans; $ans=lc $ans; if ( $ans !~ /^\s*y(es)?\s*$/ ) { print "Leaving $dev as is\n"; return; } } $forceit = 1; } } else { #Not a device file if ( ! $force ) { print "$dev exists as a non-special file\n"; print "Replace it[n]?"; my $ans = <>; chop $ans; $ans=lc $ans; if ( $ans !~ /^\s*y(es)?\s*$/ ) { print "Leaving $dev as is\n"; return; } } $forceit=1; } } if ( $forceit ) { print "Deleting $dev prior to making device\n" if ($debug); unlink $dev unless $test; } my $mknod = "/usr/sbin/mknod"; if( ! $test ) { my $rc = 0xffff & system($mknod,$dev,$type,$major,$minor); if ($rc) { die "Unable to mnod $dev, exit code is $rc, error $!"; } } print "Made special file $dev ($type $major $minor)\n" if ($debug); if( ! $test ) { chown $uid, $gid, $dev or die "Unable to chown $dev to $uid,$gid"; } print "Chowned $dev to $owner ($uid) and $group ($gid)\n" if ($debug); #Modes corresponding to block and char specials my $Bmode = 060000; my $Cmode = 020000; my $newmode = $mode; if ( $type eq 'b' ) { $newmode |= $Bmode; } elsif ( $type eq 'c' ) { $newmode |= $Cmode; } else { die "Illegal type $type"; } if( ! $test ) { chmod $newmode, $dev or die "Can't chmod $dev to $newmode"; } printf "Chmoded %s to %06o\n", $dev, $newmode if ($debug); } sub make_directory($$$$;$$$$) { my $dir = shift; my $owner = shift; my $group = shift; my $origmode = shift; my $test = shift || 0; my $force = shift || 0; my $verbose = shift || 0; my $debug = shift || 0; #Convert from octal to decimal my $mode = oct $origmode; print < uid $uid\ngroup $group => gid $gid\n" if ( $debug ); my $forceit =0; if ( -e $dir ) { print "$dir already exists\n" if ($debug); if (-d $dir ) { print "dir $dir already exists, didn't check perms" if ($verbose); return; } else { if ( ! $force ) { print "A non-directory exists at $dir, we expected a directory\n"; print "Replace it[n]?"; my $ans = <>; chop $ans; $ans=lc $ans; if ( $ans !~ /^\s*y(es)?\s*$/ ) { print "Leaving $dir as is\n"; return; } } $forceit=1; } } if ( $forceit ) { print "Deleting $dir prior to making directory\n" if ($debug); unlink $dir unless $test; } if (! $test ) { mkdir $dir,$mode or die "Unable to mdir $dir: $!"; } print "Created directory $dir with mode $origmode\n" if ($debug); if( ! $test ) { chown $uid, $gid, $dir or die "Unable to chown $dir to $uid,$gid"; } print "Chowned $dir to $owner ($uid) and $group ($gid)\n" if ($debug); } #----------- Main script ------------------- my $FORCE=0; my $helpflag= 0; my $VERBOSE=0; my $DEBUG=0; my $PROCEED=0; my $TEST=0; &GetOptions( "force|f!" => \$FORCE, "help|h" => \$helpflag, "verbose|v!" => \$VERBOSE, "debug|d!" => \$DEBUG, "yes|y!" =>\$PROCEED, "test|t!" => \$TEST, ); if ( $helpflag ) { usage(); exit 0; } if ( scalar(@ARGV) ) { usage(); die "Unknown arguments :", @ARGV; } if ( $DEBUG ) { $VERBOSE=1; } give_warning($PROCEED); #Make directories my ($dir,$owner,$group,$mode); #Common $owner="root"; $group="daemon"; $mode="755"; $dir = "/dev/md/shared"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/1"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/1/dsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/1/rdsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/2"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/2/dsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/2/rdsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/3"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/3/dsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); $dir="/dev/md/shared/3/rdsk"; print "Making $dir\n" if ($DEBUG); make_directory($dir,$owner,$group,$mode,$TEST,$FORCE,$VERBOSE,$DEBUG); #Make links my ($src,$dest); $dest = "/dev/md/admin"; $src = "../../devices/pseudo/md\@0:admin"; print "Making $dest\n" if ($DEBUG); make_symlink($src,$dest,$TEST,$FORCE,$VERBOSE,$DEBUG); my ($i,$j); for ($i=0; $i<128; $i++) { $src = "../../../devices/pseudo/md\@0:0,$i,blk"; $dest = "/dev/md/dsk/d$i"; print "Making $dest\n" if ($DEBUG); make_symlink($src,$dest,$TEST,$FORCE,$VERBOSE,$DEBUG); } for ($i=0; $i<128; $i++) { $src = "../../../devices/pseudo/md\@0:0,$i,raw"; $dest = "/dev/md/rdsk/d$i"; print "Making $dest\n" if ($DEBUG); make_symlink($src,$dest,$TEST,$FORCE,$VERBOSE,$DEBUG); } for ($j=1; $j<4; $j++) { for ($i=0; $i<128; $i++) { $src = "../../../../../devices/pseudo/md\@0:$j,$i,blk"; $dest = "/dev/md/shared/$j/dsk/d$i"; print "Making $dest\n" if ($DEBUG); make_symlink($src,$dest,$TEST,$FORCE,$VERBOSE,$DEBUG); } } for ($j=1; $j<4; $j++) { for ($i=0; $i<128; $i++) { $src = "../../../../../devices/pseudo/md\@0:$j,$i,raw"; $dest = "/dev/md/shared/$j/rdsk/d$i"; print "Making $dest\n" if ($DEBUG); make_symlink($src,$dest,$TEST,$FORCE,$VERBOSE,$DEBUG); } } #Make devices my ($dev,$type,$major,$minor); $dev="/devices/pseudo/md\@0:admin"; $type="c"; $major=85; $minor=262143; $owner="root"; $group="kmem"; $mode="0644"; #ignore leading c/b make_device($dev,$type,$major,$minor,$owner,$group,$mode, $TEST,$FORCE,$VERBOSE,$DEBUG); for ($j=0; $j<4; $j++) { for ($i=0; $i<128; $i++) { $dev="/devices/pseudo/md\@0:$j,$i,blk"; $type='b'; $major=85; $minor=8192*$j + $i; $owner="root"; $group="kmem"; $mode="0640"; print "Making $dev ($type $major $minor)\n" if ($DEBUG); make_device($dev,$type,$major,$minor,$owner,$group,$mode, $TEST,$FORCE,$VERBOSE,$DEBUG); } } for ($j=0; $j<4; $j++) { for ($i=0; $i<128; $i++) { $dev="/devices/pseudo/md\@0:$j,$i,raw"; $type='c'; $major=85; $minor=8192*$j + $i; $owner="root"; $group="kmem"; $mode="0640"; print "Making $dev ($type $major $minor)\n" if ($DEBUG); make_device($dev,$type,$major,$minor,$owner,$group,$mode, $TEST,$FORCE,$VERBOSE,$DEBUG); } }