vos: take RO volume offline during convertROtoRW
[openafs.git] / src / volser / vsprocs.c
index 0b926f2..cddacac 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,39 +489,19 @@ SubEnumerateEntry(struct nvldbentry *entry)
     int isMixed = 0;
     char hoststr[16];
 
-#ifdef notdef
-    fprintf(STDOUT, "  readWriteID %-10u ", entry->volumeId[RWVOL]);
-    if (entry->flags & RW_EXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    fprintf(STDOUT, "  readOnlyID  %-10u ", entry->volumeId[ROVOL]);
-    if (entry->flags & RO_EXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    fprintf(STDOUT, "  backUpID    %-10u ", entry->volumeId[BACKVOL]);
-    if (entry->flags & BACK_EXISTS)
-       fprintf(STDOUT, " valid \n");
-    else
-       fprintf(STDOUT, " invalid \n");
-    if ((entry->cloneId != 0) && (entry->flags & RO_EXISTS))
-       fprintf(STDOUT, "    releaseClone %-10u \n", entry->cloneId);
-#else
-    if (entry->flags & RW_EXISTS)
+    if (entry->flags & VLF_RWEXISTS)
        fprintf(STDOUT, "    RWrite: %-10u", entry->volumeId[RWVOL]);
-    if (entry->flags & RO_EXISTS)
+    if (entry->flags & VLF_ROEXISTS)
        fprintf(STDOUT, "    ROnly: %-10u", entry->volumeId[ROVOL]);
-    if (entry->flags & BACK_EXISTS)
+    if (entry->flags & VLF_BACKEXISTS)
        fprintf(STDOUT, "    Backup: %-10u", entry->volumeId[BACKVOL]);
-    if ((entry->cloneId != 0) && (entry->flags & RO_EXISTS))
+    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++) {
-       if (entry->serverFlags[i] & NEW_REPSITE)
+       if (entry->serverFlags[i] & VLSF_NEWREPSITE)
            isMixed = 1;
     }
     for (i = 0; i < entry->nServers; i++) {
@@ -587,18 +509,18 @@ SubEnumerateEntry(struct nvldbentry *entry)
        fprintf(STDOUT, "       server %s partition %s ",
                noresolve ? afs_inet_ntoa_r(entry->serverNumber[i], hoststr) :
                 hostutil_GetNameByINet(entry->serverNumber[i]), pname);
-       if (entry->serverFlags[i] & ITSRWVOL)
+       if (entry->serverFlags[i] & VLSF_RWVOL)
            fprintf(STDOUT, "RW Site ");
        else
            fprintf(STDOUT, "RO Site ");
        if (isMixed) {
-           if (entry->serverFlags[i] & NEW_REPSITE)
+           if (entry->serverFlags[i] & VLSF_NEWREPSITE)
                fprintf(STDOUT," -- New release");
            else
-               if (!(entry->serverFlags[i] & ITSRWVOL))
+               if (!(entry->serverFlags[i] & VLSF_RWVOL))
                    fprintf(STDOUT," -- Old release");
        } else {
-           if (entry->serverFlags[i] & RO_DONTUSE)
+           if (entry->serverFlags[i] & VLSF_DONTUSE)
                fprintf(STDOUT, " -- Not released");
        }
        fprintf(STDOUT, "\n");
@@ -643,7 +565,6 @@ 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) {
@@ -722,9 +643,10 @@ UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
     struct volintInfo tstatus;
 
     tid = 0;
-    aconn = (struct rx_connection *)0;
     error = 0;
 
+    memset(&storeEntry, 0, sizeof(struct nvldbentry));
+
     init_volintInfo(&tstatus);
     tstatus.maxquota = aquota;
 
@@ -797,8 +719,8 @@ UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
                                         * level of indirection later */
     entry.serverPartition[0] = apart;  /* this should also have
                                         * another indirection level */
-    entry.flags = RW_EXISTS;   /* this records that rw volume exists */
-    entry.serverFlags[0] = ITSRWVOL;   /*this rep site has rw  vol */
+    entry.flags = VLF_RWEXISTS;        /* this records that rw volume exists */
+    entry.serverFlags[0] = VLSF_RWVOL; /*this rep site has rw  vol */
     entry.volumeId[RWVOL] = *anewid;
     entry.volumeId[ROVOL] = aroid ? *aroid : 0;
     entry.volumeId[BACKVOL] = abkid ? *abkid : 0;
@@ -855,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;
 
@@ -865,16 +789,11 @@ UV_AddVLDBEntry(afs_uint32 aserver, afs_int32 apart, char *aname,
                                         * level of indirection later */
     entry.serverPartition[0] = apart;  /* this should also have
                                         * another indirection level */
-    entry.flags = RW_EXISTS;   /* this records that rw volume exists */
-    entry.serverFlags[0] = ITSRWVOL;   /*this rep site has rw  vol */
+    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 */
@@ -913,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) {
@@ -957,14 +878,14 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
        /* Its a backup volume, modify the VLDB entry. Check that the
         * backup volume is on the server/partition we asked to delete.
         */
-       if (!(entry.flags & BACK_EXISTS) || !Lp_Match(aserver, apart, &entry)) {
+       if (!(entry.flags & VLF_BACKEXISTS) || !Lp_Match(aserver, apart, &entry)) {
            notinvldb = 2;      /* Not on this server and partition */
            ERROR_EXIT(0);
        }
 
        VPRINT1("Marking the backup volume %u deleted in the VLDB\n", avolid);
 
-       entry.flags &= ~BACK_EXISTS;
+       entry.flags &= ~VLF_BACKEXISTS;
        vtype = BACKVOL;
     }
 
@@ -987,7 +908,7 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
        Lp_SetROValue(&entry, aserver, apart, 0, 0);    /* delete the site */
        entry.nServers--;
        if (!Lp_ROMatch(0, 0, &entry))
-           entry.flags &= ~RO_EXISTS;  /* This was the last ro volume */
+           entry.flags &= ~VLF_ROEXISTS;       /* This was the last ro volume */
        vtype = ROVOL;
     }
 
@@ -996,7 +917,7 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
         * Check that the readwrite volumes is on the server/partition we
         * asked to delete.
         */
-       if (!(entry.flags & RW_EXISTS) || !Lp_Match(aserver, apart, &entry)) {
+       if (!(entry.flags & VLF_RWEXISTS) || !Lp_Match(aserver, apart, &entry)) {
            notinvldb = 2;      /* Not found on this server and partition */
            ERROR_EXIT(0);
        }
@@ -1016,15 +937,15 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
                    "Marking the readwrite volume %lu%s deleted in the VLDB\n",
                    (unsigned long)avolid,
                    ((entry.
-                     flags & BACK_EXISTS) ? ", and its backup volume," :
+                     flags & VLF_BACKEXISTS) ? ", and its backup volume," :
                     ""));
 
        Lp_SetRWValue(&entry, aserver, apart, 0L, 0L);
        entry.nServers--;
-       entry.flags &= ~(BACK_EXISTS | RW_EXISTS);
+       entry.flags &= ~(VLF_BACKEXISTS | VLF_RWEXISTS);
        vtype = RWVOL;
 
-       if (entry.flags & RO_EXISTS)
+       if (entry.flags & VLF_ROEXISTS)
            fprintf(STDERR, "WARNING: ReadOnly copy(s) may still exist\n");
     }
 
@@ -1034,7 +955,7 @@ UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
     }
 
     /* Either delete or replace the VLDB entry */
