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>
17 #include <afs/bubasics.h>
18 #include <afs/audit.h>
20 #include "budb_errs.h"
22 #include "error_macros.h"
23 #include "budb_internal.h"
26 struct memoryDB db; /* really allocate it here */
29 db_panic(char *reason)
31 LogError(0, "db_panic: %s\n", reason);
42 memset(&db, 0, sizeof(db));
43 if ((code = InitDBalloc()) || (code = InitDBhash()))
48 /* package up seek and write into one procedure for ease of use */
51 * write a portion of the database
53 * pos - offset into the database (disk address). If this is in the
54 * database header, then buff must be a ptr to a portion of
56 * buff - the information to write
57 * len - size of the write
61 dbwrite(struct ubik_trans *ut, afs_int32 pos, void *buff, afs_int32 len)
65 if (((pos < sizeof(db.h)) && (buff != (char *)&db.h + pos))
66 || (pos >= ntohl(db.h.eofPtr))) {
67 Log("dbwrite: Illegal attempt to write at location 0 or past EOF\n");
71 code = ubik_Seek(ut, 0, pos);
73 LogError(code, "dbwrite: ubik_Seek to %d failed\n", pos);
76 code = ubik_Write(ut, buff, len);
78 LogError(code, "dbwrite: ubik_Write failed\n");
83 if (((++pollCount) % 4) == 0) { /* Poll every 4 reads/writes */
84 #ifndef AFS_PTHREAD_ENV
92 /* same thing for read */
95 dbread(struct ubik_trans *ut, afs_int32 pos, void *buff, afs_int32 len)
99 if (pos >= ntohl(db.h.eofPtr)) {
100 LogError(0, "dbread: Attempt to read @%d (past EOF)\n", pos);
104 code = ubik_Seek(ut, 0, pos);
106 LogError(code, "dbread: ubik_Seek to %d failed\n", pos);
109 code = ubik_Read(ut, buff, len);
111 LogError(code, "dbread: ubik_Read pos %d, buff %"AFS_PTR_FMT
112 ", len %d\n", pos, buff, len);
117 if (((++pollCount) % 4) == 0) { /* Poll every 4 reads/writes */
118 #ifndef AFS_PTHREAD_ENV
126 /* Same as dbread excepts it does checking */
128 cdbread(struct ubik_trans *ut, int type, afs_int32 pos, void *buff, afs_int32 len)
132 code = checkDiskAddress(pos, type, 0, 0);
134 LogError(code, "cdbread: Bad Address for block %d (addr 0x%x)\n",
139 code = ubik_Seek(ut, 0, pos);
141 LogError(code, "cdbread: ubik_Seek to 0x%x failed\n", pos);
144 code = ubik_Read(ut, buff, len);
146 LogError(code, "cdbread: ubik_Read pos 0x%x, buff %"AFS_PTR_FMT
147 ", len %d\n", pos, buff, len);
152 if (((++pollCount) % 4) == 0) { /* Poll every 4 reads/writes */
153 #ifndef AFS_PTHREAD_ENV
161 /* check that the database has been initialized. Be careful to fail in a safe
162 manner, to avoid bogusly reinitializing the db. */
165 * reads in db cache from ubik.
167 * @param[in] ut ubik transaction
168 * @param[in] rock opaque pointer to an int (*) (struct ubik_trans *), which
169 * will be called on rebuilding the database (or NULL to not
172 * @return operation status
176 UpdateCache(struct ubik_trans *ut, void *rock)
178 int (*db_init) (struct ubik_trans *ut) = rock;
181 db.h.eofPtr = htonl(sizeof(db.h)); /* for sanity check in dbread */
182 code = dbread(ut, 0, (char *)&db.h, sizeof(db.h));
186 if ((ntohl(db.h.version) != BUDB_VERSION)
187 || (ntohl(db.h.checkVersion) != BUDB_VERSION)) {
189 if ((ntohl(db.h.version) == 0) || (ntohl(db.h.checkVersion) == 0))
192 LogError(0, "DB version should be %d; Initial = %d; Terminal = %d\n",
193 BUDB_VERSION, ntohl(db.h.version), ntohl(db.h.checkVersion));
197 db.readTime = time(0);
198 ht_Reset(&db.volName);
199 ht_Reset(&db.tapeName);
200 ht_Reset(&db.dumpName);
201 ht_Reset(&db.dumpIden);
205 if ((code == UEOF) || (code == BUDB_EMPTY)) {
207 LogDebug(0, "No data base - Building new one\n");
209 /* try to write a good header */
210 memset(&db.h, 0, sizeof(db.h));
211 db.h.version = htonl(BUDB_VERSION);
212 db.h.checkVersion = htonl(BUDB_VERSION);
213 db.h.lastUpdate = db.h.lastDumpId = htonl(time(0));
214 db.h.eofPtr = htonl(sizeof(db.h));
216 /* text ptrs cleared by bzero */
219 code = dbwrite(ut, 0, (char *)&db.h, sizeof(db.h));
221 code = BUDB_IO; /* return the error code */
223 code = db_init(ut); /* initialize the db */
225 LogDebug(0, "No data base\n");
229 LogDebug(0, "I/O Error\n");
237 CheckInit(struct ubik_trans *ut,
238 int (*db_init) (struct ubik_trans *ut)) /* call if rebuilding DB */
240 return ubik_CheckCache(ut, UpdateCache, db_init);