2 # Copyright (C) 2000 by Sam Hartman
3 # This file may be copied either under the terms of the GNU GPL or the IBM
4 # Public License either version 2 or later of the GPL or version 1.0 or later
9 use Debian
::OpenAFS
::ConfigUtils
;
11 use Socket
qw(inet_ntoa);
12 use vars
qw($admin $server $requirements_met $shutdown_needed);
13 my $rl = new Term::ReadLine('afs-newcell');
15 # The default file server options are poor. Until they've been updated, use
16 # the following from Harald Barth; it should be an improvement for most
18 my $fs_options = '-p 23 -busyat 600 -rxpck 400 -s 1200 -l 1200 -cb 65535'
23 afs-newcell - Set up initial database server for AFS cell
27 B<afs-newcell> [B<--requirements-met>] [B<--admin> admin_user]
31 This script sets up the initial AFS database and configures the first
34 The B<--requirements-met> option specifies that the initial requirements have
35 been met and that the script can proceed without displaying the initial
36 banner or asking for confirmation.
38 The B<--admin> option specifies the name of the administrative user. This
39 user will be given system:administrators and susers permission in the cell.
43 Sam Hartman <hartmans@debian.org>
47 # Flush all output immediately.
50 GetOptions ("requirements-met" => \$requirements_met, "admin=s" => \$admin);
52 unless ($requirements_met) {
56 In order to set up a new AFS cell, you must meet the following:
58 1) You need a working Kerberos realm with Kerberos4 support. You
59 should install Heimdal with KTH Kerberos compatibility or MIT
62 2) You need to create the single-DES AFS key and load it into
63 /etc/openafs/server/KeyFile. If your cell's name is the same as
64 your Kerberos realm then create a principal called afs. Otherwise,
65 create a principal called afs/cellname in your realm. The cell
66 name should be all lower case, unlike Kerberos realms which are all
67 upper case. You can use asetkey from the openafs-krb5 package, or
68 if you used AFS3 salt to create the key, the bos addkey command.
70 3) This machine should have a filesystem mounted on /vicepa. If you
71 do not have a free partition, then create a large file by using dd
72 to extract bytes from /dev/zero. Create a filesystem on this file
73 and mount it using -oloop.
75 4) You will need an administrative principal created in a Kerberos
76 realm. This principal will be added to susers and
77 system:administrators and thus will be able to run administrative
78 commands. Generally the user is a root or admin instance of some
79 administrative user. For example if jruser is an administrator then
80 it would be reasonable to create jruser/admin (or jruser/root) and
81 specify that as the user to be added in this script.
83 5) The AFS client must not be running on this workstation. It will be
84 at the end of this script.
89 $_ = $rl->readline("Do you meet these requirements? [y/n] ");
91 print "Run this script again when you meet the requirements\n";
96 die "This script should almost always be run as root. Use the\n"
97 . "--requirements-met option to run as non-root.\n";
101 # Make sure the AFS client is not already running.
102 open(MOUNT
, "mount |") or die "Failed to run mount: $!\n";
105 print "The AFS client is currently running on this workstation.\n";
106 print "Please restart this script after running"
107 . " service openafs-client stop\n";
113 # Make sure there is a keyfile.
114 unless ( -f
"/etc/openafs/server/KeyFile") {
115 print "You do not have an AFS keyfile. Please create this using\n";
116 print "asetkey from openafs-krb5 or the bos addkey command\n";
120 # Stop the file server.
121 print "If the fileserver is not running, this may hang for 30 seconds.\n";
122 run
("service openafs-fileserver stop");
124 # Get the local hostname. Use the fully-qualified hostname to be safer.
125 $server = `hostname -f`;
127 my $ip = gethostbyname $server;
128 if (inet_ntoa
($ip) eq '127.0.0.1') {
130 print "Your hostname $server resolves to 127.0.0.1, which AFS cannot\n";
131 print "cope with. Make sure your hostname resolves to a non-loopback\n";
132 print "IP address. (Check /etc/hosts and make sure that your hostname\n";
133 print "isn't listed on the 127.0.0.1 line. If it is, removing it from\n";
134 print "that line will probably solve this problem.)\n";
138 # Determine the admin principal.
139 $admin = $rl->readline("What administrative principal should be used? ")
142 die "Please specify an administrative user\n" unless $admin;
143 my $afs_admin = $admin;
144 $afs_admin =~ s
:/:.:g
;
145 if ($afs_admin =~ /@/) {
146 die "The administrative user must be in the same realm as the cell and\n"
147 . "no realm may be specified.\n";
150 # Determine the local cell. This should be configured via debconf, from the
151 # openafs-client configuration, when openafs-fileserver is installed.
152 open(CELL
, "/etc/openafs/server/ThisCell")
153 or die "Cannot open /etc/openafs/server/ThisCell: $!\n";
157 # Make sure the new cell is configured in the client CellServDB.
158 open(CELLSERVDB
, "/etc/openafs/CellServDB")
159 or die "Cannot open /etc/openafs/CellServDB: $!\n";
161 while (<CELLSERVDB
>) {
162 next unless /^>\Q$cell\E\s/;
163 while (<CELLSERVDB
>) {
165 my ($dbserver) = split ' ';
166 if ($dbserver eq inet_ntoa
($ip)) {
175 print "The new cell $cell is not configured in /etc/openafs/CellServDB\n";
176 print "Add configuration like:\n\n";
178 print inet_ntoa
($ip), "\t\t\t#$server\n\n";
179 print "to that file before continuing.\n";
183 # Write out a new CellServDB for the local cell containing only this server.
184 if (-f
"/etc/openafs/server/CellServDB") {
185 print "/etc/openafs/server/CellServDB already exists, renaming to .old\n";
186 rename("/etc/openafs/server/CellServDB",
187 "/etc/openafs/server/CellServDB.old")
188 or die "Cannot rename /etc/openafs/server/CellServDB: $!\n";
190 open(CELLSERVDB
, "> /etc/openafs/server/CellServDB")
191 or die "Cannot create /etc/openafs/server/CellServDB: $!\n";
192 print CELLSERVDB
">$cell\n";
193 print CELLSERVDB inet_ntoa
($ip), "\t\t\t#$server\n";
194 close CELLSERVDB
or die "Cannot write to /etc/openafs/server/CellServDB: $!\n";
196 # Now, we should be able to start bos and add the admin user.
197 run
("service openafs-fileserver start");
198 $shutdown_needed = 1;
199 run
("bos adduser $server $afs_admin -localauth");
200 unwind
("bos removeuser $server $afs_admin -localauth");
202 # Create the initial protection database using pt_util. This is safer than
203 # the standard mechanism of starting the cell in noauth mode until the first
204 # user has been created.
205 if (-f
"/var/lib/openafs/db/prdb.DB0") {
206 warn "ERROR: Protection database already exists; cell already partially\n";
207 warn "ERROR: created. If you do not want the current database, remove\n";
208 warn "ERROR: all files in /var/lib/openafs/db and then run this program\n";
209 warn "ERROR: again.\n";
212 print "\nCreating initial protection database. This will print some errors\n";
213 print "about an id already existing and a bad ubik magic. These errors can\n";
214 print "be safely ignored.\n\n";
215 open(PRDB
, "| pt_util -p /var/lib/openafs/db/prdb.DB0 -w")
216 or die "Unable to start pt_util: $!\n";
217 print PRDB
"$afs_admin 128/20 1 -204 -204\n";
218 print PRDB
"system:administrators 130/20 -204 -204 -204\n";
219 print PRDB
" $afs_admin 1\n";
221 unwind
("rm /var/lib/openafs/db/prdb*");
224 # We should now be able to start ptserver and vlserver.
225 run
("bos create $server ptserver simple /usr/lib/openafs/ptserver -localauth");
226 unwind
("bos delete $server ptserver -localauth");
227 run
("bos create $server vlserver simple /usr/lib/openafs/vlserver -localauth");
228 unwind
("bos delete $server vlserver -localauth");
230 # Create a file server as well.
231 run
("bos create $server dafs dafs"
232 . " -cmd '/usr/lib/openafs/dafileserver $fs_options'"
233 . " -cmd /usr/lib/openafs/davolserver"
234 . " -cmd /usr/lib/openafs/salvageserver"
235 . " -cmd /usr/lib/openafs/dasalvager -localauth");
236 unwind
("bos delete $server dafs -localauth");
238 # Make sure that there is no scheduled general restart time; it's not needed.
239 run
("bos setrestart $server -time never -general -localauth");
241 # Pause for a while for ubik to catch up.
242 print "Waiting for database elections: ";
246 # Past this point we want to control when bos shutdown happens.
247 $shutdown_needed = 0;
248 unwind
("bos shutdown $server -localauth -wait");
249 run
("vos create $server a root.afs -localauth");
250 unwind
("vos remove $server a root.afs -localauth");
252 # We should now be able to bring up the client (it may need root.afs to exist
253 # if not using dynroot). We override whatever default cell was configured for
254 # the client, just in case it was pointing to some other cell.
255 open(THIS
, "> /etc/openafs/ThisCell")
256 or die "ERROR: Cannot create /etc/openafs/ThisCell: $!\n";
257 print THIS
"$cell\n";
258 close THIS
or die "ERROR: Cannot write to /etc/openafs/ThisCell: $!\n";
259 run
("service openafs-client force-start");
261 # Verify that AFS has managed to start.
263 open(MOUNT
, "mount |") or die "ERROR: Failed to run mount: $!\n";
269 unless ($afs_running) {
270 print "ERROR: The AFS client failed to start.\n";
271 print "ERROR: Please fix whatever problem kept it from running.\n";
275 print "Now, get tokens as $admin in the $cell cell.\n";
276 print "Then, run afs-rootvol.\n";
278 # Success, so clear the unwind commands.
281 # If we fail before all the instances are created, we need to back out of
282 # everything we did as much as possible.
284 if ($shutdown_needed || @unwinds) {
285 print "\nCell setup failed, ABORTING\n";
287 system("bos shutdown $server -localauth -wait") if $shutdown_needed;
288 run
(pop @unwinds) while @unwinds;