-    if ((entry.nServers <= 0) || !(entry.flags & (RO_EXISTS | RW_EXISTS))) {
+    if ((entry.nServers <= 0) || !(entry.flags & (VLF_ROEXISTS | VLF_RWEXISTS))) {
        if (verbose)
            fprintf(STDOUT,
                    "Last reference to the VLDB entry for %lu - deleting entry\n",
@@ -1173,6 +1094,12 @@ DoVolDelete(struct rx_connection *aconn, afs_uint32 avolid,
     code =
        AFSVolTransCreate_retry(aconn, avolid, apart, ITOffline, &ttid);
 
+    /* return early and quietly for VNOVOL; don't continue the attempt to delete. */
+    if (code == VNOVOL) {
+       error = code;
+       goto dfail;
+    }
+
     EGOTO2(dfail, code, "%sFailed to start transaction on %u\n",
           prefix, avolid);
 
@@ -1334,6 +1261,181 @@ cfail:
     return error;
 }
 
+/* Convert volume from RO to RW; adjust the VLDB entry to match.
+ * The nvldbentry passed to us has already been MapHostToNetwork'd
+ * by the caller.
+ */
+
+int
+UV_ConvertRO(afs_uint32 server, afs_uint32 partition, afs_uint32 volid,
+               struct nvldbentry *entry)
+{
+    afs_int32 code, i, same;
+    struct nvldbentry checkEntry, storeEntry;
+    afs_int32 vcode;
+    afs_int32 rwindex = 0;
+    afs_uint32 rwserver = 0;
+    afs_int32 roindex = 0;
+    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);
+    if (vcode) {
+       fprintf(STDERR,
+               "Unable to lock volume %lu, code %d\n",
+               (unsigned long)entry->volumeId[RWVOL],vcode);
+       PrintError("", vcode);
+       return -1;
+    }
+
+    /* make sure the VLDB entry hasn't changed since we started */
+    memset(&checkEntry, 0, sizeof(checkEntry));
+    vcode = VLDB_GetEntryByID(volid, -1, &checkEntry);
+    if (vcode) {
+       fprintf(STDERR,
+                "Could not fetch the entry for volume %lu from VLDB\n",
+                (unsigned long)volid);
+       PrintError("convertROtoRW ", vcode);
+       code = vcode;
+       goto error_exit;
+    }
+
+    MapHostToNetwork(&checkEntry);
+    entry->flags &= ~VLOP_ALLOPERS;  /* clear any stale lock operation flags */
+    entry->flags |= VLOP_MOVE;        /* set to match SetLock operation above */
+    if (memcmp(entry, &checkEntry, sizeof(*entry)) != 0) {
+        fprintf(STDERR,
+                "VLDB entry for volume %lu has changed; please reissue the command.\n",
+                (unsigned long)volid);
+        code = -1;
+        goto error_exit;
+    }
+
+    /* extract information from the original entry */
+    for (i = 0; i < entry->nServers; i++) {
+       if (entry->serverFlags[i] & VLSF_RWVOL) {
+           rwindex = i;
+           rwserver = entry->serverNumber[i];
+       /*  rwpartition = entry->serverPartition[i]; */
+           if (roserver)
+               break;
+       } else if ((entry->serverFlags[i] & VLSF_ROVOL) && !roserver) {
+           same = VLDB_IsSameAddrs(server, entry->serverNumber[i], &code);
+           if (code) {
+               fprintf(STDERR,
+                       "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
+                       server, code);
+               code = ENOENT;
+               goto error_exit;
+           }
+           if (same) {
+               roindex = i;
+               roserver = entry->serverNumber[i];
+       /*      ropartition = entry->serverPartition[i]; */
+               if (rwserver)
+                    break;
+           }
+       }
+    }
+
+    /* 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) {
+       fprintf(STDERR,
+               "Converting RO volume %lu to RW volume failed with code %d\n",
+               (unsigned long)volid, code);
+       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) {
+       entry->serverFlags[roindex] = VLSF_RWVOL;
+    } else {
+       /* Add a new site entry for the newly created RW.  It's possible
+        * (but unlikely) that we are already at MAXNSERVERS and that this
+        * new site will invalidate the whole VLDB entry;  however,
+        * VLDB_ReplaceEntry will detect this and return VL_BADSERVER,
+        * so we need no extra guard logic here.
+        */
+       afs_int32 newrwindex = entry->nServers;
+       (entry->nServers)++;
+       entry->serverNumber[newrwindex] = server;
+       entry->serverPartition[newrwindex] = partition;
+       entry->serverFlags[newrwindex] = VLSF_RWVOL;
+    }
+    entry->flags |= VLF_RWEXISTS;
+    entry->flags &= ~VLF_BACKEXISTS;
+
+    /* if the old RW was in the VLDB, remove it by decrementing the number */
+    /* of servers, replacing the RW entry with the last entry, and zeroing */
+    /* out the last entry. */
+    if (rwserver) {
+       (entry->nServers)--;
+       if (rwindex != entry->nServers) {
+           entry->serverNumber[rwindex] = entry->serverNumber[entry->nServers];
+           entry->serverPartition[rwindex] =
+               entry->serverPartition[entry->nServers];
+           entry->serverFlags[rwindex] = entry->serverFlags[entry->nServers];
+           entry->serverNumber[entry->nServers] = 0;
+           entry->serverPartition[entry->nServers] = 0;
+           entry->serverFlags[entry->nServers] = 0;
+       }
+    }
+    entry->flags &= ~VLF_ROEXISTS;
+    for (i = 0; i < entry->nServers; i++) {
+       if (entry->serverFlags[i] & VLSF_ROVOL) {
+           if (!(entry->serverFlags[i] & (VLSF_DONTUSE | VLSF_NEWREPSITE)))
+               entry->flags |= VLF_ROEXISTS;
+       }
+    }
+    MapNetworkToHost(entry, &storeEntry);
+    code =
+       VLDB_ReplaceEntry(entry->volumeId[RWVOL], RWVOL, &storeEntry,
+                         (LOCKREL_OPCODE | LOCKREL_AFSID |
+                          LOCKREL_TIMESTAMP));
+    if (code) {
+       fprintf(STDERR,
+               "Warning: volume converted, but vldb update failed with code %d!\n",
+               code);
+    }
+
+  error_exit:
+    vcode = UV_LockRelease(entry->volumeId[RWVOL]);
+    if (vcode) {
+       fprintf(STDERR,
+               "Unable to unlock volume %lu, code %d\n",
+               (unsigned long)entry->volumeId[RWVOL],vcode);
+       PrintError("", vcode);
+    }
+    return code;
+}
+
+
 /* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
  * <atopart>.  The operation is almost idempotent.  The following
  * flags are recognized:
@@ -1405,8 +1507,11 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fprintf(STDOUT, "First test point - operation not started.\n");
        fprintf(STDOUT, "...test here (y, n)? ");
        fflush(STDOUT);
-       fscanf(stdin, "%c", &in);
-       fscanf(stdin, "%c", &lf);       /* toss away */
+       if (fscanf(stdin, "%c", &in) < 1)
+           in = 0;
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away; don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1448,7 +1553,7 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
                    (unsigned long)afromvol);
            fprintf(STDERR, "The current site is :");
            for (i = 0; i < entry.nServers; i++) {
-               if (entry.serverFlags[i] == ITSRWVOL) {
+               if (entry.serverFlags[i] == VLSF_RWVOL) {
                    char pname[10];
                    MapPartIdIntoName(entry.serverPartition[i], pname);
                    fprintf(STDERR, " server %s partition %s \n",
@@ -1515,7 +1620,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.
@@ -1754,15 +1859,18 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
 
     Lp_SetRWValue(&entry, afromserver, afrompart, atoserver, atopart);
     MapNetworkToHost(&entry, &storeEntry);
-    storeEntry.flags &= ~BACK_EXISTS;
+    storeEntry.flags &= ~VLF_BACKEXISTS;
 
     if (TESTC) {
        fprintf(STDOUT,
                "Second test point - operation in progress but not complete.\n");
        fprintf(STDOUT, "...test here (y, n)? ");
        fflush(STDOUT);
-       fscanf(stdin, "%c", &in);
-       fscanf(stdin, "%c", &lf);       /* toss away */
+       if (fscanf(stdin, "%c", &in) < 1)
+           in = 0;
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away, don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1794,8 +1902,11 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
                "Third test point - operation complete but no cleanup.\n");
        fprintf(STDOUT, "...test here (y, n)? ");
        fflush(STDOUT);
-       fscanf(stdin, "%c", &in);
-       fscanf(stdin, "%c", &lf);       /* toss away */
+       if (fscanf(stdin, "%c", &in) < 1)
+           in = 0;
+       if (fscanf(stdin, "%c", &lf) < 0) {
+           /* toss away; don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1806,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);
@@ -1861,10 +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 && code != VNOVOL) {
            error = code;
            goto mfail;
        }
+
+       code = 0;       /* clone missing? that's okay */
     }
 
     /* fall through */
@@ -1874,8 +1972,11 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        fprintf(STDOUT, "Fourth test point - operation complete.\n");
        fprintf(STDOUT, "...test here (y, n)? ");
        fflush(STDOUT);
-       fscanf(stdin, "%c", &in);
-       fscanf(stdin, "%c", &lf);       /* toss away */
+       if (fscanf(stdin, "%c", &in) < 1)
+           in = 0;
+       if (fscanf(stdin, "%c", &lf) < 0) {     /* toss away */
+           /* don't care */
+       }
        if (in == 'y') {
            fprintf(STDOUT, "type control-c\n");
            while (1) {
@@ -1889,7 +1990,7 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
 
     /* normal cleanup code */
 
-    if (entry.flags & RO_EXISTS)
+    if (entry.flags & VLF_ROEXISTS)
        fprintf(STDERR, "WARNING : readOnly copies still exist \n");
 
     if (islocked) {
@@ -2024,9 +2125,13 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
            fflush(STDOUT);
        }
 
-       if (volid && toconn)
+       if (volid && toconn) {
            code = DoVolDelete(toconn, volid, atopart,
                               "destination", 0, NULL, "Recovery:");
+           if (code == VNOVOL) {
+               EPRINT1(code, "Recovery: Failed to start transaction on %u\n", volid);
+           }
+        }
 
        /* put source volume on-line */
        if (fromconn) {
@@ -2067,17 +2172,26 @@ UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
        if (fromconn) {
            code = DoVolDelete(fromconn, backupId, afrompart,
                               "backup", 0, NULL, "Recovery:");
+           if (code == VNOVOL) {
+               EPRINT1(code, "Recovery: Failed to start transaction on %u\n", backupId);
+           }
 
            code = DoVolDelete(fromconn, afromvol, afrompart, "source",
                               (atoserver != afromserver)?atoserver:0,
-                              NULL, NULL);
+                       NULL, NULL);
+           if (code == VNOVOL) {
+               EPRINT1(code, "Failed to start transaction on %u\n", afromvol);
+           }
        }
     }
 
     /* common cleanup - delete local clone */
     if (newVol) {
        code = DoVolDelete(fromconn, newVol, afrompart,
-                          "clone", 0, NULL, "Recovery:");
+                          "clone", 0, NULL, "Recovery:");
+       if (code == VNOVOL) {
+           EPRINT1(code, "Recovery: Failed to start transaction on %u\n", newVol);
+       }
     }
 
     /* unlock VLDB entry */
@@ -2087,7 +2201,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)
@@ -2455,10 +2568,12 @@ cpincr:
     if (!(flags & RV_NOCLONE)) {
        code = DoVolDelete(fromconn, cloneVol, afrompart,
                           "cloned", 0, NULL, NULL);
-       if (code) {
+       if (code && code != VNOVOL) {
            error = code;
            goto mfail;
        }
+
+       code = 0;               /* clone missing? that's ok */
     }
 
     if (!(flags & RV_NOVLDB)) {
@@ -2467,8 +2582,8 @@ cpincr:
        newentry.nServers = 1;
        newentry.serverNumber[0] = atoserver;
        newentry.serverPartition[0] = atopart;
-       newentry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
-       newentry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
+       newentry.flags = (flags & RV_RDONLY) ? VLF_ROEXISTS : VLF_RWEXISTS;
+       newentry.serverFlags[0] = (flags & RV_RDONLY) ? VLSF_ROVOL : VLSF_RWVOL;
        newentry.volumeId[RWVOL] = newVol;
        newentry.volumeId[ROVOL] = (flags & RV_RDONLY) ? newVol : 0;
        newentry.volumeId[BACKVOL] = 0;
@@ -2581,9 +2696,10 @@ cpincr:
     MapHostToNetwork(&entry);
 
     /* common cleanup - delete local clone */
-    if (cloneVol)
-       code = DoVolDelete(fromconn, cloneVol, afrompart,
-                          "clone", 0, NULL, "Recovery:");
+    if (cloneVol) {
+       DoVolDelete(fromconn, cloneVol, afrompart, "clone", 0, NULL,
+                   "Recovery:");
+    }
 
   done:                        /* routine cleanup */
     if (fromconn)
@@ -2641,7 +2757,7 @@ UV_BackupVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
     /* These operations require the VLDB be locked since it means the VLDB
      * will change or the vldb is already locked.
      */
-    if (!(entry.flags & BACK_EXISTS) ||        /* backup volume doesnt exist */
+    if (!(entry.flags & VLF_BACKEXISTS) ||     /* backup volume doesnt exist */
        (entry.flags & VLOP_ALLOPERS) ||        /* vldb lock already held */
        (entry.volumeId[BACKVOL] == INVALID_BID)) {     /* no assigned backup volume id */
 
@@ -2699,8 +2815,8 @@ UV_BackupVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
     }
 
     /* Mark vldb as backup exists */
-    if (!(entry.flags & BACK_EXISTS)) {
-       entry.flags |= BACK_EXISTS;
+    if (!(entry.flags & VLF_BACKEXISTS)) {
+       entry.flags |= VLF_BACKEXISTS;
        vldbmod = 1;
     }
 
@@ -2732,8 +2848,6 @@ UV_BackupVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
        goto bfail;
     }
 
-    VDONE;
-
     /* Will update the vldb below */
 
   bfail:
@@ -2857,7 +2971,7 @@ UV_CloneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid,
        type = backupVolume;
 
     code = DoVolClone(aconn, avolid, apart, type, acloneid, "clone",
-                     NULL, ".clone", NULL, NULL, NULL);
+                     NULL, aname, NULL, NULL, NULL);
     if (code) {
        error = code;
        goto bfail;
@@ -2893,8 +3007,6 @@ UV_CloneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid,
        }
     }
 
-    VDONE;
-
   bfail:
     if (ttid) {
        code = AFSVolEndTrans(aconn, ttid, &rcode);
@@ -2977,7 +3089,7 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
                              vldbEntryPtr->serverPartition[index], ITOffline,
                              transPtr);
 
-       if (!code && (origflags[index] & RO_DONTUSE)) {
+       if (!code && (origflags[index] & VLSF_DONTUSE)) {
            /* If RO_DONTUSE is set, this is supposed to be an entirely new
             * site. Don't trust any data on it, since it is possible we
             * have encountered some temporary volume from some other
@@ -3018,7 +3130,7 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
 
     /* If the volume does not exist, create it */
     if (!volid || code) {
-       char volname[64];
+       char volname[VL_MAXNAMELEN];
         char hoststr[16];
 
        if (volid && (code != VNOVOL)) {
@@ -3027,11 +3139,15 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
            goto fail;
        }
 
-       strcpy(volname, vldbEntryPtr->name);
-       if (tmpVolId)
-           strcat(volname, ".roclone");
-       else
-           strcat(volname, ".readonly");
+       strlcpy(volname, vldbEntryPtr->name, sizeof(volname));
+
+       if (strlcat(volname,
+                   tmpVolId?".roclone":".readonly",
+                   sizeof(volname)) >= sizeof(volname)) {
+           code = ENOMEM;
+           PrintError("Volume name is too long\n", code);
+           goto fail;
+       }
 
        if (verbose) {
            fprintf(STDOUT,
@@ -3231,58 +3347,30 @@ 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;
-}
-
-/* UV_ReleaseVolume()
- *    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.
- *    forceflag: Performs a full release.
+/**
+ * Release a volume to read-only sites
+ *
+ * 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,
+ * ensure that the VLDB says at least one RO is available all
+ * the time: Influences when we write back the VLDB entry.
  *
- *    Will create a clone from the RW, then dump the clone out to
- *    the remaining replicas. If there is more than 1 RO sites,
- *    ensure that the VLDB says at least one RO is available all
- *    the time: Influences when we write back the VLDB entry.
+ * @param[in] afromvol      volume to be released
+ * @param[in] afromserver   server containing afromvol
+ * @param[in] afrompart     partition containing afromvol
+ * @param[in] flags         bitmap of options
+ *                            REL_COMPLETE  - force a complete release
+ *                            REL_FULLDUMPS - force full dumps
  */
-
 int
 UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
-                afs_int32 afrompart, int forceflag, int stayUp)
+                afs_int32 afrompart, int flags)
 {
     char vname[64];
     afs_int32 code = 0;
@@ -3290,7 +3378,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     afs_uint32 cloneVolId = 0, roVolId;
     struct replica *replicas = 0;
     struct nvldbentry entry, storeEntry;
-    int i, volcount = 0, m, fullrelease, vldbindex;
+    int i, volcount = 0, m, vldbindex;
     int failure;
     struct restoreCookie cookie;
     struct rx_connection **toconns = 0;
@@ -3322,6 +3410,19 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     int notreleased = 0;
     int tried_justnewsites = 0;
     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 */
+
+    typedef enum {
+        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 */
+        CR_NEW_RW     = 0x0008, /**< complete: read-write has changed */
+        CR_RO_MISSING = 0x0010, /**< complete: ro clone is missing */
+    } complete_release_t;
+
+    complete_release_t complete_release = CR_PARTIAL;
 
     memset(remembertime, 0, sizeof(remembertime));
     memset(&results, 0, sizeof(results));
@@ -3378,65 +3479,63 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        ONERROR(vcode, entry.name, "Could not update vldb entry for %s.\n");
     }
 
-    /* Will we be completing a previously unfinished release. -force overrides */
-    for (s = 0, m = 0, fullrelease=0, i=0; (i<entry.nServers); i++) {
-       if (entry.serverFlags[i] & ITSROVOL) {
-           m++;
-           if (entry.serverFlags[i] & NEW_REPSITE) s++;
-           if (entry.serverFlags[i] & RO_DONTUSE) notreleased++;
+    /*
+     * Determine if this is to be a complete release or a recovery of a
+     * previous unfinished release. The previous release is considered to be
+     * unfinished when the clone was successfully distributed to at least one
+     * (but not all) of the read-only sites, as indicated by the NEW_REPSITE
+     * vldb flags.
+     *
+     * The caller can override the vldb flags check using the -force
+     * or -force-reclone flag, to force this to be a complete release.
+     */
+    for (i = 0; i < entry.nServers; i++) {
+       if (entry.serverFlags[i] & VLSF_ROVOL) {
+           sites++;
+           if (entry.serverFlags[i] & VLSF_NEWREPSITE)
+               new_sites++;
+           if (entry.serverFlags[i] & VLSF_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) {
+    if (flags & REL_COMPLETE) {
+       complete_release |= CR_FORCED;
+    }
+
+    if (new_sites == 0) {
+       complete_release |= CR_LAST_OK;
+    } else if (new_sites == sites) {
+       complete_release |= CR_ALL_NEW;
+    }
+
+    if ((complete_release & (CR_LAST_OK | CR_ALL_NEW))
+       && !(complete_release & CR_FORCED)) {
+       if (notreleased && notreleased != sites) {
            /* we have some new unreleased sites. try to just release to those,
-            * if the RW has not changed */
+            * if the RW has not changed. The caller can override with -force
+            * or with -force-reclone. */
            justnewsites = 1;
        }
     }
 
     /* Determine which volume id to use and see if it exists */
-    cloneVolId =
-       ((fullrelease
-         || (entry.cloneId == 0)) ? entry.volumeId[ROVOL] : entry.cloneId);
+    cloneVolId = (complete_release || entry.cloneId == 0)
+                 ? entry.volumeId[ROVOL] : entry.cloneId;
+
     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] & ITSROVOL)) {
-               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,
                "Cannot establish connection with server 0x%x\n");
 
-    if (!fullrelease) {
-       if (!roexists)
-           fullrelease = 1;    /* Do a full release if RO clone does not exist */
-       else {
+    if (!complete_release) {
+       if (!roexists) {
+           complete_release |= CR_RO_MISSING;  /* Do a complete release if RO clone does not exist */
+       } else {
            /* Begin transaction on RW and mark it busy while we query it */
            code = AFSVolTransCreate_retry(
                        fromconn, afromvol, afrompart, ITBusy, &fromtid
@@ -3476,58 +3575,67 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                    "Failed to end transaction on RW clone %u\n");
 
            if (rwcrdate > clcrdate)
-               fullrelease = 2;/* Do a full release if RO clone older than RW */
+               complete_release |= CR_NEW_RW; /* Do a complete release if RO clone older than RW */
        }
     }
 
-    if (fullrelease != 1) {
+    if (!complete_release || (complete_release & CR_NEW_RW)) {
        /* in case the RW has changed, and just to be safe */
        justnewsites = 0;
     }
 
     if (verbose) {
-       switch (fullrelease) {
-           case 2:
-               fprintf(STDOUT, "RW %lu changed, doing a complete release\n",
-                       (unsigned long)afromvol);
-               break;
-           case 1:
-               fprintf(STDOUT, "This is a complete release of volume %lu\n",
-                       (unsigned long)afromvol);
+       if (!complete_release) {
+           fprintf(STDOUT,
+                   "This is a recovery of previously failed release\n");
+       } else {
+           fprintf(STDOUT, "This is a complete release of volume %u", afromvol);
+           if (complete_release == CR_LAST_OK) {
                if (justnewsites) {
                    tried_justnewsites = 1;
-                   fprintf(STDOUT, "There are new RO sites; we will try to "
-                                   "only release to new sites\n");
+                   fprintf(STDOUT, "\nThere are new RO sites; we will try to "
+                           "only release to new sites");
                }
-               break;
-           case 0:
-               fprintf(STDOUT, "This is a completion of a previous release\n");
-               break;
+           } else {
+               char *sep = " (";
+               if (complete_release & CR_FORCED) {
+                   fprintf(STDOUT, "%sforced", sep);
+                   sep = ", ";
+               }
+               if (complete_release & CR_LAST_OK) {
+                   fprintf(STDOUT, "%slast ok", sep);
+                   sep = ", ";
+               }
+               if (complete_release & CR_ALL_NEW) {
+                   fprintf(STDOUT, "%sall sites are new", sep);
+                   sep = ", ";
+               }
+               if (complete_release & CR_NEW_RW) {
+                   fprintf(STDOUT, "%srw %u changed", sep, afromvol);
+                   sep = ", ";
+               }
+               if (complete_release & CR_RO_MISSING) {
+                   fprintf(STDOUT, "%sro clone missing", sep);
+               }
+               fprintf(STDOUT, ")");
+           }
+           fprintf(STDOUT, "\n");
        }
     }
 
-    if (fullrelease) {
+    if (complete_release) {
        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
         * 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] & RO_DONTUSE))) {
+           && (!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);
@@ -3541,10 +3649,10 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                struct rx_connection *conn;
                afs_int32 crdate;
 
-               if (!(entry.serverFlags[vldbindex] & ITSROVOL)) {
+               if (!(entry.serverFlags[vldbindex] & VLSF_ROVOL)) {
                    continue;
                }
-               if ((entry.serverFlags[vldbindex] & RO_DONTUSE)) {
+               if ((entry.serverFlags[vldbindex] & VLSF_DONTUSE)) {
                    continue;
                }
                conn = UV_Bind(entry.serverNumber[vldbindex], AFSCONF_VOLUMEPORT);
@@ -3616,18 +3724,18 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
         */
        for (i = 0; i < entry.nServers; i++) {
            if (justnewsites) {
-               if ((entry.serverFlags[i] & RO_DONTUSE)) {
-                   entry.serverFlags[i] &= ~NEW_REPSITE;
+               if ((entry.serverFlags[i] & VLSF_DONTUSE)) {
+                   entry.serverFlags[i] &= ~VLSF_NEWREPSITE;
                } else {
-                   entry.serverFlags[i] |= NEW_REPSITE;
+                   entry.serverFlags[i] |= VLSF_NEWREPSITE;
                }
            } else {
-               entry.serverFlags[i] &= ~NEW_REPSITE;
-               entry.serverFlags[i] |= RO_DONTUSE;
+               entry.serverFlags[i] &= ~VLSF_NEWREPSITE;
+               entry.serverFlags[i] |= VLSF_DONTUSE;
            }
        }
-       entry.serverFlags[rwindex] |= NEW_REPSITE;
-       entry.serverFlags[rwindex] &= ~RO_DONTUSE;
+       entry.serverFlags[rwindex] |= VLSF_NEWREPSITE;
+       entry.serverFlags[rwindex] &= ~VLSF_DONTUSE;
     }
 
     if (justnewsites && roexists) {
@@ -3635,20 +3743,17 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
         * anything with the RO clone, so skip the reclone */
        /* noop */
 
-    } else if (fullrelease) {
+    } else if (complete_release) {
 
        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;
@@ -3659,11 +3764,11 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            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[i] &= ~VLSF_NEWREPSITE;
+               entry.serverFlags[i] |= VLSF_DONTUSE;
            }
-           entry.serverFlags[rwindex] |= NEW_REPSITE;
-           entry.serverFlags[rwindex] &= ~RO_DONTUSE;
+           entry.serverFlags[rwindex] |= VLSF_NEWREPSITE;
+           entry.serverFlags[rwindex] &= ~VLSF_DONTUSE;
        }
 
        rwcrdate = volstatus.creationDate;
@@ -3671,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);
@@ -3704,9 +3809,9 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                sleep(5);
 
            /* Mark the RO clone in the VLDB as a good site (already released) */
-           entry.serverFlags[roindex] |= NEW_REPSITE;
-           entry.serverFlags[roindex] &= ~RO_DONTUSE;
-           entry.flags |= RO_EXISTS;
+           entry.serverFlags[roindex] |= VLSF_NEWREPSITE;
+           entry.serverFlags[roindex] &= ~VLSF_DONTUSE;
+           entry.flags |= VLF_ROEXISTS;
 
            releasecount++;
 
@@ -3727,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 */
-       fullrelease = 0;
+       complete_release = CR_PARTIAL;
     } else if (tried_justnewsites) {
        VPRINT("RW vol has changed; releasing to all sites\n");
     }
@@ -3741,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;
@@ -3752,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;
@@ -3772,28 +3874,19 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
        memset(&orig_status, 0, sizeof(orig_status));
        code = AFSVolGetStatus(fromconn, fromtid, &orig_status);
     }
-    if (!fullrelease && code)
+    if (!complete_release && code)
        ONERROR(VOLSERNOVOL, afromvol,
                "Old clone is inaccessible. Try vos release -f %u.\n");
     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 && !fullrelease) {
-       entry.serverFlags[roindex] |= NEW_REPSITE;
-       entry.serverFlags[roindex] &= ~RO_DONTUSE;
-       entry.flags |= RO_EXISTS;
-
-       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
@@ -3805,10 +3898,10 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
 
            if (vldbindex == roindex)
                continue;       /* the clone    */
-           if ((entry.serverFlags[vldbindex] & NEW_REPSITE)
-               && !(entry.serverFlags[vldbindex] & RO_DONTUSE))
+           if ((entry.serverFlags[vldbindex] & VLSF_NEWREPSITE)
+               && !(entry.serverFlags[vldbindex] & VLSF_DONTUSE))
                continue;
-           if (!(entry.serverFlags[vldbindex] & ITSROVOL))
+           if (!(entry.serverFlags[vldbindex] & VLSF_ROVOL))
                continue;       /* not a RO vol */
 
 
@@ -3828,20 +3921,38 @@ 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;
 
            /* Thisdate is the date from which we want to pick up all changes */
-           if (forceflag || !fullrelease
-               || (rwcrdate > times[volcount].crtime)) {
-               /* If the forceflag is set, then we want to do a full dump.
-                * If it's not a full release, we can't be sure that the creation
-                *  date is good (so we also do a full dump).
-                * If the RW volume was replaced (its creation date is newer than
-                *  the last release), then we can't be sure what has changed (so
-                *  we do a full dump).
+           if (flags & REL_FULLDUMPS) {
+               /* Do a full dump when forced by the caller. */
+               VPRINT("This will be a full dump: forced\n");
+               thisdate = 0;
+           } 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. */
+               VPRINT
+                   ("This will be a full dump: read-only volume needs to be created\n");
+               thisdate = 0;
+           } else if ((rwcrdate > times[volcount].crtime)) {
+               /* If the RW volume was replaced (its creation date is newer than
+                * the last release), then we can't be sure what has changed (so
+                * we do a full dump).
                 */
+               VPRINT
+                   ("This will be a full dump: read-write volume was replaced\n");
                thisdate = 0;
            } else if (remembertime[vldbindex].validtime) {
                /* Trans was prev ended. Use the time from the prev trans
@@ -3880,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.
@@ -3904,7 +4015,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
            }
 
            if (fromdate == 0)
-               fprintf(STDOUT, " (full release)");
+               fprintf(STDOUT, " (entire volume)");
            else {
                tmv = fromdate;
                fprintf(STDOUT, " (as of %.24s)", ctime(&tmv));
@@ -3967,173 +4078,19 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                    continue;
                }
 
-               entry.serverFlags[times[m].vldbEntryIndex] |= NEW_REPSITE;
-               entry.serverFlags[times[m].vldbEntryIndex] &= ~RO_DONTUSE;
-               entry.flags |= RO_EXISTS;
+               entry.serverFlags[times[m].vldbEntryIndex] |= VLSF_NEWREPSITE;
+               entry.serverFlags[times[m].vldbEntryIndex] &= ~VLSF_DONTUSE;
+               entry.flags |= VLF_ROEXISTS;
                releasecount++;
            }
        }
 
-       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] &= ~NEW_REPSITE;
-               entry.serverFlags[roindex] |= RO_DONTUSE;
-           } else {
-               entry.serverFlags[roindex] |= NEW_REPSITE;
-               entry.serverFlags[roindex] &= ~RO_DONTUSE;
-               entry.flags |= RO_EXISTS;
-               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] |= RO_DONTUSE;
-                   }
-                   entry.serverFlags[vldbindex] &= ~NEW_REPSITE;
-                   PrintError("Failed: ",
-                              code);
-               } else
-                   VDONE;
-
-               if (entry.serverFlags[vldbindex] != RO_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] &= ~NEW_REPSITE;
-                       entry.serverFlags[s] |= RO_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);
@@ -4145,7 +4102,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
 
     /* Figure out if any volume were not released and say so */
     for (failure = 0, i = 0; i < entry.nServers; i++) {
-       if (!(entry.serverFlags[i] & NEW_REPSITE))
+       if (!(entry.serverFlags[i] & VLSF_NEWREPSITE))
            failure++;
     }
     if (failure) {
@@ -4154,7 +4111,7 @@ UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                "The volume %lu could not be released to the following %d sites:\n",
                (unsigned long)afromvol, failure);
        for (i = 0; i < entry.nServers; i++) {
-           if (!(entry.serverFlags[i] & NEW_REPSITE)) {
+           if (!(entry.serverFlags[i] & VLSF_NEWREPSITE)) {
                MapPartIdIntoName(entry.serverPartition[i], pname);
                fprintf(STDERR, "\t%35s %s\n",
                         noresolve ? afs_inet_ntoa_r(entry.serverNumber[i], hoststr) :
@@ -4173,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);
@@ -4181,12 +4138,13 @@ 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;
     }
 
     for (i = 0; i < entry.nServers; i++)
-       entry.serverFlags[i] &= ~NEW_REPSITE;
+       entry.serverFlags[i] &= ~VLSF_NEWREPSITE;
 
     /* Update the VLDB */
     VPRINT("updating VLDB ...");
@@ -4295,7 +4253,7 @@ UV_DumpVolume(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
     struct rx_connection * volatile fromconn = NULL;
     afs_int32 volatile fromtid = 0;
 
-    afs_int32 rxError = 0, rcode = 0;
+    afs_int32 rcode = 0;
     afs_int32 code, error = 0;
     afs_int32 tmp;
     time_t tmv = fromdate;
@@ -4345,7 +4303,7 @@ UV_DumpVolume(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
 
   error_exit:
     if (fromcall) {
-       code = rx_EndCall(fromcall, rxError);
+       code = rx_EndCall(fromcall, 0);
        if (code && code != RXGEN_OPCODE)
            fprintf(STDERR, "Error in rx_EndCall\n");
        if (code && !error)
@@ -4390,11 +4348,11 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     afs_uint32 volatile clonevol = 0;
 
     afs_int32 tmp;
-    afs_int32 fromtid = 0, rxError = 0, rcode = 0;
+    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);
@@ -4420,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;
@@ -4433,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);
@@ -4487,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);
@@ -4498,7 +4464,7 @@ UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
     }
 
     if (fromcall) {
-       code = rx_EndCall(fromcall, rxError);
+       code = rx_EndCall(fromcall, 0);
        if (code) {
            fprintf(STDERR, "Error in rx_EndCall\n");
            if (!error)
@@ -4540,14 +4506,12 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
     struct rx_connection *toconn, *tempconn;
     struct rx_call *tocall;
     afs_int32 totid, code, rcode, vcode, terror = 0;
-    afs_int32 rxError = 0;
     struct volser_status tstatus;
     struct volintInfo vinfo;
     char partName[10];
     char tovolreal[VOLSER_OLDMAXVOLNAME];
     afs_uint32 pvolid;
     afs_int32 temptid, pparentid;
-    int success;
     struct nvldbentry entry, storeEntry;
     afs_int32 error;
     int islocked;
@@ -4555,17 +4519,17 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
     int reuseID;
     afs_int32 volflag, voltype, volsertype;
     afs_int32 oldCreateDate, oldUpdateDate, newCreateDate, newUpdateDate;
+    VolumeId oldCloneId = 0;
+    VolumeId oldBackupId = 0;
     int index, same, errcode;
     char apartName[10];
     char hoststr[16];
 
     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;
@@ -4593,7 +4557,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
            }
            reuseID = 0;
        } else if (flags & RV_RDONLY) {
-           if (entry.flags & RW_EXISTS) {
+           if (entry.flags & VLF_RWEXISTS) {
                fprintf(STDERR,
                        "Entry for ReadWrite volume %s already exists!\n",
                        entry.name);
@@ -4666,6 +4630,8 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
        }
        oldCreateDate = tstatus.creationDate;
        oldUpdateDate = tstatus.updateDate;
+       oldCloneId = tstatus.cloneID;
+       oldBackupId = tstatus.backupID;
     } else {
        oldCreateDate = 0;
        oldUpdateDate = 0;
@@ -4689,7 +4655,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
        error = code;
        goto refail;
     }
-    terror = rx_EndCall(tocall, rxError);
+    terror = rx_EndCall(tocall, 0);
     tocall = (struct rx_call *)0;
     if (terror) {
        fprintf(STDERR, "rx_EndCall Failed \n");
@@ -4704,9 +4670,10 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
        error = code;
        goto refail;
     }
-    code = AFSVolSetIdsTypes(toconn, totid, tovolreal, voltype, pparentid, 0, 0);
+    code = AFSVolSetIdsTypes(toconn, totid, tovolreal, voltype, pparentid,
+                               oldCloneId, oldBackupId);
     if (code) {
-       fprintf(STDERR, "Could not set the right type and ID on %lu\n",
+       fprintf(STDERR, "Could not set the right type and IDs on %lu\n",
                (unsigned long)pvolid);
        error = code;
        goto refail;
@@ -4762,10 +4729,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.
         */
@@ -4786,8 +4752,8 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
            entry.nServers = 1;
            entry.serverNumber[0] = toserver;   /*should be indirect */
            entry.serverPartition[0] = topart;
-           entry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
-           entry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
+           entry.serverFlags[0] = (flags & RV_RDONLY) ? VLSF_ROVOL : VLSF_RWVOL;
+           entry.flags = (flags & RV_RDONLY) ? VLF_ROEXISTS : VLF_RWEXISTS;
            if (flags & RV_RDONLY)
                entry.volumeId[ROVOL] = pvolid;
            else if (tstatus.cloneID != 0) {
@@ -4843,7 +4809,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
                entry.serverNumber[entry.nServers] = toserver;
                entry.serverPartition[entry.nServers] = topart;
                entry.serverFlags[entry.nServers] =
-                   (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
+                   (flags & RV_RDONLY) ? VLSF_ROVOL : VLSF_RWVOL;
                entry.nServers++;
            } else {
                /* This volume should be deleted on the old site
@@ -4892,7 +4858,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
                entry.serverPartition[index] = topart;
            }
 
-           entry.flags |= (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
+           entry.flags |= (flags & RV_RDONLY) ? VLF_ROEXISTS : VLF_RWEXISTS;
            MapNetworkToHost(&entry, &storeEntry);
            vcode =
                VLDB_ReplaceEntry(pvolid, voltype, &storeEntry,
@@ -4914,7 +4880,7 @@ UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
     }
   refail:
     if (tocall) {
-       code = rx_EndCall(tocall, rxError);
+       code = rx_EndCall(tocall, 0);
        if (!error)
            error = code;
     }
@@ -5048,7 +5014,7 @@ UV_AddSite2(afs_uint32 server, afs_int32 part, afs_uint32 volid,
 
     /* See if it's on the same server */
     for (j = 0; j < entry.nServers; j++) {
-       if (entry.serverFlags[j] & ITSROVOL) {
+       if (entry.serverFlags[j] & VLSF_ROVOL) {
            nro++;
            if (VLDB_IsSameAddrs(server, entry.serverNumber[j], &error)) {
                if (error) {
@@ -5098,9 +5064,9 @@ UV_AddSite2(afs_uint32 server, afs_int32 part, afs_uint32 volid,
     entry.serverNumber[entry.nServers] = server;
     entry.serverPartition[entry.nServers] = part;
     if (!valid) {
-       entry.serverFlags[entry.nServers] = (ITSROVOL | RO_DONTUSE);
+       entry.serverFlags[entry.nServers] = (VLSF_ROVOL | VLSF_DONTUSE);
     } else {
-       entry.serverFlags[entry.nServers] = (ITSROVOL);
+       entry.serverFlags[entry.nServers] = (VLSF_ROVOL);
     }
     entry.nServers++;
 
@@ -5174,8 +5140,8 @@ UV_RemoveSite(afs_uint32 server, afs_int32 part, afs_uint32 volid)
     } else {                   /*remove the rep site */
        Lp_SetROValue(&entry, server, part, 0, 0);
        entry.nServers--;
-       if ((entry.nServers == 1) && (entry.flags & RW_EXISTS))
-           entry.flags &= ~RO_EXISTS;
+       if ((entry.nServers == 1) && (entry.flags & VLF_RWEXISTS))
+           entry.flags &= ~VLF_ROEXISTS;
        if (entry.nServers < 1) {       /*this is the last ref */
            VPRINT1("Deleting the VLDB entry for %u ...", volid);
            fflush(STDOUT);
@@ -5341,7 +5307,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++) {
@@ -5386,7 +5351,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))
@@ -5468,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 */
@@ -5538,7 +5501,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;
@@ -5580,8 +5542,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;
@@ -5644,7 +5604,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;
@@ -5742,7 +5701,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);
            }
@@ -5762,8 +5721,8 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
        if (createentry) {
            fprintf(STDOUT, "\n**does not exist**\n");
        } else {
-           if ((entry.flags & RW_EXISTS) || (entry.flags & RO_EXISTS)
-               || (entry.flags & BACK_EXISTS))
+           if ((entry.flags & VLF_RWEXISTS) || (entry.flags & VLF_ROEXISTS)
+               || (entry.flags & VLF_BACKEXISTS))
                EnumerateEntry(&entry);
        }
        fprintf(STDOUT, "\n");
@@ -5790,7 +5749,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
            } else {            /* RW index found in the VLDB entry. */
                /* Verify if this volume's location matches where the VLDB says it is */
                if (!Lp_Match(aserver, apart, &entry)) {
-                   if (entry.flags & RW_EXISTS) {
+                   if (entry.flags & VLF_RWEXISTS) {
                        /* The RW volume exists elsewhere - report this one a duplicate */
                        if (pass == 1) {
                            MapPartIdIntoName(apart, pname);
@@ -5816,7 +5775,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
                        addvolume++;
 
                        /* Check for orphaned BK volume on old partition */
-                       if (entry.flags & BACK_EXISTS) {
+                       if (entry.flags & VLF_BACKEXISTS) {
                            if (pass == 1) {
                                MapPartIdIntoName(entry.serverPartition[idx],
                                                  pname);
@@ -5854,14 +5813,14 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
        }
 
        if (addvolume) {
-           entry.flags |= RW_EXISTS;
+           entry.flags |= VLF_RWEXISTS;
            entry.volumeId[RWVOL] = rwvolid;
            if (!entry.volumeId[BACKVOL])
                entry.volumeId[BACKVOL] = volumeinfo->backupID;
            if (!entry.volumeId[ROVOL])
                entry.volumeId[ROVOL] = volumeinfo->cloneID;
 
-           entry.serverFlags[idx] = ITSRWVOL;
+           entry.serverFlags[idx] = VLSF_RWVOL;
            entry.serverNumber[idx] = aserver;
            entry.serverPartition[idx] = apart;
            strncpy(entry.name, volumeinfo->name, VOLSER_OLDMAXVOLNAME);
@@ -5919,7 +5878,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
                    }
                } else {
                    if (volumeinfo->volid != entry.volumeId[BACKVOL]) {
-                       if (!(entry.flags & BACK_EXISTS)) {
+                       if (!(entry.flags & VLF_BACKEXISTS)) {
                            addvolume++;
                        } else if (volumeinfo->volid >
                                   entry.volumeId[BACKVOL]) {
@@ -5962,13 +5921,13 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
            }
        }
        if (addvolume) {
-           entry.flags |= BACK_EXISTS;
+           entry.flags |= VLF_BACKEXISTS;
            entry.volumeId[RWVOL] = rwvolid;
            entry.volumeId[BACKVOL] = volumeinfo->volid;
 
            entry.serverNumber[idx] = aserver;
            entry.serverPartition[idx] = apart;
-           entry.serverFlags[idx] = ITSBACKVOL;
+           entry.serverFlags[idx] = VLSF_RWVOL;
 
            modified++;
        }
@@ -5986,7 +5945,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
                entry.nServers++;
                addvolume++;
            } else {
-               if (!(entry.flags & RO_EXISTS)) {
+               if (!(entry.flags & VLF_ROEXISTS)) {
                    addvolume++;
                }
            }
@@ -6000,7 +5959,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
            if (mod)
                modified++;
 
-           if (!(entry.flags & RO_EXISTS)) {
+           if (!(entry.flags & VLF_ROEXISTS)) {
                /* No RO exists in the VLDB entry - add this one */
                idx = entry.nServers;
                entry.nServers++;
@@ -6011,7 +5970,7 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
                 * all the RO volumes listed in VLDB entry and add this volume.
                 */
                for (j = 0; j < entry.nServers; j++) {
-                   if (entry.serverFlags[j] & ITSROVOL) {
+                   if (entry.serverFlags[j] & VLSF_ROVOL) {
                        /* Verify this volume exists and print message we are orphaning it */
                        if (pass == 1) {
                            MapPartIdIntoName(apart, pname);
@@ -6070,13 +6029,13 @@ CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
        }
 
        if (addvolume) {
-           entry.flags |= RO_EXISTS;
+           entry.flags |= VLF_ROEXISTS;
            entry.volumeId[RWVOL] = rwvolid;
            entry.volumeId[ROVOL] = volumeinfo->volid;
 
            entry.serverNumber[idx] = aserver;
            entry.serverPartition[idx] = apart;
-           entry.serverFlags[idx] = ITSROVOL;
+           entry.serverFlags[idx] = VLSF_ROVOL;
 
            modified++;
        }
@@ -6229,8 +6188,8 @@ UV_SyncVolume(afs_uint32 aserver, afs_int32 apart, char *avolname, int flags)
        if (vcode) {
            fprintf(STDOUT, "\n**does not exist**\n");
        } else {
-           if ((vldbentry.flags & RW_EXISTS) || (vldbentry.flags & RO_EXISTS)
-               || (vldbentry.flags & BACK_EXISTS))
+           if ((vldbentry.flags & VLF_RWEXISTS) || (vldbentry.flags & VLF_ROEXISTS)
+               || (vldbentry.flags & VLF_BACKEXISTS))
                EnumerateEntry(&vldbentry);
        }
        fprintf(STDOUT, "\n");
@@ -6596,12 +6555,12 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
        *modified = 0;
     idx = Lp_GetRwIndex(entry);
 
-    /* Check to see if the RW volume exists and set the RW_EXISTS
+    /* Check to see if the RW volume exists and set the VLF_RWEXISTS
      * flag accordingly.
      */
     if (idx == -1) {           /* Did not find a RW entry */
-       if (entry->flags & RW_EXISTS) { /* ... yet entry says RW exists */
-           entry->flags &= ~RW_EXISTS; /* ... so say RW does not exist */
+       if (entry->flags & VLF_RWEXISTS) {      /* ... yet entry says RW exists */
+           entry->flags &= ~VLF_RWEXISTS;      /* ... so say RW does not exist */
            modentry++;
        }
     } else {
@@ -6609,18 +6568,18 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
            VolumeExists(entry->serverNumber[idx],
                         entry->serverPartition[idx], entry->volumeId[RWVOL]);
        if (code == 0) {        /* RW volume exists */
-           if (!(entry->flags & RW_EXISTS)) {  /* ... yet entry says RW does not exist */
-               entry->flags |= RW_EXISTS;      /* ... so say RW does exist */
+           if (!(entry->flags & VLF_RWEXISTS)) {       /* ... yet entry says RW does not exist */
+               entry->flags |= VLF_RWEXISTS;   /* ... so say RW does exist */
                modentry++;
            }
        } else if (code == ENODEV) {    /* RW volume does not exist */
-           if (entry->flags & RW_EXISTS) {     /* ... yet entry says RW exists */
-               entry->flags &= ~RW_EXISTS;     /* ... so say RW does not exist */
+           if (entry->flags & VLF_RWEXISTS) {  /* ... yet entry says RW exists */
+               entry->flags &= ~VLF_RWEXISTS;  /* ... so say RW does not exist */
                modentry++;
            }
        } else {
            /* If VLDB says it didn't exist, then ignore error */
-           if (entry->flags & RW_EXISTS) {
+           if (entry->flags & VLF_RWEXISTS) {
                MapPartIdIntoName(entry->serverPartition[idx], pname);
                fprintf(STDERR,
                        "Transaction call failed for RW volume %u on server %s %s\n",
@@ -6634,12 +6593,12 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
        }
     }
 
-    /* Check to see if the BK volume exists and set the BACK_EXISTS
+    /* Check to see if the BK volume exists and set the VLF_BACKEXISTS
      * flag accordingly. idx already ponts to the RW entry.
      */
     if (idx == -1) {           /* Did not find a RW entry */
-       if (entry->flags & BACK_EXISTS) {       /* ... yet entry says BK exists */
-           entry->flags &= ~BACK_EXISTS;       /* ... so say BK does not exist */
+       if (entry->flags & VLF_BACKEXISTS) {    /* ... yet entry says BK exists */
+           entry->flags &= ~VLF_BACKEXISTS;    /* ... so say BK does not exist */
            modentry++;
        }
     } else {                   /* Found a RW entry */
@@ -6648,18 +6607,18 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
                         entry->serverPartition[idx],
                         entry->volumeId[BACKVOL]);
        if (code == 0) {        /* BK volume exists */
-           if (!(entry->flags & BACK_EXISTS)) {        /* ... yet entry says BK does not exist */
-               entry->flags |= BACK_EXISTS;    /* ... so say BK does exist */
+           if (!(entry->flags & VLF_BACKEXISTS)) {     /* ... yet entry says BK does not exist */
+               entry->flags |= VLF_BACKEXISTS; /* ... so say BK does exist */
                modentry++;
            }
        } else if (code == ENODEV) {    /* BK volume does not exist */
-           if (entry->flags & BACK_EXISTS) {   /* ... yet entry says BK exists */
-               entry->flags &= ~BACK_EXISTS;   /* ... so say BK does not exist */
+           if (entry->flags & VLF_BACKEXISTS) {        /* ... yet entry says BK exists */
+               entry->flags &= ~VLF_BACKEXISTS;        /* ... so say BK does not exist */
                modentry++;
            }
        } else {
            /* If VLDB says it didn't exist, then ignore error */
-           if (entry->flags & BACK_EXISTS) {
+           if (entry->flags & VLF_BACKEXISTS) {
                MapPartIdIntoName(entry->serverPartition[idx], pname);
                fprintf(STDERR,
                        "Transaction call failed for BK volume %u on server %s %s\n",
@@ -6676,8 +6635,8 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
     /* If there is an idx but the BK and RW volumes no
      * longer exist, then remove the RW entry.
      */
-    if ((idx != -1) && !(entry->flags & RW_EXISTS)
-       && !(entry->flags & BACK_EXISTS)) {
+    if ((idx != -1) && !(entry->flags & VLF_RWEXISTS)
+       && !(entry->flags & VLF_BACKEXISTS)) {
        Lp_SetRWValue(entry, entry->serverNumber[idx],
                      entry->serverPartition[idx], 0L, 0L);
        entry->nServers--;
@@ -6702,11 +6661,11 @@ CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified)
     if (modified)
        *modified = 0;
 
-    /* Check to see if the RO volumes exist and set the RO_EXISTS
+    /* Check to see if the RO volumes exist and set the VLF_ROEXISTS
      * flag accordingly.
      */
     for (idx = 0; idx < entry->nServers; idx++) {
-       if (!(entry->serverFlags[idx] & ITSROVOL)) {
+       if (!(entry->serverFlags[idx] & VLSF_ROVOL)) {
            continue;           /* not a RO */
        }
 
@@ -6734,13 +6693,13 @@ CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified)
     }
 
     if (foundro) {             /* A RO volume exists */
-       if (!(entry->flags & RO_EXISTS)) {      /* ... yet entry says RW does not exist */
-           entry->flags |= RO_EXISTS;  /* ... so say RW does exist */
+       if (!(entry->flags & VLF_ROEXISTS)) {   /* ... yet entry says RW does not exist */
+           entry->flags |= VLF_ROEXISTS;       /* ... so say RW does exist */
            modentry++;
        }
     } else {                   /* A RO volume does not exist */
-       if (entry->flags & RO_EXISTS) { /* ... yet entry says RO exists */
-           entry->flags &= ~RO_EXISTS; /* ... so say RO does not exist */
+       if (entry->flags & VLF_ROEXISTS) {      /* ... yet entry says RO exists */
+           entry->flags &= ~VLF_ROEXISTS;      /* ... so say RO does not exist */
            modentry++;
        }
     }
@@ -6770,8 +6729,8 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified, afs_int32 * deleted)
     if (verbose) {
        fprintf(STDOUT, "_______________________________\n");
        fprintf(STDOUT, "\n-- status before -- \n");
-       if ((entry->flags & RW_EXISTS) || (entry->flags & RO_EXISTS)
-           || (entry->flags & BACK_EXISTS))
+       if ((entry->flags & VLF_RWEXISTS) || (entry->flags & VLF_ROEXISTS)
+           || (entry->flags & VLF_BACKEXISTS))
            EnumerateEntry(entry);
        fprintf(STDOUT, "\n");
     }
@@ -6834,8 +6793,8 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified, afs_int32 * deleted)
        if (pass == 1)
            goto retry;
 
-       if (!(entry->flags & RW_EXISTS) && !(entry->flags & BACK_EXISTS)
-           && !(entry->flags & RO_EXISTS) && doit) {
+       if (!(entry->flags & VLF_RWEXISTS) && !(entry->flags & VLF_BACKEXISTS)
+           && !(entry->flags & VLF_ROEXISTS) && doit) {
            /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
            code =
                ubik_VL_DeleteEntry(cstruct, 0, entry->volumeId[RWVOL],
@@ -6920,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)) {
@@ -7045,7 +7005,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
     VPRINT1("Recorded the new name %s in VLDB\n", newname);
     /*at this stage the intent to rename is recorded in the vldb, as far as the vldb
      * is concerned, oldname is lost */
-    if (entry->flags & RW_EXISTS) {
+    if (entry->flags & VLF_RWEXISTS) {
        index = Lp_GetRwIndex(entry);
        if (index == -1) {      /* there is a serious discrepancy */
            fprintf(STDERR,
@@ -7095,7 +7055,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
        aconn = (struct rx_connection *)0;
     }
     /*end rw volume processing */
-    if (entry->flags & BACK_EXISTS) {  /*process the backup volume */
+    if (entry->flags & VLF_BACKEXISTS) {       /*process the backup volume */
        index = Lp_GetRwIndex(entry);
        if (index == -1) {      /* there is a serious discrepancy */
            fprintf(STDERR,
@@ -7152,9 +7112,9 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
     if (aconn)
        rx_DestroyConnection(aconn);
     aconn = (struct rx_connection *)0;
-    if (entry->flags & RO_EXISTS) {    /*process the ro volumes */
+    if (entry->flags & VLF_ROEXISTS) { /*process the ro volumes */
        for (i = 0; i < entry->nServers; i++) {
-           if (entry->serverFlags[i] & ITSROVOL) {
+           if (entry->serverFlags[i] & VLSF_ROVOL) {
                aconn = UV_Bind(entry->serverNumber[i], AFSCONF_VOLUMEPORT);
                code =
                    AFSVolTransCreate_retry(aconn, entry->volumeId[ROVOL],
@@ -7282,6 +7242,9 @@ UV_VolumeZap(afs_uint32 server, afs_int32 part, afs_uint32 volid)
     aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
     error = DoVolDelete(aconn, volid, part,
                        "the", 0, NULL, NULL);
+    if (error == VNOVOL) {
+       EPRINT1(error, "Failed to start transaction on %u\n", volid);
+    }
 
     PrintError("", error);
     if (aconn)
@@ -7432,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;*/