mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 15:00:12 +00:00
vos: fix name availability check in vos rename
The UV_RenameVolume() function first updates the volume name in the VLDB, then read-write volume header and backup volume header, and finally all of the read-only volume headers. If this function is interrupted or a remote site is not reachable, the names in some of the volume headers will be out of sync with name in the VLDB entry. The implementation of UV_RenameVolume() is idempotent, so can be safely called with the same name as in the volume's VLDB entry. This could be used to bring all the names in the volume headers in sync with the name in the VLDB. Unfortunately, due to the check of the -newname parameter, vos rename will not invoke UV_RenameVolume() when the name in the VLDB has already been changed. The vos rename command attempts to verify the desired name (-newname) is available before invoking UV_RenameVolume() by simply checking if a VLDB entry exists with that name, and incorrectly assumes when a VLDB entry exists with that name it is an entry for a different volume. Change the -newname check to allow vos rename to proceed when name has already been set in the VLDB entry of the volume being renamed. This allows admins to run vos rename command to complete a previously incomplete rename operation and bring the names in the volume headers in sync with the name in the VLDB entry. Note: Before this commit, administrators could workaround this vos rename limitation by renaming the volume twice, first to an unused volume name, then to the actual desired volume name. Remove the useless checks of the code1 return code after exit in the RenameVolume() function. These checks for code1 are never performed since the function exits early when the first VLDB_GetEntryByName() fails for any reason. Update the vos rename man page to show vos rename can be used to fix previously interrupted/failed rename. Also document the -oldname parameter accepts a numeric volume id to specify the volume to be renamed. Change-Id: Ibb5dbe3148e9b8295347925a59cd7bdbccbe8fe0 Reviewed-on: https://gerrit.openafs.org/13720 Reviewed-by: Cheyenne Wills <cwills@sinenomine.net> Reviewed-by: Andrew Deason <adeason@sinenomine.net> Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
parent
6c54bc9e12
commit
9238b1eb9e
@ -40,14 +40,17 @@ command.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-oldname> <I<old volume name>>
|
||||
=item B<-oldname> <I<old volume name or id>>
|
||||
|
||||
Is the current name of the read/write volume.
|
||||
Is the current name or numeric id of the read/write volume to be renamed.
|
||||
|
||||
=item B<-newname> <I<new volume name>>
|
||||
|
||||
Is the desired new name for the volume.
|
||||
|
||||
The new name may be the same as the current volume name in the VLDB
|
||||
in order to complete a previously interrupted volume rename.
|
||||
|
||||
=include fragments/vos-common.pod
|
||||
|
||||
=back
|
||||
|
@ -4153,25 +4153,39 @@ VolserStatus(struct cmd_syndesc *as, void *arock)
|
||||
static int
|
||||
RenameVolume(struct cmd_syndesc *as, void *arock)
|
||||
{
|
||||
afs_int32 code1, code2, code;
|
||||
afs_int32 code;
|
||||
struct nvldbentry entry;
|
||||
struct nvldbentry entry2;
|
||||
|
||||
code1 = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
|
||||
if (code1) {
|
||||
/* Get the entry of the volume to be renamed (-oldname), by name or id. */
|
||||
code = VLDB_GetEntryByName(as->parms[0].items->data, &entry);
|
||||
if (code) {
|
||||
fprintf(STDERR, "vos: Could not find entry for volume %s\n",
|
||||
as->parms[0].items->data);
|
||||
exit(1);
|
||||
}
|
||||
code2 = VLDB_GetEntryByName(as->parms[1].items->data, &entry);
|
||||
if ((!code1) && (!code2)) { /*the newname already exists */
|
||||
fprintf(STDERR, "vos: volume %s already exists\n",
|
||||
as->parms[1].items->data);
|
||||
PrintError("", code);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (code1 && code2) {
|
||||
fprintf(STDERR, "vos: Could not find entry for volume %s or %s\n",
|
||||
as->parms[0].items->data, as->parms[1].items->data);
|
||||
/*
|
||||
* Verify the new name is available before attempting to rename.
|
||||
* Allow renaming of the same volume in order to complete a
|
||||
* previously interrupted rename.
|
||||
*/
|
||||
code = VLDB_GetEntryByName(as->parms[1].items->data, &entry2);
|
||||
if (code != 0 && code != VL_NOENT) {
|
||||
fprintf(STDERR, "vos: Could not check entry for volume %s\n",
|
||||
as->parms[1].items->data);
|
||||
PrintError("", code);
|
||||
exit(1);
|
||||
}
|
||||
if (code == 0 && entry.volumeId[RWVOL] != entry2.volumeId[RWVOL]) {
|
||||
fprintf(STDERR, "vos: Cannot rename volume %s (%lu) to %s;"
|
||||
" volume %s (%lu) already exists\n",
|
||||
as->parms[0].items->data,
|
||||
(unsigned long)entry.volumeId[RWVOL],
|
||||
as->parms[1].items->data,
|
||||
as->parms[1].items->data,
|
||||
(unsigned long)entry2.volumeId[RWVOL]);
|
||||
exit(1);
|
||||
}
|
||||
if (!VolNameOK(as->parms[0].items->data)) {
|
||||
|
Loading…
Reference in New Issue
Block a user