vos: avoid CreateVolume when restoring over an existing volume
[openafs.git] / src / volser / vsprocs.c
index 6e8df65..12961e3 100644 (file)
@@ -159,11 +159,6 @@ do { \
 
 
 /* Protos for static routines */
-#if 0
-static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn,
-                                     afs_int32 apart, afs_uint32 okvol,
-                                     afs_uint32 delvol);
-#endif
 static int GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
                    struct rx_connection **connPtr, afs_int32 * transPtr,
                    afs_uint32 * crtimePtr, afs_uint32 * uptimePtr,
@@ -172,8 +167,6 @@ static int SimulateForwardMultiple(struct rx_connection *fromconn,
                                   afs_int32 fromtid, afs_int32 fromdate,
                                   manyDests * tr, afs_int32 flags,
                                   void *cookie, manyResults * results);
-static int DoVolOnline(struct nvldbentry *vldbEntryPtr, afs_uint32 avolid,
-                      int index, char *vname, struct rx_connection *connPtr);
 static int DoVolClone(struct rx_connection *aconn, afs_uint32 avolid,
                      afs_int32 apart, int type, afs_uint32 cloneid,
                      char *typestring, char *pname, char *vname, char *suffix,
@@ -487,57 +480,6 @@ AFSVolTransCreate_retry(struct rx_connection *z_conn,
     return code;
 }
 
-#if 0
-/* if <okvol> is allright(indicated by beibg able to
- * start a transaction, delete the <delvol> */
-static afs_int32
-CheckAndDeleteVolume(struct rx_connection *aconn, afs_int32 apart,
-                    afs_uint32 okvol, afs_uint32 delvol)
-{
-    afs_int32 error, code, tid, rcode;
-    error = 0;
-    code = 0;
-
-    if (okvol == 0) {
-       code = AFSVolTransCreate_retry(aconn, delvol, apart, ITOffline, &tid);
-       if (!error && code)
-           error = code;
-       code = AFSVolDeleteVolume(aconn, tid);
-       if (!error && code)
-           error = code;
-       code = AFSVolEndTrans(aconn, tid, &rcode);
-       if (!code)
-           code = rcode;
-       if (!error && code)
-           error = code;
-       return error;
-    } else {
-       code = AFSVolTransCreate_retry(aconn, okvol, apart, ITOffline, &tid);
-       if (!code) {
-           code = AFSVolEndTrans(aconn, tid, &rcode);
-           if (!code)
-               code = rcode;
-           if (!error && code)
-               error = code;
-           code = AFSVolTransCreate_retry(aconn, delvol, apart, ITOffline, &tid);
-           if (!error && code)
-               error = code;
-           code = AFSVolDeleteVolume(aconn, tid);
-           if (!error && code)
-               error = code;
-           code = AFSVolEndTrans(aconn, tid, &rcode);
-           if (!code)
-               code = rcode;
-           if (!error && code)
-               error = code;
-       } else
-           error = code;
-       return error;
-    }
-}
-
-#endif
-
 /* called by EmuerateEntry, show vldb entry in a reasonable format */
 void
 SubEnumerateEntry(struct nvldbentry *entry)
@@ -547,25 +489,6 @@ SubEnumerateEntry(struct nvldbentry *entry)
     int isMixed = 0;
     char hoststr[16];
 
-#ifdef notdef
-    fprintf(STDOUT, "  readWriteID %-10u ", entry->volumeId[RWVOL]);
-    if (entry->flags & VLF_RWEXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    fprintf(STDOUT, "  readOnlyID  %-10u ", entry->volumeId[ROVOL]);
-    if (entry->flags & VLF_ROEXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    fprintf(STDOUT, "  backUpID    %-10u ", entry->volumeId[BACKVOL]);
-    if (entry->flags & VLF_BACKEXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    if ((entry->cloneId != 0) && (entry->flags & VLF_ROEXISTS))
-       fprintf(STDOUT, "    releaseClone %-10u \n", entry->cloneId);
-#else
     if (entry->flags & VLF_RWEXISTS)
        fprintf(STDOUT, "    RWrite: %-10u", entry->volumeId[RWVOL]);
     if (entry->flags & VLF_ROEXISTS)
@@ -575,7 +498,6 @@ SubEnumerateEntry(struct nvldbentry *entry)
     if ((entry->cloneId != 0) && (entry->flags & VLF_ROEXISTS))
        fprintf(STDOUT, "    RClone: %-10lu", (unsigned long)entry->cloneId);
     fprintf(STDOUT, "\n");
-#endif
     fprintf(STDOUT, "    number of sites -> %lu\n",
            (unsigned long)entry->nServers);
     for (i = 0; i < entry->nServers; i++) {
@@ -723,6 +645,8 @@ UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
     tid = 0;
     error = 0;
 
+    memset(&storeEntry, 0, sizeof(struct nvldbentry));
+
     init_volintInfo(&tstatus);
     tstatus.maxquota = aquota;
 
@@ -853,6 +777,8 @@ UV_AddVLDBEntry(afs_uint32 aserver, afs_int32 apart, char *aname,
     afs_int32 vcode;
     struct nvldbentry entry, storeEntry;       /*the new vldb entry */
 
+    memset(&storeEntry, 0, sizeof(struct nvldbentry));
+
     aconn = (struct rx_connection *)0;
     error = 0;
 
@@ -866,13 +792,8 @@ UV_AddVLDBEntry(afs_uint32 aserver, afs_int32 apart, char *aname,
     entry.flags = VLF_RWEXISTS;        /* this records that rw volume exists */
     entry.serverFlags[0] = VLSF_RWVOL; /*this rep site has rw  vol */
     entry.volumeId[RWVOL] = aid;
-#ifdef notdef
-    entry.volumeId[ROVOL] = anewid + 1;        /* rw,ro, bk id are related in the default case */
-    entry.volumeId[BACKVOL] = *anewid + 2;
-#else
     entry.volumeId[ROVOL] = 0;
     entry.volumeId[BACKVOL] = 0;
-#endif
     entry.cloneId = 0;
     /*map into right byte order, before passing to xdr, the stuff has to be in host
      * byte order. Xdr converts it into network order */
@@ -911,6 +832,8 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
     afs_int32 avoltype = -1, vtype;
     int notondisk = 0, notinvldb = 0;
 
+    memset(&storeEntry, 0, sizeof(struct nvldbentry));
+
     /* Find and read bhe VLDB entry for this volume */
     code = ubik_VL_SetLock(cstruct, 0, avolid, avoltype, VLOP_DELETE);
     if (code) {
@@ -1356,6 +1279,8 @@ UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid,
     afs_uint32 roserver = 0;
     struct rx_connection *aconn;
 
+    memset(&storeEntry, 0, sizeof(struct nvldbentry));
+
     vcode =
        ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL,
                  VLOP_MOVE);
@@ -1417,6 +1342,14 @@ UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid,
        }
     }
 
+    /* volume must be inaccessible during this process */
+    code = UV_SetVolume(server, partition, volid, ITOffline, VTOutOfService, 0);
+    if (code != 0) {
+       fprintf(STDERR, "Taking RO volume %u offline failed with code %d.\n",
+               volid, code);
+       goto error_exit;
+    }
+
     aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
     code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
     if (code) {
@@ -1426,6 +1359,18 @@ UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid,
        PrintError("convertROtoRW ", code);
        goto error_exit;
     }
+
+    /*
+     * Since the inService flag is copied from the RO volume, the new RW copy is
+     * offline. Change the status of this RW volume to online.
+     */
+    code = UV_SetVolume(server, partition, entry->volumeId[RWVOL], ITOffline,
+                       0 /* online */, 0);
+    if (code != 0) {
+       fprintf(STDERR, "Warning: Attempt to set RW volume %u as online failed "
+                       "with code %d.\n", entry->volumeId[RWVOL], code);
+    }
+
     /* Update the VLDB to match what we did on disk as much as possible.  */
     /* If the converted RO was in the VLDB, make it look like the new RW. */
     if (roserver) {
@@ -1564,8 +1509,9 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fflush(STDOUT);
        if (fscanf(stdin, "%c", &in) < 1)
            in = 0;
-       if (fscanf(stdin, "%c", &lf) < 0)       /* toss away */
-           ; /* don't care */
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away; don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1922,8 +1868,9 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fflush(STDOUT);
        if (fscanf(stdin, "%c", &in) < 1)
            in = 0;
-       if (fscanf(stdin, "%c", &lf) < 0)       /* toss away */
-           ; /* don't care */
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away, don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1957,8 +1904,9 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fflush(STDOUT);
        if (fscanf(stdin, "%c", &in) < 1)
            in = 0;
-       if (fscanf(stdin, "%c", &lf) < 0)       /* toss away */
-           ; /* don't care */
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away; don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1969,21 +1917,6 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        }
        /* or drop through */
     }
-#ifdef notdef
-    /* This is tricky.  File server is very stupid, and if you mark the volume
-     * as VTOutOfService, it may mark the *good* instance (if you're moving
-     * between partitions on the same machine) as out of service.  Since
-     * we're cleaning this code up in DEcorum, we're just going to kludge around
-     * it for now by removing this call. */
-    /* already out of service, just zap it now */
-    code =
-       AFSVolSetFlags(fromconn, fromtid, VTDeleteOnSalvage | VTOutOfService);
-    if (code) {
-       fprintf(STDERR,
-               "Failed to set the flags to make the old source volume offline\n");
-       goto mfail;
-    }
-#endif
     if (atoserver != afromserver) {
        /* set forwarding pointer for moved volumes */
        VPRINT1("Setting forwarding pointer for volume %u ...", afromvol);
@@ -2024,13 +1957,12 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
     if (!(flags & RV_NOCLONE)) {
        code = DoVolDelete(fromconn, newVol, afrompart,
                           "cloned", 0, NULL, NULL);
-       if (code) {
-           if (code == VNOVOL) {
-               EPRINT1(code, "Failed to start transaction on %u\n", newVol);
-           }
+       if (code && code != VNOVOL) {
            error = code;
            goto mfail;
        }
+
+       code = 0;       /* clone missing? that's okay */
     }
 
     /* fall through */
@@ -2042,8 +1974,9 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fflush(STDOUT);
        if (fscanf(stdin, "%c", &in) < 1)
            in = 0;
-       if (fscanf(stdin, "%c", &lf) < 0)       /* toss away */
-           ; /* don't care */
+       if (fscanf(stdin, "%c", &lf) < 0) {     /* toss away */
+           /* don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -2635,13 +2568,12 @@ cpincr:
     if (!(flags & RV_NOCLONE)) {
        code = DoVolDelete(fromconn, cloneVol, afrompart,
                           "cloned", 0, NULL, NULL);
-       if (code) {
-           if (code == VNOVOL) {
-               EPRINT1(code, "Failed to start transaction on %u\n", cloneVol);
-           }
+       if (code && code != VNOVOL) {
            error = code;
            goto mfail;
        }
+
+       code = 0;               /* clone missing? that's ok */
     }
 
     if (!(flags & RV_NOVLDB)) {
@@ -2765,11 +2697,8 @@ cpincr:
 
     /* common cleanup - delete local clone */
     if (cloneVol) {
-       code = DoVolDelete(fromconn, cloneVol, afrompart,
-                          "clone", 0, NULL, "Recovery:");
-       if (code == VNOVOL) {
-           EPRINT1(code, "Recovery: Failed to start transaction on %u\n", cloneVol);
-       }
+       DoVolDelete(fromconn, cloneVol, afrompart, "clone", 0, NULL,
+                   "Recovery:");
     }
 
   done:                        /* routine cleanup */
@@ -2919,8 +2848,6 @@ UV_BackupVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
        goto bfail;
     }
 
-    VDONE;
-
     /* Will update the vldb below */
 
   bfail:
@@ -3080,8 +3007,6 @@ UV_CloneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid,
        }
     }
 
-    VDONE;
-
   bfail:
     if (ttid) {
        code = AFSVolEndTrans(aconn, ttid, &rcode);
@@ -3422,49 +3347,14 @@ PutTrans(afs_int32 *vldbindex, struct replica *replicas,
     }
 }
 
-static int
-DoVolOnline(struct nvldbentry *vldbEntryPtr, afs_uint32 avolid, int index,
-           char *vname, struct rx_connection *connPtr)
-{
-    afs_int32 code = 0, rcode = 0, onlinetid = 0;
-
-    code =
-       AFSVolTransCreate_retry(connPtr, avolid,
-                               vldbEntryPtr->serverPartition[index],
-                               ITOffline,
-                               &onlinetid);
-    if (code)
-      EPRINT(code, "Could not create transaction on readonly...\n");
-
-    else {
-       code = AFSVolSetFlags(connPtr, onlinetid, 0);
-       if (code)
-           EPRINT(code, "Could not set flags on readonly...\n");
-    }
-
-    if (!code) {
-       code =
-           AFSVolSetIdsTypes(connPtr, onlinetid, vname,
-                             ROVOL, vldbEntryPtr->volumeId[RWVOL],
-                             0, 0);
-       if (code)
-           EPRINT(code, "Could not set ids on readonly...\n");
-    }
-    if (!code)
-       code = AFSVolEndTrans(connPtr, onlinetid, &rcode);
-    if (!code)
-       code = rcode;
-    return code;
-}
-
 /**
  * Release a volume to read-only sites
  *
- * Release volume <afromvol> on <afromserver> <afrompart> to all
- * its RO sites (full release). Unless the previous release was
- * incomplete: in which case we bring the remaining incomplete
- * volumes up to date with the volumes that were released
- * successfully.
+ * Release volume <afromvol> on <afromserver> <afrompart> to all its RO
+ * sites (complete release), unless the previous release was incomplete
+ * or new sites were added without changes to the read-write volume, in
+ * which case we bring the remaining volumes up to date with the volumes
+ * that were previously released successfully.
  *
  * Will create a clone from the RW, then dump the clone out to
  * the remaining replicas. If there is more than 1 RO sites,
@@ -3477,7 +3367,6 @@ DoVolOnline(struct nvldbentry *vldbEntryPtr, afs_uint32 avolid, int index,
  * @param[in] flags         bitmap of options
  *                            REL_COMPLETE  - force a complete release
  *                            REL_FULLDUMPS - force full dumps
- *                            REL_STAYUP    - dump to clones to avoid offline time
  */
 int
 UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
@@ -3523,10 +3412,9 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     int justnewsites = 0; /* are we just trying to release to new RO sites? */
     int sites = 0; /* number of ro sites */
     int new_sites = 0; /* number of ro sites markes as new */
-    int stayUp = (flags & REL_STAYUP);
 
     typedef enum {
-        CR_RECOVER    = 0x0000, /**< not complete: a recovery from a previous failed release */
+        CR_PARTIAL    = 0x0000, /**< just new sites added or recover from a previous failed release */
         CR_FORCED     = 0x0001, /**< complete: forced by caller */
         CR_LAST_OK    = 0x0002, /**< complete: no sites have been marked as new release */
         CR_ALL_NEW    = 0x0004, /**< complete: all sites have been marked as new release */
@@ -3534,7 +3422,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
         CR_RO_MISSING = 0x0010, /**< complete: ro clone is missing */
     } complete_release_t;
 
-    complete_release_t complete_release = CR_RECOVER;
+    complete_release_t complete_release = CR_PARTIAL;
 
     memset(remembertime, 0, sizeof(remembertime));
     memset(&results, 0, sizeof(results));
@@ -3639,29 +3527,6 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     code = VolumeExists(afromserver, afrompart, cloneVolId);
     roexists = ((code == ENODEV) ? 0 : 1);
 
-    /* For stayUp case, if roclone is the only site, bypass special handling */
-    if (stayUp && roclone) {
-       int e;
-       error = 0;
-
-       for (e = 0; (e < entry.nServers) && !error; e++) {
-           if ((entry.serverFlags[e] & VLSF_ROVOL)) {
-               if (!(VLDB_IsSameAddrs(entry.serverNumber[e], afromserver,
-                                      &error)))
-                   break;
-           }
-       }
-       if (e >= entry.nServers)
-           stayUp = 0;
-    }
-
-    /* If we had a previous release to complete, do so, else: */
-    if (stayUp && (cloneVolId == entry.volumeId[ROVOL])) {
-       code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &cloneVolId);
-       ONERROR(code, afromvol,
-               "Cannot get temporary clone id for volume %u\n");
-    }
-
     fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
     if (!fromconn)
        ONERROR(-1, afromserver,
@@ -3725,8 +3590,13 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                    "This is a recovery of previously failed release\n");
        } else {
            fprintf(STDOUT, "This is a complete release of volume %u", afromvol);
-           /* Give the reasons for a complete release, except if only CR_LAST_OK. */
-           if (complete_release != CR_LAST_OK) {
+           if (complete_release == CR_LAST_OK) {
+               if (justnewsites) {
+                   tried_justnewsites = 1;
+                   fprintf(STDOUT, "\nThere are new RO sites; we will try to "
+                           "only release to new sites");
+               }
+           } else {
                char *sep = " (";
                if (complete_release & CR_FORCED) {
                    fprintf(STDOUT, "%sforced", sep);
@@ -3750,11 +3620,6 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                fprintf(STDOUT, ")");
            }
            fprintf(STDOUT, "\n");
-           if (justnewsites) {
-               tried_justnewsites = 1;
-               fprintf(STDOUT, "There are new RO sites; we will try to "
-                       "only release to new sites\n");
-           }
        }
     }
 
@@ -3765,21 +3630,12 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
         * (it was recently added), then also delete it. We do not
         * want to "reclone" a temporary RO clone.
         */
-       if (stayUp) {
-           code = VolumeExists(afromserver, afrompart, cloneVolId);
-           if (!code) {
-               code = DoVolDelete(fromconn, cloneVolId, afrompart, "previous clone", 0,
-                                  NULL, NULL);
-               if (code && (code != VNOVOL))
-                   ERROREXIT(code);
-               VDONE;
-           }
-       }
+
        /* clean up any previous tmp clone before starting if staying up */
        if (roexists
            && (!roclone || (entry.serverFlags[roindex] & VLSF_DONTUSE))) {
            code = DoVolDelete(fromconn,
-                              stayUp ? entry.volumeId[ROVOL] : cloneVolId,
+                              cloneVolId,
                               afrompart, "the", 0, NULL, NULL);
            if (code && (code != VNOVOL))
                ERROREXIT(code);
@@ -3891,16 +3747,13 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
 
        if (roclone) {
            strcpy(vname, entry.name);
-           if (stayUp)
-               strcat(vname, ".roclone");
-           else
-               strcat(vname, ".readonly");
+           strcat(vname, ".readonly");
        } else {
            strcpy(vname, "readonly-clone-temp");
        }
 
        code = DoVolClone(fromconn, afromvol, afrompart, readonlyVolume,
-                         cloneVolId, (roclone && !stayUp)?"permanent RO":
+                         cloneVolId, roclone?"permanent RO":
                          "temporary RO", NULL, vname, NULL, &volstatus, NULL);
        if (code) {
            error = code;
@@ -3923,7 +3776,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        /* Remember clone volume ID in case we fail or are interrupted */
        entry.cloneId = cloneVolId;
 
-       if (roclone && !stayUp) {
+       if (roclone) {
            /* Bring the RO clone online - though not if it's a temporary clone */
            VPRINT1("Starting transaction on RO clone volume %u...",
                    cloneVolId);
@@ -3979,7 +3832,7 @@ 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 */
-       complete_release = CR_RECOVER;
+       complete_release = CR_PARTIAL;
     } else if (tried_justnewsites) {
        VPRINT("RW vol has changed; releasing to all sites\n");
     }
@@ -3993,10 +3846,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
      */
 
     strcpy(vname, entry.name);
-    if (stayUp)
-       strcat(vname, ".roclone");
-    else
-       strcat(vname, ".readonly");
+    strcat(vname, ".readonly");
     memset(&cookie, 0, sizeof(cookie));
     strncpy(cookie.name, vname, VOLSER_OLDMAXVOLNAME);
     cookie.type = ROVOL;
@@ -4004,7 +3854,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     cookie.clone = 0;
 
     /* how many to do at once, excluding clone */
-    if (stayUp || justnewsites)
+    if (justnewsites)
        nservers = entry.nServers; /* can do all, none offline */
     else
        nservers = entry.nServers / 2;
@@ -4030,22 +3880,13 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     ONERROR0(code, "Failed to create transaction on the release clone\n");
     VDONE;
 
-    /* if we have a clone, treat this as done, for now */
-    if (stayUp && !complete_release) {
-       entry.serverFlags[roindex] |= VLSF_NEWREPSITE;
-       entry.serverFlags[roindex] &= ~VLSF_DONTUSE;
-       entry.flags |= VLF_ROEXISTS;
-
-       releasecount++;
-    }
-
     /* For each index in the VLDB */
     for (vldbindex = 0; vldbindex < entry.nServers;) {
        /* Get a transaction on the replicas. Pick replicas which have an old release. */
        for (volcount = 0;
             ((volcount < nservers) && (vldbindex < entry.nServers));
             vldbindex++) {
-           if (!stayUp && !justnewsites) {
+           if (!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
@@ -4080,7 +3921,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                         &(replicas[volcount].trans),
                         &(times[volcount].crtime),
                         &(times[volcount].uptime),
-                        origflags, stayUp?cloneVolId:0);
+                        origflags, 0);
            if (code)
                continue;
 
@@ -4089,11 +3930,16 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                /* Do a full dump when forced by the caller. */
                VPRINT("This will be a full dump: forced\n");
                thisdate = 0;
-           } else if (!complete_release) {
-               /* If this release is a recovery of a failed release, we can't be
-                * sure the creation date is good, so do a full dump.
-                */
-               VPRINT("This will be a full dump: previous release failed\n");
+           } else if (complete_release == CR_PARTIAL) {
+               if (justnewsites) {
+                   VPRINT("This will be a full dump: read-only volume needs be created for new site\n");
+               } else {
+                   /*
+                    * We cannot be sure the creation date is good since the previous
+                    * release failed, so do a full dump.
+                    */
+                   VPRINT("This will be a full dump: previous release failed\n");
+               }
                thisdate = 0;
            } else if (times[volcount].crtime == 0) {
                /* A full dump is needed for a new read-only volume. */
@@ -4145,14 +3991,14 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
 
        code = CheckTrans(fromconn, &fromtid, afrompart, &orig_status);
        if (code) {
-           code = ENOENT;
+           error = ENOENT;
            goto rfail;
        }
 
        if (verbose) {
            fprintf(STDOUT, "Starting ForwardMulti from %lu to %u on %s",
-                   (unsigned long)cloneVolId, stayUp?
-                   cloneVolId:entry.volumeId[ROVOL],
+                   (unsigned long)cloneVolId,
+                   entry.volumeId[ROVOL],
                     noresolve ? afs_inet_ntoa_r(entry.serverNumber[times[0].
                                                 vldbEntryIndex], hoststr) :
                     hostutil_GetNameByINet(entry.
@@ -4239,166 +4085,12 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            }
        }
 
-       if (!stayUp) {
-           PutTrans(&vldbindex, replicas, toconns, times, volcount);
-           MapNetworkToHost(&entry, &storeEntry);
-           vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0);
-           ONERROR(vcode, afromvol,
-                   " Could not update VLDB entry for volume %u\n");
-       }
-    }                          /* for each index in the vldb */
-
-    /* for the stayup case, put back at the end */
-    if (stayUp) {
-       afs_uint32 tmpVol = entry.volumeId[ROVOL];
-       strcpy(vname, entry.name);
-       strcat(vname, ".readonly");
-
-       if (roclone) {
-           /* have to clear flags to ensure new vol goes online
-            */
-           code = AFSVolSetFlags(fromconn, fromtid, 0);
-           if (code && (code != ENOENT)) {
-               PrintError("Failed to set flags on ro volume: ",
-                          code);
-           }
-
-           VPRINT3("%sloning to permanent RO %u on %s...", roexists?"Re-c":"C", tmpVol,
-                   noresolve ?
-                   afs_inet_ntoa_r(entry.serverNumber[roindex],
-                                   hoststr) :
-                   hostutil_GetNameByINet(entry.serverNumber[roindex]));
-
-           code = AFSVolClone(fromconn, fromtid, roexists?tmpVol:0,
-                              readonlyVolume, vname, &tmpVol);
-
-           if (!code) {
-               VDONE;
-               VPRINT("Bringing readonly online...");
-               code = DoVolOnline(&entry, tmpVol, roindex, vname,
-                                  fromconn);
-           }
-           if (code) {
-               EPRINT(code, "Failed: ");
-               entry.serverFlags[roindex] &= ~VLSF_NEWREPSITE;
-               entry.serverFlags[roindex] |= VLSF_DONTUSE;
-           } else {
-               entry.serverFlags[roindex] |= VLSF_NEWREPSITE;
-               entry.serverFlags[roindex] &= ~VLSF_DONTUSE;
-               entry.flags |= VLF_ROEXISTS;
-               VDONE;
-           }
-
-       }
-       for (s = 0; s < volcount; s++) {
-           if (replicas[s].trans) {
-               vldbindex = times[s].vldbEntryIndex;
-
-               /* ok, so now we have to end the previous transaction */
-               code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode);
-               if (!code)
-                   code = rcode;
-
-               if (!code) {
-                   code = AFSVolTransCreate_retry(toconns[s],
-                                                  cloneVolId,
-                                                  entry.serverPartition[vldbindex],
-                                                  ITBusy,
-                                                  &(replicas[s].trans));
-                   if (code) {
-                       PrintError("Unable to begin transaction on temporary clone: ", code);
-                   }
-               } else {
-                   PrintError("Unable to end transaction on temporary clone: ", code);
-               }
-
-               VPRINT3("%sloning to permanent RO %u on %s...", times[s].crtime?"Re-c":"C",
-                       tmpVol, noresolve ?
-                       afs_inet_ntoa_r(htonl(replicas[s].server.destHost),
-                                       hoststr) :
-                       hostutil_GetNameByINet(htonl(replicas[s].server.destHost)));
-               if (times[s].crtime)
-                   code = AFSVolClone(toconns[s], replicas[s].trans, tmpVol,
-                                      readonlyVolume, vname, &tmpVol);
-               else
-                   code = AFSVolClone(toconns[s], replicas[s].trans, 0,
-                                      readonlyVolume, vname, &tmpVol);
-
-               if (code) {
-                   if (!times[s].crtime) {
-                       entry.serverFlags[vldbindex] |= VLSF_DONTUSE;
-                   }
-                   entry.serverFlags[vldbindex] &= ~VLSF_NEWREPSITE;
-                   PrintError("Failed: ",
-                              code);
-               } else
-                   VDONE;
-
-               if (entry.serverFlags[vldbindex] != VLSF_DONTUSE) {
-                   /* bring it online (mark it InService) */
-                   VPRINT1("Bringing readonly online on %s...",
-                           noresolve ?
-                           afs_inet_ntoa_r(
-                               htonl(replicas[s].server.destHost),
-                               hoststr) :
-                           hostutil_GetNameByINet(
-                               htonl(replicas[s].server.destHost)));
-
-                   code = DoVolOnline(&entry, tmpVol, vldbindex, vname,
-                                      toconns[s]);
-                   /* needed to come online for cloning */
-                   if (code) {
-                       /* technically it's still new, just not online */
-                       entry.serverFlags[s] &= ~VLSF_NEWREPSITE;
-                       entry.serverFlags[s] |= VLSF_DONTUSE;
-                       if (code != ENOENT) {
-                           PrintError("Failed to set correct names and ids: ",
-                                      code);
-                       }
-                   } else
-                       VDONE;
-               }
-
-               VPRINT("Marking temporary clone for deletion...\n");
-               code = AFSVolSetFlags(toconns[s],
-                                     replicas[s].trans,
-                                     VTDeleteOnSalvage |
-                                     VTOutOfService);
-               if (code)
-                 EPRINT(code, "Failed: ");
-               else
-                 VDONE;
-
-               VPRINT("Ending transaction on temporary clone...\n");
-               code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode);
-               if (!code)
-                   rcode = code;
-               if (code)
-                   PrintError("Failed: ", code);
-               else {
-                   VDONE;
-                   /* ended successfully */
-                   replicas[s].trans = 0;
-
-                   VPRINT2("Deleting temporary clone %u on %s...", cloneVolId,
-                           noresolve ?
-                           afs_inet_ntoa_r(htonl(replicas[s].server.destHost),
-                                           hoststr) :
-                           hostutil_GetNameByINet(htonl(replicas[s].server.destHost)));
-                   code = DoVolDelete(toconns[s], cloneVolId,
-                                      entry.serverPartition[vldbindex],
-                                      NULL, 0, NULL, NULL);
-                   if (code) {
-                       EPRINT(code, "Failed: ");
-                   } else
-                       VDONE;
-               }
-           }
-       }
-
-       /* done. put the vldb entry in the success tail case*/
        PutTrans(&vldbindex, replicas, toconns, times, volcount);
-    }
+       MapNetworkToHost(&entry, &storeEntry);
+       vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0);
+       ONERROR(vcode, afromvol,
+               " Could not update VLDB entry for volume %u\n");
+    }                          /* for each index in the vldb */
 
     /* End the transaction on the cloned volume */
     code = AFSVolEndTrans(fromconn, fromtid, &rcode);
@@ -4438,7 +4130,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
 
     entry.cloneId = 0;
     /* All the ROs were release successfully. Remove the temporary clone */
-    if (!roclone || stayUp) {
+    if (!roclone) {
        if (verbose) {
            fprintf(STDOUT, "Deleting the releaseClone %lu ...",
                    (unsigned long)cloneVolId);
@@ -4446,7 +4138,8 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        }
        code = DoVolDelete(fromconn, cloneVolId, afrompart, NULL, 0, NULL,
                           NULL);
-       ONERROR(code, cloneVolId, "Failed to delete volume %u.\n");
+       if (code && code != VNOVOL)
+           ONERROR(code, cloneVolId, "Failed to delete volume %u.\n");
        VDONE;
     }
 
@@ -4658,8 +4351,8 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     afs_int32 fromtid = 0, rcode = 0;
     afs_int32 code = 0, error = 0;
     afs_uint32 tmpVol;
-    char vname[64];
     time_t tmv = fromdate;
+    char *volName = NULL;
 
     if (setjmp(env))
        ERROR_EXIT(EPIPE);
@@ -4685,6 +4378,12 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
           afromvol);
     VEDONE;
 
+    VEPRINT1("Getting the name for volume %u ...", afromvol);
+    code = AFSVolGetName(fromconn, fromtid, &volName);
+    EGOTO1(error_exit, code,
+          "Failed to get the name of the volume %u\n",afromvol);
+    VEDONE;
+
     /* Get a clone id */
     VEPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
     tmpVol = clonevol;
@@ -4698,10 +4397,9 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
     VEPRINT2("Cloning source volume %u to clone volume %u...", afromvol,
            clonevol);
-    strcpy(vname, "dump-clone-temp");
     tmpVol = clonevol;
     code =
-       AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &tmpVol);
+       AFSVolClone(fromconn, fromtid, 0, readonlyVolume, volName, &tmpVol);
     clonevol = tmpVol;
     EGOTO1(error_exit, code, "Failed to clone the source volume %u\n",
           afromvol);
@@ -4752,6 +4450,9 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     VEDONE;
 
   error_exit:
+    if (volName)
+       free(volName);
+
     /* now delete the clone */
     VEPRINT1("Deleting the cloned volume %u ...", clonevol);
     code = AFSVolDeleteVolume(fromconn, clonetid);
@@ -4900,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;
@@ -5471,7 +5171,8 @@ UV_RemoveSite(afs_uint32 server, afs_int32 part, afs_uint32 volid)
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
            return (vcode);
        }
-       VDONE;
+       fprintf(STDOUT, " done\n");
+       fflush(STDOUT);
     }
     return 0;
 }
@@ -5731,7 +5432,6 @@ UV_ListVolumes(afs_uint32 aserver, afs_int32 apart, int all,
     afs_int32 code = 0;
     volEntries volumeInfo;
 
-    code = 0;
     *size = 0;
     *resultPtr = (volintInfo *) 0;
     volumeInfo.volEntries_val = (volintInfo *) 0;      /*this hints the stub to allocate space */
@@ -7179,6 +6879,7 @@ UV_SyncServer(afs_uint32 aserver, afs_int32 apart, int flags, int force)
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
 
     /* Set up attributes to search VLDB  */
+    memset(&attributes, 0, sizeof(attributes));
     attributes.server = ntohl(aserver);
     attributes.Mask = VLLIST_SERVER;
     if ((flags & 1)) {
@@ -7694,6 +7395,8 @@ MapNetworkToHost(struct nvldbentry *old, struct nvldbentry *new)
 {
     int i, count;
 
+    memset(new, 0, sizeof(struct nvldbentry));
+
     /*copy all the fields */
     strcpy(new->name, old->name);
 /*    new->volumeType = old->volumeType;*/