Revert "Convert from using nvldbentry to uvldbentry"
[openafs.git] / src / volser / vsprocs.c
index 2fad506..4f71e0a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <afs/procmgmt.h>      /* signal(), kill(), wait(), etc. */
+#include <roken.h>
 
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <string.h>
 #ifdef AFS_AIX_ENV
 #include <sys/statfs.h>
 #endif
@@ -27,21 +28,12 @@ RCSID
 #include <netinet/in.h>
 #endif
 
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
 #include <lock.h>
 #include <afs/voldefs.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <afs/vlserver.h>
 #include <afs/nfs.h>
-#include <afs/auth.h>
 #include <afs/cellconfig.h>
 #include <afs/keys.h>
 #include <ubik.h>
@@ -53,22 +45,32 @@ RCSID
 #include <rx/rxkad.h>
 #include <afs/kautils.h>
 #include <afs/cmd.h>
+#include <afs/ihandle.h>
+#ifdef AFS_NT40_ENV
+#include <afs/ntops.h>
+#endif
+#include <afs/vnode.h>
+#include <afs/volume.h>
 #include <errno.h>
 #define ERRCODE_RANGE 8                /* from error_table.h */
 #define        CLOCKSKEW   2           /* not really skew, but resolution */
+#define CLOCKADJ(x) (((x) < CLOCKSKEW) ? 0 : (x) - CLOCKSKEW)
 
 /* for UV_MoveVolume() recovery */
 
-#include <afs/procmgmt.h>      /* signal(), kill(), wait(), etc. */
 #include <setjmp.h>
 
-#include <volser_prototypes.h>
+#include "volser_internal.h"
+#include "volser_prototypes.h"
+#include "vsutils_prototypes.h"
+#include "lockprocs_prototypes.h"
 
 struct ubik_client *cstruct;
-int verbose = 0;
+int verbose = 0, noresolve = 0;
 
 struct release {
-    afs_int32 time;
+    afs_uint32 crtime;
+    afs_uint32 uptime;
     afs_int32 vldbEntryIndex;
 };
 
@@ -147,30 +149,45 @@ do { \
        { if (verbose) { fprintf(STDOUT, (es), (p1), (p2), (p3)); fflush(STDOUT); } }
 #define VDONE \
        { if (verbose) { fprintf(STDOUT, " done\n"); fflush(STDOUT); } }
+#define VEPRINT(es) \
+       { if (verbose) { fprintf(STDERR, (es)); fflush(STDERR); } }
+#define VEPRINT1(es, p) \
+       { if (verbose) { fprintf(STDERR, (es), (p)); fflush(STDERR); } }
+#define VEPRINT2(es, p1, p2) \
+       { if (verbose) { fprintf(STDERR, (es), (p1), (p2)); fflush(STDERR); } }
+#define VEPRINT3(es, p1, p2, p3) \
+       { if (verbose) { fprintf(STDERR, (es), (p1), (p2), (p3)); fflush(STDERR); } }
+#define VEDONE \
+       { if (verbose) { fprintf(STDERR, " done\n"); fflush(STDERR); } }
 
 
 
 /* getting rid of this */
-#define ERROR_EXIT(code) {error=(code); goto error_exit;}
+#define ERROR_EXIT(code) do { \
+    error = (code); \
+    goto error_exit; \
+} while (0)
 
 
 /* Protos for static routines */
+#if 0
 static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn,
-                                     afs_int32 apart, afs_int32 okvol,
-                                     afs_int32 delvol);
-static int DelVol(struct rx_connection *conn, afs_int32 vid, afs_int32 part,
+                                     afs_int32 apart, afs_uint32 okvol,
+                                     afs_uint32 delvol);
+#endif
+static int DelVol(struct rx_connection *conn, afs_uint32 vid, afs_int32 part,
                  afs_int32 flags);
 static int GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
                    struct rx_connection **connPtr, afs_int32 * transPtr,
-                   afs_int32 * timePtr);
+                   afs_uint32 * crtimePtr, afs_uint32 * uptimePtr,
+                   afs_int32 *origflags);
 static int SimulateForwardMultiple(struct rx_connection *fromconn,
                                   afs_int32 fromtid, afs_int32 fromdate,
                                   manyDests * tr, afs_int32 flags,
                                   void *cookie, manyResults * results);
-static int rel_compar(struct release *r1, struct release *r2);
-static afs_int32 CheckVolume(volintInfo * volumeinfo, afs_int32 aserver,
+static afs_int32 CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver,
                             afs_int32 apart, afs_int32 * modentry,
-                            afs_uint32 * maxvolid);
+                            afs_uint32 * maxvolid, struct nvldbentry *aentry);
 
 
 /*map the partition <partId> into partition name <partName>*/
@@ -193,24 +210,9 @@ MapPartIdIntoName(afs_int32 partId, char *partName)
 }
 
 int
-yesprompt(char *str)
-{
-    int response, c;
-    int code;
-
-    fprintf(STDERR, "Do you want to %s? [yn](n): ", str);
-    response = c = getchar();
-    while (!(c == EOF || c == '\n'))
-       c = getchar();          /*skip to end of line */
-    code = (response == 'y' || response == 'Y');
-    return code;
-}
-
-
-int
 PrintError(char *msg, afs_int32 errcode)
 {
-    fprintf(STDERR, msg);
+    fprintf(STDERR, "%s", msg);
     /*replace by a big switch statement */
     switch (errcode) {
     case 0:
@@ -387,9 +389,6 @@ PrintError(char *msg, afs_int32 errcode)
        break;
     default:
        {
-
-           afs_int32 offset;
-
            initialize_KA_error_table();
            initialize_RXK_error_table();
            initialize_KTC_error_table();
@@ -397,51 +396,107 @@ PrintError(char *msg, afs_int32 errcode)
            initialize_CMD_error_table();
            initialize_VL_error_table();
 
-           offset = errcode & ((1 << ERRCODE_RANGE) - 1);
-           fprintf(STDERR, "%s: %s\n", error_table_name(errcode),
-                   error_message(errcode));
+           fprintf(STDERR, "%s: %s\n", afs_error_table_name(errcode),
+                   afs_error_message(errcode));
            break;
        }
     }
     return 0;
 }
 
+void init_volintInfo(struct volintInfo *vinfo) {
+    memset(vinfo, 0, sizeof(struct volintInfo));
+
+    vinfo->maxquota = -1;
+    vinfo->dayUse = -1;
+    vinfo->creationDate = -1;
+    vinfo->updateDate = -1;
+    vinfo->flags = -1;
+    vinfo->spare0 = -1;
+    vinfo->spare1 = -1;
+    vinfo->spare2 = -1;
+    vinfo->spare3 = -1;
+}
 
 static struct rx_securityClass *uvclass = 0;
 static int uvindex = -1;
 /* called by VLDBClient_Init to set the security module to be used in the RPC */
 int
-UV_SetSecurity(register struct rx_securityClass *as, afs_int32 aindex)
+UV_SetSecurity(struct rx_securityClass *as, afs_int32 aindex)
 {
     uvindex = aindex;
     uvclass = as;
+    return 0;
 }
 
 /* bind to volser on <port> <aserver> */
 /* takes server address in network order, port in host order.  dumb */
 struct rx_connection *
-UV_Bind(afs_int32 aserver, afs_int32 port)
+UV_Bind(afs_uint32 aserver, afs_int32 port)
 {
-    register struct rx_connection *tc;
+    struct rx_connection *tc;
 
     tc = rx_NewConnection(aserver, htons(port), VOLSERVICE_ID, uvclass,
                          uvindex);
     return tc;
 }
 
