Can one find a mount point just knowing the volume name?
William Setzer
William_Setzer@ncsu.edu
08 Feb 2001 15:26:57 -0500
Here's a version of the "traverse cell looking for mount points" that
I wrote. It pretty much handles all the scary cases that have been
pointed out. It also uses the AFS module maintained by Norbert E
Gruener (http://www.Mpa-Garching.MPG.DE/~nog/) rather than forking fs
each time.
It outputs the information to a particularly named file, called
"mntpt-<cell>-<path>", and will read in any other similar files in
order to build the exclusion list of already-visited volumes. The
only place where it might be (Unix) OS specific is where I use the
mode flags to find out if it's a directory or not.
For other features, read the source; there's not that much. No
warranty expressed or implied. Void where prohibited by law.
William
8<-8<-8<-8<- Cut 8<-8<-8<-8<-
#!/ncsu/perl56/bin/perl
##
## Copyright (c) 2000 William Setzer
##
## You may distribute under the terms of either the Artistic License
## or the GNU General Public License, ie, the same terms as perl.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## Artistic License for more details.
#
#
# dump-mntpt-cell: generate a list of mount points along a path
#
# Usage: dump-mntpt-cell [-f] <mount point>
# where
# -f -- force (see below)
#
# This script walks the given path and dumps the list of mount points
# found to a file. Normally, it looks for other files generated by
# this script and preloads them so that AFS volumes aren't walked
# more than once. Also, the argument must be a mount point, so that
# all mount points will be found.
#
# When "force" is set via -f, this preloading is not done, and
# the script does not require the argument to be a mount point.
use AFS qw(lsmount whichcell);
## lsmount modifies its arg. bleh.
#
sub fs_lsmount { my $path = shift; lsmount $path, 0 }
sub fs_whichcell { my $path = shift; whichcell $path, 0 }
my $base = shift;
my $force;
if ($base eq '-f') {
$force++;
$base = shift;
}
die "Usage: $0 [-f] <mount point>\n" unless defined $base;
die "Usage: $0 [-f] <mount point>\n" if not $force and not fs_lsmount $base;
my $cell = fs_whichcell $base;
die "Can't find base cell: $AFS:CODE\n" if $AFS::CODE or $cell eq '';
my %mnt = { "$cell:root.afs" => 1};
unless ($force) {
opendir DIR, "." or die "Can't opendir .: $!\n";
while (1) {
my $entry = readdir DIR;
last unless defined $entry;
next unless $entry =~ /^mntpt-$cell/;
open IN, $entry or die "Can't open $entry: $!\n";
while (<IN>) {
next unless /^[\#%](?:(\S+):)?(\S+)\s/;
my $pcell = $1 || $cell;
$mnt{"$pcell:$2"}++;
}
close IN;
}
close DIR;
}
my @path = ( $base );
$base =~ s!/afs/!!;
$base =~ s!^/*!!;
$base =~ s!/*$!!;
$base =~ s!/+!-!g;
open OUT, ">> mntpt-$base" or die "Can't open mntpt-$base: $!\n";
open ERR, ">> err-$base" or die "Can't open err-$base: $!\n";
select OUT; $| = 1;
select ERR; $| = 1;
while (1) {
my $path = pop @path;
last unless defined $path;
print STDOUT $path, "\n";
my $mount = fs_lsmount $path;
if ($AFS::CODE and $AFS::CODE != 22) {
print ERR "lsmount $path: $AFS::CODE\n";
next;
}
if ($mount) {
print OUT $mount, " " x (40 - length $mount), $path, "\n";
my $mcell = fs_whichcell $path;
if ($AFS::CODE) {
print ERR "whichcell $path: $AFS::CODE\n";
next;
}
next if $mcell ne $cell;
$mount =~ s/^[#%]//;
$mount =~ s/^\S+://;
next if $mnt{"$mcell:$mount"}++;
next if $mount =~ /\.readonly$/;
next if $mount =~ /\.backup$/;
}
opendir DIR, $path or print ERR "$path: $!\n" and next;
while (1) {
my $entry = readdir DIR;
last unless defined $entry;
next if $entry eq '.';
next if $entry eq '..';
my $new = "$path/$entry";
my $mode = (lstat $new)[2] or print ERR "$new: $!\n";
next unless ($mode & 0170000) == 040000;
push @path, $new;
}
closedir DIR;
## Be nice to the filesystem
#
select undef, undef, undef, 0.25;
}
close ERR;
close OUT;