vldb_check: Check for volume lock inconsistencies 07/14307/8
authorMichael Meffie <mmeffie@sinenomine.net>
Mon, 17 Aug 2020 19:44:55 +0000 (15:44 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 27 Nov 2020 04:08:07 +0000 (23:08 -0500)
Verify the a lock timestamp is set if, and only if, a lock volume
operation flag is also set.

When running vldb_check with the -fix option, fix the inconsistent
entries by setting the lock timestamp to the current time if a lock flag
is set, or by setting the VLOP_DELETE flag if the lock timestamp is set
but no lock flags are set. (The VLOP_DELETE flag is the flag set by the
'vos lock command, and is shown in vos output as "delete/misc".)

Volume lock fields can be put into an inconsistent state, at least, by
interupted vos rename operations, due to bugs in vos rename. When the
volume lock timestamp and lock flags are in this inconsistent state, the
volume is locked, but that is not indicated by 'vos listvldb'. The
volume can be unlocked by issuing 'vos unlock'.

Change-Id: Idc4f821a9eb7675edd78a8547fdfe46e838b0c89
Reviewed-on: https://gerrit.openafs.org/14307
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/vlserver/vldb_check.c

index 5e454d2..87efccb 100644 (file)
@@ -1465,6 +1465,14 @@ WorkerBee(struct cmd_syndesc *as, void *arock)
                log_error(VLDB_CHECK_ERROR,"address %u (offset 0x%0x): Record not in a BK chain (type 0x%0x)\n",
                       record[i].addr, OFFSET(record[i].addr), record[i].type);
            }
+           if ((vlentry.LockTimestamp == 0 && (vlentry.flags & VLOP_ALLOPERS) != 0) ||
+              (vlentry.LockTimestamp != 0 && (vlentry.flags & VLOP_ALLOPERS) == 0)) {
+               log_error(VLDB_CHECK_ERROR,
+                   "address %u (offset 0x%0x): Lock inconsistency in volume '%s'; timestamp %d, lock flags 0x%0x\n",
+                   record[i].addr, OFFSET(record[i].addr), vlentry.name,
+                   vlentry.LockTimestamp, (vlentry.flags & VLOP_ALLOPERS));
+           }
+
            if (fix) {
                afs_uint32 oldhash, newhash;
                char oldNameBuffer[10 + VL_MAXNAMELEN];
@@ -1564,6 +1572,21 @@ WorkerBee(struct cmd_syndesc *as, void *arock)
                    vlentry.nextIdHash[j] = header.VolidHash[j][hash];
                    header.VolidHash[j][hash] = record[i].addr;
                }
+
+               /*
+                * Fix lock timestamp and flag inconsistencies.
+                */
+               if (vlentry.LockTimestamp == 0 && (vlentry.flags & VLOP_ALLOPERS) != 0) {
+                   quiet_println("FIX: Record %u: Inconsistent lock in volume %s; setting timestamp.\n",
+                                 record[i].addr, vlentry.name);
+                   vlentry.LockTimestamp = time(NULL);
+               }
+               if (vlentry.LockTimestamp != 0 && (vlentry.flags & VLOP_ALLOPERS) == 0) {
+                   quiet_println("FIX: Record %u: Inconsistent lock in volume %s; setting misc lock flag.\n",
+                                 record[i].addr, vlentry.name);
+                   vlentry.flags |= VLOP_DELETE; /* Shown by vos as "delete/misc". */
+               }
+
                writeentry(record[i].addr, &vlentry);
            }
        }