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 <netinet/in.h>
19 #include <sys/types.h>
22 #include <afs/bubasics.h>
23 #include "budb_errs.h"
25 #include "error_macros.h"
26 #include "budb_internal.h"
27 #include "afs/audit.h"
31 struct memoryDB db
; /* really allocate it here */
34 db_panic(char *reason
)
36 LogError(0, "db_panic: %s\n", reason
);
47 memset(&db
, 0, sizeof(db
));
48 if ((code
= InitDBalloc()) || (code
= InitDBhash()))
53 /* package up seek and write into one procedure for ease of use */
56 * write a portion of the database
58 * pos - offset into the database (disk address). If this is in the
59 * database header, then buff must be a ptr to a portion of
61 * buff - the information to write
62 * len - size of the write
66 dbwrite(struct ubik_trans
*ut
, afs_int32 pos
, void *buff
, afs_int32 len
)
70 if (((pos
< sizeof(db
.h
)) && (buff
!= (char *)&db
.h
+ pos
))
71 || (pos
>= ntohl(db
.h
.eofPtr
))) {
72 Log("dbwrite: Illegal attempt to write at location 0 or past EOF\n");
76 code
= ubik_Seek(ut
, 0, pos
);
78 LogError(code
, "dbwrite: ubik_Seek to %d failed\n", pos
);
81 code
= ubik_Write(ut
, buff
, len
);
83 LogError(code
, "dbwrite: ubik_Write failed\n");
88 if (((++pollCount
) % 4) == 0) { /* Poll every 4 reads/writes */
89 #ifndef AFS_PTHREAD_ENV
97 /* same thing for read */
100 dbread(struct ubik_trans
*ut
, afs_int32 pos
, void *buff
, afs_int32 len
)
104 if (pos
>= ntohl(db
.h
.eofPtr
)) {
105 LogError(0, "dbread: Attempt to read @%d (past EOF)\n", pos
);
109 code
= ubik_Seek(ut
, 0, pos
);
111 LogError(code
, "dbread: ubik_Seek to %d failed\n", pos
);
114 code
= ubik_Read(ut
, buff
, len
);
116 LogError(code
, "dbread: ubik_Read pos %d, buff %"AFS_PTR_FMT
117 ", len %d\n", pos
, buff
, len
);
122 if (((++pollCount
) % 4) == 0) { /* Poll every 4 reads/writes */
123 #ifndef AFS_PTHREAD_ENV
131 /* Same as dbread excepts it does checking */
133 cdbread(struct ubik_trans
*ut
, int type
, afs_int32 pos
, void *buff
, afs_int32 len
)
137 code
= checkDiskAddress(pos
, type
, 0, 0);
139 LogError(code
, "cdbread: Bad Address for block %d (addr 0x%x)\n",
144 code
= ubik_Seek(ut
, 0, pos
);
146 LogError(code
, "cdbread: ubik_Seek to 0x%x failed\n", pos
);
149 code
= ubik_Read(ut
, buff
, len
);
151 LogError(code
, "cdbread: ubik_Read pos 0x%x, buff %"AFS_PTR_FMT
152 ", len %d\n", pos
, buff
, len
);
157 if (((++pollCount
) % 4) == 0) { /* Poll every 4 reads/writes */
158 #ifndef AFS_PTHREAD_ENV
166 /* check that the database has been initialized. Be careful to fail in a safe
167 manner, to avoid bogusly reinitializing the db. */
170 * reads in db cache from ubik.
172 * @param[in] ut ubik transaction
173 * @param[in] rock opaque pointer to an int (*) (struct ubik_trans *), which
174 * will be called on rebuilding the database (or NULL to not
177 * @return operation status
181 UpdateCache(struct ubik_trans
*ut
, void *rock
)
183 int (*db_init
) (struct ubik_trans
*ut
) = rock
;
186 db
.h
.eofPtr
= htonl(sizeof(db
.h
)); /* for sanity check in dbread */
187 code
= dbread(ut
, 0, (char *)&db
.h
, sizeof(db
.h
));
191 if ((ntohl(db
.h
.version
) != BUDB_VERSION
)
192 || (ntohl(db
.h
.checkVersion
) != BUDB_VERSION
)) {
194 if ((ntohl(db
.h
.version
) == 0) || (ntohl(db
.h
.checkVersion
) == 0))
197 LogError(0, "DB version should be %d; Initial = %d; Terminal = %d\n",
198 BUDB_VERSION
, ntohl(db
.h
.version
), ntohl(db
.h
.checkVersion
));
202 db
.readTime
= time(0);
203 ht_Reset(&db
.volName
);
204 ht_Reset(&db
.tapeName
);
205 ht_Reset(&db
.dumpName
);
206 ht_Reset(&db
.dumpIden
);
210 if ((code
== UEOF
) || (code
== BUDB_EMPTY
)) {
212 LogDebug(0, "No data base - Building new one\n");
214 /* try to write a good header */
215 memset(&db
.h
, 0, sizeof(db
.h
));
216 db
.h
.version
= htonl(BUDB_VERSION
);
217 db
.h
.checkVersion
= htonl(BUDB_VERSION
);
218 db
.h
.lastUpdate
= db
.h
.lastDumpId
= htonl(time(0));
219 db
.h
.eofPtr
= htonl(sizeof(db
.h
));
221 /* text ptrs cleared by bzero */
224 code
= dbwrite(ut
, 0, (char *)&db
.h
, sizeof(db
.h
));
226 code
= BUDB_IO
; /* return the error code */
228 code
= db_init(ut
); /* initialize the db */
230 LogDebug(0, "No data base\n");
234 LogDebug(0, "I/O Error\n");
242 CheckInit(struct ubik_trans
*ut
,
243 int (*db_init
) (struct ubik_trans
*ut
)) /* call if rebuilding DB */
245 return ubik_CheckCache(ut
, UpdateCache
, db_init
);