2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <netinet/in.h>
20 #include <sys/types.h>
24 #include <afs/bubasics.h>
25 #include "budb_errs.h"
27 #include "error_macros.h"
28 #include "afs/audit.h"
33 struct memoryDB db; /* really allocate it here */
35 void db_panic (reason)
38 LogError(0, "db_panic: %s\n", reason);
47 memset(&db, 0, sizeof(db));
49 if ((code = InitDBalloc ()) || (code = InitDBhash ()))
54 /* package up seek and write into one procedure for ease of use */
57 * write a portion of the database
59 * pos - offset into the database (disk address). If this is in the
60 * database header, then buff must be a ptr to a portion of
62 * buff - the information to write
63 * len - size of the write
66 afs_int32 dbwrite (ut, pos, buff, len)
67 struct ubik_trans *ut;
74 if ( ( (pos < sizeof(db.h)) && (buff != (char *)&db.h + pos) ) ||
75 (pos >= ntohl(db.h.eofPtr)) )
77 Log("dbwrite: Illegal attempt to write at location 0 or past EOF\n");
81 code = ubik_Seek(ut, 0, pos);
84 LogError(code, "dbwrite: ubik_Seek to %d failed\n", pos);
87 code = ubik_Write(ut,buff,len);
90 LogError(code, "dbwrite: ubik_Write failed\n");
95 if (((++pollCount) % 4) == 0) /* Poll every 4 reads/writes */
103 /* same thing for read */
105 afs_int32 dbread (ut, pos, buff, len)
106 struct ubik_trans *ut;
113 if (pos >= ntohl(db.h.eofPtr))
115 LogError(0, "dbread: Attempt to read @%d (past EOF)\n", pos);
119 code = ubik_Seek(ut, 0, pos);
122 LogError(code, "dbread: ubik_Seek to %d failed\n", pos);
125 code = ubik_Read(ut, buff, len);
128 LogError(code, "dbread: ubik_Read pos %d, buff %d, len %d\n", pos, buff, len);
133 if (((++pollCount) % 4) == 0) /* Poll every 4 reads/writes */
141 /* Same as dbread excepts it does checking */
142 afs_int32 cdbread (ut, type, pos, buff, len)
143 struct ubik_trans *ut;
151 code = checkDiskAddress(pos, type, 0, 0);
154 LogError(code, "cdbread: Bad Address for block %d (addr 0x%x)\n",
159 code = ubik_Seek(ut, 0, pos);
162 LogError(code, "cdbread: ubik_Seek to 0x%x failed\n", pos);
165 code = ubik_Read(ut, buff, len);
168 LogError(code, "cdbread: ubik_Read pos 0x%x, buff %d, len %d\n", pos, buff, len);
173 if (((++pollCount) % 4) == 0) /* Poll every 4 reads/writes */
181 /* check that the database has been initialized. Be careful to fail in a safe
182 manner, to avoid bogusly reinitializing the db. */
185 CheckInit (ut, db_init)
186 struct ubik_trans *ut;
187 int (*db_init)(); /* procedure to call if rebuilding DB */
189 register afs_int32 code;
191 /* Don't read header if not necessary */
192 if (!ubik_CacheUpdate (ut)) return 0;
194 ObtainWriteLock (&db.lock);
196 db.h.eofPtr = htonl(sizeof(db.h)); /* for sanity check in dbread */
197 code = dbread(ut, 0, (char *) &db.h, sizeof(db.h));
198 if (code) ERROR(code);
200 if ((ntohl(db.h.version) != BUDB_VERSION) || (ntohl(db.h.checkVersion) != BUDB_VERSION))
203 if ((ntohl(db.h.version) == 0) || (ntohl(db.h.checkVersion) == 0))
206 LogError(0, "DB version should be %d; Initial = %d; Terminal = %d\n",
207 BUDB_VERSION, ntohl(db.h.version), ntohl(db.h.checkVersion));
211 db.readTime = time(0);
212 ht_Reset (&db.volName);
213 ht_Reset (&db.tapeName);
214 ht_Reset (&db.dumpName);
215 ht_Reset (&db.dumpIden);
218 ReleaseWriteLock (&db.lock);
221 if ((code == UEOF) || (code == BUDB_EMPTY))
225 LogDebug(0, "No data base - Building new one\n");
227 /* try to write a good header */
228 memset(&db.h, 0, sizeof(db.h));
229 db.h.version = htonl(BUDB_VERSION);
230 db.h.checkVersion = htonl(BUDB_VERSION);
231 db.h.lastUpdate = db.h.lastDumpId = htonl(time(0));
232 db.h.eofPtr = htonl(sizeof(db.h));
234 /* text ptrs cleared by bzero */
237 code = dbwrite(ut, 0, (char *) &db.h, sizeof(db.h));
238 if (code) code = BUDB_IO; /* return the error code */
239 else code = db_init(ut); /* initialize the db */
243 LogDebug(0, "No data base\n");
249 LogDebug(0, "I/O Error\n");