+static int
+AFSVolCreateVolume_retry(struct rx_connection *z_conn,
+                      afs_int32 partition, char *name, afs_int32 type,
+                      afs_int32 parent, afs_uint32 *volid, afs_int32 *trans)
+{
+    afs_int32 code;
+    int retries = 3;
+    while (retries) {
+       code = AFSVolCreateVolume(z_conn, partition, name, type, parent,
+                                 volid, trans);
+        if (code != VOLSERVOLBUSY)
+            break;
+        retries--;
+#ifdef AFS_PTHREAD_ENV
+        sleep(3-retries);
+#else
+        IOMGR_Sleep(3-retries);
+#endif
+    }
+    return code;
+}
+
+static int
+AFSVolTransCreate_retry(struct rx_connection *z_conn,
+                       afs_int32 volume, afs_int32 partition,
+                       afs_int32 flags, afs_int32 * trans)
+{
+    afs_int32 code;
+    int retries = 3;
+    while (retries) {
+       code = AFSVolTransCreate(z_conn, volume, partition, flags, trans);
+        if (code != VOLSERVOLBUSY)
+            break;
+        retries--;
+#ifdef AFS_PTHREAD_ENV
+        sleep(3-retries);
+#else
+        IOMGR_Sleep(3-retries);
+#endif
+    }
+    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_int32 okvol, afs_int32 delvol)
+                    afs_uint32 okvol, afs_uint32 delvol)
 {
     afs_int32 error, code, tid, rcode;
-
     error = 0;
     code = 0;
 
     if (okvol == 0) {
-       code = AFSVolTransCreate(aconn, delvol, apart, ITOffline, &tid);
+       code = AFSVolTransCreate_retry(aconn, delvol, apart, ITOffline, &tid);
        if (!error && code)
            error = code;
        code = AFSVolDeleteVolume(aconn, tid);
@@ -454,14 +509,14 @@ CheckAndDeleteVolume(struct rx_connection *aconn, afs_int32 apart,
            error = code;
        return error;
     } else {
-       code = AFSVolTransCreate(aconn, okvol, apart, ITOffline, &tid);
+       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(aconn, delvol, apart, ITOffline, &tid);
+           code = AFSVolTransCreate_retry(aconn, delvol, apart, ITOffline, &tid);
            if (!error && code)
                error = code;
            code = AFSVolDeleteVolume(aconn, tid);
@@ -478,6 +533,8 @@ CheckAndDeleteVolume(struct rx_connection *aconn, afs_int32 apart,
     }
 }
 
+#endif
+
 /* called by EmuerateEntry, show vldb entry in a reasonable format */
 void
 SubEnumerateEntry(struct nvldbentry *entry)
@@ -485,6 +542,7 @@ SubEnumerateEntry(struct nvldbentry *entry)
     int i;
     char pname[10];
     int isMixed = 0;
+    char hoststr[16];
 
 #ifdef notdef
     fprintf(STDOUT, "  readWriteID %-10u ", entry->volumeId[RWVOL]);
@@ -524,16 +582,18 @@ SubEnumerateEntry(struct nvldbentry *entry)
     for (i = 0; i < entry->nServers; i++) {
        MapPartIdIntoName(entry->serverPartition[i], pname);
        fprintf(STDOUT, "       server %s partition %s ",
-               hostutil_GetNameByINet(entry->serverNumber[i]), pname);
+               noresolve ? afs_inet_ntoa_r(entry->serverNumber[i], hoststr) :
+                hostutil_GetNameByINet(entry->serverNumber[i]), pname);
        if (entry->serverFlags[i] & ITSRWVOL)
            fprintf(STDOUT, "RW Site ");
        else
            fprintf(STDOUT, "RO Site ");
        if (isMixed) {
            if (entry->serverFlags[i] & NEW_REPSITE)
-               fprintf(STDOUT, " -- New release");
+               fprintf(STDOUT," -- New release");
            else
-               fprintf(STDOUT, " -- Old release");
+               if (!(entry->serverFlags[i] & ITSRWVOL))
+                   fprintf(STDOUT," -- Old release");
        } else {
            if (entry->serverFlags[i] & RO_DONTUSE)
                fprintf(STDOUT, " -- Not released");
@@ -558,10 +618,10 @@ EnumerateEntry(struct nvldbentry *entry)
 
 /* forcibly remove a volume.  Very dangerous call */
 int
-UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_int32 volid)
+UV_NukeVolume(afs_uint32 server, afs_int32 partid, afs_uint32 volid)
 {
-    register struct rx_connection *tconn;
-    register afs_int32 code;
+    struct rx_connection *tconn;
+    afs_int32 code;
 
     tconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
     if (tconn) {
@@ -574,16 +634,28 @@ UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_int32 volid)
 
 /* like df. Return usage of <pname> on <server> in <partition> */
 int
-UV_PartitionInfo(afs_int32 server, char *pname,
-                struct diskPartition *partition)
+UV_PartitionInfo64(afs_uint32 server, char *pname,
+                  struct diskPartition64 *partition)
 {
-    register struct rx_connection *aconn;
-    afs_int32 code;
+    struct rx_connection *aconn;
+    afs_int32 code = 0;
 
-    code = 0;
     aconn = (struct rx_connection *)0;
     aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
-    code = AFSVolPartitionInfo(aconn, pname, partition);
+    code = AFSVolPartitionInfo64(aconn, pname, partition);
+    if (code == RXGEN_OPCODE) {
+       struct diskPartition *dpp =
+           (struct diskPartition *)malloc(sizeof(struct diskPartition));
+       code = AFSVolPartitionInfo(aconn, pname, dpp);
+       if (!code) {
+           strncpy(partition->name, dpp->name, 32);
+           strncpy(partition->devName, dpp->devName, 32);
+           partition->lock_fd = dpp->lock_fd;
+           partition->free = dpp->free;
+           partition->minFree = dpp->minFree;
+       }
+       free(dpp);
+    }
     if (code) {
        fprintf(STDERR, "Could not get information on partition %s\n", pname);
        PrintError("", code);
@@ -593,55 +665,119 @@ UV_PartitionInfo(afs_int32 server, char *pname,
     return code;
 }
 
-/* old interface to create volume */
+/* old interface to create volumes */
 int
-UV_CreateVolume(afs_int32 aserver, afs_int32 apart, char *aname,
-               afs_int32 * anewid)
+UV_CreateVolume(afs_uint32 aserver, afs_int32 apart, char *aname,
+               afs_uint32 * anewid)
 {
     afs_int32 code;
+    *anewid = 0;
     code = UV_CreateVolume2(aserver, apart, aname, 5000, 0, 0, 0, 0, anewid);
     return code;
 }
 
-/* create a volume, given a server, partition number, volume name --> sends
-* back new vol id in <anewid>*/
+/* less old interface to create volumes */
 int
-UV_CreateVolume2(afs_int32 aserver, afs_int32 apart, char *aname,
+UV_CreateVolume2(afs_uint32 aserver, afs_int32 apart, char *aname,
                 afs_int32 aquota, afs_int32 aspare1, afs_int32 aspare2,
-                afs_int32 aspare3, afs_int32 aspare4, afs_int32 * anewid)
+                afs_int32 aspare3, afs_int32 aspare4, afs_uint32 * anewid)
 {
+    afs_uint32 roid = 0, bkid = 0;
+    return UV_CreateVolume3(aserver, apart, aname, aquota, aspare1, aspare2,
+       aspare3, aspare4, anewid, &roid, &bkid);
+}
 
-    register struct rx_connection *aconn;
+/**
+ * Create a volume on the given server and partition
+ *
+ * @param aserver  server to create volume on
+ * @param spart  partition to create volume on
+ * @param aname  name of new volume
+ * @param aquota  quota for new volume
+ * @param anewid  contains the desired volume id for the new volume. If
+ *                *anewid == 0, a new id will be chosen, and will be placed
+ *                in *anewid when UV_CreateVolume3 returns.
+ * @param aroid  contains the desired RO volume id. If NULL, the RO id entry
+ *               will be unset. If *aroid == 0, an id will be chosen, and
+ *               will be placed in *anewid when UV_CreateVolume3 returns.
+ * @param abkid  same as aroid, except for the BK volume id instead of the
+ *               RO volume id.
+ * @return 0 on success, error code otherwise.
+ */
+int
+UV_CreateVolume3(afs_uint32 aserver, afs_int32 apart, char *aname,
+                afs_int32 aquota, afs_int32 aspare1, afs_int32 aspare2,
+                afs_int32 aspare3, afs_int32 aspare4, afs_uint32 * anewid,
+                afs_uint32 * aroid, afs_uint32 * abkid)
+{
+    struct rx_connection *aconn;
     afs_int32 tid;
-    register afs_int32 code;
+    afs_int32 code;
     afs_int32 error;
     afs_int32 rcode, vcode;
+    afs_int32 lastid;
     struct nvldbentry entry, storeEntry;       /*the new vldb entry */
     struct volintInfo tstatus;
 
     tid = 0;
     aconn = (struct rx_connection *)0;
     error = 0;
-    memset(&tstatus, 0, sizeof(struct volintInfo));
-    tstatus.dayUse = -1;
+
+    init_volintInfo(&tstatus);
     tstatus.maxquota = aquota;
 
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
-    /* next the next 3 available ids from the VLDB */
-    vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 3, anewid);
-    EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
+
+    if (aroid && *aroid) {
+       VPRINT1("Using RO volume ID %d.\n", *aroid);
+    }
+    if (abkid && *abkid) {
+       VPRINT1("Using BK volume ID %d.\n", *abkid);
+    }
+
+    if (*anewid) {
+        vcode = VLDB_GetEntryByID(*anewid, -1, &entry);
+       if (!vcode) {
+           fprintf(STDERR, "Volume ID %d already exists\n", *anewid);
+           return VVOLEXISTS;
+       }
+       VPRINT1("Using volume ID %d.\n", *anewid);
+    } else {
+       vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, anewid);
+       EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
+
+       if (aroid && *aroid == 0) {
+           vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, aroid);
+           EGOTO1(cfail, vcode, "Could not get an RO Id for volume %s\n", aname);
+       }
+
+       if (abkid && *abkid == 0) {
+           vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, abkid);
+           EGOTO1(cfail, vcode, "Could not get a BK Id for volume %s\n", aname);
+       }
+    }
+
+    /* rw,ro, bk id are related in the default case */
+    /* If caller specified RW id, but not RO/BK ids, have them be RW+1 and RW+2 */
+    lastid = *anewid;
+    if (aroid && *aroid == 0) {
+       *aroid = ++lastid;
+    }
+    if (abkid && *abkid == 0) {
+       *abkid = ++lastid;
+    }
 
     code =
-       AFSVolCreateVolume(aconn, apart, aname, volser_RW, 0, anewid, &tid);
-    EGOTO2(cfail, vcode, "Failed to create the volume %s %u \n", aname,
+       AFSVolCreateVolume_retry(aconn, apart, aname, volser_RW, 0, anewid, &tid);
+    EGOTO2(cfail, code, "Failed to create the volume %s %u \n", aname,
           *anewid);
 
     code = AFSVolSetInfo(aconn, tid, &tstatus);
     if (code)
-       EPRINT(code, "Could not change quota (error %d), continuing...\n");
+       EPRINT(code, "Could not change quota, continuing...\n");
 
     code = AFSVolSetFlags(aconn, tid, 0);      /* bring it online (mark it InService */
-    EGOTO2(cfail, vcode, "Could not bring the volume %s %u online \n", aname,
+    EGOTO2(cfail, code, "Could not bring the volume %s %u online \n", aname,
           *anewid);
 
     VPRINT2("Volume %s %u created and brought online\n", aname, *anewid);
@@ -649,15 +785,15 @@ UV_CreateVolume2(afs_int32 aserver, afs_int32 apart, char *aname,
     /* set up the vldb entry for this volume */
     strncpy(entry.name, aname, VOLSER_OLDMAXVOLNAME);
     entry.nServers = 1;
-    entry.serverNumber[0] = aserver;   /* this should have another 
+    entry.serverNumber[0] = aserver;   /* this should have another
                                         * level of indirection later */
-    entry.serverPartition[0] = apart;  /* this should also have 
+    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.volumeId[RWVOL] = *anewid;
-    entry.volumeId[ROVOL] = *anewid + 1;       /* rw,ro, bk id are related in the default case */
-    entry.volumeId[BACKVOL] = *anewid + 2;
+    entry.volumeId[ROVOL] = aroid ? *aroid : 0;
+    entry.volumeId[BACKVOL] = abkid ? *abkid : 0;
     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 */
@@ -698,17 +834,15 @@ UV_CreateVolume2(afs_int32 aserver, afs_int32 apart, char *aname,
        rx_DestroyConnection(aconn);
     PrintError("", error);
     return error;
-
-
 }
 
 /* create a volume, given a server, partition number, volume name --> sends
 * back new vol id in <anewid>*/
 int
-UV_AddVLDBEntry(afs_int32 aserver, afs_int32 apart, char *aname,
-               afs_int32 aid)
+UV_AddVLDBEntry(afs_uint32 aserver, afs_int32 apart, char *aname,
+               afs_uint32 aid)
 {
-    register struct rx_connection *aconn;
+    struct rx_connection *aconn;
     afs_int32 error;
     afs_int32 vcode;
     struct nvldbentry entry, storeEntry;       /*the new vldb entry */
@@ -719,9 +853,9 @@ UV_AddVLDBEntry(afs_int32 aserver, afs_int32 apart, char *aname,
     /* set up the vldb entry for this volume */
     strncpy(entry.name, aname, VOLSER_OLDMAXVOLNAME);
     entry.nServers = 1;
-    entry.serverNumber[0] = aserver;   /* this should have another 
+    entry.serverNumber[0] = aserver;   /* this should have another
                                         * level of indirection later */
-    entry.serverPartition[0] = apart;  /* this should also have 
+    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 */
@@ -756,11 +890,11 @@ UV_AddVLDBEntry(afs_int32 aserver, afs_int32 apart, char *aname,
 }
 
 /* Delete the volume <volid>on <aserver> <apart>
- * the physical entry gets removed from the vldb only if the ref count 
+ * the physical entry gets removed from the vldb only if the ref count
  * becomes zero
  */
 int
-UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
+UV_DeleteVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
 {
     struct rx_connection *aconn = (struct rx_connection *)0;
     afs_int32 ttid = 0;
@@ -772,7 +906,7 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     int notondisk = 0, notinvldb = 0;
 
     /* Find and read bhe VLDB entry for this volume */
-    code = ubik_Call(VL_SetLock, cstruct, 0, avolid, avoltype, VLOP_DELETE);
+    code = ubik_VL_SetLock(cstruct, 0, avolid, avoltype, VLOP_DELETE);
     if (code) {
        if (code != VL_NOENT) {
            EGOTO1(error_exit, code,
@@ -793,7 +927,7 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 
     /* Whether volume is in the VLDB or not. Delete the volume on disk */
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
-    code = AFSVolTransCreate(aconn, avolid, apart, ITOffline, &ttid);
+    code = AFSVolTransCreate_retry(aconn, avolid, apart, ITOffline, &ttid);
     if (code) {
        if (code == VNOVOL) {
            notondisk = 1;
@@ -840,7 +974,7 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     else if (avolid == entry.volumeId[ROVOL]) {
        /* Its a read-only volume, modify the VLDB entry. Check that the
         * readonly volume is on the server/partition we asked to delete.
-        * If flags does not have RO_EIXSTS set, then this may mean the RO 
+        * If flags does not have RO_EIXSTS set, then this may mean the RO
         * hasn't been released (and could exist in VLDB).
         */
        if (!Lp_ROMatch(aserver, apart, &entry)) {
@@ -872,8 +1006,9 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 
        /* Delete backup if it exists */
        code =
-           AFSVolTransCreate(aconn, entry.volumeId[BACKVOL], apart,
-                             ITOffline, &ttid);
+           AFSVolTransCreate_retry(aconn, entry.volumeId[BACKVOL], apart,
+                                   ITOffline, &ttid);
+
        if (!code) {
            if (verbose) {
                fprintf(STDOUT, "Trying to delete the backup volume %u ...",
@@ -922,7 +1057,7 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
            fprintf(STDOUT,
                    "Last reference to the VLDB entry for %lu - deleting entry\n",
                    (unsigned long)avolid);
-       code = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, vtype);
+       code = ubik_VL_DeleteEntry(cstruct, 0, avolid, vtype);
        EGOTO1(error_exit, code,
               "Could not delete the VLDB entry for the volume %u \n",
               avolid);
@@ -971,8 +1106,9 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 
     if (islocked) {
        code =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, -1,
-                     (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
+           ubik_VL_ReleaseLock(cstruct, 0, avolid, -1,
+                               (LOCKREL_OPCODE | LOCKREL_AFSID |
+                                LOCKREL_TIMESTAMP));
        if (code) {
            EPRINT1(code,
                    "Could not release the lock on the VLDB entry for the volume %u \n",
@@ -994,11 +1130,19 @@ UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 jmp_buf env;
 int interrupt = 0;
 
-void
-sigint_handler(int x)
+static void *
+do_interrupt(void * unused)
 {
-    if (interrupt)
+    if (interrupt) {
+#if !defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV)
+       /* Avoid UNIX LWP from getting confused that our stack has suddenly
+        * changed. This will avoid some sanity checks, but until a better way
+        * is found, the only alternative is always crashing and burning on at
+        * least the stack-overflow check. */
+       lwp_cpptr->stack = NULL;
+#endif
        longjmp(env, 0);
+    }
 
     fprintf(STDOUT, "\nSIGINT handler: vos move operation in progress\n");
     fprintf(STDOUT,
@@ -1007,37 +1151,62 @@ sigint_handler(int x)
     fflush(STDOUT);
 
     interrupt = 1;
-    (void)signal(SIGINT, sigint_handler);
+    return NULL;
+}
 
-    return;
+static void
+sigint_handler(int x)
+{
+#ifdef AFS_PTHREAD_ENV
+    do_interrupt(NULL);
+#else
+    IOMGR_SoftSig(do_interrupt, 0);
+#endif
+    (void)signal(SIGINT, sigint_handler);
 }
 
 /* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
- * <atopart>. The operation is almost idempotent 
+ * <atopart>.  The operation is almost idempotent.  The following
+ * flags are recognized:
+ *
+ *     RV_NOCLONE - don't use a copy clone
  */
 
 int
-UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
-             afs_int32 atoserver, afs_int32 atopart)
+UV_MoveVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
+              afs_uint32 atoserver, afs_int32 atopart, int flags)
 {
-    struct rx_connection *toconn, *fromconn;
-    afs_int32 fromtid, totid, clonetid;
+    /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+     * be changing during the move */
+    struct rx_connection * volatile toconn;
+    struct rx_connection * volatile fromconn;
+    afs_int32 volatile fromtid;
+    afs_int32 volatile totid;
+    afs_int32 volatile clonetid;
+    afs_uint32 volatile newVol;
+    afs_uint32 volatile volid;
+    afs_uint32 volatile backupId;
+    int volatile islocked;
+    int volatile pntg;
+
     char vname[64];
     char *volName = 0;
     char tmpName[VOLSER_MAXVOLNAME + 1];
     afs_int32 rcode;
     afs_int32 fromDate;
+    afs_int32 tmp;
+    afs_uint32 tmpVol;
     struct restoreCookie cookie;
-    register afs_int32 vcode, code;
-    afs_int32 newVol, volid, backupId;
+    afs_int32 vcode, code;
     struct volser_status tstatus;
     struct destServer destination;
 
     struct nvldbentry entry, storeEntry;
-    int i, islocked, pntg;
+    int i;
     afs_int32 error;
     char in, lf;               /* for test code */
     int same;
+    char hoststr[16];
 
 #ifdef ENABLE_BUGFIX_1165
     volEntries volumeInfo;
@@ -1090,7 +1259,7 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        exit(1);
     }
 
-    vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_MOVE);
+    vcode = ubik_VL_SetLock(cstruct, 0, afromvol, RWVOL, VLOP_MOVE);
     EGOTO1(mfail, vcode, "Could not lock entry for volume %u \n", afromvol);
     islocked = 1;
 
@@ -1114,12 +1283,13 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
                    char pname[10];
                    MapPartIdIntoName(entry.serverPartition[i], pname);
                    fprintf(STDERR, " server %s partition %s \n",
-                           hostutil_GetNameByINet(entry.serverNumber[i]),
+                           noresolve ? afs_inet_ntoa_r(entry.serverNumber[i], hoststr) :
+                            hostutil_GetNameByINet(entry.serverNumber[i]),
                            pname);
                }
            }
            vcode =
-               ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
+               ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
                          (LOCKREL_OPCODE | LOCKREL_AFSID |
                           LOCKREL_TIMESTAMP));
            EGOTO1(mfail, vcode,
@@ -1138,9 +1308,12 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        fromtid = 0;
        pntg = 1;
 
+       tmp = fromtid;
        code =
-           AFSVolTransCreate(fromconn, afromvol, afrompart, ITOffline,
-                             &fromtid);
+           AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITOffline,
+                                   &tmp);
+       fromtid = tmp;
+
        if (!code) {            /* volume exists - delete it */
            VPRINT1("Setting flags on leftover source volume %u ...",
                    afromvol);
@@ -1174,8 +1347,10 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        /*delete the backup volume now */
        fromtid = 0;
        code =
-           AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline,
-                             &fromtid);
+           AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
+                                   &tmp);
+       fromtid = tmp;
+
        if (!code) {            /* backup volume exists - delete it */
            VPRINT1("Setting flags on leftover backup volume %u ...",
                    backupId);
@@ -1211,8 +1386,8 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     }
 
     /* From-info matches the vldb info about volid,
-     * its ok start the move operation, the backup volume 
-     * on the old site is deleted in the process 
+     * its ok start the move operation, the backup volume
+     * on the old site is deleted in the process
      */
     if (afrompart == atopart) {
        same = VLDB_IsSameAddrs(afromserver, atoserver, &error);
@@ -1237,31 +1412,40 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
      * ***/
 
     VPRINT1("Starting transaction on source volume %u ...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+    code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+    fromtid = tmp;
     EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n",
           afromvol);
     VDONE;
 
-    /* Get a clone id */
-    VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
-    newVol = 0;
-    vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
-    EGOTO1(mfail, vcode,
-          "Could not get an ID for the clone of volume %u from the VLDB\n",
-          afromvol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       /* Get a clone id */
+       VPRINT1("Allocating new volume id for clone of volume %u ...",
+               afromvol);
+       newVol = tmpVol = 0;
+       vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+       newVol = tmpVol;
+       EGOTO1(mfail, vcode,
+              "Could not get an ID for the clone of volume %u from the VLDB\n",
+              afromvol);
+       VDONE;
 
-    /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
-    VPRINT1("Cloning source volume %u ...", afromvol);
-    strcpy(vname, "move-clone-temp");
-    code = AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &newVol);
-    EGOTO1(mfail, code, "Failed to clone the source volume %u\n", afromvol);
-    VDONE;
+       /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
+       VPRINT1("Cloning source volume %u ...", afromvol);
+       strcpy(vname, "move-clone-temp");
+       code =
+           AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &tmpVol);
+       newVol = tmpVol;
+       EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
+              afromvol);
+       VDONE;
+    }
 
     /* lookup the name of the volume we just cloned */
     volid = afromvol;
     code = AFSVolGetName(fromconn, fromtid, &volName);
-    EGOTO1(mfail, code, "Failed to get the name of the volume %u\n", newVol);
+    EGOTO1(mfail, code, "Failed to get the name of the volume %u\n",
+          afromvol);
 
     VPRINT1("Ending the transaction on the source volume %u ...", afromvol);
     rcode = 0;
@@ -1278,27 +1462,41 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
      * Create the destination volume
      * ***/
 
-    VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
-    code =
-       AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, &clonetid);
-    EGOTO1(mfail, code,
-          "Failed to start a transaction on the cloned volume%u\n", newVol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       /* All of this is to get the fromDate */
+       VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
+       tmp = clonetid;
+       code =
+           AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+                             &tmp);
+       clonetid = tmp;
+       EGOTO1(mfail, code,
+              "Failed to start a transaction on the cloned volume%u\n",
+              newVol);
+       VDONE;
 
-    VPRINT1("Setting flags on cloned volume %u ...", newVol);
-    code = AFSVolSetFlags(fromconn, clonetid, VTDeleteOnSalvage | VTOutOfService);     /*redundant */
-    EGOTO1(mfail, code, "Could not set falgs on the cloned volume %u\n",
-          newVol);
-    VDONE;
+       VPRINT1("Setting flags on cloned volume %u ...", newVol);
+       code =
+           AFSVolSetFlags(fromconn, clonetid,
+                          VTDeleteOnSalvage | VTOutOfService); /*redundant */
+       EGOTO1(mfail, code, "Could not set flags on the cloned volume %u\n",
+              newVol);
+       VDONE;
 
-    /* remember time from which we've dumped the volume */
-    VPRINT1("Getting status of cloned volume %u ...", newVol);
-    code = AFSVolGetStatus(fromconn, clonetid, &tstatus);
-    EGOTO1(mfail, code, "Failed to get the status of the cloned volume %u\n",
-          newVol);
-    VDONE;
+       /* remember time from which we've dumped the volume */
+       VPRINT1("Getting status of cloned volume %u ...", newVol);
+       code = AFSVolGetStatus(fromconn, clonetid, &tstatus);
+       EGOTO1(mfail, code,
+              "Failed to get the status of the cloned volume %u\n",
+              newVol);
+       VDONE;
+
+       fromDate = CLOCKADJ(tstatus.creationDate);
+    } else {
+       /* With RV_NOCLONE, just do a full copy from the source */
+       fromDate = 0;
+    }
 
-    fromDate = tstatus.creationDate - CLOCKSKEW;
 
 #ifdef ENABLE_BUGFIX_1165
     /*
@@ -1315,11 +1513,15 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
 
     infop = (volintInfo *) volumeInfo.volEntries_val;
     infop->maxquota = -1;      /* Else it will replace the default quota */
+    infop->creationDate = -1;  /* Else it will use the source creation date */
+    infop->updateDate = -1;    /* Else it will use the source update date */
 #endif
 
     /* create a volume on the target machine */
     volid = afromvol;
-    code = AFSVolTransCreate(toconn, volid, atopart, ITOffline, &totid);
+    tmp = totid;
+    code = AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+    totid = tmp;
     if (!code) {
        /* Delete the existing volume.
         * While we are deleting the volume in these steps, the transaction
@@ -1347,9 +1549,13 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     }
 
     VPRINT1("Creating the destination volume %u ...", volid);
+    tmp = totid;
+    tmpVol = volid;
     code =
-       AFSVolCreateVolume(toconn, atopart, volName, volser_RW, volid, &volid,
-                          &totid);
+       AFSVolCreateVolume(toconn, atopart, volName, volser_RW, volid, &tmpVol,
+                          &tmp);
+    totid = tmp;
+    volid = tmpVol;
     EGOTO1(mfail, code, "Failed to create the destination volume %u\n",
           volid);
     VDONE;
@@ -1373,46 +1579,56 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     destination.destPort = AFSCONF_VOLUMEPORT;
     destination.destSSID = 1;
 
-    /* Copy the clone to the new volume */
-    VPRINT2("Dumping from clone %u on source to volume %u on destination ...",
-           newVol, afromvol);
     strncpy(cookie.name, tmpName, VOLSER_OLDMAXVOLNAME);
     cookie.type = RWVOL;
     cookie.parent = entry.volumeId[RWVOL];
     cookie.clone = 0;
-    code = AFSVolForward(fromconn, clonetid, 0, &destination, totid, &cookie);
-    EGOTO1(mfail, code, "Failed to move data for the volume %u\n", volid);
-    VDONE;
 
-    VPRINT1("Ending transaction on cloned volume %u ...", newVol);
-    code = AFSVolEndTrans(fromconn, clonetid, &rcode);
-    if (!code)
-       code = rcode;
-    clonetid = 0;
-    EGOTO1(mfail, code,
-          "Failed to end the transaction on the cloned volume %u\n", newVol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       /* Copy the clone to the new volume */
+       VPRINT2("Dumping from clone %u on source to volume %u on destination ...",
+               newVol, afromvol);
+       code =
+           AFSVolForward(fromconn, clonetid, 0, &destination, totid,
+                         &cookie);
+       EGOTO1(mfail, code, "Failed to move data for the volume %u\n", volid);
+       VDONE;
+
+       VPRINT1("Ending transaction on cloned volume %u ...", newVol);
+       code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+       if (!code)
+           code = rcode;
+       clonetid = 0;
+       EGOTO1(mfail, code,
+              "Failed to end the transaction on the cloned volume %u\n",
+              newVol);
+       VDONE;
+    }
 
     /* ***
      * reattach to the main-line volume, and incrementally dump it.
      * ***/
 
     VPRINT1("Starting transaction on source volume %u ...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+    tmp = fromtid;
+    code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+    fromtid = tmp;
     EGOTO1(mfail, code,
           "Failed to create a transaction on the source volume %u\n",
           afromvol);
     VDONE;
 
     /* now do the incremental */
-    VPRINT1
-       ("Doing the incremental dump from source to destination for volume %u ... ",
+    VPRINT2
+       ("Doing the%s dump from source to destination for volume %u ... ",
+        (flags & RV_NOCLONE) ? "" : " incremental",
         afromvol);
     code =
        AFSVolForward(fromconn, fromtid, fromDate, &destination, totid,
                      &cookie);
-    EGOTO(mfail, code,
-         "Failed to do the incremental dump from rw volume on old site to rw volume on newsite\n");
+    EGOTO1(mfail, code,
+          "Failed to do the%s dump from rw volume on old site to rw volume on newsite\n",
+         (flags & RV_NOCLONE) ? "" : " incremental");
     VDONE;
 
     /* now adjust the flags so that the new volume becomes official */
@@ -1547,8 +1763,10 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     /* Delete the backup volume on the original site */
     VPRINT1("Creating transaction for backup volume %u on source ...",
            backupId);
+    tmp = fromtid;
     code =
-       AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, &fromtid);
+       AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline, &tmp);
+    fromtid = tmp;
     VDONE;
     if (!code) {
        VPRINT1("Setting flags on backup volume %u on source ...", backupId);
@@ -1581,27 +1799,35 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        code = 0;               /* no backup volume? that's okay */
 
     fromtid = 0;
-    VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
-    code =
-       AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, &clonetid);
-    EGOTO1(mfail, code,
-          "Failed to start a transaction on the cloned volume%u\n", newVol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
+       tmp = clonetid;
+       code =
+           AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+                             &tmp);
+       clonetid = tmp;
+       EGOTO1(mfail, code,
+              "Failed to start a transaction on the cloned volume%u\n",
+              newVol);
+       VDONE;
 
-    /* now delete the clone */
-    VPRINT1("Deleting the cloned volume %u ...", newVol);
-    code = AFSVolDeleteVolume(fromconn, clonetid);
-    EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n", newVol);
-    VDONE;
+       /* now delete the clone */
+       VPRINT1("Deleting the cloned volume %u ...", newVol);
+       code = AFSVolDeleteVolume(fromconn, clonetid);
+       EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n",
+              newVol);
+       VDONE;
 
-    VPRINT1("Ending transaction on cloned volume %u ...", newVol);
-    code = AFSVolEndTrans(fromconn, clonetid, &rcode);
-    if (!code)
-       code = rcode;
-    clonetid = 0;
-    EGOTO1(mfail, code,
-          "Failed to end the transaction on the cloned volume %u\n", newVol);
-    VDONE;
+       VPRINT1("Ending transaction on cloned volume %u ...", newVol);
+       code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+       if (!code)
+           code = rcode;
+       clonetid = 0;
+       EGOTO1(mfail, code,
+              "Failed to end the transaction on the cloned volume %u\n",
+              newVol);
+       VDONE;
+    }
 
     /* fall through */
     /* END OF MOVE */
@@ -1631,7 +1857,7 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     if (islocked) {
        VPRINT1("Cleanup: Releasing VLDB lock on volume %u ...", afromvol);
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
+           ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
                      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
        if (vcode) {
            VPRINT("\n");
@@ -1651,8 +1877,8 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        if (code || rcode) {
            VPRINT("\n");
            fprintf(STDERR,
-                   "Could not end transaction on the source's clone volume %lu\n",
-                   (unsigned long)newVol);
+                   "Could not end transaction on the source volume %lu\n",
+                   (unsigned long)afromvol);
            if (!error)
                error = (code ? code : rcode);
        }
@@ -1713,9 +1939,10 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     /* unlock VLDB entry */
     if (islocked) {
        VPRINT1("Recovery: Releasing VLDB lock on volume %u ...", afromvol);
-       ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
+       ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
                  (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
        VDONE;
+       islocked = 0;
     }
 
     if (clonetid) {
@@ -1747,9 +1974,9 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     }
     MapHostToNetwork(&entry);
 
-    /* Delete either the volume on the source location or the target location. 
+    /* Delete either the volume on the source location or the target location.
      * If the vldb entry still points to the source location, then we know the
-     * volume move didn't finish so we remove the volume from the target 
+     * volume move didn't finish so we remove the volume from the target
      * location. Otherwise, we remove the volume from the source location.
      */
     if (Lp_Match(afromserver, afrompart, &entry)) {    /* didn't move - delete target volume */
@@ -1763,8 +1990,10 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
            VPRINT1
                ("Recovery: Creating transaction for destination volume %u ...",
                 volid);
+           tmp = totid;
            code =
-               AFSVolTransCreate(toconn, volid, atopart, ITOffline, &totid);
+               AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+           totid = tmp;
 
            if (!code) {
                VDONE;
@@ -1797,9 +2026,11 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        if (fromconn) {
            VPRINT1("Recovery: Creating transaction on source volume %u ...",
                    afromvol);
+           tmp = fromtid;
            code =
-               AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
-                                 &fromtid);
+               AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+                                 &tmp);
+           fromtid = tmp;
            if (!code) {
                VDONE;
 
@@ -1830,9 +2061,11 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
        if (fromconn) {
            VPRINT1("Recovery: Creating transaction on backup volume %u ...",
                    backupId);
+           tmp = fromtid;
            code =
-               AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline,
-                                 &fromtid);
+               AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
+                                 &tmp);
+           fromtid = tmp;
            if (!code) {
                VDONE;
 
@@ -1860,9 +2093,11 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
            /* delete source volume */
            VPRINT1("Recovery: Creating transaction on source volume %u ...",
                    afromvol);
+           tmp = fromtid;
            code =
-               AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
-                                 &fromtid);
+               AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+                                 &tmp);
+           fromtid = tmp;
            if (!code) {
                VDONE;
 
@@ -1899,9 +2134,11 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     if (newVol) {
        VPRINT1("Recovery: Creating transaction on clone volume %u ...",
                newVol);
+       tmp = clonetid;
        code =
-           AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline,
-                             &clonetid);
+           AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+                             &tmp);
+       clonetid = tmp;
        if (!code) {
            VDONE;
 
@@ -1921,12 +2158,14 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     }
 
     /* unlock VLDB entry */
-    VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...",
-           afromvol);
-    ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
-             (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
-    VDONE;
-
+    if (islocked) {
+       VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...",
+               afromvol);
+       ubik_VL_ReleaseLock(cstruct, 0, afromvol, -1,
+                           (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
+       VDONE;
+       islocked = 0;
+    }
   done:                        /* routine cleanup */
     if (volName)
        free(volName);
@@ -1947,32 +2186,55 @@ UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
 }
 
 
-/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
- * <atopart>. The operation is almost idempotent 
- */
+int
+UV_MoveVolume(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
+             afs_uint32 atoserver, afs_int32 atopart)
+{
+    return UV_MoveVolume2(afromvol, afromserver, afrompart,
+                         atoserver, atopart, 0);
+}
+
 
+/* Copy volume <afromvol> from <afromserver> <afrompart> to <atoserver>
+ * <atopart>.  The new volume is named by <atovolname>.  The new volume
+ * has ID <atovolid> if that is nonzero; otherwise a new ID is allocated
+ * from the VLDB.  the following flags are supported:
+ *
+ *     RV_RDONLY  - target volume is RO
+ *     RV_OFFLINE - leave target volume offline
+ *     RV_CPINCR  - do incremental dump if target exists
+ *     RV_NOVLDB  - don't create/update VLDB entry
+ *     RV_NOCLONE - don't use a copy clone
+ */
 int
-UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
-             char *atovolname, afs_int32 atoserver, afs_int32 atopart)
+UV_CopyVolume2(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
+              char *atovolname, afs_uint32 atoserver, afs_int32 atopart,
+              afs_uint32 atovolid, int flags)
 {
-    struct rx_connection *toconn, *fromconn;
-    afs_int32 fromtid, totid, clonetid;
+    /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+     * be changing during the copy */
+    int volatile pntg;
+    afs_int32 volatile clonetid;
+    afs_int32 volatile totid;
+    afs_int32 volatile fromtid;
+    struct rx_connection * volatile fromconn;
+    struct rx_connection * volatile toconn;
+    afs_uint32 volatile cloneVol;
+
     char vname[64];
-    char tmpName[VOLSER_MAXVOLNAME + 1];
     afs_int32 rcode;
-    afs_int32 fromDate;
+    afs_int32 fromDate, cloneFromDate;
     struct restoreCookie cookie;
-    register afs_int32 vcode, code;
-    afs_int32 cloneVol, newVol;
+    afs_int32 vcode, code;
+    afs_uint32 newVol;
+    afs_int32 volflag;
     struct volser_status tstatus;
     struct destServer destination;
-
     struct nvldbentry entry, newentry, storeEntry;
-    int islocked, pntg;
     afs_int32 error;
-    int justclone = 0;
+    afs_int32 tmp;
+    afs_uint32 tmpVol;
 
-    islocked = 0;
     fromconn = (struct rx_connection *)0;
     toconn = (struct rx_connection *)0;
     fromtid = 0;
@@ -1998,90 +2260,135 @@ UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
     fromtid = totid = 0;       /* initialize to uncreated */
 
-
-    /* check if we can shortcut and use a local clone instead of a full copy */
-    if (afromserver == atoserver && afrompart == atopart) {
-       justclone = 1;
-    }
-
     /* ***
      * clone the read/write volume locally.
      * ***/
 
-    VPRINT1("Starting transaction on source volume %u ...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
-    EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n",
-          afromvol);
-    VDONE;
+    cloneVol = 0;
+    if (!(flags & RV_NOCLONE)) {
+       VPRINT1("Starting transaction on source volume %u ...", afromvol);
+       tmp = fromtid;
+       code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+                                &tmp);
+       fromtid = tmp;
+       EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n",
+              afromvol);
+       VDONE;
 
-    /* Get a clone id */
-    VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
-    newVol = 0;
-    vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &cloneVol);
-    EGOTO1(mfail, vcode,
+       /* Get a clone id */
+       VPRINT1("Allocating new volume id for clone of volume %u ...",
+               afromvol);
+       cloneVol = 0;
+       tmpVol = cloneVol;
+       vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+       cloneVol = tmpVol;
+       EGOTO1(mfail, vcode,
           "Could not get an ID for the clone of volume %u from the VLDB\n",
           afromvol);
-    VDONE;
-
-    /* Get a new volume id */
-    VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol);
-    newVol = 0;
-    vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
-    EGOTO1(mfail, vcode,
-          "Could not get an ID for the copy of volume %u from the VLDB\n",
-          afromvol);
-    VDONE;
+       VDONE;
+    }
 
-    /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
-    VPRINT1("Cloning source volume %u ...", afromvol);
-    strcpy(vname, "copy-clone-temp");
-    code =
-       AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &cloneVol);
-    EGOTO1(mfail, code, "Failed to clone the source volume %u\n", afromvol);
-    VDONE;
+    if (atovolid) {
+       newVol = atovolid;
+    } else {
+       /* Get a new volume id */
+       VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol);
+       newVol = 0;
+       vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &newVol);
+       EGOTO1(mfail, vcode,
+              "Could not get an ID for the copy of volume %u from the VLDB\n",
+              afromvol);
+       VDONE;
+    }
 
-    VPRINT1("Ending the transaction on the source volume %u ...", afromvol);
-    rcode = 0;
-    code = AFSVolEndTrans(fromconn, fromtid, &rcode);
-    fromtid = 0;
-    if (!code)
-       code = rcode;
-    EGOTO1(mfail, code,
-          "Failed to end the transaction on the source volume %u\n",
-          afromvol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
+       VPRINT1("Cloning source volume %u ...", afromvol);
+       strcpy(vname, "copy-clone-temp");
+       tmpVol = cloneVol;
+       code =
+           AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname,
+                       &tmpVol);
+       cloneVol = tmpVol;
+       EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
+              afromvol);
+       VDONE;
 
-    /* ***
-     * Create the destination volume
+       VPRINT1("Ending the transaction on the source volume %u ...", afromvol);
+       rcode = 0;
+       code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+       fromtid = 0;
+       if (!code)
+           code = rcode;
+       EGOTO1(mfail, code,
+              "Failed to end the transaction on the source volume %u\n",
+              afromvol);
+       VDONE;
+    }
+
+    /* ***
+     * Create the destination volume
      * ***/
 
-    VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
-    code =
-       AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline,
-                         &clonetid);
-    EGOTO1(mfail, code,
-          "Failed to start a transaction on the cloned volume%u\n",
-          cloneVol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+       tmp = clonetid;
+       code =
+           AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+                         &tmp);
+       clonetid = tmp;
+       EGOTO1(mfail, code,
+              "Failed to start a transaction on the cloned volume%u\n",
+              cloneVol);
+       VDONE;
 
-    VPRINT1("Setting flags on cloned volume %u ...", cloneVol);
-    code = AFSVolSetFlags(fromconn, clonetid, VTDeleteOnSalvage | VTOutOfService);     /*redundant */
-    EGOTO1(mfail, code, "Could not set falgs on the cloned volume %u\n",
-          cloneVol);
-    VDONE;
+       VPRINT1("Setting flags on cloned volume %u ...", cloneVol);
+       code =
+           AFSVolSetFlags(fromconn, clonetid,
+                          VTDeleteOnSalvage | VTOutOfService); /*redundant */
+       EGOTO1(mfail, code, "Could not set flags on the cloned volume %u\n",
+              cloneVol);
+       VDONE;
 
-    /* remember time from which we've dumped the volume */
-    VPRINT1("Getting status of cloned volume %u ...", cloneVol);
-    code = AFSVolGetStatus(fromconn, clonetid, &tstatus);
-    EGOTO1(mfail, code, "Failed to get the status of the cloned volume %u\n",
-          cloneVol);
-    VDONE;
+       /* remember time from which we've dumped the volume */
+       VPRINT1("Getting status of cloned volume %u ...", cloneVol);
+       code = AFSVolGetStatus(fromconn, clonetid, &tstatus);
+       EGOTO1(mfail, code,
+              "Failed to get the status of the cloned volume %u\n",
+              cloneVol);
+       VDONE;
 
-    fromDate = tstatus.creationDate - CLOCKSKEW;
+       fromDate = CLOCKADJ(tstatus.creationDate);
+    } else {
+       fromDate = 0;
+    }
 
     /* create a volume on the target machine */
-    code = AFSVolTransCreate(toconn, newVol, atopart, ITOffline, &totid);
+    cloneFromDate = 0;
+    tmp = totid;
+    code = AFSVolTransCreate_retry(toconn, newVol, atopart, ITOffline, &tmp);
+    totid = tmp;
     if (!code) {
+       if ((flags & RV_CPINCR)) {
+           VPRINT1("Getting status of pre-existing volume %u ...", newVol);
+           code = AFSVolGetStatus(toconn, totid, &tstatus);
+           EGOTO1(mfail, code,
+                  "Failed to get the status of the pre-existing volume %u\n",
+                  newVol);
+           VDONE;
+
+           /* Using the update date should be OK here, but add some fudge */
+           cloneFromDate = CLOCKADJ(tstatus.updateDate);
+           if ((flags & RV_NOCLONE))
+               fromDate = cloneFromDate;
+
+           /* XXX We should check that the source volume's creationDate is
+            * XXX not newer than the existing target volume, and if not,
+            * XXX throw away the existing target and do a full dump. */
+
+           goto cpincr;
+       }
+
        /* Delete the existing volume.
         * While we are deleting the volume in these steps, the transaction
         * we started against the cloned volume (clonetid above) will be
@@ -2108,15 +2415,16 @@ UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     }
 
     VPRINT1("Creating the destination volume %u ...", newVol);
+    tmp = totid;
     code =
-       AFSVolCreateVolume(toconn, atopart, atovolname, volser_RW, newVol,
-                          &newVol, &totid);
+       AFSVolCreateVolume(toconn, atopart, atovolname,
+                          (flags & RV_RDONLY) ? volser_RO : volser_RW,
+                          newVol, &newVol, &tmp);
+    totid = tmp;
     EGOTO1(mfail, code, "Failed to create the destination volume %u\n",
           newVol);
     VDONE;
 
-    strncpy(tmpName, atovolname, VOLSER_OLDMAXVOLNAME);
-
     VPRINT1("Setting volume flags on destination volume %u ...", newVol);
     code =
        AFSVolSetFlags(toconn, totid, (VTDeleteOnSalvage | VTOutOfService));
@@ -2124,63 +2432,76 @@ UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
           "Failed to set the flags on the destination volume %u\n", newVol);
     VDONE;
 
-    /***
-     * Now dump the clone to the new volume
-     ***/
+cpincr:
 
     destination.destHost = ntohl(atoserver);
     destination.destPort = AFSCONF_VOLUMEPORT;
     destination.destSSID = 1;
 
+    strncpy(cookie.name, atovolname, VOLSER_OLDMAXVOLNAME);
+    cookie.type = (flags & RV_RDONLY) ? ROVOL : RWVOL;
+    cookie.parent = 0;
+    cookie.clone = 0;
 
-/* probably should have some code here that checks to see if we are copying to same server
-and partition - if so, just use a clone to save disk space */
+    /***
+     * Now dump the clone to the new volume
+     ***/
 
-    /* Copy the clone to the new volume */
-    VPRINT2("Dumping from clone %u on source to volume %u on destination ...",
+    if (!(flags & RV_NOCLONE)) {
+       /* XXX probably should have some code here that checks to see if
+        * XXX we are copying to same server and partition - if so, just
+        * XXX use a clone to save disk space */
+
+       /* Copy the clone to the new volume */
+       VPRINT2("Dumping from clone %u on source to volume %u on destination ...",
            cloneVol, newVol);
-    strncpy(cookie.name, tmpName, VOLSER_OLDMAXVOLNAME);
-    cookie.type = RWVOL;
-    cookie.parent = 0;
-    cookie.clone = 0;
-    code = AFSVolForward(fromconn, clonetid, 0, &destination, totid, &cookie);
-    EGOTO1(mfail, code, "Failed to move data for the volume %u\n", newVol);
-    VDONE;
+       code =
+           AFSVolForward(fromconn, clonetid, cloneFromDate, &destination,
+                         totid, &cookie);
+       EGOTO1(mfail, code, "Failed to move data for the volume %u\n",
+              newVol);
+       VDONE;
 
-    VPRINT1("Ending transaction on cloned volume %u ...", cloneVol);
-    code = AFSVolEndTrans(fromconn, clonetid, &rcode);
-    if (!code)
-       code = rcode;
-    clonetid = 0;
-    EGOTO1(mfail, code,
-          "Failed to end the transaction on the cloned volume %u\n",
-          cloneVol);
-    VDONE;
+       VPRINT1("Ending transaction on cloned volume %u ...", cloneVol);
+       code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+       if (!code)
+           code = rcode;
+       clonetid = 0;
+       EGOTO1(mfail, code,
+              "Failed to end the transaction on the cloned volume %u\n",
+              cloneVol);
+       VDONE;
+    }
 
     /* ***
      * reattach to the main-line volume, and incrementally dump it.
      * ***/
 
     VPRINT1("Starting transaction on source volume %u ...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+    tmp = fromtid;
+    code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+    fromtid = tmp;
     EGOTO1(mfail, code,
           "Failed to create a transaction on the source volume %u\n",
           afromvol);
     VDONE;
 
     /* now do the incremental */
-    VPRINT1
-       ("Doing the incremental dump from source to destination for volume %u ... ",
+    VPRINT2
+       ("Doing the%s dump from source to destination for volume %u ... ",
+        (flags & RV_NOCLONE) ? "" : " incremental",
         afromvol);
     code =
        AFSVolForward(fromconn, fromtid, fromDate, &destination, totid,
                      &cookie);
-    EGOTO(mfail, code,
-         "Failed to do the incremental dump from rw volume on old site to rw volume on newsite\n");
+    EGOTO1(mfail, code,
+          "Failed to do the%s dump from old site to new site\n",
+          (flags & RV_NOCLONE) ? "" : " incremental");
     VDONE;
 
     VPRINT1("Setting volume flags on destination volume %u ...", newVol);
-    code = AFSVolSetFlags(toconn, totid, 0);
+    volflag = ((flags & RV_OFFLINE) ? VTOutOfService : 0);     /* off or on-line */
+    code = AFSVolSetFlags(toconn, totid, volflag);
     EGOTO(mfail, code,
          "Failed to set the flags to make destination volume online\n");
     VDONE;
@@ -2207,59 +2528,67 @@ and partition - if so, just use a clone to save disk space */
     VDONE;
 
     fromtid = 0;
-    VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
-    code =
-       AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline,
-                         &clonetid);
-    EGOTO1(mfail, code,
-          "Failed to start a transaction on the cloned volume%u\n",
-          cloneVol);
-    VDONE;
 
-    /* now delete the clone */
-    VPRINT1("Deleting the cloned volume %u ...", cloneVol);
-    code = AFSVolDeleteVolume(fromconn, clonetid);
-    EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n", cloneVol);
-    VDONE;
+    if (!(flags & RV_NOCLONE)) {
+       VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+       tmp = clonetid;
+       code =
+           AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+                             &tmp);
+       clonetid = tmp;
+       EGOTO1(mfail, code,
+              "Failed to start a transaction on the cloned volume%u\n",
+              cloneVol);
+       VDONE;
 
-    VPRINT1("Ending transaction on cloned volume %u ...", cloneVol);
-    code = AFSVolEndTrans(fromconn, clonetid, &rcode);
-    if (!code)
-       code = rcode;
-    clonetid = 0;
-    EGOTO1(mfail, code,
-          "Failed to end the transaction on the cloned volume %u\n",
-          cloneVol);
-    VDONE;
+       /* now delete the clone */
+       VPRINT1("Deleting the cloned volume %u ...", cloneVol);
+       code = AFSVolDeleteVolume(fromconn, clonetid);
+       EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n",
+              cloneVol);
+       VDONE;
 
-    /* create the vldb entry for the copied volume */
-    strncpy(newentry.name, atovolname, VOLSER_OLDMAXVOLNAME);
-    newentry.nServers = 1;
-    newentry.serverNumber[0] = atoserver;
-    newentry.serverPartition[0] = atopart;
-    newentry.flags = RW_EXISTS;        /* this records that rw volume exists */
-    newentry.serverFlags[0] = ITSRWVOL;        /*this rep site has rw vol */
-    newentry.volumeId[RWVOL] = newVol;
-    newentry.volumeId[ROVOL] = 0;
-    newentry.volumeId[BACKVOL] = 0;
-    newentry.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 */
-    MapNetworkToHost(&newentry, &storeEntry);
-    /* create the vldb entry */
-    vcode = VLDB_CreateEntry(&storeEntry);
-    if (vcode) {
-       fprintf(STDERR,
-               "Could not create a VLDB entry for the volume %s %lu\n",
-               atovolname, (unsigned long)newVol);
-       /*destroy the created volume */
-       VPRINT1("Deleting the newly created volume %u\n", newVol);
-       AFSVolDeleteVolume(toconn, totid);
-       error = vcode;
-       goto mfail;
+       VPRINT1("Ending transaction on cloned volume %u ...", cloneVol);
+       code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+       if (!code)
+           code = rcode;
+       clonetid = 0;
+       EGOTO1(mfail, code,
+              "Failed to end the transaction on the cloned volume %u\n",
+              cloneVol);
+       VDONE;
+    }
+
+    if (!(flags & RV_NOVLDB)) {
+       /* create the vldb entry for the copied volume */
+       strncpy(newentry.name, atovolname, VOLSER_OLDMAXVOLNAME);
+       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.volumeId[RWVOL] = newVol;
+       newentry.volumeId[ROVOL] = (flags & RV_RDONLY) ? newVol : 0;
+       newentry.volumeId[BACKVOL] = 0;
+       newentry.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 */
+       MapNetworkToHost(&newentry, &storeEntry);
+       /* create the vldb entry */
+       vcode = VLDB_CreateEntry(&storeEntry);
+       if (vcode) {
+           fprintf(STDERR,
+                   "Could not create a VLDB entry for the volume %s %lu\n",
+                   atovolname, (unsigned long)newVol);
+           /*destroy the created volume */
+           VPRINT1("Deleting the newly created volume %u\n", newVol);
+           AFSVolDeleteVolume(toconn, totid);
+           error = vcode;
+           goto mfail;
+       }
+       VPRINT2("Created the VLDB entry for the volume %s %u\n", atovolname,
+               newVol);
     }
-    VPRINT2("Created the VLDB entry for the volume %s %u\n", atovolname,
-           newVol);
 
     /* normal cleanup code */
 
@@ -2353,9 +2682,11 @@ and partition - if so, just use a clone to save disk space */
     if (cloneVol) {
        VPRINT1("Recovery: Creating transaction on clone volume %u ...",
                cloneVol);
+       tmp = clonetid;
        code =
-           AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline,
-                             &clonetid);
+           AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+                             &tmp);
+       clonetid = tmp;
        if (!code) {
            VDONE;
 
@@ -2388,19 +2719,26 @@ and partition - if so, just use a clone to save disk space */
 }
 
 
+int
+UV_CopyVolume(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
+             char *atovolname, afs_uint32 atoserver, afs_int32 atopart)
+{
+    return UV_CopyVolume2(afromvol, afromserver, afrompart,
+                          atovolname, atoserver, atopart, 0, 0);
+}
 
 
 
-/* Make a new backup of volume <avolid> on <aserver> and <apart> 
- * if one already exists, update it 
+/* Make a new backup of volume <avolid> on <aserver> and <apart>
+ * if one already exists, update it
  */
 
 int
-UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
+UV_BackupVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid)
 {
     struct rx_connection *aconn = (struct rx_connection *)0;
     afs_int32 ttid = 0, btid = 0;
-    afs_int32 backupID;
+    afs_uint32 backupID;
     afs_int32 code = 0, rcode = 0;
     char vname[VOLSER_MAXVOLNAME + 1];
     struct nvldbentry entry, storeEntry;
@@ -2428,7 +2766,7 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
        (entry.flags & VLOP_ALLOPERS) ||        /* vldb lock already held */
        (entry.volumeId[BACKVOL] == INVALID_BID)) {     /* no assigned backup volume id */
 
-       code = ubik_Call(VL_SetLock, cstruct, 0, avolid, RWVOL, VLOP_BACKUP);
+       code = ubik_VL_SetLock(cstruct, 0, avolid, RWVOL, VLOP_BACKUP);
        if (code) {
            fprintf(STDERR,
                    "Could not lock the VLDB entry for the volume %lu\n",
@@ -2460,9 +2798,9 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     backupID = entry.volumeId[BACKVOL];
     if (backupID == INVALID_BID) {
        /* Get a backup volume id from the VLDB and update the vldb
-        * entry with it. 
+        * entry with it.
         */
-       code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &backupID);
+       code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &backupID);
        if (code) {
            fprintf(STDERR,
                    "Could not allocate ID for the backup volume of  %lu from the VLDB\n",
@@ -2477,7 +2815,7 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     /* Test to see if the backup volume exists by trying to create
      * a transaction on the backup volume. We've assumed the backup exists.
      */
-    code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid);
+    code = AFSVolTransCreate_retry(aconn, backupID, apart, ITOffline, &btid);
     if (code) {
        if (code != VNOVOL) {
            fprintf(STDERR, "Could not reach the backup volume %lu\n",
@@ -2500,9 +2838,9 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     }
 
     /* Now go ahead and try to clone the RW volume.
-     * First start a transaction on the RW volume 
+     * First start a transaction on the RW volume
      */
-    code = AFSVolTransCreate(aconn, avolid, apart, ITBusy, &ttid);
+    code = AFSVolTransCreate_retry(aconn, avolid, apart, ITBusy, &ttid);
     if (code) {
        fprintf(STDERR, "Could not start a transaction on the volume %lu\n",
                (unsigned long)avolid);
@@ -2510,7 +2848,7 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
        goto bfail;
     }
 
-    /* Clone or reclone the volume, depending on whether the backup 
+    /* Clone or reclone the volume, depending on whether the backup
      * volume exists or not
      */
     if (backexists) {
@@ -2556,7 +2894,7 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
     }
 
     /* Now go back to the backup volume and bring it on line */
-    code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid);
+    code = AFSVolTransCreate_retry(aconn, backupID, apart, ITOffline, &btid);
     if (code) {
        fprintf(STDERR,
                "Failed to start a transaction on the backup volume %lu\n",
@@ -2585,8 +2923,228 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 
     VDONE;
 
-    /* Will update the vldb below */
-
+    /* Will update the vldb below */
+
+  bfail:
+    if (ttid) {
+       code = AFSVolEndTrans(aconn, ttid, &rcode);
+       if (code || rcode) {
+           fprintf(STDERR, "Could not end transaction on the volume %lu\n",
+                   (unsigned long)avolid);
+           if (!error)
+               error = (code ? code : rcode);
+       }
+    }
+
+    if (btid) {
+       code = AFSVolEndTrans(aconn, btid, &rcode);
+       if (code || rcode) {
+           fprintf(STDERR,
+                   "Could not end transaction the backup volume %lu\n",
+                   (unsigned long)backupID);
+           if (!error)
+               error = (code ? code : rcode);
+       }
+    }
+
+    /* Now update the vldb - if modified */
+    if (vldblocked) {
+       if (vldbmod) {
+           MapNetworkToHost(&entry, &storeEntry);
+           code =
+               VLDB_ReplaceEntry(avolid, RWVOL, &storeEntry,
+                                 (LOCKREL_OPCODE | LOCKREL_AFSID |
+                                  LOCKREL_TIMESTAMP));
+           if (code) {
+               fprintf(STDERR,
+                       "Could not update the VLDB entry for the volume %lu \n",
+                       (unsigned long)avolid);
+               if (!error)
+                   error = code;
+           }
+       } else {
+           code =
+               ubik_VL_ReleaseLock(cstruct, 0, avolid, RWVOL,
+                         (LOCKREL_OPCODE | LOCKREL_AFSID |
+                          LOCKREL_TIMESTAMP));
+           if (code) {
+               fprintf(STDERR,
+                       "Could not unlock the VLDB entry for the volume %lu \n",
+                       (unsigned long)avolid);
+               if (!error)
+                   error = code;
+           }
+       }
+    }
+
+    if (aconn)
+       rx_DestroyConnection(aconn);
+
+    PrintError("", error);
+    return error;
+}
+
+/* Make a new clone of volume <avolid> on <aserver> and <apart>
+ * using volume ID <acloneid>, or a new ID allocated from the VLDB.
+ * The new volume is named by <aname>, or by appending ".clone" to
+ * the existing name if <aname> is NULL.  The following flags are
+ * supported:
+ *
+ *     RV_RDONLY  - target volume is RO
+ *     RV_OFFLINE - leave target volume offline
+ */
+
+int
+UV_CloneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 avolid,
+              afs_uint32 acloneid, char *aname, int flags)
+{
+    struct rx_connection *aconn = (struct rx_connection *)0;
+    afs_int32 ttid = 0, btid = 0;
+    afs_int32 code = 0, rcode = 0;
+    char vname[VOLSER_MAXVOLNAME + 1];
+    afs_int32 error = 0;
+    int backexists = 1;
+    volEntries volumeInfo;
+
+    aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
+
+    if (!aname) {
+       volumeInfo.volEntries_val = (volintInfo *) 0;
+       volumeInfo.volEntries_len = 0;
+       code = AFSVolListOneVolume(aconn, apart, avolid, &volumeInfo);
+       if (code) {
+           fprintf(stderr, "Could not get info for volume %lu\n",
+                   (unsigned long)avolid);
+           error = code;
+           goto bfail;
+       }
+       strncpy(vname, volumeInfo.volEntries_val[0].name,
+               VOLSER_OLDMAXVOLNAME - 7);
+       vname[VOLSER_OLDMAXVOLNAME - 7] = 0;
+       strcat(vname, ".clone");
+       aname = vname;
+       if (volumeInfo.volEntries_val)
+           free(volumeInfo.volEntries_val);
+    }
+
+    if (!acloneid) {
+       /* Get a clone id */
+       VPRINT1("Allocating new volume id for clone of volume %u ...",
+               avolid);
+       code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &acloneid);
+       EGOTO1(bfail, code,
+          "Could not get an ID for the clone of volume %u from the VLDB\n",
+          avolid);
+       VDONE;
+    }
+
+    /* Test to see if the clone volume exists by trying to create
+     * a transaction on the clone volume. We've assumed the clone exists.
+     */
+    /* XXX I wonder what happens if the clone has some other parent... */
+    code = AFSVolTransCreate_retry(aconn, acloneid, apart, ITOffline, &btid);
+    if (code) {
+       if (code != VNOVOL) {
+           fprintf(STDERR, "Could not reach the clone volume %lu\n",
+                   (unsigned long)acloneid);
+           error = code;
+           goto bfail;
+       }
+       backexists = 0;         /* backup volume does not exist */
+    }
+    if (btid) {
+       code = AFSVolEndTrans(aconn, btid, &rcode);
+       btid = 0;
+       if (code || rcode) {
+           fprintf(STDERR,
+                   "Could not end transaction on the previous clone volume %lu\n",
+                   (unsigned long)acloneid);
+           error = (code ? code : rcode);
+           goto bfail;
+       }
+    }
+
+    /* Now go ahead and try to clone the RW volume.
+     * First start a transaction on the RW volume
+     */
+    code = AFSVolTransCreate_retry(aconn, avolid, apart, ITBusy, &ttid);
+    if (code) {
+       fprintf(STDERR, "Could not start a transaction on the volume %lu\n",
+               (unsigned long)avolid);
+       error = code;
+       goto bfail;
+    }
+
+    /* Clone or reclone the volume, depending on whether the backup
+     * volume exists or not
+     */
+    if (backexists) {
+       VPRINT1("Re-cloning clone volume %u ...", acloneid);
+
+       code = AFSVolReClone(aconn, ttid, acloneid);
+       if (code) {
+           fprintf(STDERR, "Could not re-clone backup volume %lu\n",
+                   (unsigned long)acloneid);
+           error = code;
+           goto bfail;
+       }
+    } else {
+       VPRINT1("Creating a new clone %u ...", acloneid);
+
+       code = AFSVolClone(aconn, ttid, 0,
+                          (flags & RV_RDONLY) ? readonlyVolume : backupVolume,
+                          aname, &acloneid);
+       if (code) {
+           fprintf(STDERR, "Failed to clone the volume %lu\n",
+                   (unsigned long)avolid);
+           error = code;
+           goto bfail;
+       }
+    }
+
+    /* End the transaction on the RW volume */
+    code = AFSVolEndTrans(aconn, ttid, &rcode);
+    ttid = 0;
+    if (code || rcode) {
+       fprintf(STDERR,
+               "Failed to end the transaction on the rw volume %lu\n",
+               (unsigned long)avolid);
+       error = (code ? code : rcode);
+       goto bfail;
+    }
+
+    /* Now go back to the backup volume and bring it on line */
+    if (!(flags & RV_OFFLINE)) {
+       code = AFSVolTransCreate_retry(aconn, acloneid, apart, ITOffline, &btid);
+       if (code) {
+           fprintf(STDERR,
+                   "Failed to start a transaction on the clone volume %lu\n",
+                   (unsigned long)acloneid);
+           error = code;
+           goto bfail;
+       }
+
+       code = AFSVolSetFlags(aconn, btid, 0);
+       if (code) {
+           fprintf(STDERR, "Could not mark the clone volume %lu on line \n",
+                   (unsigned long)acloneid);
+           error = code;
+           goto bfail;
+       }
+
+       code = AFSVolEndTrans(aconn, btid, &rcode);
+       btid = 0;
+       if (code || rcode) {
+           fprintf(STDERR,
+                   "Failed to end the transaction on the clone volume %lu\n",
+                   (unsigned long)acloneid);
+           error = (code ? code : rcode);
+           goto bfail;
+       }
+    }
+
+    VDONE;
+
   bfail:
     if (ttid) {
        code = AFSVolEndTrans(aconn, ttid, &rcode);
@@ -2602,43 +3160,13 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
        code = AFSVolEndTrans(aconn, btid, &rcode);
        if (code || rcode) {
            fprintf(STDERR,
-                   "Could not end transaction the backup volume %lu\n",
-                   (unsigned long)backupID);
+                   "Could not end transaction on the clone volume %lu\n",
+                   (unsigned long)acloneid);
            if (!error)
                error = (code ? code : rcode);
        }
     }
 
-    /* Now update the vldb - if modified */
-    if (vldblocked) {
-       if (vldbmod) {
-           MapNetworkToHost(&entry, &storeEntry);
-           code =
-               VLDB_ReplaceEntry(avolid, RWVOL, &storeEntry,
-                                 (LOCKREL_OPCODE | LOCKREL_AFSID |
-                                  LOCKREL_TIMESTAMP));
-           if (code) {
-               fprintf(STDERR,
-                       "Could not update the VLDB entry for the volume %lu \n",
-                       (unsigned long)avolid);
-               if (!error)
-                   error = code;
-           }
-       } else {
-           code =
-               ubik_Call(VL_ReleaseLock, cstruct, 0, avolid, RWVOL,
-                         (LOCKREL_OPCODE | LOCKREL_AFSID |
-                          LOCKREL_TIMESTAMP));
-           if (code) {
-               fprintf(STDERR,
-                       "Could not unlock the VLDB entry for the volume %lu \n",
-                       (unsigned long)avolid);
-               if (!error)
-                   error = code;
-           }
-       }
-    }
-
     if (aconn)
        rx_DestroyConnection(aconn);
 
@@ -2647,13 +3175,13 @@ UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
 }
 
 static int
-DelVol(struct rx_connection *conn, afs_int32 vid, afs_int32 part,
+DelVol(struct rx_connection *conn, afs_uint32 vid, afs_int32 part,
        afs_int32 flags)
 {
     afs_int32 acode, ccode, rcode, tid;
     ccode = rcode = tid = 0;
 
-    acode = AFSVolTransCreate(conn, vid, part, flags, &tid);
+    acode = AFSVolTransCreate_retry(conn, vid, part, flags, &tid);
     if (!acode) {              /* It really was there */
        acode = AFSVolDeleteVolume(conn, tid);
        if (acode) {
@@ -2674,25 +3202,45 @@ DelVol(struct rx_connection *conn, afs_int32 vid, afs_int32 part,
     return acode;
 }
 
-#define ONERROR(ec, ep, es) if (ec) { fprintf(STDERR, (es), (ep)); error = (ec); goto rfail; }
-#define ERROREXIT(ec) { error = (ec); goto rfail; }
+#define ONERROR(ec, ep, es) do { \
+    if (ec) { \
+        fprintf(STDERR, (es), (ep)); \
+        error = (ec); \
+        goto rfail; \
+    } \
+} while (0)
+#define ONERROR0(ec, es) do { \
+    if (ec) { \
+        fprintf(STDERR, (es)); \
+        error = (ec); \
+        goto rfail; \
+    } \
+} while (0)
+#define ERROREXIT(ec) do { \
+    error = (ec); \
+    goto rfail; \
+} while (0)
 
-/* Get a "transaction" on this replica.  Create the volume 
+/* Get a "transaction" on this replica.  Create the volume
  * if necessary.  Return the time from which a dump should
  * be made (0 if it's a new volume)
  */
 static int
 GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
         struct rx_connection **connPtr, afs_int32 * transPtr,
-        afs_int32 * timePtr)
+        afs_uint32 * crtimePtr, afs_uint32 * uptimePtr,
+        afs_int32 *origflags)
 {
-    afs_int32 volid;
+    afs_uint32 volid;
     struct volser_status tstatus;
-    int code, rcode, tcode;
+    int code = 0;
+    int rcode, tcode;
+    char hoststr[16];
 
     *connPtr = (struct rx_connection *)0;
-    *timePtr = 0;
     *transPtr = 0;
+    *crtimePtr = 0;
+    *uptimePtr = 0;
 
     /* get connection to the replication site */
     *connPtr = UV_Bind(vldbEntryPtr->serverNumber[index], AFSCONF_VOLUMEPORT);
@@ -2700,15 +3248,55 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
        goto fail;              /* server is down */
 
     volid = vldbEntryPtr->volumeId[ROVOL];
-    if (volid)
+    if (volid) {
        code =
-           AFSVolTransCreate(*connPtr, volid,
+           AFSVolTransCreate_retry(*connPtr, volid,
                              vldbEntryPtr->serverPartition[index], ITOffline,
                              transPtr);
 
+       if (!code && (origflags[index] & RO_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
+            * incomplete volume operation. It is difficult to detect if
+            * that has happened vs if this is a legit volume, so just
+            * delete it to be safe. */
+
+           VPRINT1("Deleting extant RO_DONTUSE site on %s...",
+                    noresolve ? afs_inet_ntoa_r(vldbEntryPtr->
+                                                serverNumber[index], hoststr) :
+                    hostutil_GetNameByINet(vldbEntryPtr->
+                                          serverNumber[index]));
+
+           code = AFSVolDeleteVolume(*connPtr, *transPtr);
+           if (code) {
+               PrintError("Failed to delete RO_DONTUSE site: ", code);
+               goto fail;
+           }
+
+           tcode = AFSVolEndTrans(*connPtr, *transPtr, &rcode);
+           *transPtr = 0;
+           if (!tcode) {
+               tcode = rcode;
+           }
+           if (tcode) {
+               PrintError("Failed to end transaction on RO_DONTUSE site: ",
+                          tcode);
+               goto fail;
+           }
+
+           VDONE;
+
+           /* emulate what TransCreate would have returned, so we try to
+            * create the volume below */
+           code = VNOVOL;
+       }
+    }
+
     /* If the volume does not exist, create it */
     if (!volid || code) {
        char volname[64];
+        char hoststr[16];
 
        if (volid && (code != VNOVOL)) {
            PrintError("Failed to start a transaction on the RO volume.\n",
@@ -2723,7 +3311,9 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
            fprintf(STDOUT,
                    "Creating new volume %lu on replication site %s: ",
                    (unsigned long)volid,
-                   hostutil_GetNameByINet(vldbEntryPtr->
+                    noresolve ? afs_inet_ntoa_r(vldbEntryPtr->
+                                                serverNumber[index], hoststr) :
+                    hostutil_GetNameByINet(vldbEntryPtr->
                                           serverNumber[index]));
            fflush(STDOUT);
        }
@@ -2752,11 +3342,13 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
     }
 
     /* Otherwise, the transaction did succeed, so get the creation date of the
-     * latest RO volume on the replication site 
+     * latest RO volume on the replication site
      */
     else {
        VPRINT2("Updating existing ro volume %u on %s ...\n", volid,
-               hostutil_GetNameByINet(vldbEntryPtr->serverNumber[index]));
+                noresolve ? afs_inet_ntoa_r(vldbEntryPtr->
+                                            serverNumber[index], hoststr) :
+                hostutil_GetNameByINet(vldbEntryPtr->serverNumber[index]));
 
        code = AFSVolGetStatus(*connPtr, *transPtr, &tstatus);
        if (code) {
@@ -2764,7 +3356,8 @@ GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
                       code);
            goto fail;
        }
-       *timePtr = tstatus.creationDate - CLOCKSKEW;
+       *crtimePtr = CLOCKADJ(tstatus.creationDate);
+       *uptimePtr = CLOCKADJ(tstatus.updateDate);
     }
 
     return 0;
@@ -2787,7 +3380,7 @@ SimulateForwardMultiple(struct rx_connection *fromconn, afs_int32 fromtid,
                        afs_int32 fromdate, manyDests * tr, afs_int32 flags,
                        void *cookie, manyResults * results)
 {
-    int i;
+    unsigned int i;
 
     for (i = 0; i < tr->manyDests_len; i++) {
        results->manyResults_val[i] =
@@ -2798,13 +3391,73 @@ SimulateForwardMultiple(struct rx_connection *fromconn, afs_int32 fromtid,
     return 0;
 }
 
-
+/**
+ * Check if a trans has timed out, and recreate it if necessary.
+ *
+ * @param[in] aconn  RX connection to the relevant server
+ * @param[inout] atid  Transaction ID to check; if we recreated the trans,
+ *                     contains the new trans ID on success
+ * @param[in] apart  Partition for the transaction
+ * @param[in] astat  The status of the original transaction
+ *
+ * @return operation status
+ *  @retval 0 existing transaction is still valid, or we managed to recreate
+ *            the trans successfully
+ *  @retval nonzero Fatal error; bail out
+ */
 static int
-rel_compar(struct release *r1, struct release *r2)
+CheckTrans(struct rx_connection *aconn, afs_int32 *atid, afs_int32 apart,
+           struct volser_status *astat)
 {
-    return (r1->time - r2->time);
+    struct volser_status new_status;
+    afs_int32 code;
+
+    memset(&new_status, 0, sizeof(new_status));
+    code = AFSVolGetStatus(aconn, *atid, &new_status);
+    if (code) {
+       if (code == ENOENT) {
+           *atid = 0;
+           VPRINT1("Old transaction on cloned volume %lu timed out, "
+                   "restarting transaction\n", (long unsigned) astat->volID);
+           code = AFSVolTransCreate_retry(aconn, astat->volID, apart,
+                                          ITBusy, atid);
+           if (code) {
+               PrintError("Failed to recreate cloned RO volume transaction\n",
+                          code);
+               return 1;
+           }
+
+           memset(&new_status, 0, sizeof(new_status));
+           code = AFSVolGetStatus(aconn, *atid, &new_status);
+           if (code) {
+               PrintError("Failed to get status on recreated transaction\n",
+                          code);
+               return 1;
+           }
+
+           if (memcmp(&new_status, astat, sizeof(new_status)) != 0) {
+               PrintError("Recreated transaction on cloned RO volume, but "
+                          "the volume has changed!\n", 0);
+               return 1;
+           }
+       } else {
+           PrintError("Unable to get status of current cloned RO transaction\n",
+                      code);
+           return 1;
+       }
+    } else {
+       if (memcmp(&new_status, astat, sizeof(new_status)) != 0) {
+           /* sanity check */
+           PrintError("Internal error: current GetStatus does not match "
+                      "original GetStatus?\n", 0);
+           return 1;
+       }
+    }
+
+    return 0;
 }
 
+
 /* UV_ReleaseVolume()
  *    Release volume <afromvol> on <afromserver> <afrompart> to all
  *    its RO sites (full release). Unless the previous release was
@@ -2813,19 +3466,20 @@ rel_compar(struct release *r1, struct release *r2)
  *    successfully.
  *    forceflag: Performs a full release.
  *
- *    Will create a clone from the RW, then dump the clone out to 
+ *    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.
  */
 
 int
-UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
+UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                 afs_int32 afrompart, int forceflag)
 {
     char vname[64];
-    afs_int32 code, vcode, rcode, tcode;
-    afs_int32 cloneVolId, roVolId;
+    afs_int32 code = 0;
+    afs_int32 vcode, rcode, tcode;
+    afs_uint32 cloneVolId, roVolId;
     struct replica *replicas = 0;
     struct nvldbentry entry, storeEntry;
     int i, volcount, m, fullrelease, vldbindex;
@@ -2839,23 +3493,30 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     int islocked = 0;
     afs_int32 clonetid = 0, onlinetid;
     afs_int32 fromtid = 0;
-    afs_uint32 fromdate, thisdate;
+    afs_uint32 fromdate = 0;
+    afs_uint32 thisdate;
+    time_t tmv;
     int s;
     manyDests tr;
     manyResults results;
     int rwindex, roindex, roclone, roexists;
-    afs_int32 rwcrdate, clcrdate;
+    afs_uint32 rwcrdate = 0;
+    afs_uint32 clcrdate;
     struct rtime {
        int validtime;
-       afs_uint32 time;
+       afs_uint32 uptime;
     } remembertime[NMAXNSERVERS];
     int releasecount = 0;
     struct volser_status volstatus;
+    char hoststr[16];
+    afs_int32 origflags[NMAXNSERVERS];
+    struct volser_status orig_status;
 
-    memset((char *)remembertime, 0, sizeof(remembertime));
-    memset((char *)&results, 0, sizeof(results));
+    memset(remembertime, 0, sizeof(remembertime));
+    memset(&results, 0, sizeof(results));
+    memset(origflags, 0, sizeof(origflags));
 
-    vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
+    vcode = ubik_VL_SetLock(cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
     if (vcode != VL_RERELEASE)
        ONERROR(vcode, afromvol,
                "Could not lock the VLDB entry for the volume %u.\n");
@@ -2892,12 +3553,12 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     roclone = ((roindex == -1) ? 0 : 1);
     rwindex = Lp_GetRwIndex(&entry);
     if (rwindex < 0)
-       ONERROR(VOLSERNOVOL, 0, "There is no RW volume \n");
+       ONERROR0(VOLSERNOVOL, "There is no RW volume \n");
 
     /* Make sure we have a RO volume id to work with */
     if (entry.volumeId[ROVOL] == INVALID_BID) {
        /* need to get a new RO volume id */
-       vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &roVolId);
+       vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &roVolId);
        ONERROR(vcode, entry.name, "Cant allocate ID for RO volume of %s\n");
 
        entry.volumeId[ROVOL] = roVolId;
@@ -2907,11 +3568,14 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     }
 
     /* Will we be completing a previously unfinished release. -force overrides */
-    for (fullrelease = 1, i = 0; (fullrelease && (i < entry.nServers)); i++) {
-       if (entry.serverFlags[i] & NEW_REPSITE)
-           fullrelease = 0;
+    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++;
+       }
+       origflags[i] = entry.serverFlags[i];
     }
-    if (forceflag && !fullrelease)
+    if ((forceflag && !fullrelease) || (s == m) || (s == 0))
        fullrelease = 1;
 
     /* Determine which volume id to use and see if it exists */
@@ -2931,7 +3595,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            fullrelease = 1;    /* Do a full release if RO clone does not exist */
        else {
            /* Begin transaction on RW and mark it busy while we query it */
-           code = AFSVolTransCreate(
+           code = AFSVolTransCreate_retry(
                        fromconn, afromvol, afrompart, ITBusy, &fromtid
                   );
            ONERROR(code, afromvol,
@@ -2950,7 +3614,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
                    "Failed to end transaction on RW volume %u\n");
 
            /* Begin transaction on clone and mark it busy while we query it */
-           code = AFSVolTransCreate(
+           code = AFSVolTransCreate_retry(
                        fromconn, cloneVolId, afrompart, ITBusy, &clonetid
                   );
            ONERROR(code, cloneVolId,
@@ -2962,11 +3626,11 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
                    "Failed to get the status of RW clone %u\n");
            clcrdate = volstatus.creationDate;
 
-           /* End transaction on RW */
+           /* End transaction on clone */
            code = AFSVolEndTrans(fromconn, clonetid, &rcode);
            clonetid = 0;
            ONERROR((code ? code : rcode), cloneVolId,
-                   "Failed to end transaction on RW volume %u\n");
+                   "Failed to end transaction on RW clone %u\n");
 
            if (rwcrdate > clcrdate)
                fullrelease = 2;/* Do a full release if RO clone older than RW */
@@ -3016,7 +3680,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
 
        /* Begin transaction on RW and mark it busy while we clone it */
        code =
-           AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
+           AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
                              &clonetid);
        ONERROR(code, afromvol, "Failed to start transaction on volume %u\n");
 
@@ -3030,10 +3694,10 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            if (roclone) {
                strcpy(vname, entry.name);
                strcat(vname, ".readonly");
-               VPRINT("Cloning RW volume %u to permanent RO...");
+               VPRINT1("Cloning RW volume %u to permanent RO...", afromvol);
            } else {
                strcpy(vname, "readonly-clone-temp");
-               VPRINT("Cloning RW volume %u to temporary RO...");
+               VPRINT1("Cloning RW volume %u to temporary RO...", afromvol);
            }
            code =
                AFSVolClone(fromconn, clonetid, 0, readonlyVolume, vname,
@@ -3043,18 +3707,18 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
        }
 
        /* Get the time the RW was created for future information */
-       VPRINT1("Getting status of RW volume %u...", cloneVolId);
+       VPRINT1("Getting status of RW volume %u...", afromvol);
        code = AFSVolGetStatus(fromconn, clonetid, &volstatus);
-       ONERROR(code, cloneVolId,
+       ONERROR(code, afromvol,
                "Failed to get the status of the RW volume %u\n");
        VDONE;
        rwcrdate = volstatus.creationDate;
 
        /* End the transaction on the RW volume */
-       VPRINT1("Ending cloning transaction on RW volume %u...", cloneVolId);
+       VPRINT1("Ending cloning transaction on RW volume %u...", afromvol);
        code = AFSVolEndTrans(fromconn, clonetid, &rcode);
        clonetid = 0;
-       ONERROR((code ? code : rcode), cloneVolId,
+       ONERROR((code ? code : rcode), afromvol,
                "Failed to end cloning transaction on RW %u\n");
        VDONE;
 
@@ -3066,7 +3730,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            VPRINT1("Starting transaction on RO clone volume %u...",
                    cloneVolId);
            code =
-               AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITOffline,
+               AFSVolTransCreate_retry(fromconn, cloneVolId, afrompart, ITOffline,
                                  &onlinetid);
            ONERROR(code, cloneVolId,
                    "Failed to start transaction on volume %u\n");
@@ -3085,7 +3749,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            ONERROR(tcode, cloneVolId, "Could not bring volume %u on line\n");
 
            /* Sleep so that a client searching for an online volume won't
-            * find the clone offline and then the next RO offline while the 
+            * find the clone offline and then the next RO offline while the
             * release brings the clone online and the next RO offline (race).
             * There is a fix in the 3.4 client that does not need this sleep
             * anymore, but we don't know what clients we have.
@@ -3140,7 +3804,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     results.manyResults_val =
        (afs_int32 *) malloc(sizeof(afs_int32) * nservers + 1);
     if (!replicas || !times || !!!results.manyResults_val || !toconns)
-       ONERROR(ENOMEM, 0,
+       ONERROR0(ENOMEM,
                "Failed to create transaction on the release clone\n");
 
     memset(replicas, 0, (sizeof(struct replica) * nservers + 1));
@@ -3151,11 +3815,15 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     /* Create a transaction on the cloned volume */
     VPRINT1("Starting transaction on cloned volume %u...", cloneVolId);
     code =
-       AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITBusy, &fromtid);
+       AFSVolTransCreate_retry(fromconn, cloneVolId, afrompart, ITBusy, &fromtid);
+    if (!code) {
+       memset(&orig_status, 0, sizeof(orig_status));
+       code = AFSVolGetStatus(fromconn, fromtid, &orig_status);
+    }
     if (!fullrelease && code)
        ONERROR(VOLSERNOVOL, afromvol,
                "Old clone is inaccessible. Try vos release -f %u.\n");
-    ONERROR(code, 0, "Failed to create transaction on the release clone\n");
+    ONERROR0(code, "Failed to create transaction on the release clone\n");
     VDONE;
 
     /* For each index in the VLDB */
@@ -3185,7 +3853,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            /* Get a Transaction on this replica. Get a new connection if
             * necessary.  Create the volume if necessary.  Return the
             * time from which the dump should be made (0 if it's a new
-            * volume).  Each volume might have a different time. 
+            * volume).  Each volume might have a different time.
             */
            replicas[volcount].server.destHost =
                ntohl(entry.serverNumber[vldbindex]);
@@ -3196,13 +3864,15 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            code =
                GetTrans(&entry, vldbindex, &(toconns[volcount]),
                         &(replicas[volcount].trans),
-                        &(times[volcount].time));
+                        &(times[volcount].crtime),
+                        &(times[volcount].uptime),
+                        origflags);
            if (code)
                continue;
 
            /* Thisdate is the date from which we want to pick up all changes */
            if (forceflag || !fullrelease
-               || (rwcrdate > times[volcount].time)) {
+               || (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).
@@ -3217,14 +3887,14 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
                 * case time[volcount].time would be now instead of 0.
                 */
                thisdate =
-                   (remembertime[vldbindex].time <
-                    times[volcount].time) ? remembertime[vldbindex].
-                   time : times[volcount].time;
+                   (remembertime[vldbindex].uptime < times[volcount].uptime)
+                       ? remembertime[vldbindex].uptime
+                       : times[volcount].uptime;
            } else {
-               thisdate = times[volcount].time;
+               thisdate = times[volcount].uptime;
            }
            remembertime[vldbindex].validtime = 1;
-           remembertime[vldbindex].time = thisdate;
+           remembertime[vldbindex].uptime = thisdate;
 
            if (volcount == 0) {
                fromdate = thisdate;
@@ -3246,22 +3916,36 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
        if (!volcount)
            continue;
 
+       code = CheckTrans(fromconn, &fromtid, afrompart, &orig_status);
+       if (code) {
+           code = ENOENT;
+           goto rfail;
+       }
+
        if (verbose) {
            fprintf(STDOUT, "Starting ForwardMulti from %lu to %u on %s",
                    (unsigned long)cloneVolId, entry.volumeId[ROVOL],
-                   hostutil_GetNameByINet(entry.
+                    noresolve ? afs_inet_ntoa_r(entry.serverNumber[times[0].
+                                                vldbEntryIndex], hoststr) :
+                    hostutil_GetNameByINet(entry.
                                           serverNumber[times[0].
                                                        vldbEntryIndex]));
 
            for (s = 1; s < volcount; s++) {
                fprintf(STDOUT, " and %s",
-                       hostutil_GetNameByINet(entry.
+                        noresolve ? afs_inet_ntoa_r(entry.serverNumber[times[s].
+                                                    vldbEntryIndex], hoststr) :
+                        hostutil_GetNameByINet(entry.
                                               serverNumber[times[s].
                                                            vldbEntryIndex]));
            }
 
            if (fromdate == 0)
                fprintf(STDOUT, " (full release)");
+           else {
+               tmv = fromdate;
+               fprintf(STDOUT, " (as of %.24s)", ctime(&tmv));
+           }
            fprintf(STDOUT, ".\n");
            fflush(STDOUT);
        }
@@ -3309,7 +3993,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
 
                /* have to clear dest. flags to ensure new vol goes online:
                 * because the restore (forwarded) operation copied
-                * the V_inService(=0) flag over to the destination. 
+                * the V_inService(=0) flag over to the destination.
                 */
                code = AFSVolSetFlags(toconns[m], replicas[m].trans, 0);
                if (code) {
@@ -3380,7 +4064,8 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
            if (!(entry.serverFlags[i] & NEW_REPSITE)) {
                MapPartIdIntoName(entry.serverPartition[i], pname);
                fprintf(STDERR, "\t%35s %s\n",
-                       hostutil_GetNameByINet(entry.serverNumber[i]), pname);
+                        noresolve ? afs_inet_ntoa_r(entry.serverNumber[i], hoststr) :
+                        hostutil_GetNameByINet(entry.serverNumber[i]), pname);
            }
        }
 
@@ -3451,9 +4136,10 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
                fprintf(STDERR,
                        "Failed to end transaction on ro volume %u at server %s\n",
                        entry.volumeId[ROVOL],
-                       hostutil_GetNameByINet(htonl
-                                              (replicas[i].server.
-                                               destHost)));
+                        noresolve ? afs_inet_ntoa_r(htonl(replicas[i].server.
+                                                        destHost), hoststr) :
+                        hostutil_GetNameByINet(htonl
+                                              (replicas[i].server.destHost)));
                if (!error)
                    error = code;
            }
@@ -3465,7 +4151,7 @@ UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
     }
     if (islocked) {
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, afromvol, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
            fprintf(STDERR,
@@ -3502,16 +4188,24 @@ dump_sig_handler(int x)
 /* Dump the volume <afromvol> on <afromserver> and
  * <afrompart> to <afilename> starting from <fromdate>.
  * DumpFunction does the real work behind the scenes after
- * extracting parameters from the rock 
+ * extracting parameters from the rock
  */
 int
-UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
-             afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock)
+UV_DumpVolume(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
+             afs_int32 fromdate,
+             afs_int32(*DumpFunction) (struct rx_call *, void *), void *rock,
+             afs_int32 flags)
 {
-    struct rx_connection *fromconn = (struct rx_connection *)0;
-    struct rx_call *fromcall = (struct rx_call *)0;
-    afs_int32 fromtid = 0, rxError = 0, rcode = 0;
+    /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+     * be changing during the dump */
+    struct rx_call * volatile fromcall = NULL;
+    struct rx_connection * volatile fromconn = NULL;
+    afs_int32 volatile fromtid = 0;
+
+    afs_int32 rxError = 0, rcode = 0;
     afs_int32 code, error = 0;
+    afs_int32 tmp;
+    time_t tmv = fromdate;
 
     if (setjmp(env))
        ERROR_EXIT(EPIPE);
@@ -3521,45 +4215,51 @@ UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     (void)signal(SIGINT, dump_sig_handler);
 
     if (!fromdate) {
-       VPRINT("Full Dump ...\n");
+       VEPRINT("Full Dump ...\n");
     } else {
-       VPRINT1("Incremental Dump (as of %.24s)...\n",
-               ctime((time_t *) & fromdate));
+       VEPRINT1("Incremental Dump (as of %.24s)...\n",
+               ctime(&tmv));
     }
 
     /* get connections to the servers */
     fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
 
-    VPRINT1("Starting transaction on volume %u...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+    VEPRINT1("Starting transaction on volume %u...", afromvol);
+    tmp = fromtid;
+    code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+    fromtid = tmp;
     EGOTO1(error_exit, code,
           "Could not start transaction on the volume %u to be dumped\n",
           afromvol);
-    VDONE;
+    VEDONE;
 
     fromcall = rx_NewCall(fromconn);
 
-    VPRINT1("Starting volume dump on volume %u...", afromvol);
-    code = StartAFSVolDump(fromcall, fromtid, fromdate);
+    VEPRINT1("Starting volume dump on volume %u...", afromvol);
+    if (flags & VOLDUMPV2_OMITDIRS)
+       code = StartAFSVolDumpV2(fromcall, fromtid, fromdate, flags);
+    else
+       code = StartAFSVolDump(fromcall, fromtid, fromdate);
     EGOTO(error_exit, code, "Could not start the dump process \n");
-    VDONE;
+    VEDONE;
 
-    VPRINT1("Dumping volume %u...", afromvol);
+    VEPRINT1("Dumping volume %u...", afromvol);
     code = DumpFunction(fromcall, rock);
+    if (code == RXGEN_OPCODE)
+       goto error_exit;
     EGOTO(error_exit, code, "Error while dumping volume \n");
-    VDONE;
+    VEDONE;
 
   error_exit:
     if (fromcall) {
        code = rx_EndCall(fromcall, rxError);
-       if (code) {
+       if (code && code != RXGEN_OPCODE)
            fprintf(STDERR, "Error in rx_EndCall\n");
-           if (!error)
-               error = code;
-       }
+       if (code && !error)
+           error = code;
     }
     if (fromtid) {
-       VPRINT1("Ending transaction on volume %u...", afromvol);
+       VEPRINT1("Ending transaction on volume %u...", afromvol);
        code = AFSVolEndTrans(fromconn, fromtid, &rcode);
        if (code || rcode) {
            fprintf(STDERR, "Could not end transaction on the volume %lu\n",
@@ -3567,33 +4267,41 @@ UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
            if (!error)
                error = (code ? code : rcode);
        }
-       VDONE;
+       VEDONE;
     }
     if (fromconn)
        rx_DestroyConnection(fromconn);
 
-    PrintError("", error);
+    if (error != RXGEN_OPCODE)
+       PrintError("", error);
     return (error);
 }
 
 /* Clone the volume <afromvol> on <afromserver> and
- * <afrompart>, and then dump the clone volume to 
+ * <afrompart>, and then dump the clone volume to
  * <afilename> starting from <fromdate>.
  * DumpFunction does the real work behind the scenes after
- * extracting parameters from the rock 
+ * extracting parameters from the rock
  */
 int
-UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
+UV_DumpClonedVolume(afs_uint32 afromvol, afs_uint32 afromserver,
                    afs_int32 afrompart, afs_int32 fromdate,
-                   afs_int32(*DumpFunction) (), char *rock)
+                   afs_int32(*DumpFunction) (struct rx_call *, void *),
+                   void *rock, afs_int32 flags)
 {
-    struct rx_connection *fromconn = (struct rx_connection *)0;
-    struct rx_call *fromcall = (struct rx_call *)0;
+    /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+     * be changing during the dump */
+    struct rx_connection * volatile fromconn = NULL;
+    struct rx_call * volatile fromcall = NULL;
+    afs_int32 volatile clonetid = 0;
+    afs_uint32 volatile clonevol = 0;
+
+    afs_int32 tmp;
     afs_int32 fromtid = 0, rxError = 0, rcode = 0;
-    afs_int32 clonetid = 0;
-    afs_int32 code = 0, vcode = 0, error = 0;
-    afs_int32 clonevol = 0;
+    afs_int32 code = 0, error = 0;
+    afs_uint32 tmpVol;
     char vname[64];
+    time_t tmv = fromdate;
 
     if (setjmp(env))
        ERROR_EXIT(EPIPE);
@@ -3603,41 +4311,45 @@ UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
     (void)signal(SIGINT, dump_sig_handler);
 
     if (!fromdate) {
-       VPRINT("Full Dump ...\n");
+       VEPRINT("Full Dump ...\n");
     } else {
-       VPRINT1("Incremental Dump (as of %.24s)...\n",
-               ctime((time_t *) & fromdate));
+       VEPRINT1("Incremental Dump (as of %.24s)...\n",
+               ctime(&tmv));
     }
 
     /* get connections to the servers */
     fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
 
-    VPRINT1("Starting transaction on volume %u...", afromvol);
-    code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+    VEPRINT1("Starting transaction on volume %u...", afromvol);
+    code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
     EGOTO1(error_exit, code,
           "Could not start transaction on the volume %u to be dumped\n",
           afromvol);
-    VDONE;
+    VEDONE;
 
     /* Get a clone id */
-    VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
-    code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &clonevol);
+    VEPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
+    tmpVol = clonevol;
+    code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+    clonevol = tmpVol;
     EGOTO1(error_exit, code,
           "Could not get an ID for the clone of volume %u from the VLDB\n",
           afromvol);
-    VDONE;
+    VEDONE;
 
     /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
-    VPRINT2("Cloning source volume %u to clone volume %u...", afromvol,
+    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, &clonevol);
+       AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &tmpVol);
+    clonevol = tmpVol;
     EGOTO1(error_exit, code, "Failed to clone the source volume %u\n",
           afromvol);
-    VDONE;
+    VEDONE;
 
-    VPRINT1("Ending the transaction on the volume %u ...", afromvol);
+    VEPRINT1("Ending the transaction on the volume %u ...", afromvol);
     rcode = 0;
     code = AFSVolEndTrans(fromconn, fromtid, &rcode);
     fromtid = 0;
@@ -3645,46 +4357,51 @@ UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
        code = rcode;
     EGOTO1(error_exit, code,
           "Failed to end the transaction on the volume %u\n", afromvol);
-    VDONE;
+    VEDONE;
 
 
-    VPRINT1("Starting transaction on the cloned volume %u ...", clonevol);
+    VEPRINT1("Starting transaction on the cloned volume %u ...", clonevol);
+    tmp = clonetid;
     code =
-       AFSVolTransCreate(fromconn, clonevol, afrompart, ITOffline,
-                         &clonetid);
+       AFSVolTransCreate_retry(fromconn, clonevol, afrompart, ITOffline,
+                         &tmp);
+    clonetid = tmp;
     EGOTO1(error_exit, code,
           "Failed to start a transaction on the cloned volume%u\n",
           clonevol);
-    VDONE;
+    VEDONE;
 
-    VPRINT1("Setting flags on cloned volume %u ...", clonevol);
+    VEPRINT1("Setting flags on cloned volume %u ...", clonevol);
     code = AFSVolSetFlags(fromconn, clonetid, VTDeleteOnSalvage | VTOutOfService);     /*redundant */
     EGOTO1(error_exit, code, "Could not set falgs on the cloned volume %u\n",
           clonevol);
-    VDONE;
+    VEDONE;
 
 
     fromcall = rx_NewCall(fromconn);
 
-    VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
-    code = StartAFSVolDump(fromcall, clonetid, fromdate);
+    VEPRINT1("Starting volume dump from cloned volume %u...", clonevol);
+    if (flags & VOLDUMPV2_OMITDIRS)
+       code = StartAFSVolDumpV2(fromcall, clonetid, fromdate, flags);
+    else
+       code = StartAFSVolDump(fromcall, clonetid, fromdate);
     EGOTO(error_exit, code, "Could not start the dump process \n");
-    VDONE;
+    VEDONE;
 
-    VPRINT1("Dumping volume %u...", afromvol);
+    VEPRINT1("Dumping volume %u...", afromvol);
     code = DumpFunction(fromcall, rock);
     EGOTO(error_exit, code, "Error while dumping volume \n");
-    VDONE;
+    VEDONE;
 
   error_exit:
     /* now delete the clone */
-    VPRINT1("Deleting the cloned volume %u ...", clonevol);
+    VEPRINT1("Deleting the cloned volume %u ...", clonevol);
     code = AFSVolDeleteVolume(fromconn, clonetid);
     if (code) {
        fprintf(STDERR, "Failed to delete the cloned volume %lu\n",
                (unsigned long)clonevol);
     } else {
-       VDONE;
+       VEDONE;
     }
 
     if (fromcall) {
@@ -3696,7 +4413,7 @@ UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
        }
     }
     if (clonetid) {
-       VPRINT1("Ending transaction on cloned volume %u...", clonevol);
+       VEPRINT1("Ending transaction on cloned volume %u...", clonevol);
        code = AFSVolEndTrans(fromconn, clonetid, &rcode);
        if (code || rcode) {
            fprintf(STDERR,
@@ -3705,7 +4422,7 @@ UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
            if (!error)
                error = (code ? code : rcode);
        }
-       VDONE;
+       VEDONE;
     }
     if (fromconn)
        rx_DestroyConnection(fromconn);
@@ -3719,31 +4436,35 @@ UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
 /*
  * Restore a volume <tovolid> <tovolname> on <toserver> <topart> from
  * the dump file <afilename>. WriteData does all the real work
- * after extracting params from the rock 
+ * after extracting params from the rock
  */
 int
-UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
-                char tovolname[], int flags, afs_int32(*WriteData) (),
-                char *rock)
+UV_RestoreVolume2(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
+                 afs_uint32 toparentid, char tovolname[], int flags,
+                 afs_int32(*WriteData) (struct rx_call *, void *),
+                 void *rock)
 {
     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];
-    afs_int32 pvolid;
-    afs_int32 temptid;
+    char tovolreal[VOLSER_OLDMAXVOLNAME];
+    afs_uint32 pvolid;
+    afs_int32 temptid, pparentid;
     int success;
     struct nvldbentry entry, storeEntry;
     afs_int32 error;
     int islocked;
     struct restoreCookie cookie;
     int reuseID;
-    afs_int32 newDate, volflag, voltype, volsertype;
+    afs_int32 volflag, voltype, volsertype;
+    afs_int32 oldCreateDate, oldUpdateDate, newCreateDate, newUpdateDate;
     int index, same, errcode;
     char apartName[10];
-
+    char hoststr[16];
 
     memset(&cookie, 0, sizeof(cookie));
     islocked = 0;
@@ -3765,11 +4486,12 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     }
 
     pvolid = tovolid;
+    pparentid = toparentid;
     toconn = UV_Bind(toserver, AFSCONF_VOLUMEPORT);
     if (pvolid == 0) {         /*alot a new id if needed */
        vcode = VLDB_GetEntryByName(tovolname, &entry);
        if (vcode == VL_NOENT) {
-           vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &pvolid);
+           vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &pvolid);
            if (vcode) {
                fprintf(STDERR, "Could not get an Id for the volume %s\n",
                        tovolname);
@@ -3793,33 +4515,54 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
                goto refail;
            }
            pvolid = entry.volumeId[ROVOL];
+           pparentid = entry.volumeId[RWVOL];
        } else {
            pvolid = entry.volumeId[RWVOL];
+           pparentid = entry.volumeId[RWVOL];
        }
     }
+    if (!pparentid) pparentid = pvolid;
     /* at this point we have a volume id to use/reuse for the volume to be restored */
+    strncpy(tovolreal, tovolname, VOLSER_OLDMAXVOLNAME);
+
     if (strlen(tovolname) > (VOLSER_OLDMAXVOLNAME - 1)) {
        EGOTO1(refail, VOLSERBADOP,
               "The volume name %s exceeds the maximum limit of (VOLSER_OLDMAXVOLNAME -1 ) bytes\n",
               tovolname);
+    } else {
+       if ((pparentid != pvolid) && (flags & RV_RDONLY)) {
+           if (strlen(tovolname) > (VOLSER_OLDMAXVOLNAME - 10)) {
+               EGOTO1(refail, VOLSERBADOP,
+                      "The volume name %s exceeds the maximum limit of (VOLSER_OLDMAXVOLNAME -1 ) bytes\n", tovolname);
+           }
+           snprintf(tovolreal, VOLSER_OLDMAXVOLNAME, "%s.readonly", tovolname);
+       }
     }
     MapPartIdIntoName(topart, partName);
     fprintf(STDOUT, "Restoring volume %s Id %lu on server %s partition %s ..",
-           tovolname, (unsigned long)pvolid,
+           tovolreal, (unsigned long)pvolid,
+            noresolve ? afs_inet_ntoa_r(toserver, hoststr) :
            hostutil_GetNameByINet(toserver), partName);
     fflush(STDOUT);
     code =
-       AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0, &pvolid,
+       AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid, &pvolid,
                           &totid);
     if (code) {
        if (flags & RV_FULLRST) {       /* full restore: delete then create anew */
            VPRINT1("Deleting the previous volume %u ...", pvolid);
 
            code =
-               AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
+               AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
            EGOTO1(refail, code, "Failed to start transaction on %u\n",
                   pvolid);
 
+           code = AFSVolGetStatus(toconn, totid, &tstatus);
+           EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
+                  pvolid);
+
+           oldCreateDate = tstatus.creationDate;
+           oldUpdateDate = tstatus.updateDate;
+
            code =
                AFSVolSetFlags(toconn, totid,
                               VTDeleteOnSalvage | VTOutOfService);
@@ -3838,27 +4581,31 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
            VDONE;
 
            code =
-               AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,
+               AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
                                   &pvolid, &totid);
            EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
-
-           newDate = 0;
        } else {
            code =
-               AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
+               AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
            EGOTO1(refail, code, "Failed to start transaction on %u\n",
                   pvolid);
 
            code = AFSVolGetStatus(toconn, totid, &tstatus);
            EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
                   pvolid);
-           newDate = tstatus.creationDate;
+
+           oldCreateDate = tstatus.creationDate;
+           oldUpdateDate = tstatus.updateDate;
        }
+    } else {
+       oldCreateDate = 0;
+       oldUpdateDate = 0;
     }
