X-Git-Url: https://git.hcoop.net/hcoop/debian/openafs.git/blobdiff_plain/805e021f69f66af52e8de6f9e3614206f025d6a8..b7cfede04a4b54709c461d9bfd696eaee5964310:/debian/afs-rootvol diff --git a/debian/afs-rootvol b/debian/afs-rootvol new file mode 100755 index 0000000..9a8da2f --- /dev/null +++ b/debian/afs-rootvol @@ -0,0 +1,194 @@ +#!/usr/bin/perl -w +# Copyright (C) 2000 by Sam Hartman +# This file may be copied either under the terms of the GNU GPL or the IBM +# Public License either version 2 or later of the GPL or version 1.0 or later +# of the IPL. + +use strict; +use Debian::OpenAFS::ConfigUtils; +use Term::ReadLine; +use Getopt::Long; +use vars qw($rl $server $part $requirements_met); + +=head1 NAME + +afs-rootvol - Generate and populate root volumes for new AFS cells. + +=head1 SYNOPSIS + +B [B<--requirements-met>] [B<--server> I] +[B<--partition> I] + +=head1 DESCRIPTION + +This script sets up an AFS cell's root volumes. It assumes that you already +have a fileserver and database servers. The fileserver should have an empty +root.afs. This script creates root.cell, user, and service and populates +root.afs. + +=head1 AUTHOR + +Sam Hartman + +=cut +#'# cperl-mode + +# This subroutine creates a volume, mounts it and then sets the access +# to allow read by anyuser. The volume is scheduled for deletion in +# case of error. +sub mkvol($$) { + my ($vol, $mnt) = @_; + run("vos create $server $part $vol -localauth"); + unwind("vos remove $server $part $vol -localauth"); + run("fs mkm $mnt $vol "); + run("fs sa $mnt system:anyuser rl"); +} + +# Main script. Flush all output immediately. +$| = 1; +$rl = new Term::ReadLine('AFS'); +GetOptions ("requirements-met" => \$requirements_met, + "server=s" => \$server, + "partition=s" => \$part); +unless ($requirements_met) { + print <readline("Do you meet these conditions? (y/n) "); + unless (/^y/i ) { + print "Please restart the script when you meet these conditions.\n"; + exit(1); + } + if ($> != 0) { + die "This script should almost always be run as root. Use the\n" + . "--requirements-met option to run as non-root.\n"; + } +} + +# Get configuration information we need. +open(CELL, "/etc/openafs/server/ThisCell") + or die "Unable to find out what cell this machine serves: $!\n"; +my $cell = ; +close CELL; +chomp $cell; + +unless ($server) { + print <readline("What AFS Server should volumes be placed on? "); + die "Please select a server.\n" unless $server; +} +unless ($part) { + $part = $rl->readline("What partition? [a] "); + $part = "a" unless $part; +} +print "\n"; + +# Make sure the user has tokens. Forgetting to do this is a common error. +my $status = system("tokens | grep Expires > /dev/null"); +if ($status != 0) { + die "You appear to not have AFS tokens. Obtain tokens (with aklog,\n" + . "for example) and then run this script again.\n"; +} + +# Figure out where root.afs is. There are two possibilities: either we aren't +# running with dynroot, and root.afs is therefore accessible as /afs, or we +# are running with dynroot, in which case we have to create root.cell first +# and then mount root.afs under it. +# +# Always create root.cell first; we may need it if running with dynroot, and +# it doesn't hurt to do it now regardless. +my $rootmnt = "/afs"; +run("vos create $server $part root.cell -localauth"); +unwind("vos remove $server $part root.cell -localauth"); +my $dynroot = (-d "$rootmnt/$cell/."); +if ($dynroot) { + run("fs mkm /afs/$cell/.root.afs root.afs -rw"); + unwind("fs rmm /afs/$cell/.root.afs"); + $rootmnt = "/afs/$cell/.root.afs"; +} +run("fs sa $rootmnt system:anyuser rl"); + +# Scan CellServDB and create the cell mount points for every cell found there. +# Force these commands to succeed, since it's possible to end up with +# duplicate entries in CellServDB (and the second fs mkm will fail). +open(CELLSERVDB, "/etc/openafs/CellServDB") + or die "Unable to open /etc/openafs/CellServDB: $!\n"; +while () { + chomp; + if (/^>\s*([a-z0-9_\-.]+)/) { + run("fs mkm $rootmnt/$1 root.cell -cell $1 -fast || true"); + unwind("fs rmm $rootmnt/$1 || true"); + } +} + +# Now, create the read/write mount points for root.cell and root.afs and set +# root.cell system:anyuser read. +run("fs sa /afs/$cell system:anyuser rl"); +run("fs mkm $rootmnt/.$cell root.cell -cell $cell -rw"); +unwind("fs rmm $rootmnt/.$cell"); +run("fs mkm $rootmnt/.root.afs root.afs -rw"); +unwind("fs rmm $rootmnt/.root.afs"); + +# Create the user and service mount point volumes to fit the semi-standard AFS +# cell layout. +mkvol("user", "/afs/$cell/user"); +mkvol("service", "/afs/$cell/service"); + +# Strip the domain off of the cell name and create the short symlinks. +$cell =~ /^([^.]+)/; +my $cellpart = $1; +if ($cellpart && $cellpart ne $cell) { + run("ln -s $cell $rootmnt/$cellpart"); + unwind("rm $rootmnt/$cellpart"); + run("ln -s .$cell $rootmnt/.$cellpart"); + unwind("rm $rootmnt/.$cellpart"); +} +if ($dynroot) { + run("fs rmm /afs/$cell/.root.afs"); + unwind("fs mkm /afs/$cell/.root.afs root.afs -rw"); +} + +# Now, replicate the infrastructure volumes. +run("vos addsite $server $part root.afs -localauth"); +run("vos addsite $server $part root.cell -localauth"); +run("vos release root.afs -localauth"); +run("vos release root.cell -localauth"); +unwind("vos remove $server $part root.cell.readonly -localauth"); +unwind("vos remove $server $part root.afs.readonly -localauth"); + +# Success, so clear the unwind commands. +@unwinds = (); + +# If we fail before all the instances are created, we need to back out of +# everything we did as much as possible. +END { + if (@unwinds) { + print "\nRoot volume setup failed, ABORTING\n"; + } + run(pop @unwinds) while @unwinds; +}