volser: Lock entry properly in UV_RestoreVolume2

Since the original IBM code import, UV_RestoreVolume (later renamed to
to the current name UV_RestoreVolume2) has called VLDB_GetEntryByID to
obtain the VLDB entry of the target/destination volume.  This entry is
then modified to match the restore changes, locked via VL_SetLock, and
replaced via VL_ReplaceEntryN.

Unfortunately, this allows for a race with other volume operations
against the same volume, if another operation alters the entry after we
call VLDB_GetEntryByID but before ubik_VL_SetLock. To avoid this, call
GetLockedEntry to ensure that the entry is locked while we are reading
and modifying it.

Change-Id: I772ef80158205f45c04f8ef0aa95726f1f2c4ac4
Reviewed-on: https://gerrit.openafs.org/14354
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
This commit is contained in:
Mark Vitale 2020-08-31 15:08:40 -04:00 committed by Andrew Deason
parent 1073e94779
commit c14536545d

View File

@ -4675,16 +4675,17 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
/* Volume was restored on the file server, update the
* VLDB to reflect the change.
*/
vcode = VLDB_GetEntryByID(pvolid, voltype, &entry);
vcode = GetLockedEntry(pvolid, voltype, VLOP_RESTORE, &entry);
if (vcode != 0 && vcode != VL_NOENT) {
fprintf(STDERR,
"Could not fetch the entry for volume number %lu from VLDB \n",
"Could not fetch locked VLDB entry for volume %lu\n",
(unsigned long)pvolid);
error = vcode;
goto refail;
}
if (!vcode)
MapHostToNetwork(&entry);
islocked = 1;
if (vcode == VL_NOENT) { /* it doesnot exist already */
/*make the vldb return this indication specifically */
VPRINT("------- Creating a new VLDB entry ------- \n");
@ -4716,7 +4717,6 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
error = vcode;
goto refail;
}
islocked = 0;
if (verbose)
EnumerateEntry(&entry);
} else { /*update the existing entry */
@ -4726,17 +4726,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
EnumerateEntry(&entry);
fprintf(STDOUT, "------- New entry -------\n");
}
vcode =
ubik_VL_SetLock(cstruct, 0, pvolid, voltype,
VLOP_RESTORE);
if (vcode) {
fprintf(STDERR,
"Could not lock the entry for volume number %lu \n",
(unsigned long)pvolid);
error = vcode;
goto refail;
}
islocked = 1;
strcpy(entry.name, tovolname);
/* Update the vlentry with the new information */