-    cookie.parent = pvolid;
+
+    cookie.parent = pparentid;
     cookie.type = voltype;
     cookie.clone = 0;
-    strncpy(cookie.name, tovolname, VOLSER_OLDMAXVOLNAME);
+    strncpy(cookie.name, tovolreal, VOLSER_OLDMAXVOLNAME);
 
     tocall = rx_NewCall(toconn);
     terror = StartAFSVolRestore(tocall, totid, 1, &cookie);
@@ -3888,19 +4635,40 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
        error = code;
        goto refail;
     }
-    code = AFSVolSetIdsTypes(toconn, totid, tovolname, voltype, pvolid, 0, 0);
+    code = AFSVolSetIdsTypes(toconn, totid, tovolreal, voltype, pparentid, 0, 0);
     if (code) {
        fprintf(STDERR, "Could not set the right type and ID on %lu\n",
                (unsigned long)pvolid);
        error = code;
        goto refail;
     }
-    if (!newDate)
-       newDate = time(0);
-    code = AFSVolSetDate(toconn, totid, newDate);
+
+    if (flags & RV_CRDUMP)
+       newCreateDate = tstatus.creationDate;
+    else if (flags & RV_CRKEEP && oldCreateDate != 0)
+       newCreateDate = oldCreateDate;
+    else
+       newCreateDate = time(0);
+    if (flags & RV_LUDUMP)
+       newUpdateDate = tstatus.updateDate;
+    else if (flags & RV_LUKEEP)
+       newUpdateDate = oldUpdateDate;
+    else
+       newUpdateDate = time(0);
+    code = AFSVolSetDate(toconn,totid, newCreateDate);
     if (code) {
-       fprintf(STDERR, "Could not set the date on %lu\n",
-               (unsigned long)pvolid);
+       fprintf(STDERR, "Could not set the 'creation' date on %u\n", pvolid);
+       error = code;
+       goto refail;
+    }
+
+    init_volintInfo(&vinfo);
+    vinfo.creationDate = newCreateDate;
+    vinfo.updateDate = newUpdateDate;
+    code = AFSVolSetInfo(toconn, totid, &vinfo);
+    if (code) {
+       fprintf(STDERR, "Could not set the 'last updated' date on %u\n",
+               pvolid);
        error = code;
        goto refail;
     }
