From ab05f33a0f59714921815569d658e356a071cf19 Mon Sep 17 00:00:00 2001 From: danw Date: Thu, 24 Oct 1996 21:34:29 +0000 Subject: [PATCH] dbck fixes by kcr, dkk, and myself from the end of the summer. It shouldn't destroy data now. [The delay in checking in was because we hadn't yet tested the -p, -f, and -c options since the changes.] --- dbck/FIXES | 71 ++++--- dbck/Imakefile | 4 +- dbck/Makefile | 18 +- dbck/dbck.dc | 12 +- dbck/dbck.h | 45 ++-- dbck/fix.dc | 21 +- dbck/members.dc | 15 +- dbck/nhash.c | 180 ++++++++++++++++ dbck/phase1.dc | 355 ++++++++++++++++++++----------- dbck/phase2.dc | 540 +++++++++++++++++++++++++++++++++++++++++++----- dbck/phase3.dc | 17 +- dbck/phase4.dc | 34 ++- 12 files changed, 1066 insertions(+), 246 deletions(-) create mode 100644 dbck/nhash.c diff --git a/dbck/FIXES b/dbck/FIXES index a1648de5..a470147d 100644 --- a/dbck/FIXES +++ b/dbck/FIXES @@ -1,48 +1,67 @@ P if fixed in preen step +F if not fixed in fast mode * if not offered to fix *if not actually checked ================================ PHASE 1: looking for duplicates + * don't delete both if one is placeholder * + Each users_id must be unique Alloc new ID - Each login name must be unique (if -f flag not specified) +F Each login name must be unique If full names match, delete; else unregister +F* Each user can appear at most once in the krbmap +F* Each principal can appear at most once in the krbmap Each mach_id must be unique Alloc new ID - * Each machine name must be unique (if -f flag not specified) +F* Each machine name must be unique +F* Each hostalias name must be unique +F* Each hostalias name must not be the same as any machine name Each snet_id must be unique Alloc new ID +F**Each subnet name must be unique Each clu_id must be unique Alloc new ID - * Each cluster must have a unique name (if -f flag not specified) +F* Each cluster must have a unique name Each list_id must be unique Alloc new ID - * Each list must have a unique name (if -f flag not specified) +F* Each list must have a unique name Each filsys_id must be unique Alloc new ID +F**Each filesys name must be unique Each nfsphys_id must be unique Alloc new ID - Each strings_id must be unique - Delete duplicate - * Each string must have a unique value - * Each user can appear at most once in the krbmap (if -f flag not specified) - * Each principal can appear at most once in the krbmap (if -f flag - not specified) + Each string must be unique + Delete second copy and remember this for phase 2 + Each string_id must be unique + Delete all copies +F**Each printer name must be unique + *Each palladium id must be unique + Alloc new ID +F**Each palladium name must be unique PHASE 2: checking references + Each reference to a string must not point to a duplicate string + Reset it to point to the first copy of that string + Each reference to a string must point to a real string + Reset it to point to string 0 Each user's POP pobox must be on a real machine Delete pobox Each user's SMTP pobox must have a string Delete pobox +P Every machine must be on a subnet + Set to placeholder subnet +P Every machine owner must exist + Set dummy owner + Every subnet owner must exist + Set dummy owner P Every entry in the machine-cluster map must reference machine & cluster Delete entry P Every piece of cluster data must be attached to a real cluster. Delete data -P Every LIST list ACE must exist - Make list it's own acl -P Every USER list ACE must exist +P Every list ACE must exist Make list it's own acl P Every member must be a member of a real list Delete the member @@ -54,33 +73,29 @@ P Every STRING member must be a real string Delete the member P Every KERBEROS member must be a real string Delete the member -P Every machine owner must exist - Set dummy owner -P Every machine must be on a subnet - Set to placeholder subnet P Every service USER owner must be a real user Make user 0 own service P Every service LIST owner must be a real list Make list 0 own service Every server/host tuple must refer to a real machine Delete tuple + Every NFS physical's machine must exist + Delete entry Every filesys must be on a real machine Put it on machine 0 P Every filesys' owning user must exist Make it user 0 P Every filesys' owning group must exist Make it list 0 + Every NFS filesys' phys_id must exist +P Set to correct one if found + else create one Every fsgroup must exist Delete the fsgroup - Every fsgroup must be of type FSGROUP + *Every fsgroup must be of type FSGROUP Change type P Every fsgroup member must exist Delete member - Every NFS filesys' phys_id must exist -P Set to correct one if found - else create one - Every NFS physical's machine must exist - Delete entry P Every USER quota must be for a real user Delete quota P Every GROUP quota must be for a real list @@ -89,22 +104,20 @@ P Every GROUP quota must be for a real list Delete quota P Every quota's phys_id must match the filesys' phys_id Fix phys_id -P Every user in the krbmap must exist - Delete map entry -P Every string in the krbmap must exist - Delete map entry **Zephyr checks * Every hostaccess must be for a real machine * Every hostaccess USER must exist * Every hostaccess LIST must exist P Every palladium server must be on a real machine Delete the palladium entry +P Every user in the krbmap must exist + Delete map entry +P Every string in the krbmap must exist + Delete map entry * Every list used in capacls must exist PHASE 3: finding unused objects - Every machine must be in at least one cluster (if -w flag not specified) - Print warning Every list must have at least one member (if -w flag not specified) Print warning P Every string must be used at least once diff --git a/dbck/Imakefile b/dbck/Imakefile index 08c9b4f2..9b82e4a2 100644 --- a/dbck/Imakefile +++ b/dbck/Imakefile @@ -8,8 +8,8 @@ # Imakefile for server directory. # -SRCS = dbck.c fix.c phase1.c phase2.c phase3.c phase4.c -OBJS = dbck.o fix.o phase1.o phase2.o phase3.o phase4.o +SRCS = dbck.c fix.c phase1.c phase2.c phase3.c phase4.c nhash.c +OBJS = dbck.o fix.o phase1.o phase2.o phase3.o phase4.o nhash.o CODE = dbck.dc fix.dc phase1.dc phase2.dc phase3.dc phase4.dc dbck.h SRCDIR=$(SRCTOP)/dbck sqlrule() diff --git a/dbck/Makefile b/dbck/Makefile index 867d0ecf..1164d356 100644 --- a/dbck/Makefile +++ b/dbck/Makefile @@ -8,14 +8,15 @@ .SUFFIXES: .SUFFIXES: .o .c .dc .sc -CFLAGS= -I/usr/athena/include -I../include -I../lib -O +CFLAGS= -I/usr/athena/include -I/u3/kcr/moira/include -I/u3/kcr/moira/lib -O +CC=cc AWK=awk -SRCS = dbck.c fix.c phase1.c phase2.c phase3.c phase4.c members.c -OBJS = dbck.o fix.o phase1.o phase2.o phase3.o phase4.o +SRCS = dbck.c fix.c phase1.c phase2.c phase3.c phase4.c members.c nhash.c +OBJS = dbck.o fix.o phase1.o phase2.o phase3.o phase4.o nhash.o -EQLIBS = ../lib/libmoira.a ../server/libmrglue.a /usr/ingres/lib/libingres.a -lm +EQLIBS = /u3/kcr/moira/lib/libmoira.a /u3/kcr/moira/server/libmrglue.a /usr/ingres/lib/libingres.a -lm .dc.sc: $(AWK) -f /mit/moiradev/src/util/imake.includes/ingres.awk < $< > $*.sc @@ -34,14 +35,15 @@ fix.o: fix.c dbck.h fix.c: fix.sc phase1.o: phase1.c dbck.h phase1.c: phase1.sc -phase2.o: phase2.c +phase2.o: phase2.c dbck.h phase2.c: phase2.sc -phase3.o: phase3.c +phase3.o: phase3.c dbck.h phase3.c: phase3.sc -phase4.o: phase4.c +phase4.o: phase4.c dbck.h phase4.c: phase4.sc members.c: members.sc members.o: members.c +nhash.o: nhash.c members: members.o cc -o members members.o ${EQLIBS} @@ -54,7 +56,7 @@ clean: rm -f core *~ install: dbck - install -c dbck ../bin/dbck + install -c dbck /u3/kcr/moira/bin/dbck depend: ${SRCS} makedepend ${CFLAGS} ${SRCS} diff --git a/dbck/dbck.dc b/dbck/dbck.dc index 525d567a..1639cd3c 100644 --- a/dbck/dbck.dc +++ b/dbck/dbck.dc @@ -12,6 +12,7 @@ #include #include #include "dbck.h" +EXEC SQL INCLUDE sqlca; static char dbck_qc_rcsid[] = "$Header$"; @@ -23,7 +24,7 @@ int fast = 0; int warn = 1; int abort_p = 0; struct hash *users, *machines, *clusters, *lists, *filesys, *nfsphys; -struct hash *strings, *members, *subnets; +struct hash *strings, *members, *subnets, *string_dups; EXEC SQL BEGIN DECLARE SECTION; int dcmenable; EXEC SQL END DECLARE SECTION; @@ -123,7 +124,6 @@ EXEC SQL END DECLARE SECTION; EXEC SQL COMMIT WORK; } phase4(); - EXEC SQL COMMIT WORK; cleanup(); @@ -134,8 +134,14 @@ EXEC SQL END DECLARE SECTION; ingerr(num) int *num; { +EXEC SQL BEGIN DECLARE SECTION; + char buf[512]; +EXEC SQL END DECLARE SECTION; + if (*num == 100) return; - printf("An ingres error occuurred, code %d\n", *num); + printf("An ingres error occurred, code %d\n", *num); + EXEC SQL INQUIRE_SQL(:buf = errortext); + printf("%s\n", buf); printf("Aborting...\n"); if (!abort_p) { abort_p++; diff --git a/dbck/dbck.h b/dbck/dbck.h index 1cad37ce..1876e1e9 100644 --- a/dbck/dbck.h +++ b/dbck/dbck.h @@ -19,7 +19,7 @@ extern int debug, mode, fast, dcmenable, warn; extern struct hash *users, *machines, *clusters, *lists; -extern struct hash *filesys, *nfsphys, *strings, *subnets; +extern struct hash *filesys, *nfsphys, *strings, *subnets, *string_dups; #define MAX_ID_VALUE 32765 #define MIN_ID_VALUE 100 @@ -27,27 +27,44 @@ extern struct hash *filesys, *nfsphys, *strings, *subnets; #define dprintf if (debug) printf struct user { - char login[9]; - char potype; - char *fullname; - int status; - int users_id; - int pobox_id; + char login[9]; + char potype; + char *fullname; + int status; + int users_id; + int pobox_id; + int comment; + int modby; + int fmodby; + int pmodby; + int sigwho; }; struct machine { - char name[33]; - char owner_type; - int owner_id; - int snet_id; - int mach_id; - int clucount; - + char name[33]; + char owner_type; + int owner_id; + int snet_id; + int mach_id; + int clucount; + int acomment; + int ocomment; + int creator; + int modby; +}; + +struct subnet { + char name[33]; + char owner_type; + int owner_id; + int snet_id; + int modby; }; struct cluster { char name[33]; int clu_id; + int modby; }; struct list { diff --git a/dbck/fix.dc b/dbck/fix.dc index 7ae6785d..fb9995dd 100644 --- a/dbck/fix.dc +++ b/dbck/fix.dc @@ -83,7 +83,7 @@ EXEC SQL END DECLARE SECTION; EXEC SQL END DECLARE SECTION; /* replace tbl (zrfield = 0) where table.idfield = id */ - sprintf(stmt_buf,"UPDATE %s SET %d = 0 WHERE %s.%s = %d", + sprintf(stmt_buf,"UPDATE %s SET %s = 0 WHERE %s.%s = %d", tbl,zrfield,tbl,idfield,id); EXEC SQL EXECUTE IMMEDIATE :stmt_buf; /* inquire_equel(rowcount = "rowcount") */ @@ -277,3 +277,22 @@ generic_fix_id(tbl, idfield, txtfield, oldid, name) modified(tbl); return(id); } + +de_dup( tbl, idfield, id, dupfield, correct_val ) +EXEC SQL BEGIN DECLARE SECTION; +char *tbl, *idfield, *dupfield; +int id, correct_val; +EXEC SQL END DECLARE SECTION; +{ + int size, i; + EXEC SQL BEGIN DECLARE SECTION; + int rowcount; + EXEC SQL END DECLARE SECTION; + +/* replace tbl.dupfield with correct_val where tbl.idfield = id */ + sprintf( stmt_buf,"UPDATE %s SET %d = %d WHERE %s = %d", + tbl, dupfield, correct_val, idfield, id ); + size = strlen( stmt_buf ); + for( i=0; i!=NULL && i<500; i++ ) { ; } /* Move to an unused string. */ + +} diff --git a/dbck/members.dc b/dbck/members.dc index 50441d7c..924e4d0d 100644 --- a/dbck/members.dc +++ b/dbck/members.dc @@ -63,8 +63,8 @@ char **argv; /* range of m is imembers */ /* No equivalent */ - lists = create_hash(10000); - members = create_hash(10000); + lists = create_hash(50000); + members = create_hash(300000); records = 0; load_members(); @@ -100,7 +100,6 @@ char **argv; } - load_members() { struct member *m, *m1, *md, *ma; @@ -356,7 +355,10 @@ struct member *m; } l->next = NULL; l->member = m; - hash_store(lists, m->list_id, l); + if( hash_store(lists, m->list_id, l) == -1 ) { + fprintf(stderr,"Out of mem while storing lists in hash table\n"); + exit(1); + } return; } for (l1 = l; l1; l1 = l1->next) @@ -394,7 +396,10 @@ struct member *m; } l->next = NULL; l->member = m; - hash_store(members, m->member_id, l); + if( hash_store(members, m->member_id, l) == -1 ) { + fprintf(stderr,"Out of mem while storing members in hash table\n"); + exit(1); + } return; } diff --git a/dbck/nhash.c b/dbck/nhash.c new file mode 100644 index 00000000..e7a6c878 --- /dev/null +++ b/dbck/nhash.c @@ -0,0 +1,180 @@ +/* $Header$ + * + * Generic hash table routines. Uses integer keys to store integer values. + * + * (c) Copyright 1996 by the Massachusetts Institute of Technology. + * For copying and distribution information, please see the file + * . + */ + +#include +#include +/* #include */ + +struct int_bucket { + struct int_bucket *next; + int key; + int data; +}; +struct int_hash { + int size; + struct int_bucket **data; +}; + +extern char *malloc(); + +#define NULL 0 +#define int_hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size)) + +/* Create an int_hash table. The size is just a hint, not a maximum. */ + +struct int_hash *create_int_hash(size) +int size; +{ + struct int_hash *h; + + h = (struct int_hash *) malloc(sizeof(struct int_hash)); + if (h == (struct int_hash *) NULL) + return((struct int_hash *) NULL); + h->size = size; + h->data = (struct int_bucket **) malloc(size * sizeof(char *)); + if (h->data == (struct int_bucket **) NULL) { + free(h); + return((struct int_hash *) NULL); + } + bzero(h->data, size * sizeof(char *)); + return(h); +} + +/* Lookup an object in the int_hash table. Returns the value associated with + * the key, or NULL (thus NULL is not a very good value to store...) + */ + +int int_hash_lookup(h, key) +struct int_hash *h; +register int key; +{ + register struct int_bucket *b; + + b = h->data[int_hash_func(h, key)]; + while (b && b->key != key) + b = b->next; + if (b && b->key == key) + return(b->data); + else + return(0); +} + + +/* Update an existing object in the int_hash table. Returns 1 if the object + * existed, or 0 if not. + */ + +int int_hash_update(h, key, value) +struct int_hash *h; +register int key; +int value; +{ + register struct int_bucket *b; + + b = h->data[int_hash_func(h, key)]; + while (b && b->key != key) + b = b->next; + if (b && b->key == key) { + b->data = value; + return(1); + } else + return(0); +} + + +/* Store an item in the int_hash table. Returns 0 if the key was not previously + * there, 1 if it was, or -1 if we ran out of memory. + */ + +int int_hash_store(h, key, value) +struct int_hash *h; +register int key; +int value; +{ + register struct int_bucket *b, **p; + + p = &(h->data[int_hash_func(h, key)]); + if (*p == NULL) { + b = *p = (struct int_bucket *) malloc(sizeof(struct int_bucket)); + if (b == (struct int_bucket *) NULL) + return(-1); + b->next = NULL; + b->key = key; + b->data = value; + return(0); + } + + for (b = *p; b && b->key != key; b = *p) + p = (struct int_bucket **) *p; + if (b && b->key == key) { + b->data = value; + return(1); + } + b = *p = (struct int_bucket *) malloc(sizeof(struct int_bucket)); + if (b == (struct int_bucket *) NULL) + return(-1); + b->next = NULL; + b->key = key; + b->data = value; + return(0); +} + + +/* Search through the int_hash table for a given value. For each piece of + * data with that value, call the callback proc with the corresponding key. + */ + +int_hash_search(h, value, callback) +struct int_hash *h; +register int value; +void (*callback)(); +{ + register struct int_bucket *b, **p; + + for (p = &(h->data[h->size - 1]); p >= h->data; p--) { + for (b = *p; b; b = b->next) { + if (b->data == value) + (*callback)(b->key); + } + } +} + + +/* Step through the int_hash table, calling the callback proc with each key. + */ + +int_hash_step(h, callback, hint) +struct int_hash *h; +void (*callback)(); +char *hint; +{ + register struct int_bucket *b, **p; + + for (p = &(h->data[h->size - 1]); p >= h->data; p--) { + for (b = *p; b; b = b->next) { + (*callback)(b->key, b->data, hint); + } + } +} + + +/* Deallocate all of the memory associated with a table */ + +int_hash_destroy(h) +struct int_hash *h; +{ + register struct int_bucket *b, **p, *b1; + + for (p = &(h->data[h->size - 1]); p >= h->data; p--) { + for (b = *p; b; b = b1) { + b1 = b->next; + free(b); + } + } +} diff --git a/dbck/phase1.dc b/dbck/phase1.dc index a937cebe..41a7e93c 100644 --- a/dbck/phase1.dc +++ b/dbck/phase1.dc @@ -7,6 +7,7 @@ #include #include +#include #include "dbck.h" EXEC SQL INCLUDE sqlca; @@ -178,16 +179,34 @@ struct string *s; return(0); } +print_str_id(id) + int id; +{ + printf("String %d is a duplicate\n", id); + return(0); +} + +print_dup_map(key, data, hint) + int key; + int data; + char *hint; +{ + printf("String %d is a duplicate of string %d\n", key, data); + +} phase1() { EXEC SQL BEGIN DECLARE SECTION; char name[81], name1[81], last[17], first[17], buf[257]; - int id, id2, id3, aid, aid2, status, sid, sid2, sid3, sid4, sid5; + int id, id1, id2, id3, aid, aid2, status; + int sid, sid2, sid3, sid4, sid5; EXEC SQL END DECLARE SECTION; + int i, q, retval, tmp; struct save_queue *sq; struct user *u; struct machine *m; + struct subnet *sn; struct list *l; struct cluster *c; struct string *s; @@ -196,45 +215,98 @@ phase1() printf("Phase 1 - Looking for duplicates\n"); + /* self-join strings table on "string" to get duplicate strings, then + build a duplicates table to merge them. */ + + dprintf("Looking for duplicate strings...\n"); + string_dups = create_hash( 100 ); + if(!string_dups) out_of_mem("storing duplicate strings"); + + EXEC SQL DECLARE csr116 CURSOR FOR + SELECT s1.string_id, s2.string_id FROM strings s1, strings s2 + where s1.string = s2.string and s1.string_id < s2.string_id; + EXEC SQL OPEN csr116; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + /* The SELECT gives us two columns, both with non-negative integers. + * The number in the left column is always the smaller of the two, + * and each row includes string IDs for identical strings. We use + * them to make a mapping from id-to-delete to id-to-keep for all + * superflous IDs. + */ + q=0; + while(1) { + EXEC SQL FETCH csr116 INTO :id1, :id2; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + q++; + /* If id2 is already stored, skip this row. */ + i = int_hash_lookup( string_dups, id2 ); + if( i > 0 ) { continue; } + /* Follow the chain of id1 equivalent IDs back to the lowest one. */ + id=id1; + while((tmp=int_hash_lookup(string_dups, id))>0) + id=tmp; + int_hash_store( string_dups, id2, id ); + } + EXEC SQL CLOSE csr116; + dprintf("found %d duplicates\n", q); + int_hash_step(string_dups, print_dup_map, NULL); + /* We don't want to delete the duplicates now because if the dbck + is cancelled, a LOT of state will be lost. So, we'll just let + them not get marked as used and then phase3 will clean them up */ + dprintf("Loading strings...\n"); sq = sq_create(); - strings = create_hash(5000); + strings = create_hash(75000); + if(!sq || !strings) out_of_mem("loading strings"); EXEC SQL DECLARE csr101 CURSOR FOR - SELECT string_id, string FROM strings ORDER BY string_id; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + SELECT string_id, string, tid FROM strings ORDER BY string_id; EXEC SQL OPEN csr101; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + q=0; while(1) { - EXEC SQL FETCH csr101 INTO :id, :buf; + EXEC SQL FETCH csr101 INTO :id, :buf, :id1; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } - - s = (struct string *) malloc(sizeof(struct string)); + q++; + s = (struct string *) malloc(sizeof(struct string)); if (s == NULL) out_of_mem("storing strings"); s->name = strsave(strtrim(buf)); s->string_id = id; s->refc = 0; - if (hash_store(strings, id, s)) { - sq_save_data(sq, hash_lookup(strings, id)); - sq_save_data(sq, s); + retval = hash_store(strings, id, s); + if ( retval == -1 ) { + out_of_mem("storing strings in hash table"); + } else if ( retval == 1 ) { /* duplicate string_id*/ + sq_save_data(sq, hash_lookup(strings, id)); + sq_save_data(sq, s); } } EXEC SQL CLOSE csr101; - generic_delete(sq, show_str_id, "strings", "string_id", 0); + /* I'm not at all convinced this will work, so... + generic_delete(sq, show_str_id, "strings", "string_id", 0); + */ string_check(0); + printf("Loaded %d strings\n", q); + dprintf("Loading users...\n"); sq = sq_create(); - users = create_hash(10000); + users = create_hash(30000); + if(!sq || !users) out_of_mem("loading users"); EXEC SQL DECLARE csr102 CURSOR FOR SELECT users_id, login, last, first, status, potype, pop_id, box_id, - modby, fmodby, pmodby, comment, sigwho FROM users ORDER BY users_id; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + modby, fmodby, pmodby, comment, sigwho FROM users + ORDER BY users_id; EXEC SQL OPEN csr102; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr102 INTO :id, :name, :last, :first, :status, :buf, :id2, :id3, :sid, :sid2, :sid3, :sid4, :sid5; @@ -252,30 +324,29 @@ phase1() u->fullname = strsave(buf); u->status = status; u->users_id = id; + u->modby = sid; + u->fmodby = sid2; + u->pmodby = sid3; + u->comment = sid4; + u->sigwho = sid5; switch (u->potype) { case 'P': u->pobox_id = id2; break; case 'S': + /* If potype is SMTP, box_id is a string_id for the strings tbl */ u->pobox_id = id3; break; default: u->pobox_id = 0; } - if (hash_store(users, id, u)) { + retval = hash_store(users, id, u); + if ( retval == -1 ) { + out_of_mem("storing users in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(users, id)); sq_save_data(sq, u); } - if (sid < 0) - string_check(-sid); - if (sid2 < 0) - string_check(-sid2); - if (sid3 < 0) - string_check(-sid3); - if (sid4) - string_check(sid4); - if (sid5) - string_check(sid5); } EXEC SQL CLOSE csr102; @@ -283,12 +354,13 @@ phase1() if (!fast) { sq = sq_create(); + if(!sq) out_of_mem("finding duplicate logins"); EXEC SQL DECLARE csr103 CURSOR FOR SELECT u1.users_id FROM users u1, users u2 WHERE u1.login = u2.login and u1.tid != u2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr103; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr103 INTO :id; if (sqlca.sqlcode != 0) { @@ -301,16 +373,55 @@ phase1() handle_duplicate_logins(sq); } + if (!fast) { + dprintf("Scanning krbmap...\n"); + + EXEC SQL DECLARE csr113 CURSOR FOR + SELECT k1.users_id FROM krbmap k1, krbmap k2 + WHERE k1.users_id = k2.users_id AND k1.tid != k2.tid; + EXEC SQL OPEN csr113; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + while(1) { + EXEC SQL FETCH csr113 INTO :id; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + printf("User %d is in the krbmap more than once!\n", id); + printf("Not fixing this error\n"); + } + EXEC SQL CLOSE csr113; + + EXEC SQL DECLARE csr114 CURSOR FOR + SELECT k1.string_id FROM krbmap k1, krbmap k2 + WHERE k1.string_id = k2.string_id AND k1.tid != k2.tid; + EXEC SQL OPEN csr114; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + while(1) { + EXEC SQL FETCH csr114 INTO :id; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + printf("Principal %d is in the krbmap more than once!\n", id); + printf("Not fixing this error\n"); + } + EXEC SQL CLOSE csr114; + } + dprintf("Loading machines...\n"); - machines = create_hash(1000); sq = sq_create(); + machines = create_hash(20000); + if(!sq || !machines) out_of_mem("loading machines"); EXEC SQL DECLARE csr104 CURSOR FOR SELECT mach_id, name, snet_id, owner_type, owner_id, acomment, ocomment, creator, modby FROM machine ORDER BY mach_id; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr104; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr104 INTO :id, :name, :id2, :buf, :id3, :sid2, :sid3, :sid4, :sid; @@ -328,26 +439,30 @@ phase1() m->snet_id = id2; m->mach_id = id; m->clucount = 0; - if (hash_store(machines, id, m)) { + m->acomment=sid2; + m->ocomment=sid3; + m->creator=sid4; + m->modby=sid; + retval = hash_store(machines, id, m); + if ( retval == -1 ) { + out_of_mem("storing machines in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(machines, id)); sq_save_data(sq, m); } - if (sid2) string_check(sid2); - if (sid3) string_check(sid3); - if (sid4 < 0) string_check(-sid4); - if (sid < 0) string_check(-sid); } EXEC SQL CLOSE csr104; generic_fix(sq, show_mach_id, "Change ID", fix_mach_id, 0); if (!fast) { sq = sq_create(); + if(!sq) out_of_mem("looking for duplicate machine names"); EXEC SQL DECLARE csr105 CURSOR FOR SELECT m1.mach_id FROM machine m1, machine m2 WHERE m1.name = m2.name AND m1.tid != m2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr105; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr105 INTO :id; if (sqlca.sqlcode != 0) { @@ -359,23 +474,74 @@ phase1() } EXEC SQL CLOSE csr105; generic_fix(sq, show_mach_name, "Change name", cant_fix, 0); + + EXEC SQL DECLARE csr_hal1 CURSOR FOR + SELECT h1.name, m1.mach_id, m2.mach_id + FROM hostalias h1, machine m1, hostalias h2, machine m2 + WHERE h1.name=h2.name AND h1.mach_id!=h2.mach_id + AND m1.mach_id=h1.mach_id AND m2.mach_id=h2.mach_id; + EXEC SQL OPEN csr_hal1; + if(sqlca.sqlcode!=0) ingerr(&sqlca.sqlcode); + while(1) { + EXEC SQL FETCH csr_hal1 INTO :name, :id1, :id2; + if(sqlca.sqlcode!=0) { + ingerr(&sqlca.sqlcode); + break; + } + printf("Aliases for machines %d and %d have duplicate name %s\n", + id1, id2, strtrim(name)); + cant_fix(); + } + EXEC SQL CLOSE csr_hal1; + + EXEC SQL DECLARE csr_hal2 CURSOR FOR + SELECT h1.name, m1.mach_id, m2.mach_id + FROM hostalias h1, machine m1, machine m2 + WHERE h1.name=m1.name AND h1.mach_id=m2.mach_id; + EXEC SQL OPEN csr_hal2; + if(sqlca.sqlcode!=0) ingerr(&sqlca.sqlcode); + while(1) { + EXEC SQL FETCH csr_hal2 INTO :name, :id1, :id2; + if(sqlca.sqlcode!=0) { + ingerr(&sqlca.sqlcode); + break; + } + printf("Machine %d has alias `%s' that conflicts with machine %d\n", + id2, strtrim(name), id1); + cant_fix(); + } + EXEC SQL CLOSE csr_hal2; } dprintf("Loading subnets...\n"); subnets = create_hash(254); + if(!subnets) out_of_mem("loading subnets"); EXEC SQL DECLARE csr115 CURSOR FOR - SELECT snet_id, name from subnet; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + SELECT snet_id, name, owner_type, owner_id, modby from subnet; EXEC SQL OPEN csr115; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { - EXEC SQL FETCH csr115 INTO :id, :name; + EXEC SQL FETCH csr115 INTO :id, :name, :buf, :id2, :sid; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; - } - if (hash_store(subnets, id, name)) { + } + + sn = (struct subnet *) malloc(sizeof(struct machine)); + if (sn == NULL) + out_of_mem("storing subnets"); + strcpy(sn->name, strtrim(name)); + sn->owner_type=buf[0]; + sn->owner_id = id2; + sn->snet_id = id; + sn->modby = sid; + retval = hash_store(subnets, id, sn); + if ( retval == -1 ) { + out_of_mem("storing subnets in hash table"); + } else if ( retval == 1 ) { printf("Duplicate subnet ID: %d (%s)\n", id, name); + /* should add code to delete */ } } EXEC SQL CLOSE csr115; @@ -383,11 +549,12 @@ phase1() dprintf("Loading clusters...\n"); sq = sq_create(); clusters = create_hash(100); + if(!sq || !clusters) out_of_mem("loading clusters"); EXEC SQL DECLARE csr106 CURSOR FOR SELECT clu_id, name, modby FROM cluster; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr106; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr106 INTO :id, :name, :sid; if (sqlca.sqlcode != 0) { @@ -400,24 +567,27 @@ phase1() out_of_mem("storing clusters"); strcpy(c->name, strtrim(name)); c->clu_id = id; - if (hash_store(clusters, id, c)) { + c->modby = sid; + retval = hash_store(clusters, id, c); + if ( retval == -1 ) { + out_of_mem("storing clusters in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(clusters, id)); sq_save_data(sq, c); } - if (sid < 0) - string_check(-sid); } EXEC SQL CLOSE csr106; generic_fix(sq, show_clu_id, "Change ID", fix_clu_id, 0); if (!fast) { sq = sq_create(); + if(!sq) out_of_mem("looking for duplicate cluster names"); EXEC SQL DECLARE csr107 CURSOR FOR SELECT c1.clu_id FROM cluster c1, cluster c2 WHERE c1.name=c2.name AND c1.tid != c2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr107; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr107 INTO :id; if (sqlca.sqlcode != 0) { @@ -433,13 +603,14 @@ phase1() dprintf("Loading lists...\n"); sq = sq_create(); - lists = create_hash(10000); + lists = create_hash(50000); + if(!sq || !lists) out_of_mem("loading lists"); EXEC SQL DECLARE csr108 CURSOR FOR SELECT list_id, name, acl_id, acl_type, modby FROM list ORDER BY list_id; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr108; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr108 INTO :id, :name, :aid, :buf, :sid; if (sqlca.sqlcode != 0) { @@ -454,24 +625,26 @@ phase1() l->acl_id = aid; l->list_id = id; l->members = 0; - if (hash_store(lists, id, l)) { + retval = hash_store(lists, id, l); + if ( retval == -1 ) { + out_of_mem("storing lists in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(lists, id)); sq_save_data(sq, l); } - if (sid < 0) - string_check(-sid); } EXEC SQL CLOSE csr108; generic_fix(sq, show_list_id, "Change ID", fix_list_id, 0); if (!fast) { sq = sq_create(); + if(!sq) out_of_mem("looking for duplicate list names"); EXEC SQL DECLARE csr109 CURSOR FOR SELECT l1.list_id FROM list l1, list l2 WHERE l1.name=l2.name AND l1.tid != l2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr109; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr109 INTO :id; if (sqlca.sqlcode != 0) { @@ -487,13 +660,14 @@ phase1() dprintf("Loading filesys...\n"); sq = sq_create(); - filesys = create_hash(10000); + filesys = create_hash(30000); + if(!sq || !filesys) out_of_mem("loading filesys"); EXEC SQL DECLARE csr110 CURSOR FOR SELECT filsys_id, label, owner, owners, phys_id, mach_id, type, name, modby FROM filesys ORDER BY filsys_id; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr110; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr110 INTO :id, :name, :aid, :aid2, :id2, :id3, :buf, :name1, :sid; @@ -513,12 +687,13 @@ phase1() f->phys_id = id2; f->mach_id = id3; f->type = buf[0]; - if (hash_store(filesys, id, f)) { + retval = hash_store(filesys, id, f); + if ( retval == -1 ) { + out_of_mem("storing filesys in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(filesys, id)); sq_save_data(sq, f); } - if (sid < 0) - string_check(-sid); } EXEC SQL CLOSE csr110; @@ -527,11 +702,12 @@ phase1() dprintf("Loading nfsphys...\n"); sq = sq_create(); nfsphys = create_hash(500); + if(!sq || !nfsphys) out_of_mem("loading nfsphs"); EXEC SQL DECLARE csr111 CURSOR FOR SELECT nfsphys_id, dir, mach_id, allocated, modby FROM nfsphys; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr111; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr111 INTO :id, :name, :id2, :id3, :sid; if (sqlca.sqlcode != 0) { @@ -547,73 +723,18 @@ phase1() n->nfsphys_id = id; n->allocated = id3; n->count = 0; - if (hash_store(nfsphys, id, n)) { + retval = hash_store(nfsphys, id, n); + if ( retval == -1 ) { + out_of_mem("storing nfsphys in hash table"); + } else if ( retval == 1 ) { sq_save_data(sq, hash_lookup(nfsphys, id)); sq_save_data(sq, n); } - if (sid < 0) - string_check(-sid); } EXEC SQL CLOSE csr111; generic_fix(sq, show_np_id, "Change ID", fix_np_id, 0); - if (!fast) { - - dprintf("Checking for duplicate strings...\n"); - EXEC SQL DECLARE csr112 CURSOR FOR - SELECT s1.string_id, s1.string FROM strings s1, strings s2 - WHERE s1.string=s2.string AND s1.tid != s2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); - EXEC SQL OPEN csr112; - while(1) { - EXEC SQL FETCH csr112 INTO :id, :buf; - if (sqlca.sqlcode != 0) { - ingerr(&sqlca.sqlcode); - break; - } - - printf("String %s(%d) is a duplicate!\n", strtrim(buf), id); - printf("Not fixing this error\n"); - } - EXEC SQL CLOSE csr112; - } - - if (!fast) { - dprintf("Scanning krbmap...\n"); - - EXEC SQL DECLARE csr113 CURSOR FOR - SELECT k1.users_id FROM krbmap k1, krbmap k2 - WHERE k1.users_id = k2.users_id AND k1.tid != k2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); - EXEC SQL OPEN csr113; - while(1) { - EXEC SQL FETCH csr113 INTO :id; - if (sqlca.sqlcode != 0) { - ingerr(&sqlca.sqlcode); - break; - } - - printf("User %d is in the krbmap more than once!\n", id); - printf("Not fixing this error\n"); - } - EXEC SQL CLOSE csr113; - - EXEC SQL DECLARE csr114 CURSOR FOR - SELECT k1.string_id FROM krbmap k1, krbmap k2 - WHERE k1.string_id = k2.string_id AND k1.tid != k2.tid; - if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); - EXEC SQL OPEN csr114; - while(1) { - EXEC SQL FETCH csr114 INTO :id; - if (sqlca.sqlcode != 0) { - ingerr(&sqlca.sqlcode); - break; - } - - printf("Principal %d is in the krbmap more than once!\n", id); - printf("Not fixing this error\n"); - } - EXEC SQL CLOSE csr114; - } + /* csr112 */ + } diff --git a/dbck/phase2.dc b/dbck/phase2.dc index a9aea9d6..77f69486 100644 --- a/dbck/phase2.dc +++ b/dbck/phase2.dc @@ -36,7 +36,7 @@ int id; strtrim(name); found = 0; - printf("Clusqter %s, non-existant machine %d in cluster map\n", name, id); + printf("Cluster %s, non-existant machine %d in cluster map\n", name, id); } EXEC SQL CLOSE csr201; return(found); @@ -50,7 +50,10 @@ int id; char name[33]; EXEC SQL END DECLARE SECTION; - EXEC SQL DECLARE csr202 CURSOR FOR + EXEC SQL DECLARE csr202 CURSOR + + + FOR SELECT machine.name FROM machine, mcmap WHERE machine.mach_id=mcmap.mach_id AND mcmap.clu_id=:iid; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); @@ -63,6 +66,7 @@ int id; } strtrim(name); + found = 0; printf("Machine %s, non-existant cluster %d in cluster map\n", name, id); } @@ -70,35 +74,300 @@ int id; return(found); } +show_hostalias(id) +int id; +{ + EXEC SQL BEGIN DECLARE SECTION; + int iid = id, found = 1; + char name[33]; + EXEC SQL END DECLARE SECTION; + + EXEC SQL DECLARE csr234 CURSOR FOR + SELECT name FROM hostalias WHERE mach_id=:iid; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + EXEC SQL OPEN csr234; + while(1) { + EXEC SQL FETCH csr234 INTO :name; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + strtrim(name); + + found = 0; + printf("Alias %s, non-existant machine %d in hostalias map\n", name, id); + } + EXEC SQL CLOSE csr234; + return(found); +} + +show_pcap_mach(id) +int id; +{ + EXEC SQL BEGIN DECLARE SECTION; + int iid = id, found = 1; + char name[33]; + EXEC SQL END DECLARE SECTION; + + EXEC SQL DECLARE csr235 CURSOR FOR + SELECT name FROM printcap WHERE mach_id=:iid; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + EXEC SQL OPEN csr235; + while(1) { + EXEC SQL FETCH csr235 INTO :name; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + strtrim(name); + + found = 0; + printf("Printer %s, non-existant spool machine %d in printcap table\n", name, id); + } + EXEC SQL CLOSE csr235; + return(found); +} + +show_pcap_quota(id) +int id; +{ + EXEC SQL BEGIN DECLARE SECTION; + int iid = id, found = 1; + char name[33]; + EXEC SQL END DECLARE SECTION; + + EXEC SQL DECLARE csr236 CURSOR FOR + SELECT name FROM printcap WHERE quotaserver=:iid; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + EXEC SQL OPEN csr236; + while(1) { + EXEC SQL FETCH csr236 INTO :name; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + strtrim(name); + + found = 0; + printf("Printer %s, non-existant quota server %d in printcap table\n", name, id); + } + EXEC SQL CLOSE csr236; + return(found); +} + +user_check(id, u, hint) + int id; + struct user *u; + int hint; +{ + u->comment=maybe_fixup_unref_string(u->comment, id, u->login, "users", + "comment", "users_id"); + + u->modby=maybe_fixup_modby(u->modby, id, u->login, "users", + "modby", "users_id"); + + u->fmodby=maybe_fixup_modby(u->fmodby, id, u->login, "users", + "fmodby", "users_id"); + + u->pmodby=maybe_fixup_modby(u->pmodby, id, u->login, "users", + "pmodby", "users_id"); + + u->sigwho=maybe_fixup_unref_string(u->sigwho, id, u->login, "users", + "sigwho", "users_id"); + + pobox_check(id, u, hint); +} + +maybe_fixup_unref_string(sid, oid, oname, table, field, idfield) + int sid, oid; + char *oname, *table; + char *field, *idfield; +{ + int ret=(sid<0)?-sid:sid, doit=0, newid; + EXEC SQL BEGIN DECLARE SECTION; + int rowcount; + char stmt_buf[500]; + EXEC SQL END DECLARE SECTION; + + if(newid=int_hash_lookup(string_dups, ret)) { + printf("%s entry %s(%d) has a %s with duplicate string %d\n", + table, oname, oid, field, ret); + if(single_fix("Replace duplicate", 0)){ + ret = newid; + string_check(newid); + doit=1; + } + } else if(!string_check(ret)) { + printf("%s entry %s(%d) has a %s with non-existant string %d\n", + table, oname, oid, field, ret); + if (single_fix("Delete", 1)) { + ret=0; + doit=1; + } + } + + if(doit){ + sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE %s = %d", + table, field, (sid<0)?-ret:ret, idfield, oid); + EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount == 1) + printf("Fixed\n"); + else + printf("Not fixed, rowcount = %d\n", rowcount); + modified(table); + } + + return((sid<0)?-ret:ret); + +} + +maybe_fixup_modby(sid, oid, oname, table, field, idfield) + int sid, oid; + char *oname, *table; + char *field, *idfield; +{ + EXEC SQL BEGIN DECLARE SECTION; + char stmt_buf[500]; + int rowcount; + EXEC SQL END DECLARE SECTION; + + if(sid<0) + return maybe_fixup_unref_string(sid, oid, oname, table, field, idfield); + else { + if(!hash_lookup(users, sid)) { + printf("%s entry %s(%d) has a %s with non-existant user %d\n", + table, oname, oid, field, sid); + if (single_fix("Delete", 1)) { + sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE %s=%d", + table, field, 0, idfield, oid); + EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount == 1) + printf("Fixed\n"); + else + printf("Not fixed, rowcount = %d\n", rowcount); + modified(table); + } + return 0; + } + } + return sid; +} + +maybe_fixup_unref_string2(table, field, cursor, sid) + int sid; + char *field, *table, *cursor; +{ + int ret=(sid<0)?-sid:sid, doit=0, newid; + EXEC SQL BEGIN DECLARE SECTION; + int rowcount; + char stmt_buf[500]; + EXEC SQL END DECLARE SECTION; + + if(newid=int_hash_lookup(string_dups, ret)) { + printf("%s entry has a %s with duplicate string %d\n", + table, field, ret); + if(single_fix("Replace duplicate", 0)){ + ret = newid; + string_check(newid); + doit=1; + } + } else if(!string_check(ret)) { + printf("%s entry has a %s with non-existant string %d\n", + table, field, ret); + if (single_fix("Delete", 1)) { + ret=0; + doit=1; + } + } + + if(doit){ + sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE CURRENT OF %s", + table, field, (sid<0)?-ret:ret, cursor); + EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount == 1) + printf("Fixed\n"); + else + printf("Not fixed, rowcount = %d\n", rowcount); + modified(table); + } + return((sid<0)?-ret:ret); +} + +maybe_fixup_modby2(table, field, cursor, id) +{ + EXEC SQL BEGIN DECLARE SECTION; + char stmt_buf[500]; + int rowcount; + EXEC SQL END DECLARE SECTION; + + if(id<0) return maybe_fixup_unref_string2(table, field, cursor, id); + else { + if(!hash_lookup(users, id)) { + printf("%s entry has a %s with non-existant user %d\n", + table, field, id); + if (single_fix("Delete", 1)) { + sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE CURRENT OF %s", + table, field, 0, cursor); + EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount == 1) + printf("Fixed\n"); + else + printf("Not fixed, rowcount = %d\n", rowcount); + modified(table); + } + return 0; + } + } + return 1; +} + pobox_check(id, u, hint) int id; struct user *u; int hint; { - switch (u->potype) { - case 'P': - if (!hash_lookup(machines, u->pobox_id)) { - printf("User %s(%s) has P.O.Box on non-existant machine %d\n", - u->login, u->fullname, u->pobox_id); - if (single_fix("Delete", 0)) { - remove_pobox(u->users_id); - u->potype = 'N'; - } - } - break; - case 'S': - if (!string_check(u->pobox_id)) { - printf("User %s(%s) has P.O.Box with non-existant string %d\n", - u->login, u->fullname, u->pobox_id); - if (single_fix("Delete", 0)) { - remove_pobox(u->users_id); - u->potype = 'N'; - } - } - break; - default: - ; + switch (u->potype) { + case 'P': + if (!hash_lookup(machines, u->pobox_id)) { + printf("User %s(%s) has P.O.Box on non-existant machine %d\n", + u->login, u->fullname, u->pobox_id); + if (single_fix("Delete", 0)) { + remove_pobox(u->users_id); + u->potype = 'N'; + } + } + break; + case 'S': + if( int_hash_lookup( string_dups, u->pobox_id ) ) { + printf("User %s(%s) has P.O.Box with duplicate string %d\n", + u->login, u->fullname, u->pobox_id); + if(single_fix("Update", 0)){ + printf("Replacing box_id dup string ID %d with %d\n", + u->pobox_id, + int_hash_lookup(string_dups, u->pobox_id)); + u->pobox_id = int_hash_lookup( string_dups, u->pobox_id ); + fix_smtp_pobox(u->users_id, u->pobox_id); + string_check(u->pobox_id); + } + } else if (!string_check(u->pobox_id)) { + printf("User %s(%s) has P.O.Box with non-existant string %d\n", + u->login, u->fullname, u->pobox_id); + if (single_fix("Delete", 0)) { + remove_pobox(u->users_id); + u->potype = 'N'; + } } + break; + default: + ; + } } @@ -118,6 +387,21 @@ int id; modified("users"); } +fix_smtp_pobox(id, sid) +int id, sid; +{ + EXEC SQL BEGIN DECLARE SECTION; + int rowcount, iid = id, isid=sid; + EXEC SQL END DECLARE SECTION; + + EXEC SQL UPDATE users SET box_id=:isid WHERE users.users_id = :iid; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount > 0) + printf("%d entr%s updated\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not updated\n"); + modified("users"); +} mach_check(id, m, hint) int id; @@ -161,9 +445,82 @@ int hint; } } break; + case 'S': + case 'K': + if(m->owner_id) + m->owner_id=maybe_fixup_unref_string(m->owner_id, id, m->name, + "machine", "owner_id", "mach_id"); + if(m->owner_id==0) + clear_mach_owner(m); } + + if(m->acomment) + m->acomment=maybe_fixup_unref_string(m->acomment, id, m->name, + "machine", "acomment", "mach_id"); + if(m->ocomment) + m->ocomment=maybe_fixup_unref_string(m->ocomment, id, m->name, + "machine", "ocomment", "mach_id"); + + m->creator=maybe_fixup_modby(m->creator, id, m->name, "machine", + "creator", "mach_id"); + m->modby=maybe_fixup_modby(m->modby, id, m->name, "machine", + "modby", "mach_id"); } +subnet_check(id, s, hint) +int id; +struct subnet *s; +int hint; +{ + switch (s->owner_type) { + case 'U': + if (!hash_lookup(users, s->owner_id)) { + printf("Subnet %s has non-existant USER owner %d\n", + s->name, s->owner_id); + if (single_fix("Set to no owner", 1)) { + clear_subnet_owner(s); + } + } + break; + case 'L': + if (!hash_lookup(lists, s->owner_id)) { + printf("Machine %s has non-existant LIST owner %d\n", + s->name, s->owner_id); + if (single_fix("Set to no owner", 1)) { + clear_subnet_owner(s); + } + } + break; + case 'S': + case 'K': + if(s->owner_id) + s->owner_id=maybe_fixup_unref_string(s->owner_id, id, s->name, + "machine", "owner_id", "mach_id"); + if(s->owner_id==0) + clear_subnet_owner(s); + } + + s->modby=maybe_fixup_modby(s->modby, id, s->name, "subnet", + "modby", "snet_id"); +} + + +clear_subnet_owner(s) +struct subnet *s; +{ + EXEC SQL BEGIN DECLARE SECTION; + int rowcount, id = s->snet_id; + EXEC SQL END DECLARE SECTION; + + EXEC SQL UPDATE subnet SET owner_type='NONE', owner_id=0 + WHERE snet_id = :id; + EXEC SQL INQUIRE_SQL(:rowcount = rowcount); + if (rowcount > 0) + printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies"); + else + printf("Not fixed\n"); + modified("subnet"); +} clear_mach_owner(m) struct machine *m; @@ -182,6 +539,16 @@ struct machine *m; modified("machine"); } +cluster_check(id, c, hint) +int id; +struct cluster *c; +int hint; +{ + c->modby=maybe_fixup_modby(c->modby, id, c->name, "cluster", + "modby", "clu_id"); +} + + show_svc(id) int id; @@ -235,6 +602,16 @@ int hint; } } break; + case 'K': + l->acl_id = maybe_fixup_unref_string(l->acl_id, id, l->name, + "list", "acl_id", "list_id"); + if (!l->acl_id) { + printf("List %s has bad KERBEROS acl %d\n", l->name, l->acl_id); + if(single_fix("Patch", 1)) { + fix_list_acl(l->list_id); + } + } + break; } } @@ -645,7 +1022,9 @@ int hint; n->nfsphys_id = id1; n->allocated = 0; n->count = 0; - hash_store(nfsphys, id1, n); + if( hash_store(nfsphys, id1, n) == -1 ) { + out_of_mem("storing nfsphys in hash table"); + } EXEC SQL UPDATE filesys SET phys_id = :id1 WHERE filsys_id = :id2; EXEC SQL INQUIRE_SQL(:rowcount = rowcount); @@ -1187,18 +1566,25 @@ phase2() printf("Phase 2 - Checking references\n"); dprintf("Checking users...\n"); - hash_step(users, pobox_check, NULL); + hash_step(users, user_check, NULL); dprintf("Checking machines...\n"); hash_step(machines, mach_check, NULL); + dprintf("Checking subnets...\n"); + hash_step(subnets, subnet_check, NULL); + + dprintf("Checking clusters...\n"); + hash_step(clusters, cluster_check, NULL); + dprintf("Checking mcmap...\n"); sq1 = sq_create(); sq2 = sq_create(); EXEC SQL DECLARE csr221 CURSOR FOR - SELECT mach_id, clu_id FROM mcmap; + SELECT mach_id, clu_id FROM mcmap; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr221; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); while(1) { EXEC SQL FETCH csr221 INTO :id1, :id2; if (sqlca.sqlcode != 0) { @@ -1208,10 +1594,10 @@ phase2() if (!(m = (struct machine *)hash_lookup(machines, id1))) sq_save_unique_data(sq1, id1); - if (!hash_lookup(clusters, id2)) + else if (!hash_lookup(clusters, id2)) sq_save_unique_data(sq2, id2); if (m) m->clucount++; - } + } EXEC SQL CLOSE csr221; generic_delete(sq1, show_mcm_mach, "mcmap", "mach_id", 1); generic_delete(sq2, show_mcm_clu, "mcmap", "clu_id", 1); @@ -1219,7 +1605,7 @@ phase2() dprintf("Checking service clusters...\n"); sq1 = sq_create(); EXEC SQL DECLARE csr222 CURSOR FOR - SELECT clu_id FROM svc; + SELECT clu_id FROM svc; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr222; while(1) { @@ -1246,8 +1632,8 @@ phase2() sq5 = sq_create(); EXEC SQL DECLARE csr223 CURSOR FOR - SELECT list_id, member_type, member_id, ref_count, direct - FROM imembers ORDER BY list_id; + SELECT list_id, member_type, member_id, ref_count, direct + FROM imembers FOR DEFERRED UPDATE OF member_id; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr223; while(1) { @@ -1263,9 +1649,9 @@ phase2() sq_save_unique_data(sq2, id2); else if (type[0] == 'L' && !hash_lookup(lists, id2)) sq_save_unique_data(sq3, id2); - else if (type[0] == 'S' && !string_check(id2)) + else if (type[0] == 'S' && !maybe_fixup_unref_string2("imembers","member_id","csr223",id2)) sq_save_unique_data(sq4, id2); - else if (type[0] == 'K' && !string_check(id2)) + else if (type[0] == 'K' && !maybe_fixup_unref_string2("imembers","member_id","csr223",id2)) sq_save_unique_data(sq5, id2); else l->members++; @@ -1281,16 +1667,18 @@ phase2() sq1 = sq_create(); sq2 = sq_create(); EXEC SQL DECLARE csr224 CURSOR FOR - SELECT name, acl_type, acl_id FROM servers; + SELECT name, acl_type, acl_id, modby FROM servers + FOR DEFERRED UPDATE of modby; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr224; while(1) { - EXEC SQL FETCH csr224 INTO :name, :type, :id1; + EXEC SQL FETCH csr224 INTO :name, :type, :id1, :id2; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } + maybe_fixup_modby2("servers","modby","csr224",id2); strtrim(type); if (!strcmp(type, "USER") && !hash_lookup(users, id1)) { sq_save_data(sq1, id1); @@ -1305,16 +1693,18 @@ phase2() dprintf("Checking serverhosts...\n"); sq = sq_create(); EXEC SQL DECLARE csr225 CURSOR FOR - SELECT mach_id FROM serverhosts; + SELECT mach_id, modby FROM serverhosts + FOR DEFERRED UPDATE OF modby; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr225; while(1) { - EXEC SQL FETCH csr225 INTO :id1; + EXEC SQL FETCH csr225 INTO :id1, :id2; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } + maybe_fixup_modby2("serverhosts", "modby", "csr225", id2); if (!hash_lookup(machines, id1)) sq_save_data(sq, id1); } @@ -1332,7 +1722,7 @@ phase2() sq2 = sq_create(); sq3 = sq_create(); EXEC SQL DECLARE csr226 CURSOR FOR - SELECT group_id, filsys_id FROM fsgroup; + SELECT group_id, filsys_id FROM fsgroup; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr226; while(1) { @@ -1357,16 +1747,18 @@ phase2() sq3 = sq_create(); sq4 = sq_create(); EXEC SQL DECLARE csr227 CURSOR FOR - SELECT entity_id, type, filsys_id, phys_id, quota FROM quota; + SELECT entity_id, type, filsys_id, phys_id, quota, modby + FROM quota FOR DEFERRED UPDATE OF modby; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr227; while(1) { - EXEC SQL FETCH csr227 INTO :id1, :type, :id2, :id3, :id4; + EXEC SQL FETCH csr227 INTO :id1, :type, :id2, :id3, :id4, :id5; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } + maybe_fixup_modby2("quota", "modby", "csr227", id5); if (type[0] == 'U' && id1 != 0 && !hash_lookup(users, id1)) sq_save_data(sq1, id1); else if (type[0] == 'G' && !hash_lookup(lists, id1)) @@ -1390,16 +1782,18 @@ phase2() dprintf("Checking hostaccess...\n"); EXEC SQL DECLARE csr228 CURSOR FOR - SELECT mach_id, acl_type, acl_id FROM hostaccess; + SELECT mach_id, acl_type, acl_id, modby FROM hostaccess + FOR DEFERRED UPDATE OF modby; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr228; while(1) { - EXEC SQL FETCH csr228 INTO :id1, :type, :id2; + EXEC SQL FETCH csr228 INTO :id1, :type, :id2, :id3; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } + maybe_fixup_modby2("hostaccess", "modby", "csr228", id3); strtrim(type); if (!hash_lookup(machines, id1)) { printf("Hostaccess for non-existant host %d\n", id1); @@ -1418,16 +1812,18 @@ phase2() dprintf("Checking palladium...\n"); sq1 = sq_create(); EXEC SQL DECLARE csr229 CURSOR FOR - SELECT mach_id FROM palladium; + SELECT mach_id, modby FROM palladium + FOR DEFERRED UPDATE OF modby; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr229; while(1) { - EXEC SQL FETCH csr229 INTO :id1; + EXEC SQL FETCH csr229 INTO :id1, :id2; if (sqlca.sqlcode != 0) { ingerr(&sqlca.sqlcode); break; } + maybe_fixup_modby2("palladium", "modby", "csr229", id2); if (!hash_lookup(machines, id1)) { sq_save_unique_data(sq1, id1); } @@ -1439,7 +1835,8 @@ phase2() sq1 = sq_create(); sq2 = sq_create(); EXEC SQL DECLARE csr230 CURSOR FOR - SELECT users_id, string_id FROM krbmap; + SELECT users_id, string_id FROM krbmap + FOR DEFERRED UPDATE OF string_id; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr230; while(1) { @@ -1451,7 +1848,7 @@ phase2() if (!hash_lookup(users, id1)) sq_save_unique_data(sq1, id1); - if (!string_check(id2)) + else if (!maybe_fixup_unref_string2("krbmap","string_id","csr230",id2)) sq_save_unique_data(sq2, id2); } EXEC SQL CLOSE csr230; @@ -1460,7 +1857,7 @@ phase2() dprintf("Checking capacls...\n"); EXEC SQL DECLARE csr231 CURSOR FOR - SELECT list_id, tag FROM capacls; + SELECT list_id, tag FROM capacls; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); EXEC SQL OPEN csr231; while(1) { @@ -1475,7 +1872,48 @@ phase2() printf("Not fixing this error\n"); } } - EXEC SQL CLOSE csr231; + EXEC SQL CLOSE csr231; -} + dprintf("Checking hostaliases\n"); + sq1 = sq_create(); + EXEC SQL DECLARE csr232 CURSOR FOR + SELECT mach_id FROM hostalias; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + EXEC SQL OPEN csr232; + while(1) { + EXEC SQL FETCH csr232 INTO :id1; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + if (!hash_lookup(machines, id1)) + sq_save_unique_data(sq1, id1); + } + EXEC SQL CLOSE csr232; + generic_delete(sq1, show_hostalias, "hostalias", "mach_id", 1); + + dprintf("Checking printcaps\n"); + sq1 = sq_create(); + sq2 = sq_create(); + EXEC SQL DECLARE csr233 CURSOR FOR + SELECT mach_id, quotaserver, modby FROM printcap; + if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); + EXEC SQL OPEN csr233; + while(1) { + EXEC SQL FETCH csr233 INTO :id1, :id2, :id3; + if (sqlca.sqlcode != 0) { + ingerr(&sqlca.sqlcode); + break; + } + + maybe_fixup_modby2("printcap", "modby", "csr233", id3); + if (!hash_lookup(machines, id1)) + sq_save_unique_data(sq1, id1); + else if(!hash_lookup(machines, id2)) + sq_save_unique_data(sq2, id2); + } + EXEC SQL CLOSE csr233; + generic_delete(sq1, show_pcap_mach, "printcap", "mach_id", 1); + generic_delete(sq2, show_pcap_quota, "printcap", "quotaserver", 1); +} diff --git a/dbck/phase3.dc b/dbck/phase3.dc index eb0923af..78b6a7e5 100644 --- a/dbck/phase3.dc +++ b/dbck/phase3.dc @@ -51,7 +51,12 @@ struct string *s; } } - +/* This test was disabled because the MIT Moira server, which + * initially only managed host information for workstations and + * servers in the Athena Computing Environment, has been extended to + * manage all hosts in the MIT.EDU domain (but not subdomains). + */ +/* noclu_mach_check(id, m, hint) int id, hint; struct machine *m; @@ -59,22 +64,24 @@ struct machine *m; if (m->clucount == 0 && m->mach_id != 0) printf("Warning: machine %s is not in any clusters\n", m->name); } - +*/ phase3() { printf("Phase 3 - Finding unused objects\n"); if (warn) { - dprintf("Checking machines...\n"); - hash_step(machines, noclu_mach_check, NULL); - +/* dprintf("Checking machines...\n"); + * hash_step(machines, noclu_mach_check, NULL); + */ dprintf("Checking lists...\n"); hash_step(lists, empty_list_check, NULL); } + EXEC SQL SET autocommit on; dprintf("Checking strings...\n"); hash_step(strings, unref_string_check, NULL); + EXEC SQL SET autocommit off; } diff --git a/dbck/phase4.dc b/dbck/phase4.dc index f9058655..011cc126 100644 --- a/dbck/phase4.dc +++ b/dbck/phase4.dc @@ -21,13 +21,15 @@ struct hash *boxes; int i; if (u->potype == 'P') { - if (i = (int) hash_lookup(boxes, u->pobox_id)) - hash_store(boxes, u->pobox_id, i+1); - else { + if (i = (int) hash_lookup(boxes, u->pobox_id)) { + if( hash_store(boxes, u->pobox_id, i+1) == -1 ) { + out_of_mem("storing poboxes in hash table"); + } + } else { printf("User %s(%s) has pobox on non-POP server %d\n", u->fullname, u->login, u->pobox_id); printf("Not fixing this error\n"); - } + } } } @@ -115,8 +117,12 @@ phase4() break; } - hash_store(boxes, id, 1); - hash_store(counts, id, cnt); + if( hash_store(boxes, id, 1) == -1 ) { + out_of_mem("storing poboxes"); + } + if( hash_store(counts, id, cnt) == -1 ) { + out_of_mem("storing pobox counts? in hash table"); + } } EXEC SQL CLOSE csr401; hash_step(users, count_boxes, boxes); @@ -139,7 +145,7 @@ count_only_setup() struct machine *m; dprintf("Loading users...\n"); - users = create_hash(10000); + users = create_hash(30000); EXEC SQL DECLARE csr402 CURSOR FOR SELECT users_id, login, last, first, status, potype, pop_id, box_id FROM users @@ -173,12 +179,14 @@ count_only_setup() default: u->pobox_id = 0; } - hash_store(users, id, u); + if( hash_store(users, id, u) == -1 ) { + out_of_mem("storing users in hash table"); } + } EXEC SQL CLOSE csr402; dprintf("Loading machines...\n"); - machines = create_hash(1000); + machines = create_hash(20000); EXEC SQL DECLARE csr403 CURSOR FOR SELECT mach_id, name FROM machine; if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode); @@ -195,7 +203,9 @@ count_only_setup() out_of_mem("storing machines"); strcpy(m->name, strtrim(name)); m->mach_id = id; - hash_store(machines, id, m); + if( hash_store(machines, id, m) == -1 ) { + out_of_mem("storing users in hash table"); + } } EXEC SQL CLOSE csr403; @@ -220,7 +230,9 @@ count_only_setup() n->nfsphys_id = id; n->allocated = id3; n->count = 0; - hash_store(nfsphys, id, n); + if( hash_store(nfsphys, id, n) == -1 ) { + out_of_mem("storing nfsphys in hash table"); + } } EXEC SQL CLOSE csr404; -- 2.45.2