Index: arlad/Makefile.in =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/Makefile.in,v retrieving revision 1.83.2.3 diff -u -r1.83.2.3 Makefile.in --- arlad/Makefile.in 2001/05/28 23:22:46 1.83.2.3 +++ arlad/Makefile.in 2001/07/02 03:43:20 @@ -87,6 +87,7 @@ arla-cli.c \ arladeb.c \ arladebu.c \ + cellcache.c \ cmcb.c \ conn.c \ cred.c \ @@ -109,6 +110,7 @@ afs_dir.h \ arla_local.h \ arladeb.h \ + cellcache.h \ cmcb.h \ conn.h \ cred.h \ @@ -132,6 +134,7 @@ arla.o \ arladeb.o \ arladebu.o \ + cellcache.o \ cmcb.o \ conn.o \ cred.o \ Index: arlad/arla.c =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/arla.c,v retrieving revision 1.135.2.1 diff -u -r1.135.2.1 arla.c --- arlad/arla.c 2001/04/30 00:00:34 1.135.2.1 +++ arlad/arla.c 2001/07/02 20:30:35 @@ -61,6 +61,7 @@ fcache_store_state (); volcache_store_state (); cm_store_state (); + cellcache_store_state (); } struct conf_param { @@ -202,7 +203,7 @@ int cpu_usage; int version_flag; int help_flag; -int recover = 0; +int recover = 1; int dynroot_enable = 0; int cm_consistency = 0; @@ -344,7 +345,10 @@ arla_warnx (ADEBINIT, "conn_init numconns = %u", numconns); conn_init (numconns); arla_warnx (ADEBINIT, "cellcache"); - cell_init (0, arla_log_method); + if (cell_init_malloc (0, arla_log_method) >= 0){ + cellcache_init (); + cell_init_fill (); + } arla_warnx (ADEBINIT, "fprio"); fprio_init(fpriofile); arla_warnx (ADEBINIT, "volcache numvols = %u", numvols); Index: arlad/arla_local.h =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/arla_local.h,v retrieving revision 1.61.2.1 diff -u -r1.61.2.1 arla_local.h --- arlad/arla_local.h 2001/04/30 00:00:54 1.61.2.1 +++ arlad/arla_local.h 2001/07/02 03:42:11 @@ -122,6 +122,7 @@ #include "ports.h" #include "conn.h" #include "fcache.h" +#include "cellcache.h" #include "inter.h" #include "cred.h" #include "adir.h" Index: arlad/cellcache.c =================================================================== RCS file: cellcache.c diff -N cellcache.c --- /dev/null Tue May 5 22:32:27 1998 +++ cellcache.c Mon Jul 2 22:27:27 2001 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include "arla_local.h" + +RCSID("$Id: $") ; + +static int +cache_store_state(int fd, cell_entry *ce){ + int len; + char *linefeed="\n"; + int error; + + len=strlen(ce->name); + error = write(fd, ce->name, len); + if (error < 0) + return errno; + if (error != len) + return ENOSPC; + error = write(fd, linefeed, 1); + if (error < 0) + return errno; + if (error != 1) + return ENOSPC; + return 0; +} + +int +cellcache_store_state(){ + int32_t cellnum; + cell_entry *ce; + int fd; + int bignumber = 10000; + int error; + + fd = open ("cellcache.new", O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) + return errno; + /* Cells start at 1 to some big number */ + for (cellnum = 1; cellnum < bignumber; cellnum++){ + ce = cell_get_by_id(cellnum); + if (ce == NULL) + break; + if ((error = cache_store_state(fd, ce)) != 0){ + close(fd); + unlink("cellcache.new"); + return error; + } + } + assert(cellnum < bignumber); + close(fd); + if (rename ("cellcache.new", "cellcache")) + return errno; + return 0; +} + +static int +cellcache_recover_state(){ + FILE *f; + char s[1024]; + + f = fopen ("cellcache", "r"); + if (f == NULL) + return errno; + while (fgets(s, 1024, f)) { + if (isspace(s[strlen(s) - 1])) + s[strlen(s) - 1] = 0; + cell_new(s); + } + fclose(f); + return 0; +} + +void +cellcache_init(){ + if (recover) + cellcache_recover_state(); +} Index: arlad/cellcache.h =================================================================== RCS file: cellcache.h diff -N cellcache.h --- /dev/null Tue May 5 22:32:27 1998 +++ cellcache.h Mon Jul 2 20:39:40 2001 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1995-2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * The interface for the cell-cache. + */ + +/* $Id: $ */ + +#ifndef _CELLCACHE_H_ +#define _CELLCACHE_H_ + +#include + +int +cellcache_store_state (void); +void +cellcache_init(void); + +#endif /* _CELLCACHE_H_ */ Index: arlad/dynroot.c =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/dynroot.c,v retrieving revision 1.13.2.2 diff -u -r1.13.2.2 dynroot.c --- arlad/dynroot.c 2001/05/28 15:19:20 1.13.2.2 +++ arlad/dynroot.c 2001/06/23 08:57:38 @@ -53,7 +53,6 @@ static int32_t dynrootcell = 0; /* this is the dynroocell */ static Bool dynroot_enable = 0; /* is dynroot enabled ? */ -static unsigned long last_celldb_version = 0; /* last version of celldb */ /* * Magic glue wrt afsvnode# @@ -81,6 +80,10 @@ { struct create_entry *entry = (struct create_entry *) arg; int ret; + + /* dynroot itself should not be visible as an entry in /afs */ + if (cell->id == DYNROOT_CELLID) + return 0; if (!cell_dynroot(cell)) return 0; @@ -256,12 +259,16 @@ int ret, fd, rootnode; size_t len; fbuf dir; + static unsigned long last_celldb_version = 0; /* last version of celldb */ + unsigned long l; rootnode = entry->fid.fid.Vnode == DYNROOT_ROOTDIR ? 1 : 0; + l = last_celldb_version; + last_celldb_version = cell_get_version(); if (entry->flags.attrp && entry->flags.datap && - (!rootnode || last_celldb_version == cell_get_version())) + (!rootnode || last_celldb_version == l)) return 0; fd = fcache_open_file (entry, O_RDWR); @@ -347,6 +354,24 @@ } /* + * returns TRUE if `entry' is _the_ top dynroot entry (/afs) + */ + +Bool +dynroot_is_top_dynrootp (FCacheEntry *entry) +{ + assert (entry); + + if (dynroot_enable && + entry->fid.Cell == dynrootcell && + entry->fid.fid.Volume == DYNROOT_ROOTVOLUME && + entry->fid.fid.Vnode == DYNROOT_ROOTDIR) + return TRUE; + + return FALSE; +} + +/* * Return what status the dynroot is in. */ @@ -384,4 +409,26 @@ int32_t dynroot_volumeid (void) { return DYNROOT_ROOTVOLUME; +} + +/* + * Create an entry for a new cell in the root dynamically + * on the fly + */ + +int +dynroot_create_entry_dynamically (const char *cellname, + FCacheEntry *entry, + CredCacheEntry *ce) +{ + if (cell_add_dynroot(cellname)) + return ENOENT; + + dynroot_get_node(entry, ce); + break_callback(entry); + /* Turn some of the flags recently set in dynroot_get_node off again */ + entry->tokens &= ~(XFS_DATA_R|XFS_DATA_W); + entry->flags.datap = FALSE; + + return 0; } Index: arlad/dynroot.h =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/dynroot.h,v retrieving revision 1.2.2.1 diff -u -r1.2.2.1 dynroot.h --- arlad/dynroot.h 2001/05/28 15:19:20 1.2.2.1 +++ arlad/dynroot.h 2001/06/17 18:34:17 @@ -37,6 +37,10 @@ #define DYNROOT_DEFAULT 0 +int dynroot_create_entry_dynamically (const char *cellname, + FCacheEntry *cacheentry, + CredCacheEntry *ce); + int dynroot_fetch_vldbN (nvldbentry *entry); Bool dynroot_isvolumep (int cell, const char *volume); @@ -47,6 +51,8 @@ Bool dynroot_is_dynrootp (FCacheEntry *entry); +Bool dynroot_is_top_dynrootp (FCacheEntry *entry); + Bool dynroot_enablep (void); Bool dynroot_setenable (Bool enable); @@ -54,3 +60,4 @@ int32_t dynroot_cellid (void); int32_t dynroot_volumeid (void); + Index: arlad/inter.c =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/inter.c,v retrieving revision 1.110.2.3 diff -u -r1.110.2.3 inter.c --- arlad/inter.c 2001/06/05 01:27:05 1.110.2.3 +++ arlad/inter.c 2001/06/17 18:41:49 @@ -599,6 +599,12 @@ } error = adir_lookup (entry, name, res); + if (error == ENOENT && dynroot_is_top_dynrootp (entry)) { + arla_warnx(ADEBCM, "cm_lookup(): Creating dynamic entry for %s", name); + error = dynroot_create_entry_dynamically(name, entry, *ce); + if (!error) + error = adir_lookup (entry, name, res); + } if (error) { fcache_release(entry); ret.res = -1; Index: arlad/volcache.c =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/volcache.c,v retrieving revision 1.95.2.4 diff -u -r1.95.2.4 volcache.c --- arlad/volcache.c 2001/03/04 05:11:19 1.95.2.4 +++ arlad/volcache.c 2001/06/17 17:28:29 @@ -588,7 +588,11 @@ "Cannot find any db servers in cell %d(%s) while " "getting data for volume `%s'", cell, cell_num2name(cell), name); - assert (cell_is_sanep (cell)); + /* haba: cellnums cached in xfs */ + /* Instead of asserting on cell existence, try to recycle */ + /* the entry and let that code assert if that is not possible */ + recycle_entry(e); + /* assert (cell_is_sanep (cell)); */ return ENOENT; } Index: lib/ko/ko.h =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/lib/ko/ko.h,v retrieving revision 1.27.2.2 diff -u -r1.27.2.2 ko.h --- lib/ko/ko.h 2001/05/06 22:40:49 1.27.2.2 +++ lib/ko/ko.h 2001/07/02 19:37:44 @@ -67,11 +67,14 @@ time_t timeout; /* timeout of address */ } cell_db_entry; +/* + * Flags used in cell_entry + */ + enum { SUID_CELL = 0x1, /* if this is a suid cell */ DYNROOT_CELL = 0x2 /* cell should show up in dynroot */ }; - typedef struct { int32_t id; /* Cell-ID */ const char *name; /* Domain-style name */ @@ -83,7 +86,16 @@ time_t timeout; /* when this entry expire */ } cell_entry; +/* + * The magic cell id for the dynroot cell + * (normal cells are numbered from 1) + */ + +#define DYNROOT_CELLID 0 + void cell_init (int cellcachesize, Log_method *log); +int cell_init_malloc (int cellcachesize, Log_method *log); +void cell_init_fill (void); const cell_db_entry *cell_dbservers_by_id (int32_t cell, int *); @@ -96,6 +108,7 @@ cell_entry *cell_get_by_id (int32_t cell); cell_entry *cell_new (const char *name); cell_entry *cell_new_dynamic (const char *name); +int cell_add_dynroot(const char *cellname); Bool cell_dynroot (const cell_entry *c); Bool cell_issuid (const cell_entry *c); Bool cell_issuid_by_num (int32_t cell); Index: lib/ko/kocell.c =================================================================== RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/lib/ko/kocell.c,v retrieving revision 1.47.2.2 diff -u -r1.47.2.2 kocell.c --- lib/ko/kocell.c 2001/05/06 22:40:50 1.47.2.2 +++ lib/ko/kocell.c 2001/07/02 20:12:55 @@ -160,7 +160,8 @@ len = strcspn (line, " \t#"); line[len] = '\0'; - c = cell_new (line); + if ((c = cell_get_by_name(line)) == NULL) + c = cell_new (line); if (c == NULL) err (1, "malloc failed"); @@ -263,6 +264,19 @@ } /* + * cell name -> cell_entry * (hashtable only) + */ + +static cell_entry * +get_hash_by_name (const char *cellname) +{ + cell_entry key; + + key.name = cellname; + return (cell_entry *)hashtabsearch (cellnamehtab, &key); +} + +/* * try to lookup `cell' in DNS * if c == NULL, a new cell will be allocated */ @@ -277,6 +291,8 @@ int lowest_ttl; int i; struct timeval tv; + char *answerdomain = NULL; + int ret = 0; memset (dbservers, 0, sizeof(dbservers)); gettimeofday(&tv, NULL); @@ -287,13 +303,19 @@ "dns_lookup_cell: failed to resolve cell %s", cell); return 1; } - if (c == NULL) - c = cell_new_dynamic (cell); for(rr = r->head; rr;rr=rr->next){ if(rr->type == T_AFSDB) { struct mx_record *mx = (struct mx_record*)rr->u.data; - + assert(rr->domain); /* rr filled in as expected? */ + if (answerdomain == NULL) + answerdomain = rr->domain; + if (ret == 0 && strcmp(cell, rr->domain) != 0) { + log_log (cell_log, CDEBDNS, + "dns_lookup_cell: asked for %s got back domain %s", + cell, rr->domain); + ret = 1; + } if (mx->preference != 1) { break; } @@ -320,12 +342,20 @@ } } } + + if (c == NULL && answerdomain != NULL) { + if ((c = get_hash_by_name (answerdomain)) == NULL) + c = cell_new_dynamic (answerdomain); + } dns_free_data(r); + if (c == NULL) + return 1; /* catch the hosts that didn't fit in additional rr */ - c->timeout = lowest_ttl + tv.tv_sec; + if (c->timeout != 0) + c->timeout = lowest_ttl + tv.tv_sec; updatehosts (c, dbnum, dbservers); - return 0; + return ret; } /* @@ -347,20 +377,20 @@ updatehosts (c, c->ndbservers, c->dbservers); } + /* - * cell name -> cell_entry * + * cell name -> cell_entry * (hashtable or dns_lookup) */ cell_entry * cell_get_by_name (const char *cellname) { - cell_entry key, *data; + cell_entry *data; - key.name = cellname; - data = (cell_entry *)hashtabsearch (cellnamehtab, &key); + data = get_hash_by_name(cellname); if (data == NULL) { dns_lookup_cell (cellname, NULL); - data = (cell_entry *)hashtabsearch (cellnamehtab, &key); + data = get_hash_by_name(cellname); } if (data) update_cell (data); @@ -418,6 +448,7 @@ hashtabadd (cellnumhtab, c); c->timeout = 0; celldb_version++; + log_log (cell_log, CDEBERR, "Inserted cell %s with id %d", name, c->id); return c; } @@ -432,6 +463,9 @@ FILE *f; c = cell_new (name); + + return c; /* haba does not believe in changing CellServDB on the fly */ + if (c == NULL) return NULL; c->expl = "dynamically added cell"; @@ -649,24 +683,35 @@ { return parse_simple_file (filename, addsuidcell); } - /* - * + * Just as cell_add_dynroot but ignores return */ static void add_dynroot(const char *cellname) { + if (cell_add_dynroot(cellname)) + dynrootdb_in_use = 1; +} + +/* + * Adds cell to cell cache and sets its dynroot flag. + * returns NULL on error, otherwise cell_entry struct. + */ + +int +cell_add_dynroot(const char *cellname) +{ cell_entry *e; e = cell_get_by_name (cellname); - if (e == NULL) { + if (cell_get_by_name (cellname) == NULL) { log_log (cell_log, CDEBWARN, "dynroot: cell %s doesn't exist in the db\n", cellname); - } else { + return -1; + } else e->flags |= DYNROOT_CELL; - dynrootdb_in_use = 1; - } + return 0; } static int @@ -682,16 +727,20 @@ static int cell_inited = 0; void -cell_init (int cellcachesize, Log_method *log) +cell_init(int cellcachesize, Log_method *log) { - char *env; - int ret; + if (cell_init_malloc (cellcachesize, log) >= 0) + cell_init_fill(); +} +int +cell_init_malloc (int cellcachesize, Log_method *log) +{ assert (log); if (cell_inited) { log_log (cell_log, CDEBWARN, "cell_init: Already initlized"); - return; + return -1; } cell_inited = 1; @@ -712,6 +761,14 @@ cellnumhtab = hashtabnew (cellcachesize, cellnumcmp, cellnumhash); if (cellnumhtab == NULL) errx (1, "cell_init: hashtabnew failed"); + return 1; +} + +void +cell_init_fill() +{ + char *env; + int ret; env = getenv ("AFSCELL"); if (env != NULL) { @@ -1102,7 +1159,7 @@ free (c); return errno; } - c->id = 0; /* XXX */ + c->id = DYNROOT_CELLID; c->expl = "The special dynroot cell"; c->ndbservers = 0; c->dbservers = NULL;