@@ -3929,7 +4697,7 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     fprintf(STDOUT, " done\n");
     fflush(STDOUT);
     if (success && (!reuseID || (flags & RV_FULLRST))) {
-       /* Volume was restored on the file server, update the 
+       /* Volume was restored on the file server, update the
         * VLDB to reflect the change.
         */
        vcode = VLDB_GetEntryByID(pvolid, voltype, &entry);
@@ -3957,7 +4725,7 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
                entry.volumeId[ROVOL] = tstatus.cloneID;        /*this should come from status info on the volume if non zero */
            } else
                entry.volumeId[ROVOL] = INVALID_BID;
-           entry.volumeId[RWVOL] = pvolid;
+           entry.volumeId[RWVOL] = pparentid;
            entry.cloneId = 0;
            if (tstatus.backupID != 0) {
                entry.volumeId[BACKVOL] = tstatus.backupID;
@@ -3984,7 +4752,7 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
                fprintf(STDOUT, "------- New entry -------\n");
            }
            vcode =
-               ubik_Call(VL_SetLock, cstruct, 0, pvolid, voltype,
+               ubik_VL_SetLock(cstruct, 0, pvolid, voltype,
                          VLOP_RESTORE);
            if (vcode) {
                fprintf(STDERR,
@@ -4015,60 +4783,70 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
                same =
                    VLDB_IsSameAddrs(toserver, entry.serverNumber[index],
                                     &errcode);
-               EPRINT2(errcode,
-                       "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
-                       toserver, errcode);
+               if (errcode)
+                   EPRINT2(errcode,
+                           "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
+                           toserver, errcode);
                if ((!errcode && !same)
                    || (entry.serverPartition[index] != topart)) {
-                   tempconn =
-                       UV_Bind(entry.serverNumber[index],
-                               AFSCONF_VOLUMEPORT);
-
-                   MapPartIdIntoName(entry.serverPartition[index],
-                                     apartName);
-                   VPRINT3
-                       ("Deleting the previous volume %u on server %s, partition %s ...",
-                        pvolid,
-                        hostutil_GetNameByINet(entry.serverNumber[index]),
-                        apartName);
-                   code =
-                       AFSVolTransCreate(tempconn, pvolid,
-                                         entry.serverPartition[index],
-                                         ITOffline, &temptid);
-                   if (!code) {
+                   if (flags & RV_NODEL) {
+                       VPRINT2
+                           ("Not deleting the previous volume %u on server %s, ...",
+                            pvolid,
+                             noresolve ? afs_inet_ntoa_r(entry.serverNumber[index], hoststr) :
+                            hostutil_GetNameByINet(entry.serverNumber[index]));
+                   } else {
+                       tempconn =
+                           UV_Bind(entry.serverNumber[index],
+                                   AFSCONF_VOLUMEPORT);
+
+                       MapPartIdIntoName(entry.serverPartition[index],
+                                         apartName);
+                       VPRINT3
+                           ("Deleting the previous volume %u on server %s, partition %s ...",
+                            pvolid,
+                             noresolve ? afs_inet_ntoa_r(entry.serverNumber[index], hoststr) :
+                            hostutil_GetNameByINet(entry.serverNumber[index]),
+                            apartName);
                        code =
-                           AFSVolSetFlags(tempconn, temptid,
-                                          VTDeleteOnSalvage |
-                                          VTOutOfService);
-                       if (code) {
-                           fprintf(STDERR,
-                                   "Could not set flags on volume %lu on the older site\n",
-                                   (unsigned long)pvolid);
-                           error = code;
-                           goto refail;
-                       }
-                       code = AFSVolDeleteVolume(tempconn, temptid);
-                       if (code) {
-                           fprintf(STDERR,
-                                   "Could not delete volume %lu on the older site\n",
-                                   (unsigned long)pvolid);
-                           error = code;
-                           goto refail;
-                       }
-                       code = AFSVolEndTrans(tempconn, temptid, &rcode);
-                       temptid = 0;
-                       if (!code)
-                           code = rcode;
-                       if (code) {
-                           fprintf(STDERR,
-                                   "Could not end transaction on volume %lu on the older site\n",
-                                   (unsigned long)pvolid);
-                           error = code;
-                           goto refail;
+                           AFSVolTransCreate_retry(tempconn, pvolid,
+                                             entry.serverPartition[index],
+                                             ITOffline, &temptid);
+                       if (!code) {
+                           code =
+                               AFSVolSetFlags(tempconn, temptid,
+                                              VTDeleteOnSalvage |
+                                              VTOutOfService);
+                           if (code) {
+                               fprintf(STDERR,
+                                       "Could not set flags on volume %lu on the older site\n",
+                                       (unsigned long)pvolid);
+                               error = code;
+                               goto refail;
+                           }
+                           code = AFSVolDeleteVolume(tempconn, temptid);
+                           if (code) {
+                               fprintf(STDERR,
+                                       "Could not delete volume %lu on the older site\n",
+                                       (unsigned long)pvolid);
+                               error = code;
+                               goto refail;
+                           }
+                           code = AFSVolEndTrans(tempconn, temptid, &rcode);
+                           temptid = 0;
+                           if (!code)
+                               code = rcode;
+                           if (code) {
+                               fprintf(STDERR,
+                                       "Could not end transaction on volume %lu on the older site\n",
+                                       (unsigned long)pvolid);
+                               error = code;
+                               goto refail;
+                           }
+                           VDONE;
+                           MapPartIdIntoName(entry.serverPartition[index],
+                                             partName);
                        }
-                       VDONE;
-                       MapPartIdIntoName(entry.serverPartition[index],
-                                         partName);
                    }
                }
                entry.serverNumber[index] = toserver;
@@ -4103,7 +4881,7 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     }
     if (islocked) {
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, pvolid, voltype,
+           ubik_VL_ReleaseLock(cstruct, 0, pvolid, voltype,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
            fprintf(STDERR,
@@ -4143,18 +4921,26 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     return error;
 }
 
-
-/*unlocks the vldb entry associated with <volid> */
 int
-UV_LockRelease(afs_int32 volid)
+UV_RestoreVolume(afs_uint32 toserver, afs_int32 topart, afs_uint32 tovolid,
+                char tovolname[], int flags,
+                afs_int32(*WriteData) (struct rx_call *, void *),
+                void *rock)
 {
+    return UV_RestoreVolume2(toserver, topart, tovolid, 0, tovolname, flags,
+                            WriteData, rock);
+}
 
 
+/*unlocks the vldb entry associated with <volid> */
+int
+UV_LockRelease(afs_uint32 volid)
+{
     afs_int32 vcode;
 
     VPRINT("Binding to the VLDB server\n");
     vcode =
-       ubik_Call(VL_ReleaseLock, cstruct, 0, volid, -1,
+       ubik_VL_ReleaseLock(cstruct, 0, volid, -1,
                  LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
     if (vcode) {
        fprintf(STDERR,
@@ -4168,17 +4954,26 @@ UV_LockRelease(afs_int32 volid)
 
 }
 
+/* old interface to add rosites */
+int
+UV_AddSite(afs_uint32 server, afs_int32 part, afs_uint32 volid,
+          afs_int32 valid)
+{
+    return UV_AddSite2(server, part, volid, 0, valid);
+}
+
 /*adds <server> and <part> as a readonly replication site for <volid>
 *in vldb */
 int
-UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid)
+UV_AddSite2(afs_uint32 server, afs_int32 part, afs_uint32 volid,
+           afs_uint32 rovolid, afs_int32 valid)
 {
     int j, nro = 0, islocked = 0;
-    struct nvldbentry entry, storeEntry;
+    struct nvldbentry entry, storeEntry, entry2;
     afs_int32 vcode, error = 0;
     char apartName[10];
 
-    error = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
+    error = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
     if (error) {
        fprintf(STDERR,
                " Could not lock the VLDB entry for the volume %lu \n",
@@ -4241,10 +5036,33 @@ UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid)
        goto asfail;
     }
 
+    /* if rovolid == 0, we leave the RO volume id alone. If the volume doesn't
+     * have an RO volid at this point (i.e. entry.volumeId[ROVOL] ==
+     * INVALID_BID) and we leave it alone, it gets an RO volid at release-time.
+     */
+    if (rovolid) {
+       if (entry.volumeId[ROVOL] == INVALID_BID) {
+           vcode = VLDB_GetEntryByID(rovolid, -1, &entry2);
+           if (!vcode) {
+               fprintf(STDERR, "Volume ID %d already exists\n", rovolid);
+               return VVOLEXISTS;
+           }
+           VPRINT1("Using RO volume id %d.\n", rovolid);
+           entry.volumeId[ROVOL] = rovolid;
+       } else {
+           fprintf(STDERR, "Ignoring given RO id %d, since volume already has RO id %d\n",
+               rovolid, entry.volumeId[ROVOL]);
+       }
+    }
+
     VPRINT("Adding a new site ...");
     entry.serverNumber[entry.nServers] = server;
     entry.serverPartition[entry.nServers] = part;
-    entry.serverFlags[entry.nServers] = (ITSROVOL | RO_DONTUSE);
+    if (!valid) {
+       entry.serverFlags[entry.nServers] = (ITSROVOL | RO_DONTUSE);
+    } else {
+       entry.serverFlags[entry.nServers] = (ITSROVOL);
+    }
     entry.nServers++;
 
     MapNetworkToHost(&entry, &storeEntry);
@@ -4262,7 +5080,7 @@ UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid)
   asfail:
     if (islocked) {
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
            fprintf(STDERR,
@@ -4278,20 +5096,18 @@ UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid)
 
 /*removes <server> <part> as read only site for <volid> from the vldb */
 int
-UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
+UV_RemoveSite(afs_uint32 server, afs_int32 part, afs_uint32 volid)
 {
     afs_int32 vcode;
     struct nvldbentry entry, storeEntry;
-    int islocked;
 
-    vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
+    vcode = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
     if (vcode) {
        fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
                (unsigned long)volid);
        PrintError("", vcode);
        return (vcode);
     }
-    islocked = 1;
     vcode = VLDB_GetEntryByID(volid, RWVOL, &entry);
     if (vcode) {
        fprintf(STDERR,
@@ -4305,13 +5121,13 @@ UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
        /*this site doesnot exist  */
        fprintf(STDERR, "This site is not a replication site \n");
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
            fprintf(STDERR, "Could not update entry for volume %lu \n",
                    (unsigned long)volid);
            PrintError("", vcode);
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
            return (vcode);
        }
@@ -4324,7 +5140,7 @@ UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
        if (entry.nServers < 1) {       /*this is the last ref */
            VPRINT1("Deleting the VLDB entry for %u ...", volid);
            fflush(STDOUT);
-           vcode = ubik_Call(VL_DeleteEntry, cstruct, 0, volid, ROVOL);
+           vcode = ubik_VL_DeleteEntry(cstruct, 0, volid, ROVOL);
            if (vcode) {
                fprintf(STDERR,
                        "Could not delete VLDB entry for volume %lu \n",
@@ -4347,7 +5163,7 @@ UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
                    "Could not release lock on volume entry for %lu \n",
                    (unsigned long)volid);
            PrintError("", vcode);
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
            return (vcode);
        }
@@ -4358,13 +5174,13 @@ UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
 
 /*sets <server> <part> as read/write site for <volid> in the vldb */
 int
-UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 volid)
+UV_ChangeLocation(afs_uint32 server, afs_int32 part, afs_uint32 volid)
 {
     afs_int32 vcode;
     struct nvldbentry entry, storeEntry;
     int index;
 
-    vcode = ubik_Call(VL_SetLock, cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
+    vcode = ubik_VL_SetLock(cstruct, 0, volid, RWVOL, VLOP_ADDSITE);
     if (vcode) {
        fprintf(STDERR, " Could not lock the VLDB entry for volume %lu \n",
                (unsigned long)volid);
@@ -4386,7 +5202,7 @@ UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 volid)
        fprintf(STDERR, "No existing RW site for volume %lu",
                (unsigned long)volid);
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
            fprintf(STDERR,
@@ -4408,7 +5224,7 @@ UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 volid)
            fprintf(STDERR, "Could not update entry for volume %lu \n",
                    (unsigned long)volid);
            PrintError("", vcode);
-           ubik_Call(VL_ReleaseLock, cstruct, 0, volid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, volid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
            return (vcode);
        }
@@ -4419,13 +5235,13 @@ UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 volid)
 
 /*list all the partitions on <aserver> */
 int
-UV_ListPartitions(afs_int32 aserver, struct partList *ptrPartList,
+UV_ListPartitions(afs_uint32 aserver, struct partList *ptrPartList,
                  afs_int32 * cntp)
 {
     struct rx_connection *aconn;
     struct pIDs partIds;
     struct partEntries partEnts;
-    register int i, j = 0, code;
+    int i, j = 0, code;
 
     *cntp = 0;
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
@@ -4477,7 +5293,7 @@ UV_ListPartitions(afs_int32 aserver, struct partList *ptrPartList,
 /*zap the list of volumes specified by volPtrArray (the volCloneId field).
  This is used by the backup system */
 int
-UV_ZapVolumeClones(afs_int32 aserver, afs_int32 apart,
+UV_ZapVolumeClones(afs_uint32 aserver, afs_int32 apart,
                   struct volDescription *volPtr, afs_int32 arraySize)
 {
     struct rx_connection *aconn;
@@ -4496,7 +5312,7 @@ UV_ZapVolumeClones(afs_int32 aserver, afs_int32 apart,
            curPtr->volFlags &= ~CLONEZAPPED;
            success = 1;
            code =
-               AFSVolTransCreate(aconn, curPtr->volCloneId, apart, ITOffline,
+               AFSVolTransCreate_retry(aconn, curPtr->volCloneId, apart, ITOffline,
                                  &tid);
            if (code)
                success = 0;
@@ -4525,10 +5341,10 @@ UV_ZapVolumeClones(afs_int32 aserver, afs_int32 apart,
     return 0;
 }
 
-/*return a list of clones of the volumes specified by volPtrArray. Used by the 
+/*return a list of clones of the volumes specified by volPtrArray. Used by the
  backup system */
 int
-UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart,
+UV_GenerateVolumeClones(afs_uint32 aserver, afs_int32 apart,
                        struct volDescription *volPtr, afs_int32 arraySize)
 {
     struct rx_connection *aconn;
@@ -4538,7 +5354,7 @@ UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart,
     afs_int32 rcode = 0;
     afs_int32 tid;
     int reuseCloneId = 0;
-    afs_int32 curCloneId = 0;
+    afs_uint32 curCloneId = 0;
     char cloneName[256];       /*max vol name */
 
     aconn = (struct rx_connection *)0;
@@ -4548,7 +5364,7 @@ UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart,
        reuseCloneId = 1;
     else {                     /*get a bunch of id's from vldb */
        code =
-           ubik_Call(VL_GetNewVolumeId, cstruct, 0, arraySize, &curCloneId);
+           ubik_VL_GetNewVolumeId(cstruct, 0, arraySize, &curCloneId);
        if (code) {
            fprintf(STDERR, "Could not get ID's for the clone from VLDB\n");
            PrintError("", code);
@@ -4562,7 +5378,7 @@ UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart,
            curPtr->volFlags |= CLONEVALID;
            /*make a clone of curParentId and record as curPtr->volCloneId */
            code =
-               AFSVolTransCreate(aconn, curPtr->volId, apart, ITOffline,
+               AFSVolTransCreate_retry(aconn, curPtr->volId, apart, ITOffline,
                                  &tid);
            if (code)
                VPRINT2("Clone for volume %s %u failed \n", curPtr->volName,
@@ -4616,7 +5432,7 @@ UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart,
 /*list all the volumes on <aserver> and <apart>. If all = 1, then all the
 * relevant fields of the volume are also returned. This is a heavy weight operation.*/
 int
-UV_ListVolumes(afs_int32 aserver, afs_int32 apart, int all,
+UV_ListVolumes(afs_uint32 aserver, afs_int32 apart, int all,
               struct volintInfo **resultPtr, afs_int32 * size)
 {
     struct rx_connection *aconn;
@@ -4680,7 +5496,7 @@ UV_ListVolumes(afs_int32 aserver, afs_int32 apart, int all,
  *------------------------------------------------------------------------*/
 
 int
-UV_XListVolumes(afs_int32 a_serverID, afs_int32 a_partID, int a_all,
+UV_XListVolumes(afs_uint32 a_serverID, afs_int32 a_partID, int a_all,
                struct volintXInfo **a_resultPP,
                afs_int32 * a_numEntsInResultP)
 {
@@ -4728,7 +5544,7 @@ UV_XListVolumes(afs_int32 a_serverID, afs_int32 a_partID, int a_all,
 
 /* get all the information about volume <volid> on <aserver> and <apart> */
 int
-UV_ListOneVolume(afs_int32 aserver, afs_int32 apart, afs_int32 volid,
+UV_ListOneVolume(afs_uint32 aserver, afs_int32 apart, afs_uint32 volid,
                 struct volintInfo **resultPtr)
 {
     struct rx_connection *aconn;
@@ -4787,7 +5603,7 @@ UV_ListOneVolume(afs_int32 aserver, afs_int32 apart, afs_int32 volid,
  *------------------------------------------------------------------------*/
 
 int
-UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_int32 a_volID,
+UV_XListOneVolume(afs_uint32 a_serverID, afs_int32 a_partID, afs_uint32 a_volID,
                  struct volintXInfo **a_resultPP)
 {
     struct rx_connection *rxConnP;     /*Rx connection to Volume Server */
@@ -4830,17 +5646,17 @@ UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_int32 a_volID,
 }
 
 /* CheckVolume()
- *    Given a volume we read from a partition, check if it is 
+ *    Given a volume we read from a partition, check if it is
  *    represented in the VLDB correctly.
- * 
+ *
  *    The VLDB is looked up by the RW volume id (not its name).
  *    The RW contains the true name of the volume (BK and RO set
  *       the name in the VLDB only on creation of the VLDB entry).
  *    We want rules strict enough that when we check all volumes
  *       on one partition, it does not need to be done again. IE:
- *       two volumes on different partitions won't constantly 
+ *       two volumes on different partitions won't constantly
  *       change a VLDB entry away from what the other set.
- *    For RW and BK volumes, we will always check the VLDB to see 
+ *    For RW and BK volumes, we will always check the VLDB to see
  *       if the two exist on the server/partition. May seem redundant,
  *       but this is an easy check of the VLDB. IE: if the VLDB entry
  *       says the BK exists but no BK volume is there, we will detect
@@ -4849,18 +5665,24 @@ UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_int32 a_volID,
  *    Output changed to look a lot like the "vos syncserv" otuput.
  */
 static afs_int32
-CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
-           afs_int32 * modentry, afs_uint32 * maxvolid)
+CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver, afs_int32 apart,
+           afs_int32 * modentry, afs_uint32 * maxvolid,
+            struct nvldbentry *aentry)
 {
-    int idx, j;
+    int idx = 0;
+    int j;
     afs_int32 code, error = 0;
     struct nvldbentry entry, storeEntry;
     char pname[10];
-    int pass = 0, islocked = 0, createentry, addvolume, modified, mod;
-    afs_int32 rwvolid;
+    int pass = 0, createentry, addvolume, modified, mod, doit = 1;
+    afs_uint32 rwvolid;
+    char hoststr[16];
 
-    if (modentry)
+    if (modentry) {
+       if (*modentry == 1)
+           doit = 0;
        *modentry = 0;
+    }
     rwvolid =
        ((volumeinfo->type ==
          RWVOL) ? volumeinfo->volid : volumeinfo->parentID);
@@ -4871,35 +5693,38 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
      * then make the changes to it (pass 2).
      */
     if (++pass == 2) {
-       code = ubik_Call(VL_SetLock, cstruct, 0, rwvolid, RWVOL, VLOP_DELETE);
+       code = ubik_VL_SetLock(cstruct, 0, rwvolid, RWVOL, VLOP_DELETE);
        if (code) {
            fprintf(STDERR, "Could not lock VLDB entry for %lu\n",
                    (unsigned long)rwvolid);
            ERROR_EXIT(code);
        }
-       islocked = 1;
     }
 
     createentry = 0;           /* Do we need to create a VLDB entry */
     addvolume = 0;             /* Add this volume to the VLDB entry */
     modified = 0;              /* The VLDB entry was modified */
 
-    /* Read the entry from VLDB by its RW volume id */
-    code = VLDB_GetEntryByID(rwvolid, RWVOL, &entry);
-    if (code) {
-       if (code != VL_NOENT) {
-           fprintf(STDOUT,
-                   "Could not retreive the VLDB entry for volume %lu \n",
-                   (unsigned long)rwvolid);
-           ERROR_EXIT(code);
-       }
+    if (aentry) {
+       memcpy(&entry, aentry, sizeof(entry));
+    } else {
+       /* Read the entry from VLDB by its RW volume id */
+       code = VLDB_GetEntryByID(rwvolid, RWVOL, &entry);
+       if (code) {
+           if (code != VL_NOENT) {
+               fprintf(STDOUT,
+                       "Could not retreive the VLDB entry for volume %lu \n",
+                       (unsigned long)rwvolid);
+               ERROR_EXIT(code);
+           }
 
-       memset(&entry, 0, sizeof(entry));
-       vsu_ExtractName(entry.name, volumeinfo->name);  /* Store name of RW */
+           memset(&entry, 0, sizeof(entry));
+           vsu_ExtractName(entry.name, volumeinfo->name);      /* Store name of RW */
 
-       createentry = 1;
-    } else {
-       MapHostToNetwork(&entry);
+           createentry = 1;
+       } else {
+           MapHostToNetwork(&entry);
+       }
     }
 
     if (verbose && (pass == 1)) {
@@ -4943,12 +5768,16 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                            fprintf(STDERR,
                                    "*** Warning: Orphaned RW volume %lu exists on %s %s\n",
                                    (unsigned long)rwvolid,
+                                    noresolve ?
+                                    afs_inet_ntoa_r(aserver, hoststr) :
                                    hostutil_GetNameByINet(aserver), pname);
                            MapPartIdIntoName(entry.serverPartition[idx],
                                              pname);
                            fprintf(STDERR,
                                    "    VLDB reports RW volume %lu exists on %s %s\n",
                                    (unsigned long)rwvolid,
+                                    noresolve ?
+                                    afs_inet_ntoa_r(entry.serverNumber[idx], hoststr) :
                                    hostutil_GetNameByINet(entry.
                                                           serverNumber[idx]),
                                    pname);
@@ -4965,6 +5794,8 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                                fprintf(STDERR,
                                        "*** Warning: Orphaned BK volume %u exists on %s %s\n",
                                        entry.volumeId[BACKVOL],
+                                        noresolve ?
+                                        afs_inet_ntoa_r(entry.serverNumber[idx], hoststr) :
                                        hostutil_GetNameByINet(entry.
                                                               serverNumber
                                                               [idx]), pname);
@@ -4972,6 +5803,8 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                                fprintf(STDERR,
                                        "    VLDB reports its RW volume %lu exists on %s %s\n",
                                        (unsigned long)rwvolid,
+                                        noresolve ?
+                                        afs_inet_ntoa_r(aserver, hoststr) :
                                        hostutil_GetNameByINet(aserver),
                                        pname);
                            }
@@ -5042,11 +5875,15 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                        fprintf(STDERR,
                                "*** Warning: Orphaned BK volume %lu exists on %s %s\n",
                                (unsigned long)volumeinfo->volid,
+                                noresolve ?
+                                afs_inet_ntoa_r(aserver, hoststr) :
                                hostutil_GetNameByINet(aserver), pname);
                        MapPartIdIntoName(entry.serverPartition[idx], pname);
                        fprintf(STDERR,
                                "    VLDB reports its RW/BK volume %lu exists on %s %s\n",
                                (unsigned long)rwvolid,
+                                noresolve ?
+                                afs_inet_ntoa_r(entry.serverNumber[idx], hoststr) :
                                hostutil_GetNameByINet(entry.
                                                       serverNumber[idx]),
                                pname);
@@ -5065,6 +5902,8 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                                fprintf(STDERR,
                                        "*** Warning: Orphaned BK volume %u exists on %s %s\n",
                                        entry.volumeId[BACKVOL],
+                                        noresolve ?
+                                        afs_inet_ntoa_r(aserver, hoststr) :
                                        hostutil_GetNameByINet(aserver),
                                        pname);
                                fprintf(STDERR,
@@ -5077,8 +5916,10 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                                                  pname);
                                fprintf(STDERR,
                                        "*** Warning: Orphaned BK volume %lu exists on %s %s\n",
-                                       (unsigned long)volumeinfo->volid,
-                                       hostutil_GetNameByINet(aserver),
+                                        (unsigned long)volumeinfo->volid,
+                                        noresolve ?
+                                        afs_inet_ntoa_r(aserver, hoststr) :
+                                        hostutil_GetNameByINet(aserver),
                                        pname);
                                fprintf(STDERR,
                                        "    VLDB reports its BK volume ID is %u\n",
@@ -5098,7 +5939,7 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
 
            entry.serverNumber[idx] = aserver;
            entry.serverPartition[idx] = apart;
-           entry.serverFlags[idx] = ITSRWVOL;
+           entry.serverFlags[idx] = ITSBACKVOL;
 
            modified++;
        }
@@ -5106,7 +5947,7 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
 
     else if (volumeinfo->type == ROVOL) {      /* A RO volume */
        if (volumeinfo->volid == entry.volumeId[ROVOL]) {
-           /* This is a quick check to see if the RO entry exists in the 
+           /* This is a quick check to see if the RO entry exists in the
             * VLDB so we avoid the CheckVldbRO() call (which checks if each
             * RO volume listed in the VLDB exists).
             */
@@ -5148,7 +5989,9 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                            fprintf(STDERR,
                                    "*** Warning: Orphaned RO volume %u exists on %s %s\n",
                                    entry.volumeId[ROVOL],
-                                   hostutil_GetNameByINet(entry.
+                                    noresolve ?
+                                    afs_inet_ntoa_r(entry.serverNumber[j], hoststr) :
+                                    hostutil_GetNameByINet(entry.
                                                           serverNumber[j]),
                                    pname);
                            fprintf(STDERR,
@@ -5156,7 +5999,7 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                                    (unsigned long)volumeinfo->volid);
                        }
 
-                       Lp_SetRWValue(entry, entry.serverNumber[idx],
+                       Lp_SetRWValue(&entry, entry.serverNumber[idx],
                                      entry.serverPartition[idx], 0L, 0L);
                        entry.nServers--;
                        modified++;
@@ -5175,8 +6018,10 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                    MapPartIdIntoName(apart, pname);
                    fprintf(STDERR,
                            "*** Warning: Orphaned RO volume %lu exists on %s %s\n",
-                           (unsigned long)volumeinfo->volid,
-                           hostutil_GetNameByINet(aserver), pname);
+                            (unsigned long)volumeinfo->volid,
+                            noresolve ?
+                            afs_inet_ntoa_r(aserver, hoststr) :
+                            hostutil_GetNameByINet(aserver), pname);
                    fprintf(STDERR,
                            "    VLDB reports its RO volume ID is %u\n",
                            entry.volumeId[ROVOL]);
@@ -5216,7 +6061,7 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
     if (entry.volumeId[RWVOL] > *maxvolid)
        *maxvolid = entry.volumeId[RWVOL];
 
-    if (modified) {
+    if (modified && doit) {
        MapNetworkToHost(&entry, &storeEntry);
 
        if (createentry) {
@@ -5240,17 +6085,23 @@ CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
                ERROR_EXIT(code);
            }
        }
-       if (modentry)
-           *modentry = modified;
     } else if (pass == 2) {
        code =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, rwvolid, RWVOL,
+           ubik_VL_ReleaseLock(cstruct, 0, rwvolid, RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (code) {
            PrintError("Could not unlock VLDB entry ", code);
        }
     }
 
+    if (modified && modentry) {
+       *modentry = 1;
+    }
+
+    if (aentry) {
+       memcpy(aentry, &entry, sizeof(entry));
+    }
+
     if (verbose) {
        fprintf(STDOUT, "-- status after --\n");
        if (modified)
@@ -5269,7 +6120,7 @@ sortVolumes(const void *a, const void *b)
 {
     volintInfo *v1 = (volintInfo *) a;
     volintInfo *v2 = (volintInfo *) b;
-    afs_int32 rwvolid1, rwvolid2;
+    afs_uint32 rwvolid1, rwvolid2;
 
     rwvolid1 = ((v1->type == RWVOL) ? v1->volid : v1->parentID);
     rwvolid2 = ((v2->type == RWVOL) ? v2->volid : v2->parentID);
@@ -5303,30 +6154,35 @@ sortVolumes(const void *a, const void *b)
  *      if the volume exists on specified servers (similar to syncvldb).
  */
 int
-UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
+UV_SyncVolume(afs_uint32 aserver, afs_int32 apart, char *avolname, int flags)
 {
     struct rx_connection *aconn = 0;
     afs_int32 j, k, code, vcode, error = 0;
-    afs_int32 tverbose, mod, modified = 0;
+    afs_int32 tverbose;
+    afs_int32 mod, modified = 0, deleted = 0;
     struct nvldbentry vldbentry;
-    afs_int32 volumeid = 0;
+    afs_uint32 volumeid = 0;
     volEntries volumeInfo;
     struct partList PartList;
-    afs_int32 pcnt, rv;
-    afs_int32 maxvolid = 0;
+    afs_int32 pcnt;
+    afs_uint32 maxvolid = 0;
 
     volumeInfo.volEntries_val = (volintInfo *) 0;
     volumeInfo.volEntries_len = 0;
 
-    if (!aserver && flags) {
-       /* fprintf(STDERR,"Partition option requires a server option\n"); */
-       ERROR_EXIT(EINVAL);
-    }
-
     /* Turn verbose logging off and do our own verbose logging */
+    /* tverbose must be set before we call ERROR_EXIT() */
+
     tverbose = verbose;
+    if (flags & 2)
+       tverbose = 1;
     verbose = 0;
 
+    if (!aserver && (flags & 1)) {
+       /* fprintf(STDERR,"Partition option requires a server option\n"); */
+       ERROR_EXIT(EINVAL);
+    }
+
     /* Read the VLDB entry */
     vcode = VLDB_GetEntryByName(avolname, &vldbentry);
     if (vcode && (vcode != VL_NOENT)) {
@@ -5351,12 +6207,17 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
        fprintf(STDOUT, "\n");
     }
 
-    /* Verify that all of the VLDB entries exist on the repective servers 
+    /* Verify that all of the VLDB entries exist on the repective servers
      * and partitions (this does not require that avolname be a volume ID).
      * Equivalent to a syncserv.
      */
     if (!vcode) {
-       code = CheckVldb(&vldbentry, &mod);
+       /* Tell CheckVldb not to update if appropriate */
+       if (flags & 2)
+           mod = 1;
+       else
+           mod = 0;
+       code = CheckVldb(&vldbentry, &mod, &deleted);
        if (code) {
            fprintf(STDERR, "Could not process VLDB entry for volume %s\n",
                    vldbentry.name);
@@ -5369,7 +6230,7 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
     /* If aserver is given, we will search for the desired volume on it */
     if (aserver) {
        /* Generate array of partitions on the server that we will check */
-       if (!flags) {
+       if (!(flags & 1)) {
            code = UV_ListPartitions(aserver, &PartList, &pcnt);
            if (code) {
                fprintf(STDERR,
@@ -5395,10 +6256,14 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
                        ERROR_EXIT(code);
                    }
                } else {
+                   if (flags & 2)
+                       mod = 1;
+                   else
+                       mod = 0;
                    /* Found one, sync it with VLDB entry */
                    code =
                        CheckVolume(volumeInfo.volEntries_val, aserver,
-                                   PartList.partId[j], &mod, &maxvolid);
+                                   PartList.partId[j], &mod, &maxvolid, &vldbentry);
                    if (code)
                        ERROR_EXIT(code);
                    if (mod)
@@ -5415,21 +6280,7 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
        /* Check to see if the RW, BK, and RO IDs exist on any
         * partitions. We get the volume IDs from the VLDB.
         */
-       rv = 1;                 /* Read the VLDB entry ? */
        for (j = 0; j < MAXTYPES; j++) {        /* for RW, RO, and BK IDs */
-           if (rv) {
-               vcode = VLDB_GetEntryByName(avolname, &vldbentry);
-               if (vcode) {
-                   if (vcode == VL_NOENT)
-                       break;
-                   fprintf(STDERR,
-                           "Could not access the VLDB for volume %s\n",
-                           avolname);
-                   ERROR_EXIT(vcode);
-               }
-               rv = 0;
-           }
-
            if (vldbentry.volumeId[j] == 0)
                continue;
 
@@ -5445,14 +6296,18 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
                        ERROR_EXIT(code);
                    }
                } else {
+                   if (flags & 2)
+                       mod = 1;
+                   else
+                       mod = 0;
                    /* Found one, sync it with VLDB entry */
                    code =
                        CheckVolume(volumeInfo.volEntries_val, aserver,
-                                   PartList.partId[k], &mod, &maxvolid);
+                                   PartList.partId[k], &mod, &maxvolid, &vldbentry);
                    if (code)
                        ERROR_EXIT(code);
                    if (mod)
-                       modified++, rv++;
+                       modified++;
                }
 
                if (volumeInfo.volEntries_val)
@@ -5467,13 +6322,7 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
     /* If verbose output, print a summary of what changed */
     if (tverbose) {
        fprintf(STDOUT, "-- status after --\n");
-       code = VLDB_GetEntryByName(avolname, &vldbentry);
-       if (code && (code != VL_NOENT)) {
-           fprintf(STDERR, "Could not access the VLDB for volume %s\n",
-                   avolname);
-           ERROR_EXIT(code);
-       }
-       if (modified && (code == VL_NOENT)) {
+       if (deleted) {
            fprintf(STDOUT, "\n**entry deleted**\n");
        } else if (modified) {
            EnumerateEntry(&vldbentry);
@@ -5486,8 +6335,8 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
   error_exit:
     /* Now check if the maxvolid is larger than that stored in the VLDB */
     if (maxvolid) {
-       afs_int32 maxvldbid = 0;
-       code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid);
+       afs_uint32 maxvldbid = 0;
+       code = ubik_VL_GetNewVolumeId(cstruct, 0, 0, &maxvldbid);
        if (code) {
            fprintf(STDERR,
                    "Could not get the highest allocated volume id from the VLDB\n");
@@ -5496,7 +6345,7 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
        } else if (maxvolid > maxvldbid) {
            afs_uint32 id, nid;
            id = maxvolid - maxvldbid + 1;
-           code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid);
+           code = ubik_VL_GetNewVolumeId(cstruct, 0, id, &nid);
            if (code) {
                fprintf(STDERR,
                        "Error in increasing highest allocated volume id in VLDB\n");
@@ -5527,11 +6376,12 @@ UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
  *      optionally, <apart>.
  */
 int
-UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
+UV_SyncVldb(afs_uint32 aserver, afs_int32 apart, int flags, int force)
 {
     struct rx_connection *aconn;
     afs_int32 code, error = 0;
-    int i, j, pfail;
+    int i, pfail;
+    unsigned int j;
     volEntries volumeInfo;
     struct partList PartList;
     afs_int32 pcnt;
@@ -5540,6 +6390,7 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
     afs_int32 failures = 0, modifications = 0, tentries = 0;
     afs_int32 modified;
     afs_uint32 maxvolid = 0;
+    char hoststr[16];
 
     volumeInfo.volEntries_val = (volintInfo *) 0;
     volumeInfo.volEntries_len = 0;
@@ -5547,7 +6398,7 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
 
     /* Generate array of partitions to check */
-    if (!flags) {
+    if (!(flags & 1)) {
        code = UV_ListPartitions(aserver, &PartList, &pcnt);
        if (code) {
            fprintf(STDERR,
@@ -5591,11 +6442,17 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
                fprintf(STDOUT,
                        "Processing volume entry %d: %s (%lu) on server %s %s...\n",
                        j + 1, vi->name, (unsigned long)vi->volid,
-                       hostutil_GetNameByINet(aserver), pname);
+                        noresolve ?
+                        afs_inet_ntoa_r(aserver, hoststr) :
+                        hostutil_GetNameByINet(aserver), pname);
                fflush(STDOUT);
            }
 
-           code = CheckVolume(vi, aserver, apart, &modified, &maxvolid);
+           if (flags & 2)
+               modified = 1;
+           else
+               modified = 0;
+           code = CheckVolume(vi, aserver, apart, &modified, &maxvolid, NULL);
            if (code) {
                PrintError("", code);
                failures++;
@@ -5616,7 +6473,9 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
        if (pfail) {
            fprintf(STDERR,
                    "Could not process entries on server %s partition %s\n",
-                   hostutil_GetNameByINet(aserver), pname);
+                    noresolve ?
+                    afs_inet_ntoa_r(aserver, hoststr) :
+                    hostutil_GetNameByINet(aserver), pname);
        }
        if (volumeInfo.volEntries_val) {
            free(volumeInfo.volEntries_val);
@@ -5625,14 +6484,19 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
 
     }                          /* thru all partitions */
 
-    VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n", tentries,
-           failures, modifications);
+    if (flags & 2) {
+       VPRINT3("Total entries: %u, Failed to process %d, Would change %d\n",
+               tentries, failures, modifications);
+    } else {
+       VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n",
+               tentries, failures, modifications);
+    }
 
   error_exit:
     /* Now check if the maxvolid is larger than that stored in the VLDB */
     if (maxvolid) {
        afs_uint32 maxvldbid = 0;
-       code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 0, &maxvldbid);
+       code = ubik_VL_GetNewVolumeId(cstruct, 0, 0, &maxvldbid);
        if (code) {
            fprintf(STDERR,
                    "Could not get the highest allocated volume id from the VLDB\n");
@@ -5641,7 +6505,7 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
        } else if (maxvolid > maxvldbid) {
            afs_uint32 id, nid;
            id = maxvolid - maxvldbid + 1;
-           code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, id, &nid);
+           code = ubik_VL_GetNewVolumeId(cstruct, 0, id, &nid);
            if (code) {
                fprintf(STDERR,
                        "Error in increasing highest allocated volume id in VLDB\n");
@@ -5667,7 +6531,7 @@ UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
  *      still exists - so we catch these error codes.
  */
 afs_int32
-VolumeExists(afs_int32 server, afs_int32 partition, afs_int32 volumeid)
+VolumeExists(afs_uint32 server, afs_int32 partition, afs_uint32 volumeid)
 {
     struct rx_connection *conn = (struct rx_connection *)0;
     afs_int32 code = -1;
@@ -5697,6 +6561,7 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
     int idx;
     afs_int32 code, error = 0;
     char pname[10];
+    char hoststr[16];
 
     if (modified)
        *modified = 0;
@@ -5731,7 +6596,9 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
                fprintf(STDERR,
                        "Transaction call failed for RW volume %u on server %s %s\n",
                        entry->volumeId[RWVOL],
-                       hostutil_GetNameByINet(entry->serverNumber[idx]),
+                        noresolve ?
+                        afs_inet_ntoa_r(entry->serverNumber[idx], hoststr) :
+                        hostutil_GetNameByINet(entry->serverNumber[idx]),
                        pname);
                ERROR_EXIT(code);
            }
@@ -5768,7 +6635,9 @@ CheckVldbRWBK(struct nvldbentry * entry, afs_int32 * modified)
                fprintf(STDERR,
                        "Transaction call failed for BK volume %u on server %s %s\n",
                        entry->volumeId[BACKVOL],
-                       hostutil_GetNameByINet(entry->serverNumber[idx]),
+                        noresolve ?
+                        afs_inet_ntoa_r(entry->serverNumber[idx], hoststr) :
+                        hostutil_GetNameByINet(entry->serverNumber[idx]),
                        pname);
                ERROR_EXIT(code);
            }
@@ -5799,12 +6668,13 @@ CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified)
     int foundro = 0, modentry = 0;
     afs_int32 code, error = 0;
     char pname[10];
+    char hoststr[16];
 
     if (modified)
        *modified = 0;
 
     /* Check to see if the RO volumes exist and set the RO_EXISTS
-     * flag accordingly. 
+     * flag accordingly.
      */
     for (idx = 0; idx < entry->nServers; idx++) {
        if (!(entry->serverFlags[idx] & ITSROVOL)) {
@@ -5827,7 +6697,9 @@ CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified)
            fprintf(STDERR,
                    "Transaction call failed for RO %u on server %s %s\n",
                    entry->volumeId[ROVOL],
-                   hostutil_GetNameByINet(entry->serverNumber[idx]), pname);
+                    noresolve ?
+                    afs_inet_ntoa_r(entry->serverNumber[idx], hoststr) :
+                    hostutil_GetNameByINet(entry->serverNumber[idx]), pname);
            ERROR_EXIT(code);
        }
     }
@@ -5854,15 +6726,18 @@ CheckVldbRO(struct nvldbentry *entry, afs_int32 * modified)
  *      Ensure that <entry> matches with the info on file servers
  */
 afs_int32
-CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
+CheckVldb(struct nvldbentry * entry, afs_int32 * modified, afs_int32 * deleted)
 {
     afs_int32 code, error = 0;
     struct nvldbentry storeEntry;
     int islocked = 0, mod, modentry, delentry = 0;
-    int pass = 0;
+    int pass = 0, doit=1;
 
-    if (modified)
+    if (modified) {
+       if (*modified == 1)
+           doit = 0;
        *modified = 0;
+    }
     if (verbose) {
        fprintf(STDOUT, "_______________________________\n");
        fprintf(STDOUT, "\n-- status before -- \n");
@@ -5884,7 +6759,7 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
      */
     if (++pass == 2) {
        code =
-           ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL,
+           ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL,
                      VLOP_DELETE);
        if (code) {
            fprintf(STDERR, "Could not lock VLDB entry for %u \n",
@@ -5909,7 +6784,7 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
     code = CheckVldbRWBK(entry, &mod);
     if (code)
        ERROR_EXIT(code);
-    if (mod && (pass == 1))
+    if (mod && (pass == 1) && doit)
        goto retry;
     if (mod)
        modentry++;
@@ -5918,23 +6793,23 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
     code = CheckVldbRO(entry, &mod);
     if (code)
        ERROR_EXIT(code);
-    if (mod && (pass == 1))
+    if (mod && (pass == 1) && doit)
        goto retry;
     if (mod)
        modentry++;
 
-    /* The VLDB entry has been updated. If it as been modified, then 
+    /* The VLDB entry has been updated. If it as been modified, then
      * write the entry back out the the VLDB.
      */
-    if (modentry) {
+    if (modentry && doit) {
        if (pass == 1)
            goto retry;
 
        if (!(entry->flags & RW_EXISTS) && !(entry->flags & BACK_EXISTS)
-           && !(entry->flags & RO_EXISTS)) {
+           && !(entry->flags & RO_EXISTS) && doit) {
            /* The RW, BK, nor RO volumes do not exist. Delete the VLDB entry */
            code =
-               ubik_Call(VL_DeleteEntry, cstruct, 0, entry->volumeId[RWVOL],
+               ubik_VL_DeleteEntry(cstruct, 0, entry->volumeId[RWVOL],
                          RWVOL);
            if (code) {
                fprintf(STDERR,
@@ -5956,11 +6831,16 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
                ERROR_EXIT(code);
            }
        }
-       if (modified)
-           *modified = 1;
        islocked = 0;
     }
 
+    if (modified && modentry) {
+       *modified = 1;
+    }
+    if (deleted && delentry) {
+       *deleted = 1;
+    }
+
     if (verbose) {
        fprintf(STDOUT, "-- status after --\n");
        if (delentry)
@@ -5976,7 +6856,7 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
 
     if (islocked) {
        code =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL],
+           ubik_VL_ReleaseLock(cstruct, 0, entry->volumeId[RWVOL],
                      RWVOL,
                      (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
        if (code) {
@@ -5994,7 +6874,7 @@ CheckVldb(struct nvldbentry * entry, afs_int32 * modified)
  *      Synchronise <aserver> <apart>(if flags = 1) with the VLDB.
  */
 int
-UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
+UV_SyncServer(afs_uint32 aserver, afs_int32 apart, int flags, int force)
 {
     struct rx_connection *aconn;
     afs_int32 code, error = 0;
@@ -6005,12 +6885,15 @@ UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
     struct nvldbentry *vlentry;
     afs_int32 si, nsi, j;
 
+    if (flags & 2)
+       verbose = 1;
+
     aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
 
     /* Set up attributes to search VLDB  */
     attributes.server = ntohl(aserver);
     attributes.Mask = VLLIST_SERVER;
-    if (flags) {
+    if ((flags & 1)) {
        attributes.partition = apart;
        attributes.Mask |= VLLIST_PARTITION;
     }
@@ -6041,7 +6924,12 @@ UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
 
            VPRINT1("Processing VLDB entry %d ...\n", j + 1);
 
-           code = CheckVldb(vlentry, &modified);
+           /* Tell CheckVldb not to update if appropriate */
+           if (flags & 2)
+               modified = 1;
+           else
+               modified = 0;
+           code = CheckVldb(vlentry, &modified, NULL);
            if (code) {
                PrintError("", code);
                fprintf(STDERR,
@@ -6067,8 +6955,13 @@ UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
        }
     }
 
-    VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n", tentries,
-           failures, modifications);
+    if (flags & 2) {
+       VPRINT3("Total entries: %u, Failed to process %d, Would change %d\n",
+               tentries, failures, modifications);
+    } else {
+       VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n",
+               tentries, failures, modifications);
+    }
 
   error_exit:
     if (aconn)
@@ -6081,7 +6974,7 @@ UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
     return error;
 }
 
-/*rename volume <oldname> to <newname>, changing the names of the related 
+/*rename volume <oldname> to <newname>, changing the names of the related
  *readonly and backup volumes. This operation is also idempotent.
  *salvager is capable of recovering from rename operation stopping halfway.
  *to recover run syncserver on the affected machines,it will force renaming to completion. name clashes should have been detected before calling this proc */
@@ -6095,13 +6988,14 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
     afs_int32 tid;
     struct rx_connection *aconn;
     int islocked;
+    char hoststr[16];
 
     error = 0;
     aconn = (struct rx_connection *)0;
     tid = 0;
     islocked = 0;
 
-    vcode = ubik_Call(VL_SetLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);    /*last param is dummy */
+    vcode = ubik_VL_SetLock(cstruct, 0, entry->volumeId[RWVOL], RWVOL, VLOP_ADDSITE);  /*last param is dummy */
     if (vcode) {
        fprintf(STDERR,
                " Could not lock the VLDB entry for the  volume %u \n",
@@ -6120,7 +7014,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
        goto rvfail;
     }
     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 
+    /*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) {
        index = Lp_GetRwIndex(entry);
@@ -6134,7 +7028,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
        }
        aconn = UV_Bind(entry->serverNumber[index], AFSCONF_VOLUMEPORT);
        code =
-           AFSVolTransCreate(aconn, entry->volumeId[RWVOL],
+           AFSVolTransCreate_retry(aconn, entry->volumeId[RWVOL],
                              entry->serverPartition[index], ITOffline, &tid);
        if (code) {             /*volume doesnot exist */
            fprintf(STDERR,
@@ -6184,7 +7078,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
        }
        aconn = UV_Bind(entry->serverNumber[index], AFSCONF_VOLUMEPORT);
        code =
-           AFSVolTransCreate(aconn, entry->volumeId[BACKVOL],
+           AFSVolTransCreate_retry(aconn, entry->volumeId[BACKVOL],
                              entry->serverPartition[index], ITOffline, &tid);
        if (code) {             /*volume doesnot exist */
            fprintf(STDERR,
@@ -6234,7 +7128,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
            if (entry->serverFlags[i] & ITSROVOL) {
                aconn = UV_Bind(entry->serverNumber[i], AFSCONF_VOLUMEPORT);
                code =
-                   AFSVolTransCreate(aconn, entry->volumeId[ROVOL],
+                   AFSVolTransCreate_retry(aconn, entry->volumeId[ROVOL],
                                      entry->serverPartition[i], ITOffline,
                                      &tid);
                if (code) {     /*volume doesnot exist */
@@ -6259,7 +7153,9 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
                    if (!code) {
                        VPRINT2("Renamed RO volume %s on host %s\n",
                                nameBuffer,
-                               hostutil_GetNameByINet(entry->
+                                noresolve ?
+                                afs_inet_ntoa_r(entry->serverNumber[i], hoststr) :
+                                hostutil_GetNameByINet(entry->
                                                       serverNumber[i]));
                        code = AFSVolEndTrans(aconn, tid, &rcode);
                        tid = 0;
@@ -6287,7 +7183,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
   rvfail:
     if (islocked) {
        vcode =
-           ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL],
+           ubik_VL_ReleaseLock(cstruct, 0, entry->volumeId[RWVOL],
                      RWVOL,
                      LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
        if (vcode) {
@@ -6317,7 +7213,7 @@ UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
 
 /*report on all the active transactions on volser */
 int
-UV_VolserStatus(afs_int32 server, transDebugInfo ** rpntr, afs_int32 * rcount)
+UV_VolserStatus(afs_uint32 server, transDebugInfo ** rpntr, afs_int32 * rcount)
 {
     struct rx_connection *aconn;
     transDebugEntries transInfo;
@@ -6349,7 +7245,7 @@ UV_VolserStatus(afs_int32 server, transDebugInfo ** rpntr, afs_int32 * rcount)
 
 /*delete the volume without interacting with the vldb */
 int
-UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid)
+UV_VolumeZap(afs_uint32 server, afs_int32 part, afs_uint32 volid)
 {
     afs_int32 rcode, ttid, error, code;
     struct rx_connection *aconn;
@@ -6359,7 +7255,7 @@ UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid)
     ttid = 0;
 
     aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
-    code = AFSVolTransCreate(aconn, volid, part, ITOffline, &ttid);
+    code = AFSVolTransCreate_retry(aconn, volid, part, ITOffline, &ttid);
     if (code) {
        fprintf(STDERR, "Could not start transaction on volume %lu\n",
                (unsigned long)volid);
@@ -6398,7 +7294,7 @@ UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid)
 }
 
 int
-UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid,
+UV_SetVolume(afs_uint32 server, afs_int32 partition, afs_uint32 volid,
             afs_int32 transflag, afs_int32 setflag, int sleeptime)
 {
     struct rx_connection *conn = 0;
@@ -6411,7 +7307,7 @@ UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid,
        ERROR_EXIT(-1);
     }
 
-    code = AFSVolTransCreate(conn, volid, partition, transflag, &tid);
+    code = AFSVolTransCreate_retry(conn, volid, partition, transflag, &tid);
     if (code) {
        fprintf(STDERR, "SetVolumeStatus: TransCreate Failed\n");
        ERROR_EXIT(code);
@@ -6448,7 +7344,7 @@ UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid,
 }
 
 int
-UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 volid,
+UV_SetVolumeInfo(afs_uint32 server, afs_int32 partition, afs_uint32 volid,
                 volintInfo * infop)
 {
     struct rx_connection *conn = 0;
@@ -6461,7 +7357,7 @@ UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 volid,
        ERROR_EXIT(-1);
     }
 
-    code = AFSVolTransCreate(conn, volid, partition, ITOffline, &tid);
+    code = AFSVolTransCreate_retry(conn, volid, partition, ITOffline, &tid);
     if (code) {
        fprintf(STDERR, "SetVolumeInfo: TransCreate Failed\n");
        ERROR_EXIT(code);
@@ -6490,7 +7386,7 @@ UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 volid,
 }
 
 int
-UV_GetSize(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+UV_GetSize(afs_uint32 afromvol, afs_uint32 afromserver, afs_int32 afrompart,
           afs_int32 fromdate, struct volintSize *vol_size)
 {
     struct rx_connection *aconn = (struct rx_connection *)0;
@@ -6502,7 +7398,7 @@ UV_GetSize(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
     aconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
 
     VPRINT1("Starting transaction on volume %u...", afromvol);
-    code = AFSVolTransCreate(aconn, afromvol, afrompart, ITBusy, &tid);
+    code = AFSVolTransCreate_retry(aconn, afromvol, afrompart, ITBusy, &tid);
     EGOTO1(error_exit, code,
           "Could not start transaction on the volume %u to be measured\n",
           afromvol);