volser: Remove redundant success flag
[openafs.git] / src / volser / vsprocs.c
index bf59860..a5147b0 100644 (file)
@@ -21,6 +21,7 @@
 #include <afs/voldefs.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
+#include <rx/rx_queue.h>
 #include <afs/vlserver.h>
 #include <afs/nfs.h>
 #include <afs/cellconfig.h>
@@ -642,12 +643,10 @@ UV_PartitionInfo64(afs_uint32 server, char *pname,
     struct rx_connection *aconn;
     afs_int32 code = 0;
 
-    aconn = (struct rx_connection *)0;
     aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
     code = AFSVolPartitionInfo64(aconn, pname, partition);
     if (code == RXGEN_OPCODE) {
-       struct diskPartition *dpp =
-           (struct diskPartition *)malloc(sizeof(struct diskPartition));
+       struct diskPartition *dpp = malloc(sizeof(struct diskPartition));
        code = AFSVolPartitionInfo(aconn, pname, dpp);
        if (!code) {
            strncpy(partition->name, dpp->name, 32);
@@ -722,7 +721,6 @@ UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
     struct volintInfo tstatus;
 
     tid = 0;
-    aconn = (struct rx_connection *)0;
     error = 0;
 
     init_volintInfo(&tstatus);
@@ -762,6 +760,12 @@ UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
     /* rw,ro, bk id are related in the default case */
     /* If caller specified RW id, but not RO/BK ids, have them be RW+1 and RW+2 */
     lastid = *anewid;
+    if (aroid && *aroid != 0) {
+       lastid = max(lastid, *aroid);
+    }
+    if (abkid && *abkid != 0) {
+       lastid = max(lastid, *abkid);
+    }
     if (aroid && *aroid == 0) {
        *aroid = ++lastid;
     }
@@ -1509,7 +1513,7 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
     pntg = 1;
     toconn = UV_Bind(atoserver, AFSCONF_VOLUMEPORT);   /* get connections to the servers */
     fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
-    fromtid = totid = 0;       /* initialize to uncreated */
+    totid = 0; /* initialize to uncreated */
 
     /* ***
      * clone the read/write volume locally.
@@ -1526,7 +1530,7 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        /* Get a clone id */
        VPRINT1("Allocating new volume id for clone of volume %u ...",
                afromvol);
-       newVol = tmpVol = 0;
+       tmpVol = 0;
        vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
        newVol = tmpVol;
        EGOTO1(mfail, vcode,
@@ -2019,8 +2023,8 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        }
 
        if (volid && toconn)
-           code = DoVolDelete(toconn, volid, atopart,
-                              "destination", 0, NULL, "Recovery:");
+           DoVolDelete(toconn, volid, atopart,
+                       "destination", 0, NULL, "Recovery:");
 
        /* put source volume on-line */
        if (fromconn) {
@@ -2059,20 +2063,19 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
 
        /* delete backup volume */
        if (fromconn) {
-           code = DoVolDelete(fromconn, backupId, afrompart,
-                              "backup", 0, NULL, "Recovery:");
+           DoVolDelete(fromconn, backupId, afrompart,
+                       "backup", 0, NULL, "Recovery:");
 
-           code = DoVolDelete(fromconn, afromvol, afrompart, "source",
-                              (atoserver != afromserver)?atoserver:0,
-                              NULL, NULL);
+           DoVolDelete(fromconn, afromvol, afrompart, "source",
+                       (atoserver != afromserver)?atoserver:0,
+                       NULL, NULL);
        }
     }
 
     /* common cleanup - delete local clone */
-    if (newVol) {
-       code = DoVolDelete(fromconn, newVol, afrompart,
-                          "clone", 0, NULL, "Recovery:");
-    }
+    if (newVol)
+       DoVolDelete(fromconn, newVol, afrompart,
+                   "clone", 0, NULL, "Recovery:");
 
     /* unlock VLDB entry */
     if (islocked) {
@@ -2081,7 +2084,6 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
                            (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
        VDONE;
-       islocked = 0;
     }
   done:                        /* routine cleanup */
     if (volName)
@@ -3302,7 +3304,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     manyDests tr;
     manyResults results;
     int rwindex, roindex, roclone, roexists;
-    afs_uint32 rwcrdate = 0;
+    afs_uint32 rwcrdate = 0, rwupdate = 0;
     afs_uint32 clcrdate;
     struct rtime {
        int validtime;
@@ -3313,6 +3315,9 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     char hoststr[16];
     afs_int32 origflags[NMAXNSERVERS];
     struct volser_status orig_status;
+    int notreleased = 0;
+    int tried_justnewsites = 0;
+    int justnewsites = 0; /* are we just trying to release to new RO sites? */
 
     memset(remembertime, 0, sizeof(remembertime));
     memset(&results, 0, sizeof(results));
@@ -3374,12 +3379,21 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        if (entry.serverFlags[i] & ITSROVOL) {
            m++;
            if (entry.serverFlags[i] & NEW_REPSITE) s++;
+           if (entry.serverFlags[i] & RO_DONTUSE) notreleased++;
        }
        origflags[i] = entry.serverFlags[i];
     }
     if ((forceflag && !fullrelease) || (s == m) || (s == 0))
        fullrelease = 1;
 
+    if (!forceflag && (s == m || s == 0)) {
+       if (notreleased && notreleased != m) {
+           /* we have some new unreleased sites. try to just release to those,
+            * if the RW has not changed */
+           justnewsites = 1;
+       }
+    }
+
     /* Determine which volume id to use and see if it exists */
     cloneVolId =
        ((fullrelease
@@ -3462,6 +3476,11 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        }
     }
 
+    if (fullrelease != 1) {
+       /* in case the RW has changed, and just to be safe */
+       justnewsites = 0;
+    }
+
     if (verbose) {
        switch (fullrelease) {
            case 2:
@@ -3471,6 +3490,11 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            case 1:
                fprintf(STDOUT, "This is a complete release of volume %lu\n",
                        (unsigned long)afromvol);
+               if (justnewsites) {
+                   tried_justnewsites = 1;
+                   fprintf(STDOUT, "There are new RO sites; we will try to "
+                                   "only release to new sites\n");
+               }
                break;
            case 0:
                fprintf(STDOUT, "This is a completion of a previous release\n");
@@ -3479,6 +3503,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     }
 
     if (fullrelease) {
+       afs_int32 oldest = 0;
        /* If the RO clone exists, then if the clone is a temporary
         * clone, delete it. Or if the RO clone is marked RO_DONTUSE
         * (it was recently added), then also delete it. We do not
@@ -3505,16 +3530,108 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            roexists = 0;
        }
 
+       if (justnewsites) {
+           VPRINT("Querying old RO sites for update times...");
+           for (vldbindex = 0; vldbindex < entry.nServers; vldbindex++) {
+               volEntries volumeInfo;
+               struct rx_connection *conn;
+               afs_int32 crdate;
+
+               if (!(entry.serverFlags[vldbindex] & ITSROVOL)) {
+                   continue;
+               }
+               if ((entry.serverFlags[vldbindex] & RO_DONTUSE)) {
+                   continue;
+               }
+               conn = UV_Bind(entry.serverNumber[vldbindex], AFSCONF_VOLUMEPORT);
+               if (!conn) {
+                   fprintf(STDERR, "Cannot establish connection to server %s\n",
+                                   hostutil_GetNameByINet(entry.serverNumber[vldbindex]));
+                   justnewsites = 0;
+                   break;
+               }
+               volumeInfo.volEntries_val = NULL;
+               volumeInfo.volEntries_len = 0;
+               code = AFSVolListOneVolume(conn, entry.serverPartition[vldbindex],
+                                          entry.volumeId[ROVOL],
+                                          &volumeInfo);
+               if (code) {
+                   fprintf(STDERR, "Could not fetch information about RO vol %lu from server %s\n",
+                                   (unsigned long)entry.volumeId[ROVOL],
+                                   hostutil_GetNameByINet(entry.serverNumber[vldbindex]));
+                   PrintError("", code);
+                   justnewsites = 0;
+                   rx_DestroyConnection(conn);
+                   break;
+               }
+
+               crdate = CLOCKADJ(volumeInfo.volEntries_val[0].creationDate);
+
+               if (oldest == 0 || crdate < oldest) {
+                   oldest = crdate;
+               }
+
+               rx_DestroyConnection(conn);
+               free(volumeInfo.volEntries_val);
+               volumeInfo.volEntries_val = NULL;
+               volumeInfo.volEntries_len = 0;
+           }
+           VDONE;
+       }
+       if (justnewsites) {
+           volEntries volumeInfo;
+           volumeInfo.volEntries_val = NULL;
+           volumeInfo.volEntries_len = 0;
+           code = AFSVolListOneVolume(fromconn, afrompart, afromvol,
+                                      &volumeInfo);
+           if (code) {
+               fprintf(STDERR, "Could not fetch information about RW vol %lu from server %s\n",
+                               (unsigned long)afromvol,
+                               hostutil_GetNameByINet(afromserver));
+               PrintError("", code);
+               justnewsites = 0;
+           } else {
+               rwupdate = volumeInfo.volEntries_val[0].updateDate;
+
+               free(volumeInfo.volEntries_val);
+               volumeInfo.volEntries_val = NULL;
+               volumeInfo.volEntries_len = 0;
+           }
+       }
+       if (justnewsites && oldest <= rwupdate) {
+           /* RW has changed */
+           justnewsites = 0;
+       }
+
        /* Mark all the ROs in the VLDB entry as RO_DONTUSE. We don't
         * write this entry out to the vlserver until after the first
         * RO volume is released (temp RO clones don't count).
+        *
+        * If 'justnewsites' is set, we're only updating sites that have
+        * RO_DONTUSE set, so set NEW_REPSITE for all of the others.
         */
        for (i = 0; i < entry.nServers; i++) {
-           entry.serverFlags[i] &= ~NEW_REPSITE;
-           entry.serverFlags[i] |= RO_DONTUSE;
+           if (justnewsites) {
+               if ((entry.serverFlags[i] & RO_DONTUSE)) {
+                   entry.serverFlags[i] &= ~NEW_REPSITE;
+               } else {
+                   entry.serverFlags[i] |= NEW_REPSITE;
+               }
+           } else {
+               entry.serverFlags[i] &= ~NEW_REPSITE;
+               entry.serverFlags[i] |= RO_DONTUSE;
+           }
        }
        entry.serverFlags[rwindex] |= NEW_REPSITE;
        entry.serverFlags[rwindex] &= ~RO_DONTUSE;
+    }
+
+    if (justnewsites && roexists) {
+       /* if 'justnewsites' and 'roexists' are set, we don't need to do
+        * anything with the RO clone, so skip the reclone */
+       /* noop */
+
+    } else if (fullrelease) {
 
        if (roclone) {
            strcpy(vname, entry.name);
@@ -3534,6 +3651,17 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            goto rfail;
        }
 
+       if (justnewsites && rwupdate != volstatus.updateDate) {
+           justnewsites = 0;
+           /* reset the serverFlags as if 'justnewsites' had never been set */
+           for (i = 0; i < entry.nServers; i++) {
+               entry.serverFlags[i] &= ~NEW_REPSITE;
+               entry.serverFlags[i] |= RO_DONTUSE;
+           }
+           entry.serverFlags[rwindex] |= NEW_REPSITE;
+           entry.serverFlags[rwindex] &= ~RO_DONTUSE;
+       }
+
        rwcrdate = volstatus.creationDate;
 
        /* Remember clone volume ID in case we fail or are interrupted */
@@ -3568,7 +3696,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
             * There is a fix in the 3.4 client that does not need this sleep
             * anymore, but we don't know what clients we have.
             */
-           if (entry.nServers > 2)
+           if (entry.nServers > 2 && !justnewsites)
                sleep(5);
 
            /* Mark the RO clone in the VLDB as a good site (already released) */
@@ -3592,6 +3720,14 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        }
     }
 
+    if (justnewsites) {
+       VPRINT("RW vol has not changed; only releasing to new RO sites\n");
+       /* act like this is a completion of a previous release */
+       fullrelease = 0;
+    } else if (tried_justnewsites) {
+       VPRINT("RW vol has changed; releasing to all sites\n");
+    }
+
     /* Now we will release from the clone to the remaining RO replicas.
      * The first 2 ROs (counting the non-temporary RO clone) are released
      * individually: releasecount. This is to reduce the race condition
@@ -3612,7 +3748,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     cookie.clone = 0;
 
     /* how many to do at once, excluding clone */
-    if (stayUp)
+    if (stayUp || justnewsites)
        nservers = entry.nServers; /* can do all, none offline */
     else
        nservers = entry.nServers / 2;
@@ -3653,7 +3789,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        for (volcount = 0;
             ((volcount < nservers) && (vldbindex < entry.nServers));
             vldbindex++) {
-           if (!stayUp) {
+           if (!stayUp && !justnewsites) {
                /* The first two RO volumes will be released individually.
                 * The rest are then released in parallel. This is a hack
                 * for clients not recognizing right away when a RO volume
@@ -4407,7 +4543,6 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
     char tovolreal[VOLSER_OLDMAXVOLNAME];
     afs_uint32 pvolid;
     afs_int32 temptid, pparentid;
-    int success;
     struct nvldbentry entry, storeEntry;
     afs_int32 error;
     int islocked;
@@ -4421,11 +4556,9 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
 
     memset(&cookie, 0, sizeof(cookie));
     islocked = 0;
-    success = 0;
     error = 0;
     reuseID = 1;
     tocall = (struct rx_call *)0;
-    toconn = (struct rx_connection *)0;
     tempconn = (struct rx_connection *)0;
     totid = 0;
     temptid = 0;
@@ -4622,10 +4755,9 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
        goto refail;
     }
 
-    success = 1;
     fprintf(STDOUT, " done\n");
     fflush(STDOUT);
-    if (success && (!reuseID || (flags & RV_FULLRST))) {
+    if (!reuseID || (flags & RV_FULLRST)) {
        /* Volume was restored on the file server, update the
         * VLDB to reflect the change.
         */
@@ -5201,7 +5333,6 @@ UV_ZapVolumeClones(afs_uint32 aserver, afs_int32 apart,
     afs_int32 code = 0;
     afs_int32 success = 1;
 
-    aconn = (struct rx_connection *)0;
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
     curPos = 0;
     for (curPtr = volPtr; curPos < arraySize; curPtr++) {
@@ -5246,7 +5377,6 @@ UV_GenerateVolumeClones(afs_uint32 aserver, afs_int32 apart,
     afs_uint32 curCloneId = 0;
     char cloneName[256];       /*max vol name */
 
-    aconn = (struct rx_connection *)0;
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
     curPos = 0;
     if ((volPtr->volFlags & REUSECLONEID) && (volPtr->volFlags & ENTRYVALID))
@@ -5398,7 +5528,6 @@ UV_XListVolumes(afs_uint32 a_serverID, afs_int32 a_partID, int a_all,
      * We set the val field to a null pointer as a hint for the stub to
      * allocate space.
      */
-    code = 0;
     *a_numEntsInResultP = 0;
     *a_resultPP = (volintXInfo *) 0;
     volumeXInfo.volXEntries_val = (volintXInfo *) 0;
@@ -5440,8 +5569,6 @@ UV_ListOneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 volid,
     afs_int32 code = 0;
     volEntries volumeInfo;
 
-    code = 0;
-
     *resultPtr = (volintInfo *) 0;
     volumeInfo.volEntries_val = (volintInfo *) 0;      /*this hints the stub to allocate space */
     volumeInfo.volEntries_len = 0;
@@ -5504,7 +5631,6 @@ UV_XListOneVolume(afs_uint32 a_serverID, afs_int32 a_partID, afs_uint32 a_volID,
      * the info.  Setting the val field to a null pointer tells the stub
      * to allocate space for us.
      */
-    code = 0;
     *a_resultPP = (volintXInfo *) 0;
     volumeXInfo.volXEntries_val = (volintXInfo *) 0;
     volumeXInfo.volXEntries_len = 0;
@@ -5602,7 +5728,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
        if (code) {
            if (code != VL_NOENT) {
                fprintf(STDOUT,
-                       "Could not retreive the VLDB entry for volume %lu \n",
+                       "Could not retrieve the VLDB entry for volume %lu \n",
                        (unsigned long)rwvolid);
                ERROR_EXIT(code);
            }