vos: avoid CreateVolume when restoring over an existing volume 08/14208/7
authorMichael Meffie <mmeffie@sinenomine.net>
Fri, 15 May 2020 16:01:44 +0000 (12:01 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 21 Aug 2020 03:02:51 +0000 (23:02 -0400)
Currently, the UV_RestoreVolume2 function always attempts to create a
new volume, even when doing a incremental restore over an existing
volume.  When the volume already exists, the volume creation operation
fails on the volume server with a VVOLEXISTS error. The client will then
attempt to obtain a transaction on the existing volume. If a transaction
is obtained, the incremental restore operation will proceed. If a full
restore is being done, the existing volume is removed and a new empty
volume is created.

Unfortunately, the failed volume creation is logged to by the volume
server, and so litters the log file with:

    Volser: CreateVolume: Unable to create the volume; aborted, error code 104

To avoid polluting the volume server log with these messages, reverse
the logic in UV_RestoreVolume2. Assume the volume already exists and try
to get the transaction first when doing an incremental restore. Create a
new volume if the transaction cannot be obtained because the volume is
not present.  When doing a full restore, remove the existing volume, if
one exists, and then create a new empty volume.

Change-Id: I8bdc13130d12c81cd2cd18a9484852708cac64d7
Reviewed-on: https://gerrit.openafs.org/14208
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Marcio Brito Barbosa <marciobritobarbosa@gmail.com>
Tested-by: Marcio Brito Barbosa <marciobritobarbosa@gmail.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/volser/vsprocs.c

index 722701f..12961e3 100644 (file)
@@ -4601,41 +4601,40 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
             noresolve ? afs_inet_ntoa_r(toserver, hoststr) :
            hostutil_GetNameByINet(toserver), partName);
     fflush(STDOUT);
-    code =
-       AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid, &pvolid,
-                          &totid);
-    if (code) {
-       if (flags & RV_FULLRST) {       /* full restore: delete then create anew */
-           code = DoVolDelete(toconn, pvolid, topart, "the previous", 0,
-                              &tstatus, NULL);
-           if (code && code != VNOVOL) {
-               error = code;
-               goto refail;
-           }
 
-           code =
-               AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
-                                  &pvolid, &totid);
+    /*
+     * Obtain a transaction and get the status of the target volume. Create a new
+     * volume if the target volume does not already exist.
+     */
+    memset(&tstatus, 0, sizeof(tstatus));
+    if ((flags & RV_FULLRST) != 0) {
+       /* Full restore: Delete existing volume then create anew. */
+       code = DoVolDelete(toconn, pvolid, topart, "the previous", 0, &tstatus, NULL);
+       if (code && code != VNOVOL) {
+           error = code;
+           goto refail;
+       }
+       code = AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
+                                 &pvolid, &totid);
+       EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
+    } else {
+       /* Incremental restore: Obtain a transaction on the existing volume. */
+       code = AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
+       if (code == 0) {
+           code = AFSVolGetStatus(toconn, totid, &tstatus);
+           EGOTO1(refail, code, "Could not get timestamp from volume %u\n", pvolid);
+       } else if (code == VNOVOL) {
+           code = AFSVolCreateVolume(toconn, topart, tovolreal, volsertype,
+                                     pparentid, &pvolid, &totid);
            EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
        } else {
-           code =
-               AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
-           EGOTO1(refail, code, "Failed to start transaction on %u\n",
-                  pvolid);
-
-           code = AFSVolGetStatus(toconn, totid, &tstatus);
-           EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
-                  pvolid);
-
+           EGOTO1(refail, code, "Failed to start transaction on %u\n", pvolid);
        }
-       oldCreateDate = tstatus.creationDate;
-       oldUpdateDate = tstatus.updateDate;
-       oldCloneId = tstatus.cloneID;
-       oldBackupId = tstatus.backupID;
-    } else {
-       oldCreateDate = 0;
-       oldUpdateDate = 0;
     }
+    oldCreateDate = tstatus.creationDate;
+    oldUpdateDate = tstatus.updateDate;
+    oldCloneId = tstatus.cloneID;
+    oldBackupId = tstatus.backupID;
 
     cookie.parent = pparentid;
     cookie.type = voltype;