#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <string.h>
#ifdef AFS_AIX_ENV
#include <sys/statfs.h>
#endif
#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>
#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>
-
-afs_int32 VolumeExists(), CheckVldbRWBK(), CheckVldb();
+#include "volser_prototypes.h"
+#include "vsutils_prototypes.h"
+#include "lockprocs_prototypes.h"
struct ubik_client *cstruct;
-int verbose = 0;
-extern int VL_GetNewVolumeId();
-extern int VL_SetLock();
-extern int VL_ReleaseLock();
-extern int VL_DeleteEntry();
-
-void MapNetworkToHost();
-void MapHostToNetwork();
+int verbose = 0, noresolve = 0;
struct release {
- afs_int32 time;
+ afs_uint32 crtime;
+ afs_uint32 uptime;
afs_int32 vldbEntryIndex;
};
{ 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); } }
/* Protos for static routines */
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);
+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_int32 * crtimePtr, afs_int32 * uptimePtr);
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,
afs_int32 apart, afs_int32 * modentry,
afs_uint32 * maxvolid);
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;
{
uvindex = aindex;
uvclass = as;
+ return 0;
}
/* bind to volser on <port> <aserver> */
return tc;
}
+static int
+AFSVolCreateVolume_retry(struct rx_connection *z_conn,
+ afs_int32 partition, char *name, afs_int32 type,
+ afs_int32 parent, afs_int32 *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 <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);
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);
int i;
char pname[10];
int isMixed = 0;
+ char hoststr[16];
#ifdef notdef
fprintf(STDOUT, " readWriteID %-10u ", entry->volumeId[RWVOL]);
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");
/* forcibly remove a volume. Very dangerous call */
int
-UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_int32 volid)
+UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_uint32 volid)
{
register struct rx_connection *tconn;
register afs_int32 code;
/* like df. Return usage of <pname> on <server> in <partition> */
int
-UV_PartitionInfo(afs_int32 server, char *pname,
- struct diskPartition *partition)
+UV_PartitionInfo64(afs_int32 server, char *pname,
+ struct diskPartition64 *partition)
{
register struct rx_connection *aconn;
- afs_int32 code;
+ 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);
/* old interface to create volume */
int
UV_CreateVolume(afs_int32 aserver, afs_int32 apart, char *aname,
- afs_int32 * anewid)
+ afs_uint32 * anewid)
{
afs_int32 code;
code = UV_CreateVolume2(aserver, apart, aname, 5000, 0, 0, 0, 0, anewid);
int
UV_CreateVolume2(afs_int32 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)
{
-
register struct rx_connection *aconn;
afs_int32 tid;
register afs_int32 code;
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);
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 3, anewid);
EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
-
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,
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)
+ afs_uint32 aid)
{
register struct rx_connection *aconn;
afs_int32 error;
* becomes zero
*/
int
-UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
+UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_uint32 avolid)
{
struct rx_connection *aconn = (struct rx_connection *)0;
afs_int32 ttid = 0;
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,
/* 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;
/* 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 ...",
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);
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",
}
/* 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_int32 afromserver, afs_int32 afrompart,
+ afs_int32 atoserver, afs_int32 atopart, int flags)
{
struct rx_connection *toconn, *fromconn;
afs_int32 fromtid, totid, clonetid;
afs_int32 fromDate;
struct restoreCookie cookie;
register afs_int32 vcode, code;
- afs_int32 newVol, volid, backupId;
+ afs_uint32 newVol, volid, backupId;
struct volser_status tstatus;
struct destServer destination;
afs_int32 error;
char in, lf; /* for test code */
int same;
+ char hoststr[16];
#ifdef ENABLE_BUGFIX_1165
volEntries volumeInfo;
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;
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,
pntg = 1;
code =
- AFSVolTransCreate(fromconn, afromvol, afrompart, ITOffline,
- &fromtid);
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITOffline,
+ &fromtid);
+
if (!code) { /* volume exists - delete it */
VPRINT1("Setting flags on leftover source volume %u ...",
afromvol);
/*delete the backup volume now */
fromtid = 0;
code =
- AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline,
- &fromtid);
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
+ &fromtid);
+
if (!code) { /* backup volume exists - delete it */
VPRINT1("Setting flags on leftover backup volume %u ...",
backupId);
* ***/
VPRINT1("Starting transaction on source volume %u ...", afromvol);
- code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
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 = 0;
+ vcode = ubik_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;
- /* 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, &newVol);
+ 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;
* 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);
+ code =
+ AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+ &clonetid);
+ 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
/*
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);
+ code = AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &totid);
if (!code) {
/* Delete the existing volume.
* While we are deleting the volume in these steps, the transaction
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);
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
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 */
VPRINT1("Creating transaction for backup volume %u on source ...",
backupId);
code =
- AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, &fromtid);
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline, &fromtid);
VDONE;
if (!code) {
VPRINT1("Setting flags on backup volume %u on source ...", backupId);
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);
+ code =
+ AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+ &clonetid);
+ 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 */
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");
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);
}
/* 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) {
("Recovery: Creating transaction for destination volume %u ...",
volid);
code =
- AFSVolTransCreate(toconn, volid, atopart, ITOffline, &totid);
+ AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &totid);
if (!code) {
VDONE;
VPRINT1("Recovery: Creating transaction on source volume %u ...",
afromvol);
code =
- AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
&fromtid);
if (!code) {
VDONE;
VPRINT1("Recovery: Creating transaction on backup volume %u ...",
backupId);
code =
- AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline,
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
&fromtid);
if (!code) {
VDONE;
VPRINT1("Recovery: Creating transaction on source volume %u ...",
afromvol);
code =
- AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy,
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
&fromtid);
if (!code) {
VDONE;
VPRINT1("Recovery: Creating transaction on clone volume %u ...",
newVol);
code =
- AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline,
+ AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
&clonetid);
if (!code) {
VDONE;
}
/* 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);
}
-/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
- * <atopart>. The operation is almost idempotent
- */
+int
+UV_MoveVolume(afs_uint32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+ afs_int32 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_int32 afromserver, afs_int32 afrompart,
+ char *atovolname, afs_int32 atoserver, afs_int32 atopart,
+ afs_uint32 atovolid, int flags)
{
struct rx_connection *toconn, *fromconn;
afs_int32 fromtid, totid, clonetid;
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_uint32 cloneVol, newVol;
+ afs_int32 volflag;
struct volser_status tstatus;
struct destServer destination;
* 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);
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+ &fromtid);
+ 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;
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &cloneVol);
+ EGOTO1(mfail, vcode,
"Could not get an ID for the clone of volume %u from the VLDB\n",
afromvol);
- VDONE;
+ 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;
+ 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;
+ }
- /* 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 (!(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");
+ code =
+ AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname,
+ &cloneVol);
+ EGOTO1(mfail, code, "Failed to clone the source volume %u\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;
+ 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,
+ if (!(flags & RV_NOCLONE)) {
+ VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ code =
+ AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
&clonetid);
- EGOTO1(mfail, code,
- "Failed to start a transaction on the cloned volume%u\n",
- cloneVol);
- VDONE;
+ 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;
+ code = AFSVolTransCreate_retry(toconn, newVol, atopart, ITOffline, &totid);
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
VPRINT1("Creating the destination volume %u ...", newVol);
code =
- AFSVolCreateVolume(toconn, atopart, atovolname, volser_RW, newVol,
- &newVol, &totid);
+ AFSVolCreateVolume(toconn, atopart, atovolname,
+ (flags & RV_RDONLY) ? volser_RO : volser_RW,
+ newVol, &newVol, &totid);
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));
"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;
+
+ /***
+ * Now dump the clone to the new volume
+ ***/
-/* 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 */
+ 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 ...",
+ /* 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);
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
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",
+ afromvol);
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;
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);
+ code =
+ AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+ &clonetid);
+ 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 */
VPRINT1("Recovery: Creating transaction on clone volume %u ...",
cloneVol);
code =
- AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline,
+ AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
&clonetid);
if (!code) {
VDONE;
}
+int
+UV_CopyVolume(afs_uint32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+ char *atovolname, afs_int32 atoserver, afs_int32 atopart)
+{
+ return UV_CopyVolume2(afromvol, afromserver, afrompart,
+ atovolname, atoserver, atopart, 0, 0);
+}
*/
int
-UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
+UV_BackupVolume(afs_int32 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;
(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);
- if (code) {
- fprintf(STDERR,
- "Could not lock the VLDB entry for the volume %lu\n",
- (unsigned long)avolid);
- error = code;
- goto bfail;
- }
- vldblocked = 1;
+ 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",
+ (unsigned long)avolid);
+ error = code;
+ goto bfail;
+ }
+ vldblocked = 1;
+
+ /* Reread the vldb entry */
+ code = VLDB_GetEntryByID(avolid, RWVOL, &entry);
+ if (code) {
+ fprintf(STDERR,
+ "Could not fetch the entry for the volume %lu from the VLDB \n",
+ (unsigned long)avolid);
+ error = code;
+ goto bfail;
+ }
+ MapHostToNetwork(&entry);
+ }
+
+ if (!ISNAMEVALID(entry.name)) {
+ fprintf(STDERR, "Name of the volume %s exceeds the size limit\n",
+ entry.name);
+ error = VOLSERBADNAME;
+ goto bfail;
+ }
+
+ backupID = entry.volumeId[BACKVOL];
+ if (backupID == INVALID_BID) {
+ /* Get a backup volume id from the VLDB and update the vldb
+ * entry with it.
+ */
+ 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",
+ (unsigned long)avolid);
+ error = code;
+ goto bfail;
+ }
+ entry.volumeId[BACKVOL] = backupID;
+ vldbmod = 1;
+ }
+
+ /* 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_retry(aconn, backupID, apart, ITOffline, &btid);
+ if (code) {
+ if (code != VNOVOL) {
+ fprintf(STDERR, "Could not reach the backup volume %lu\n",
+ (unsigned long)backupID);
+ 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 backup volume %lu\n",
+ (unsigned long)backupID);
+ 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 backup volume %u ...", backupID);
+
+ code = AFSVolReClone(aconn, ttid, backupID);
+ if (code) {
+ fprintf(STDERR, "Could not re-clone backup volume %lu\n",
+ (unsigned long)backupID);
+ error = code;
+ goto bfail;
+ }
+ } else {
+ VPRINT1("Creating a new backup clone %u ...", backupID);
+
+ strcpy(vname, entry.name);
+ strcat(vname, ".backup");
+
+ code = AFSVolClone(aconn, ttid, 0, backupVolume, vname, &backupID);
+ 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;
+ }
+
+ /* Mork vldb as backup exists */
+ if (!(entry.flags & BACK_EXISTS)) {
+ entry.flags |= BACK_EXISTS;
+ vldbmod = 1;
+ }
+
+ /* Now go back to the backup volume and bring it on line */
+ code = AFSVolTransCreate_retry(aconn, backupID, apart, ITOffline, &btid);
+ if (code) {
+ fprintf(STDERR,
+ "Failed to start a transaction on the backup volume %lu\n",
+ (unsigned long)backupID);
+ error = code;
+ goto bfail;
+ }
+
+ code = AFSVolSetFlags(aconn, btid, 0);
+ if (code) {
+ fprintf(STDERR, "Could not mark the backup volume %lu on line \n",
+ (unsigned long)backupID);
+ error = code;
+ goto bfail;
+ }
+
+ code = AFSVolEndTrans(aconn, btid, &rcode);
+ btid = 0;
+ if (code || rcode) {
+ fprintf(STDERR,
+ "Failed to end the transaction on the backup volume %lu\n",
+ (unsigned long)backupID);
+ error = (code ? code : rcode);
+ goto bfail;
+ }
+
+ VDONE;
+
+ /* 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_int32 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);
- /* Reread the vldb entry */
- code = VLDB_GetEntryByID(avolid, RWVOL, &entry);
+ if (!aname) {
+ volumeInfo.volEntries_val = (volintInfo *) 0;
+ volumeInfo.volEntries_len = 0;
+ code = AFSVolListOneVolume(aconn, apart, avolid, &volumeInfo);
if (code) {
- fprintf(STDERR,
- "Could not fetch the entry for the volume %lu from the VLDB \n",
+ fprintf(stderr, "Could not get info for volume %lu\n",
(unsigned long)avolid);
error = code;
goto bfail;
}
- MapHostToNetwork(&entry);
- }
-
- if (!ISNAMEVALID(entry.name)) {
- fprintf(STDERR, "Name of the volume %s exceeds the size limit\n",
- entry.name);
- error = VOLSERBADNAME;
- 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);
}
- backupID = entry.volumeId[BACKVOL];
- if (backupID == INVALID_BID) {
- /* Get a backup volume id from the VLDB and update the vldb
- * entry with it.
- */
- code = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 1, &backupID);
- if (code) {
- fprintf(STDERR,
- "Could not allocate ID for the backup volume of %lu from the VLDB\n",
- (unsigned long)avolid);
- error = code;
- goto bfail;
- }
- entry.volumeId[BACKVOL] = backupID;
- vldbmod = 1;
+ 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 backup volume exists by trying to create
- * a transaction on the backup volume. We've assumed the backup exists.
+ /* Test to see if the clone volume exists by trying to create
+ * a transaction on the clone volume. We've assumed the clone exists.
*/
- code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid);
+ /* 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 backup volume %lu\n",
- (unsigned long)backupID);
+ fprintf(STDERR, "Could not reach the clone volume %lu\n",
+ (unsigned long)acloneid);
error = code;
goto bfail;
}
btid = 0;
if (code || rcode) {
fprintf(STDERR,
- "Could not end transaction on the previous backup volume %lu\n",
- (unsigned long)backupID);
+ "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(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);
* volume exists or not
*/
if (backexists) {
- VPRINT1("Re-cloning backup volume %u ...", backupID);
+ VPRINT1("Re-cloning clone volume %u ...", acloneid);
- code = AFSVolReClone(aconn, ttid, backupID);
+ code = AFSVolReClone(aconn, ttid, acloneid);
if (code) {
fprintf(STDERR, "Could not re-clone backup volume %lu\n",
- (unsigned long)backupID);
+ (unsigned long)acloneid);
error = code;
goto bfail;
}
} else {
- VPRINT1("Creating a new backup clone %u ...", backupID);
-
- strcpy(vname, entry.name);
- strcat(vname, ".backup");
+ VPRINT1("Creating a new clone %u ...", acloneid);
- code = AFSVolClone(aconn, ttid, 0, backupVolume, vname, &backupID);
+ 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);
goto bfail;
}
- /* Mork vldb as backup exists */
- if (!(entry.flags & BACK_EXISTS)) {
- entry.flags |= BACK_EXISTS;
- vldbmod = 1;
- }
-
/* Now go back to the backup volume and bring it on line */
- code = AFSVolTransCreate(aconn, backupID, apart, ITOffline, &btid);
- if (code) {
- fprintf(STDERR,
- "Failed to start a transaction on the backup volume %lu\n",
- (unsigned long)backupID);
- error = code;
- goto bfail;
- }
+ 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 backup volume %lu on line \n",
- (unsigned long)backupID);
- 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 backup volume %lu\n",
- (unsigned long)backupID);
- error = (code ? code : rcode);
- 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;
- /* Will update the vldb below */
-
bfail:
if (ttid) {
code = AFSVolEndTrans(aconn, ttid, &rcode);
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);
}
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) {
static int
GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
struct rx_connection **connPtr, afs_int32 * transPtr,
- afs_int32 * timePtr)
+ afs_int32 * crtimePtr, afs_int32 * uptimePtr)
{
- 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);
volid = vldbEntryPtr->volumeId[ROVOL];
if (volid)
code =
- AFSVolTransCreate(*connPtr, volid,
+ AFSVolTransCreate_retry(*connPtr, volid,
vldbEntryPtr->serverPartition[index], ITOffline,
transPtr);
/* 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",
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);
}
*/
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) {
code);
goto fail;
}
- *timePtr = tstatus.creationDate - CLOCKSKEW;
+ *crtimePtr = CLOCKADJ(tstatus.creationDate);
+ *uptimePtr = CLOCKADJ(tstatus.updateDate);
}
return 0;
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] =
}
-static int
-rel_compar(struct release *r1, struct release *r2)
-{
- return (r1->time - r2->time);
-}
-
/* UV_ReleaseVolume()
* Release volume <afromvol> on <afromserver> <afrompart> to all
* its RO sites (full release). Unless the previous release was
*/
int
-UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver,
+UV_ReleaseVolume(afs_uint32 afromvol, afs_int32 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;
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 rwupdate, clcrdate;
struct rtime {
int validtime;
- afs_uint32 time;
+ afs_uint32 uptime;
} remembertime[NMAXNSERVERS];
int releasecount = 0;
struct volser_status volstatus;
+ char hoststr[16];
memset((char *)remembertime, 0, sizeof(remembertime));
memset((char *)&results, 0, sizeof(results));
- 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");
/* 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;
}
/* 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++;
+ }
}
- if (forceflag && !fullrelease)
+ if ((forceflag && !fullrelease) || (s == m) || (s == 0))
fullrelease = 1;
/* Determine which volume id to use and see if it exists */
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,
ONERROR(code, afromvol,
"Failed to get the status of RW volume %u\n");
rwcrdate = volstatus.creationDate;
+ rwupdate = volstatus.updateDate;
/* End transaction on RW */
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
"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,
"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 */
/* 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");
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,
}
/* 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;
+ rwupdate = volstatus.updateDate;
/* 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;
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");
/* 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 (!fullrelease && code)
ONERROR(VOLSERNOVOL, afromvol,
"Old clone is inaccessible. Try vos release -f %u.\n");
code =
GetTrans(&entry, vldbindex, &(toconns[volcount]),
&(replicas[volcount].trans),
- &(times[volcount].time));
+ &(times[volcount].crtime),
+ &(times[volcount].uptime));
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).
* 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;
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);
}
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);
}
}
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;
}
}
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,
* 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_int32 afromserver, afs_int32 afrompart,
+ afs_int32 fromdate, afs_int32(*DumpFunction) (), char *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;
- afs_int32 code, error = 0;
+ afs_int32 code, error = 0, retry = 0;
+ time_t tmv = fromdate;
if (setjmp(env))
ERROR_EXIT(EPIPE);
(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;
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
+ retryold:
+ 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",
if (!error)
error = (code ? code : rcode);
}
- VDONE;
+ VEDONE;
}
if (fromconn)
rx_DestroyConnection(fromconn);
- PrintError("", error);
+ if (retry)
+ goto retryold;
+ if (error != RXGEN_OPCODE)
+ PrintError("", error);
return (error);
}
* extracting parameters from the rock
*/
int
-UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver,
+UV_DumpClonedVolume(afs_uint32 afromvol, afs_int32 afromserver,
afs_int32 afrompart, afs_int32 fromdate,
- afs_int32(*DumpFunction) (), char *rock)
+ afs_int32(*DumpFunction) (), char *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;
afs_int32 clonetid = 0;
afs_int32 code = 0, vcode = 0, error = 0;
- afs_int32 clonevol = 0;
+ afs_uint32 clonevol = 0;
char vname[64];
+ time_t tmv = fromdate;
if (setjmp(env))
ERROR_EXIT(EPIPE);
(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);
+ code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &clonevol);
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");
code =
AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol);
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;
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);
code =
- AFSVolTransCreate(fromconn, clonevol, afrompart, ITOffline,
+ AFSVolTransCreate_retry(fromconn, clonevol, afrompart, ITOffline,
&clonetid);
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) {
}
}
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,
if (!error)
error = (code ? code : rcode);
}
- VDONE;
+ VEDONE;
}
if (fromconn)
rx_DestroyConnection(fromconn);
* 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_int32 toserver, afs_int32 topart, afs_uint32 tovolid,
+ afs_int32 toparentid, char tovolname[], int flags,
+ afs_int32(*WriteData) (), char *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;
}
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);
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);
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);
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;
}
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;
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,
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;
}
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,
return error;
}
-
-/*unlocks the vldb entry associated with <volid> */
int
-UV_LockRelease(afs_int32 volid)
+UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_uint32 tovolid,
+ char tovolname[], int flags, afs_int32(*WriteData) (),
+ char *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,
/*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_AddSite(afs_int32 server, afs_int32 part, afs_uint32 volid, afs_int32 valid)
{
int j, nro = 0, islocked = 0;
struct nvldbentry entry, storeEntry;
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",
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);
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,
/*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_int32 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);
/*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);
}
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",
"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);
}
/*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_int32 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);
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,
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);
}
curPtr->volFlags &= ~CLONEZAPPED;
success = 1;
code =
- AFSVolTransCreate(aconn, curPtr->volCloneId, apart, ITOffline,
+ AFSVolTransCreate_retry(aconn, curPtr->volCloneId, apart, ITOffline,
&tid);
if (code)
success = 0;
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;
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);
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,
/* 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_int32 aserver, afs_int32 apart, afs_uint32 volid,
struct volintInfo **resultPtr)
{
struct rx_connection *aconn;
*------------------------------------------------------------------------*/
int
-UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_int32 a_volID,
+UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID, afs_uint32 a_volID,
struct volintXInfo **a_resultPP)
{
struct rx_connection *rxConnP; /*Rx connection to Volume Server */
CheckVolume(volintInfo * volumeinfo, afs_int32 aserver, afs_int32 apart,
afs_int32 * modentry, afs_uint32 * maxvolid)
{
- 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, islocked = 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);
* 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);
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);
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);
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);
}
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);
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,
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",
entry.serverNumber[idx] = aserver;
entry.serverPartition[idx] = apart;
- entry.serverFlags[idx] = ITSRWVOL;
+ entry.serverFlags[idx] = ITSBACKVOL;
modified++;
}
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,
(unsigned long)volumeinfo->volid);
}
- Lp_SetRWValue(entry, entry.serverNumber[idx],
+ Lp_SetRWValue(&entry, entry.serverNumber[idx],
entry.serverPartition[idx], 0L, 0L);
entry.nServers--;
modified++;
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]);
if (entry.volumeId[RWVOL] > *maxvolid)
*maxvolid = entry.volumeId[RWVOL];
- if (modified) {
+ if (modified && doit) {
MapNetworkToHost(&entry, &storeEntry);
if (createentry) {
*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 (verbose) {
+ if (verbose && doit) {
fprintf(STDOUT, "-- status after --\n");
if (modified)
EnumerateEntry(&entry);
{
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);
{
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;
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_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)) {
* Equivalent to a syncserv.
*/
if (!vcode) {
+ /* Tell CheckVldb not to update if appropriate */
+ if (flags & 2)
+ mod = 1;
+ else
+ mod = 0;
code = CheckVldb(&vldbentry, &mod);
if (code) {
fprintf(STDERR, "Could not process VLDB entry for volume %s\n",
/* 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,
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,
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,
/* if (aserver) */
/* If verbose output, print a summary of what changed */
- if (tverbose) {
+ if (tverbose && !(flags & 2)) {
fprintf(STDOUT, "-- status after --\n");
code = VLDB_GetEntryByName(avolname, &vldbentry);
if (code && (code != VL_NOENT)) {
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");
} 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");
{
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;
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;
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,
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);
}
+ if (flags & 2)
+ modified = 1;
+ else
+ modified = 0;
code = CheckVolume(vi, aserver, apart, &modified, &maxvolid);
if (code) {
PrintError("", code);
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);
} /* 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");
} 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");
* still exists - so we catch these error codes.
*/
afs_int32
-VolumeExists(afs_int32 server, afs_int32 partition, afs_int32 volumeid)
+VolumeExists(afs_int32 server, afs_int32 partition, afs_uint32 volumeid)
{
struct rx_connection *conn = (struct rx_connection *)0;
afs_int32 code = -1;
int idx;
afs_int32 code, error = 0;
char pname[10];
+ char hoststr[16];
if (modified)
*modified = 0;
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);
}
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);
}
int foundro = 0, modentry = 0;
afs_int32 code, error = 0;
char pname[10];
+ char hoststr[16];
if (modified)
*modified = 0;
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);
}
}
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");
*/
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",
code = CheckVldbRWBK(entry, &mod);
if (code)
ERROR_EXIT(code);
- if (mod && (pass == 1))
+ if (mod && (pass == 1) && doit)
goto retry;
if (mod)
modentry++;
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
* 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,
islocked = 0;
}
- if (verbose) {
+ if (verbose && doit) {
fprintf(STDOUT, "-- status after --\n");
if (delentry)
fprintf(STDOUT, "\n**entry deleted**\n");
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) {
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;
}
VPRINT1("Processing VLDB entry %d ...\n", j + 1);
+ /* Tell CheckVldb not to update if appropriate */
+ if (flags & 2)
+ modified = 1;
+ else
+ modified = 0;
code = CheckVldb(vlentry, &modified);
if (code) {
PrintError("", code);
}
}
- 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)
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",
}
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,
}
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,
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 */
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;
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) {
/*delete the volume without interacting with the vldb */
int
-UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid)
+UV_VolumeZap(afs_int32 server, afs_int32 part, afs_uint32 volid)
{
afs_int32 rcode, ttid, error, code;
struct rx_connection *aconn;
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);
}
int
-UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid,
+UV_SetVolume(afs_int32 server, afs_int32 partition, afs_uint32 volid,
afs_int32 transflag, afs_int32 setflag, int sleeptime)
{
struct rx_connection *conn = 0;
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);
}
int
-UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 volid,
+UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_uint32 volid,
volintInfo * infop)
{
struct rx_connection *conn = 0;
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);
}
int
-UV_GetSize(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+UV_GetSize(afs_uint32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
afs_int32 fromdate, struct volintSize *vol_size)
{
struct rx_connection *aconn = (struct rx_connection *)0;
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);