[OpenAFS] generating a listing of Mount points

William Setzer William_Setzer@ncsu.edu
12 Mar 2002 10:31:10 -0500


"David R Boldt" <dboldt@usgs.gov> writes:
:
: Does anyone have a program that they are willing to share
: which will generate a listing of AFS mount points (from Salvager
: output)?

Well, not from salvager output, but I wrote a perl script a while
back to walk a directory tree.  It uses the AFS perl module for
two calls: lsmount and whichcell.  If you don't have or can't find
the module, the functions are wrapped for convenient hacking.

It also might have an OS specific piece near the bottom that needs to
be modified (the bit about "($mode & 0170000) == 040000", which gives
me only directories), and the sleep between directory walks is
hard-coded and may need to be changed to taste.  It assumes that the
volume mounted at /afs is named "root.afs".  And of course buyer
beware, all sales are final, no warrantee expressed or implied, etc.

But here ya go.


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.
#
#
#  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;

    select undef, undef, undef, 0.25;

}
close ERR;
close OUT;