21
21
#define MHC 0x100 /* on multihomed chain */
22
22
#define FRC 0x200 /* on free chain */
24
#define REFRW 0x1000 /* linked from something (RW) */
25
#define REFRO 0x2000 /* linked from something (RO) */
26
#define REFBK 0x4000 /* linked from something (BK) */
27
#define REFN 0x8000 /* linked from something (name) */
29
#define vldbread(x,y,z) vldbio(x,y,z,0)
30
#define vldbwrite(x,y,z) vldbio(x,y,z,1)
24
32
#include <afsconfig.h>
25
33
#include <afs/param.h>
28
("$Header: /cvs/openafs/src/vlserver/vldb_check.c,v 1.11 2003/11/29 21:38:04 jaltman Exp $");
36
("$Header: /cvs/openafs/src/vlserver/vldb_check.c,v 1.11.2.1 2006/12/16 06:26:42 shadow Exp $");
30
38
#include <sys/types.h>
31
39
#include <sys/stat.h>
251
267
headerp->vital_header.headersize, sizeof(*headerp));
254
readMH(addr, mhblockP)
256
struct extentaddr *mhblockP;
271
writeheader(struct vlheader *headerp)
275
headerp->vital_header.vldbversion =
276
htonl(headerp->vital_header.vldbversion);
277
headerp->vital_header.headersize =
278
htonl(headerp->vital_header.headersize);
279
headerp->vital_header.freePtr = htonl(headerp->vital_header.freePtr);
280
headerp->vital_header.eofPtr = htonl(headerp->vital_header.eofPtr);
281
headerp->vital_header.allocs = htonl(headerp->vital_header.allocs);
282
headerp->vital_header.frees = htonl(headerp->vital_header.frees);
283
headerp->vital_header.MaxVolumeId =
284
htonl(headerp->vital_header.MaxVolumeId);
285
headerp->vital_header.totalEntries[0] =
286
htonl(headerp->vital_header.totalEntries[0]);
287
for (i = 0; i < MAXTYPES; i++)
288
headerp->vital_header.totalEntries[i] =
289
htonl(headerp->vital_header.totalEntries[1]);
291
headerp->SIT = htonl(headerp->SIT);
292
for (i = 0; i < MAXSERVERID; i++)
293
headerp->IpMappedAddr[i] = htonl(headerp->IpMappedAddr[i]);
294
for (i = 0; i < HASHSIZE; i++)
295
headerp->VolnameHash[i] = htonl(headerp->VolnameHash[i]);
296
for (i = 0; i < MAXTYPES; i++)
297
for (j = 0; j < HASHSIZE; j++)
298
headerp->VolidHash[i][j] = htonl(headerp->VolidHash[i][j]);
300
vldbwrite(0, headerp, sizeof(*headerp));
304
readMH(afs_int32 addr, struct extentaddr *mhblockP)
259
307
struct extentaddr *e;
405
writeentry(afs_int32 addr, struct nvlentry *vlentryp)
410
printf("Writing back entry at addr %u\n", addr);
412
for (i = 0; i < MAXTYPES; i++)
413
vlentryp->volumeId[i] = htonl(vlentryp->volumeId[i]);
414
vlentryp->flags = htonl(vlentryp->flags);
415
vlentryp->LockAfsId = htonl(vlentryp->LockAfsId);
416
vlentryp->LockTimestamp = htonl(vlentryp->LockTimestamp);
417
vlentryp->cloneId = htonl(vlentryp->cloneId);
418
for (i = 0; i < MAXTYPES; i++)
419
vlentryp->nextIdHash[i] = htonl(vlentryp->nextIdHash[i]);
420
vlentryp->nextNameHash = htonl(vlentryp->nextNameHash);
421
for (i = 0; i < NMAXNSERVERS; i++) {
422
vlentryp->serverNumber[i] = htonl(vlentryp->serverNumber[i]);
423
vlentryp->serverPartition[i] = htonl(vlentryp->serverPartition[i]);
424
vlentryp->serverFlags[i] = htonl(vlentryp->serverFlags[i]);
426
vldbwrite(addr, vlentryp, sizeof(*vlentryp));
430
readSIT(int base, int addr)
364
433
char sitbuf[VL_ADDREXTBLK_SIZE];
584
SetHashEnd(long addr, int type, long new)
586
struct nvlentry vlentry;
587
afs_int32 i, rindex, type2, next = -1;
589
for (; addr; addr = next) {
590
readentry(addr, &vlentry, &type2);
591
switch(type & 0xf0) {
593
next = vlentry.nextIdHash[0];
596
next = vlentry.nextIdHash[1];
599
next = vlentry.nextIdHash[2];
602
next = vlentry.nextNameHash;
609
switch(type & 0xf0) {
611
if (vlentry.nextIdHash[0] != 0) {printf("bwoop\n");}
612
vlentry.nextIdHash[0] = new;
615
if (vlentry.nextIdHash[1] != 0) {printf("bwoop\n");}
616
vlentry.nextIdHash[1] = new;
619
if (vlentry.nextIdHash[2] != 0) {printf("bwoop\n");}
620
vlentry.nextIdHash[2] = new;
623
if (vlentry.nextNameHash != 0) {printf("bwoop\n");}
624
vlentry.nextNameHash = new;
627
writeentry(addr, &vlentry);
512
634
* Follow each Name hash bucket marking it as read in the record array.
513
635
* Record we found it in the name hash within the record array.
514
636
* Check that the name is hashed correctly.
516
FollowNameHash(header)
517
struct vlheader *header;
639
FollowNameHash(struct vlheader *header)
519
641
int count = 0, longest = 0, shortest = -1, chainlength;
520
642
struct nvlentry vlentry;
576
700
* Record we found it in the id hash within the record array.
577
701
* Check that the ID is hashed correctly.
580
struct vlheader *header;
704
FollowIdHash(struct vlheader *header)
582
706
int count = 0, longest = 0, shortest = -1, chainlength;
583
707
struct nvlentry vlentry;
585
afs_int32 i, j, hash, type, rindex;
709
afs_int32 i, j, hash, type, rindex, ref;
587
711
/* Now follow the RW, RO, and BK Hash Tables */
589
713
printf("Check RW, RO, and BK id Hashes\n");
590
714
for (i = 0; i < MAXTYPES; i++) {
591
715
hash = ((i == 0) ? RWH : ((i == 1) ? ROH : BKH));
716
ref = ((i == 0) ? REFRW : ((i == 1) ? REFRO : REFBK));
592
717
count = longest = 0;
1029
FixBad(afs_uint32 idx, afs_uint32 addr, afs_uint32 type, afs_uint32 tmp,
1030
struct nvlentry *vlentry) {
1031
SetHashEnd(addr, type, tmp);
1032
printf("linked unlinked chain %u (index %d) to end of chain\n",
904
struct cmd_syndesc *as;
1037
WorkerBee(struct cmd_syndesc *as, char *arock)
908
afs_int32 maxentries, type;
1040
afs_int32 maxentries, type, tmp;
909
1041
struct vlheader header;
910
1042
struct nvlentry vlentry;
911
1043
int i, j, help = 0;
916
1048
listservers = (as->parms[3].items ? 1 : 0); /* -servers */
917
1049
listentries = (as->parms[4].items ? 1 : 0); /* -entries */
918
1050
verbose = (as->parms[5].items ? 1 : 0); /* -verbose */
1051
fix = (as->parms[6].items ? 1 : 0); /* -fix */
920
1053
/* open the vldb database file */
921
fd = open(dbfile, O_RDONLY, 0);
1054
fd = open(dbfile, (fix > 0)?O_RDWR:O_RDONLY, 0);
923
1056
printf("can't open file '%s'. error = %d\n", dbfile, errno);
967
1106
* on the hash chains, and its server numbers are good.
969
1108
if (record[i].type & VL) {
970
1112
readentry(record[i].addr, &vlentry, &type);
972
1114
if (InvalidVolname(vlentry.name))
973
1115
printf("Volume '%s' at addr %u has an invalid name\n",
974
1116
vlentry.name, record[i].addr);
976
if (!(record[i].type & NH))
977
printf("Volume '%s' not found in name hash\n", vlentry.name);
979
if (vlentry.volumeId[0] && !(record[i].type & RWH))
980
printf("Volume '%s' id %u not found in RW hash chain\n",
981
vlentry.name, vlentry.volumeId[0]);
983
if (vlentry.volumeId[1] && !(record[i].type & ROH))
984
printf("Volume '%s' id %u not found in RO hash chain\n",
985
vlentry.name, vlentry.volumeId[1]);
987
if (vlentry.volumeId[2] && !(record[i].type & BKH))
988
printf("Volume '%s' id %u not found in BK hash chain\n",
989
vlentry.name, vlentry.volumeId[2]);
1118
if (!(record[i].type & NH)) {
1119
nextp = ADDR(vlentry.nextNameHash);
1121
hash = NameHash(vlentry.name);
1122
nextpp = &vlentry.nextNameHash;
1124
sprintf(volidbuf, "");
1128
if (vlentry.volumeId[0] && !(record[i].type & RWH)) {
1129
nextp = ADDR(vlentry.nextIdHash[0]);
1131
hash = IdHash(vlentry.volumeId[0]);
1132
nextpp = &(vlentry.nextIdHash[0]);
1134
sprintf(volidbuf, "id %u ", vlentry.volumeId[0]);
1138
if (vlentry.volumeId[1] && !(record[i].type & ROH)) {
1139
nextp = ADDR(vlentry.nextIdHash[1]);
1141
hash = IdHash(vlentry.volumeId[1]);
1142
nextpp = &(vlentry.nextIdHash[1]);
1144
sprintf(volidbuf, "id %u ", vlentry.volumeId[1]);
1148
if (vlentry.volumeId[2] && !(record[i].type & BKH)) {
1149
nextp = ADDR(vlentry.nextIdHash[2]);
1151
hash = IdHash(vlentry.volumeId[2]);
1152
nextpp = &(vlentry.nextIdHash[2]);
1154
sprintf(volidbuf, "id %u ", vlentry.volumeId[2]);
1159
printf("%d: Volume '%s' %snot found in %s hash %d", i,
1160
vlentry.name, volidbuf, which, hash);
1162
printf(" (next %d", nextp);
1163
if (!(record[nextp].type & reft)) {
1164
printf(" not in chain ");
1165
record[nextp].type |= reft;
1166
} else if (nextp != 0) {
1167
printf(" next in chain");
1169
printf(", unchaining");
1171
writeentry(record[i].addr, &vlentry);
991
1179
for (j = 0; j < NMAXNSERVERS; j++) {
992
1180
if ((vlentry.serverNumber[j] != 255)
993
1181
&& (serveraddrs[vlentry.serverNumber[j]] == 0)) {
996
1184
vlentry.name, j, vlentry.serverNumber[j]);
1000
if (record[i].type & 0xffffff00)
1188
if (record[i].type & 0xffff0f00)
1002
1190
("Volume '%s' id %u also found on other chains (0x%x)\n",
1003
1191
vlentry.name, vlentry.volumeId[0], record[i].type);
1005
1193
/* A free entry */
1006
1194
} else if (record[i].type & FR) {
1007
1195
if (!(record[i].type & FRC))
1008
1196
printf("Free vlentry at %u not on free chain\n",
1009
1197
record[i].addr);
1011
1199
if (record[i].type & 0xfffffdf0)
1013
1201
("Free vlentry at %u also found on other chains (0x%x)\n",
1014
1202
record[i].addr, record[i].type);
1016
1204
/* A multihomed entry */
1017
1205
} else if (record[i].type & MH) {
1018
1206
if (!(record[i].type & MHC))
1019
1207
printf("Multihomed block at %u is orphaned\n",
1020
1208
record[i].addr);
1022
1210
if (record[i].type & 0xfffffef0)
1024
1212
("Multihomed block at %u also found on other chains (0x%x)\n",
1025
1213
record[i].addr, record[i].type);
1028
1216
printf("Unknown entry type at %u (0x%x)\n", record[i].addr,
1029
1217
record[i].type);
1221
/* By the time we get here, unchained entries are really unchained */
1222
printf("Scanning %u entries for possible repairs\n", maxentries);
1223
for (i = 0; i < maxentries; i++) {
1224
if (record[i].type & VL) {
1225
readentry(record[i].addr, &vlentry, &type);
1226
if (!(record[i].type & REFN) && (strlen(vlentry.name)>0)) {
1227
printf("%d: Record %u (type 0x%x) not in a name chain\n", i,
1228
record[i].addr, record[i].type);
1230
if (header.VolnameHash[NameHash(vlentry.name)] == 0)
1231
header.VolnameHash[NameHash(vlentry.name)] = record[i].addr;
1233
FixBad(i, header.VolnameHash[NameHash(vlentry.name)], NH, record[i].addr, &vlentry);
1236
if (vlentry.volumeId[0] && !(record[i].type & REFRW)) {
1237
printf("%d: Record %u (type 0x%x) not in a RW chain\n", i,
1238
record[i].addr, record[i].type);
1240
if (header.VolidHash[0][IdHash(vlentry.volumeId[0])] == 0)
1241
header.VolidHash[0][IdHash(vlentry.volumeId[0])] = record[i].addr;
1243
FixBad(i, header.VolidHash[0][IdHash(vlentry.volumeId[0])], RWH, record[i].addr, &vlentry);
1246
if (vlentry.volumeId[1] && !(record[i].type & REFRO)) {
1247
printf("%d: Record %u (type 0x%x) not in a RO chain\n", i,
1248
record[i].addr, record[i].type);
1250
if (header.VolidHash[1][IdHash(vlentry.volumeId[1])] == 0)
1251
header.VolidHash[1][IdHash(vlentry.volumeId[1])] = record[i].addr;
1253
FixBad(i, header.VolidHash[1][IdHash(vlentry.volumeId[1])], ROH, record[i].addr, &vlentry);
1256
if (vlentry.volumeId[2] && !(record[i].type & REFBK)) {
1257
printf("%d: Record %u (type 0x%x) not in a BK chain\n", i,
1258
record[i].addr, record[i].type);
1260
if (header.VolidHash[2][IdHash(vlentry.volumeId[2])] == 0)
1261
header.VolidHash[2][IdHash(vlentry.volumeId[2])] = record[i].addr;
1263
FixBad(i, header.VolidHash[2][IdHash(vlentry.volumeId[2])], BKH, record[i].addr, &vlentry);
1270
writeheader(&header);
1276
main(int argc, char **argv)
1039
1278
struct cmd_syndesc *ts;