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/06/23 08:55:10 @@ -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,6 +86,13 @@ 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); const cell_db_entry *cell_dbservers_by_id (int32_t cell, int *); @@ -96,6 +106,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/06/23 10:43:08 @@ -263,6 +263,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 +290,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 +302,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 +341,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 +376,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 +447,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 +462,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 +682,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 @@ -1102,7 +1146,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;