afs_int32 apart, afs_uint32 okvol,
afs_uint32 delvol);
#endif
+static int DelVol(struct rx_connection *conn, afs_uint32 vid, afs_int32 part,
+ afs_int32 flags);
static int GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
struct rx_connection **connPtr, afs_int32 * transPtr,
afs_uint32 * crtimePtr, afs_uint32 * uptimePtr,
- afs_int32 *origflags, afs_uint32 tmpVolId);
+ afs_int32 *origflags);
static int SimulateForwardMultiple(struct rx_connection *fromconn,
afs_int32 fromtid, afs_int32 fromdate,
manyDests * tr, afs_int32 flags,
void *cookie, manyResults * results);
-static int DoVolOnline(struct nvldbentry *vldbEntryPtr, afs_uint32 avolid,
- int index, char *vname, struct rx_connection *connPtr);
-static int DoVolClone(struct rx_connection *aconn, afs_uint32 avolid,
- afs_int32 apart, int type, afs_uint32 cloneid,
- char *typestring, char *pname, char *vname, char *suffix,
- struct volser_status *volstatus, afs_int32 *transPtr);
-static int DoVolDelete(struct rx_connection *aconn, afs_uint32 avolid,
- afs_int32 apart, char *typestring, afs_uint32 atoserver,
- struct volser_status *volstatus, char *pprefix);
static afs_int32 CheckVolume(volintInfo * volumeinfo, afs_uint32 aserver,
afs_int32 apart, afs_int32 * modentry,
afs_uint32 * maxvolid, struct nvldbentry *aentry);
/* Whether volume is in the VLDB or not. Delete the volume on disk */
aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
-
- code = DoVolDelete(aconn, avolid, apart, "the", 0, NULL, NULL);
+ code = AFSVolTransCreate_retry(aconn, avolid, apart, ITOffline, &ttid);
if (code) {
- if (code == VNOVOL)
+ if (code == VNOVOL) {
notondisk = 1;
- else {
- error = code;
- goto error_exit;
+ } else {
+ EGOTO1(error_exit, code, "Transaction on volume %u failed\n",
+ avolid);
}
+ } else {
+ VPRINT1("Trying to delete the volume %u ...", avolid);
+
+ code = AFSVolDeleteVolume(aconn, ttid);
+ EGOTO1(error_exit, code, "Could not delete the volume %u \n", avolid);
+
+ code = AFSVolEndTrans(aconn, ttid, &rcode);
+ code = (code ? code : rcode);
+ ttid = 0;
+ EGOTO1(error_exit, code,
+ "Could not end the transaction for the volume %u \n", avolid);
+ VDONE;
}
/* Now update the VLDB entry.
}
/* Delete backup if it exists */
- code = DoVolDelete(aconn, entry.volumeId[BACKVOL], apart,
- "the backup", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto error_exit;
+ code =
+ AFSVolTransCreate_retry(aconn, entry.volumeId[BACKVOL], apart,
+ ITOffline, &ttid);
+
+ if (!code) {
+ if (verbose) {
+ fprintf(STDOUT, "Trying to delete the backup volume %u ...",
+ entry.volumeId[BACKVOL]);
+ fflush(STDOUT);
+ }
+ code = AFSVolDeleteVolume(aconn, ttid);
+ EGOTO1(error_exit, code, "Could not delete the volume %u \n",
+ entry.volumeId[BACKVOL]);
+
+ code = AFSVolEndTrans(aconn, ttid, &rcode);
+ ttid = 0;
+ code = (code ? code : rcode);
+ EGOTO1(error_exit, code,
+ "Could not end the transaction for the volume %u \n",
+ entry.volumeId[BACKVOL]);
+ if (verbose)
+ fprintf(STDOUT, " done\n");
}
if (verbose)
(void)signal(SIGINT, sigint_handler);
}
-static int
-DoVolDelete(struct rx_connection *aconn, afs_uint32 avolid,
- afs_int32 apart, char *ptypestring, afs_uint32 atoserver,
- struct volser_status *volstatus, char *pprefix)
-{
- afs_int32 ttid = 0, code, rcode, error = 0;
- char *prefix, *typestring;
- int beverbose = 0;
-
- if (pprefix)
- prefix = pprefix;
- else
- prefix = "";
-
- if (ptypestring) {
- typestring = ptypestring;
- beverbose = 1;
- } else
- typestring = "the";
-
- if (beverbose)
- VPRINT3("%sDeleting %s volume %u ...", prefix, typestring, avolid);
-
- code =
- AFSVolTransCreate_retry(aconn, avolid, apart, ITOffline, &ttid);
-
- EGOTO2(dfail, code, "%sFailed to start transaction on %u\n",
- prefix, avolid);
-
- if (volstatus) {
- code = AFSVolGetStatus(aconn, ttid, volstatus);
- EGOTO2(dfail, code, "%sCould not get timestamp from volume %u\n",
- prefix, avolid);
- }
-
- code =
- AFSVolSetFlags(aconn, ttid,
- VTDeleteOnSalvage | VTOutOfService);
-
- EGOTO2(dfail, code, "%sCould not set flags on volume %u \n",
- prefix, avolid);
-
- if (atoserver) {
- VPRINT1("%sSetting volume forwarding pointer ...", prefix);
- AFSVolSetForwarding(aconn, ttid, atoserver);
- VDONE;
- }
-
- code = AFSVolDeleteVolume(aconn, ttid);
- EGOTO2(dfail, code, "%sCould not delete volume %u\n", prefix, avolid);
-
-dfail:
- if (ttid) {
- code = AFSVolEndTrans(aconn, ttid, &rcode);
- ttid = 0;
- if (!code)
- code = rcode;
- if (code) {
- fprintf(STDERR, "%sCould not end transaction on %s volume %lu \n",
- prefix, typestring, (unsigned long)avolid);
- if (!error)
- error = code;
- }
- }
-
- if (beverbose && !error)
- VDONE;
- return error;
-}
-
-static int
-DoVolClone(struct rx_connection *aconn, afs_uint32 avolid,
- afs_int32 apart, int type, afs_uint32 cloneid,
- char *typestring, char *pname, char *vname, char *suffix,
- struct volser_status *volstatus, afs_int32 *transPtr)
-{
- char cname[64];
- afs_int32 ttid = 0, btid = 0;
- afs_int32 code = 0, rcode = 0;
- afs_int32 error = 0;
- int cloneexists = 1;
-
- /* 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_retry(aconn, cloneid, apart, ITOffline, &btid);
- if (code) {
- if (code != VNOVOL) {
- EPRINT2(code, "Could not reach the %s volume %lu\n",
- typestring, (unsigned long)cloneid);
- error = code;
- goto cfail;
- }
- cloneexists = 0; /* clone 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 %s volume %lu\n",
- typestring, (unsigned long)cloneid);
- error = (code ? code : rcode);
- goto cfail;
- }
- }
-
- /* 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 cfail;
- }
-
- /* Clone or reclone the volume, depending on whether the clone
- * volume exists or not
- */
- if (cloneexists) {
- VPRINT2("Re-cloning %s volume %u ...", typestring, cloneid);
-
- code = AFSVolReClone(aconn, ttid, cloneid);
- if (code) {
- EPRINT2(code, "Could not re-clone %s volume %lu\n",
- typestring, (unsigned long)cloneid);
- error = code;
- goto cfail;
- }
- } else {
- VPRINT2("Creating a new %s clone %u ...", typestring, cloneid);
-
- if (!vname) {
- strcpy(cname, pname);
- strcat(cname, suffix);
- }
-
- code = AFSVolClone(aconn, ttid, 0, type, vname?vname:cname,
- &cloneid);
- if (code) {
- fprintf(STDERR, "Failed to clone the volume %lu\n",
- (unsigned long)avolid);
- error = code;
- goto cfail;
- }
- }
-
- VDONE;
-
- if (volstatus) {
- VPRINT1("Getting status of parent volume %u...", avolid);
- code = AFSVolGetStatus(aconn, ttid, volstatus);
- if (code) {
- fprintf(STDERR, "Failed to get the status of the parent volume %lu\n",
- (unsigned long)avolid);
- error = code;
- goto cfail;
- }
- VDONE;
- }
-
-cfail:
- 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 on the %s volume %lu\n",
- typestring, (unsigned long)cloneid);
- if (!error)
- error = (code ? code : rcode);
- }
- }
- return error;
-}
-
/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
* <atopart>. The operation is almost idempotent. The following
* flags are recognized:
* may still be existing physically on from fileserver
*/
fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
+ fromtid = 0;
pntg = 1;
- code = DoVolDelete(fromconn, afromvol, afrompart,
- "leftover", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto mfail;
+ tmp = fromtid;
+ code =
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITOffline,
+ &tmp);
+ fromtid = tmp;
+
+ if (!code) { /* volume exists - delete it */
+ VPRINT1("Setting flags on leftover source volume %u ...",
+ afromvol);
+ code =
+ AFSVolSetFlags(fromconn, fromtid,
+ VTDeleteOnSalvage | VTOutOfService);
+ EGOTO1(mfail, code,
+ "Failed to set flags on the leftover source volume %u\n",
+ afromvol);
+ VDONE;
+
+ VPRINT1("Deleting leftover source volume %u ...", afromvol);
+ code = AFSVolDeleteVolume(fromconn, fromtid);
+ EGOTO1(mfail, code,
+ "Failed to delete the leftover source volume %u\n",
+ afromvol);
+ VDONE;
+
+ VPRINT1("Ending transaction on leftover source volume %u ...",
+ afromvol);
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code)
+ code = rcode;
+ EGOTO1(mfail, code,
+ "Could not end the transaction for the leftover source volume %u \n",
+ afromvol);
+ VDONE;
}
- code = DoVolDelete(fromconn, backupId, afrompart,
- "leftover backup", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto mfail;
+ /*delete the backup volume now */
+ fromtid = 0;
+ code =
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
+ &tmp);
+ fromtid = tmp;
+
+ if (!code) { /* backup volume exists - delete it */
+ VPRINT1("Setting flags on leftover backup volume %u ...",
+ backupId);
+ code =
+ AFSVolSetFlags(fromconn, fromtid,
+ VTDeleteOnSalvage | VTOutOfService);
+ EGOTO1(mfail, code,
+ "Failed to set flags on the backup volume %u\n", backupId);
+ VDONE;
+
+ VPRINT1("Deleting leftover backup volume %u ...", backupId);
+ code = AFSVolDeleteVolume(fromconn, fromtid);
+ EGOTO1(mfail, code,
+ "Could not delete the leftover backup volume %u\n",
+ backupId);
+ VDONE;
+
+ VPRINT1("Ending transaction on leftover backup volume %u ...",
+ backupId);
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code)
+ code = rcode;
+ EGOTO1(mfail, code,
+ "Could not end the transaction for the leftover backup volume %u\n",
+ backupId);
+ VDONE;
}
fromtid = 0;
/* create a volume on the target machine */
volid = afromvol;
- code = DoVolDelete(toconn, volid, atopart,
- "pre-existing destination", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto mfail;
+ tmp = totid;
+ code = AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+ totid = tmp;
+ if (!code) {
+ /* Delete the existing volume.
+ * While we are deleting the volume in these steps, the transaction
+ * we started against the cloned volume (clonetid above) will be
+ * sitting idle. It will get cleaned up after 600 seconds
+ */
+ VPRINT1("Deleting pre-existing volume %u on destination ...", volid);
+ code = AFSVolDeleteVolume(toconn, totid);
+ EGOTO1(mfail, code,
+ "Could not delete the pre-existing volume %u on destination\n",
+ volid);
+ VDONE;
+
+ VPRINT1
+ ("Ending transaction on pre-existing volume %u on destination ...",
+ volid);
+ code = AFSVolEndTrans(toconn, totid, &rcode);
+ totid = 0;
+ if (!code)
+ code = rcode;
+ EGOTO1(mfail, code,
+ "Could not end the transaction on pre-existing volume %u on destination\n",
+ volid);
+ VDONE;
}
VPRINT1("Creating the destination volume %u ...", volid);
afromvol);
VDONE;
- code = DoVolDelete(fromconn, backupId, afrompart,
- "source backup", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto mfail;
- }
+ /* Delete the backup volume on the original site */
+ VPRINT1("Creating transaction for backup volume %u on source ...",
+ backupId);
+ tmp = fromtid;
+ code =
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline, &tmp);
+ fromtid = tmp;
+ VDONE;
+ if (!code) {
+ VPRINT1("Setting flags on backup volume %u on source ...", backupId);
+ code =
+ AFSVolSetFlags(fromconn, fromtid,
+ VTDeleteOnSalvage | VTOutOfService);
+ EGOTO1(mfail, code,
+ "Failed to set the flags on the backup volume %u on the source\n",
+ backupId);
+ VDONE;
- code = 0; /* no backup volume? that's okay */
+ VPRINT1("Deleting the backup volume %u on the source ...", backupId);
+ code = AFSVolDeleteVolume(fromconn, fromtid);
+ EGOTO1(mfail, code,
+ "Failed to delete the backup volume %u on the source\n",
+ backupId);
+ VDONE;
+
+ VPRINT1("Ending transaction on backup volume %u on source ...",
+ backupId);
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code)
+ code = rcode;
+ EGOTO1(mfail, code,
+ "Failed to end the transaction on the backup volume %u on the source\n",
+ backupId);
+ VDONE;
+ } else
+ code = 0; /* no backup volume? that's okay */
fromtid = 0;
if (!(flags & RV_NOCLONE)) {
- code = DoVolDelete(fromconn, newVol, afrompart,
- "cloned", 0, NULL, NULL);
- if (code) {
- error = code;
- goto mfail;
- }
+ VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
+ tmp = clonetid;
+ code =
+ AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+ &tmp);
+ clonetid = tmp;
+ EGOTO1(mfail, code,
+ "Failed to start a transaction on the cloned volume%u\n",
+ newVol);
+ VDONE;
+
+ /* now delete the clone */
+ VPRINT1("Deleting the cloned volume %u ...", newVol);
+ code = AFSVolDeleteVolume(fromconn, clonetid);
+ EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n",
+ newVol);
+ VDONE;
+
+ 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 */
fflush(STDOUT);
}
- if (volid && toconn)
- code = DoVolDelete(toconn, volid, atopart,
- "destination", 0, NULL, "Recovery:");
+ if (volid && toconn) {
+ VPRINT1
+ ("Recovery: Creating transaction for destination volume %u ...",
+ volid);
+ tmp = totid;
+ code =
+ AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+ totid = tmp;
+
+ if (!code) {
+ VDONE;
+
+ VPRINT1
+ ("Recovery: Setting flags on destination volume %u ...",
+ volid);
+ AFSVolSetFlags(toconn, totid,
+ VTDeleteOnSalvage | VTOutOfService);
+ VDONE;
+
+ VPRINT1("Recovery: Deleting destination volume %u ...",
+ volid);
+ AFSVolDeleteVolume(toconn, totid);
+ VDONE;
+
+ VPRINT1
+ ("Recovery: Ending transaction on destination volume %u ...",
+ volid);
+ AFSVolEndTrans(toconn, totid, &rcode);
+ VDONE;
+ } else {
+ VPRINT1
+ ("\nRecovery: Unable to start transaction on destination volume %u.\n",
+ afromvol);
+ }
+ }
/* put source volume on-line */
if (fromconn) {
/* delete backup volume */
if (fromconn) {
- code = DoVolDelete(fromconn, backupId, afrompart,
- "backup", 0, NULL, "Recovery:");
+ VPRINT1("Recovery: Creating transaction on backup volume %u ...",
+ backupId);
+ tmp = fromtid;
+ code =
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
+ &tmp);
+ fromtid = tmp;
+ if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Setting flags on backup volume %u ...",
+ backupId);
+ AFSVolSetFlags(fromconn, fromtid,
+ VTDeleteOnSalvage | VTOutOfService);
+ VDONE;
- code = DoVolDelete(fromconn, afromvol, afrompart, "source",
- (atoserver != afromserver)?atoserver:0,
- NULL, NULL);
+ VPRINT1("Recovery: Deleting backup volume %u ...", backupId);
+ AFSVolDeleteVolume(fromconn, fromtid);
+ VDONE;
+
+ VPRINT1
+ ("Recovery: Ending transaction on backup volume %u ...",
+ backupId);
+ AFSVolEndTrans(fromconn, fromtid, &rcode);
+ VDONE;
+ } else {
+ VPRINT1
+ ("\nRecovery: Unable to start transaction on backup volume %u.\n",
+ backupId);
+ }
+
+ /* delete source volume */
+ VPRINT1("Recovery: Creating transaction on source volume %u ...",
+ afromvol);
+ tmp = fromtid;
+ code =
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+ &tmp);
+ fromtid = tmp;
+ if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Setting flags on backup volume %u ...",
+ afromvol);
+ AFSVolSetFlags(fromconn, fromtid,
+ VTDeleteOnSalvage | VTOutOfService);
+ VDONE;
+
+ if (atoserver != afromserver) {
+ VPRINT("Recovery: Setting volume forwarding pointer ...");
+ AFSVolSetForwarding(fromconn, fromtid, atoserver);
+ VDONE;
+ }
+
+ VPRINT1("Recovery: Deleting source volume %u ...", afromvol);
+ AFSVolDeleteVolume(fromconn, fromtid);
+ VDONE;
+
+ VPRINT1
+ ("Recovery: Ending transaction on source volume %u ...",
+ afromvol);
+ AFSVolEndTrans(fromconn, fromtid, &rcode);
+ VDONE;
+ } else {
+ VPRINT1
+ ("\nRecovery: Unable to start transaction on source volume %u.\n",
+ afromvol);
+ }
}
}
/* common cleanup - delete local clone */
if (newVol) {
- code = DoVolDelete(fromconn, newVol, afrompart,
- "clone", 0, NULL, "Recovery:");
+ VPRINT1("Recovery: Creating transaction on clone volume %u ...",
+ newVol);
+ tmp = clonetid;
+ code =
+ AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
+ &tmp);
+ clonetid = tmp;
+ if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Deleting clone volume %u ...", newVol);
+ AFSVolDeleteVolume(fromconn, clonetid);
+ VDONE;
+
+ VPRINT1("Recovery: Ending transaction on clone volume %u ...",
+ newVol);
+ AFSVolEndTrans(fromconn, clonetid, &rcode);
+ VDONE;
+ } else {
+ VPRINT1
+ ("\nRecovery: Unable to start transaction on source volume %u.\n",
+ afromvol);
+ }
}
/* unlock VLDB entry */
fromtid = 0;
if (!(flags & RV_NOCLONE)) {
- code = DoVolDelete(fromconn, cloneVol, afrompart,
- "cloned", 0, NULL, NULL);
- if (code) {
- error = code;
- goto mfail;
- }
+ VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ tmp = clonetid;
+ code =
+ AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+ &tmp);
+ clonetid = tmp;
+ EGOTO1(mfail, code,
+ "Failed to start a transaction on the cloned volume%u\n",
+ cloneVol);
+ VDONE;
+
+ /* 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;
+
+ 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)) {
MapHostToNetwork(&entry);
/* common cleanup - delete local clone */
- if (cloneVol)
- code = DoVolDelete(fromconn, cloneVol, afrompart,
- "clone", 0, NULL, "Recovery:");
+ if (cloneVol) {
+ VPRINT1("Recovery: Creating transaction on clone volume %u ...",
+ cloneVol);
+ tmp = clonetid;
+ code =
+ AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
+ &tmp);
+ clonetid = tmp;
+ if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Deleting clone volume %u ...", cloneVol);
+ AFSVolDeleteVolume(fromconn, clonetid);
+ VDONE;
+
+ VPRINT1("Recovery: Ending transaction on clone volume %u ...",
+ cloneVol);
+ AFSVolEndTrans(fromconn, clonetid, &rcode);
+ VDONE;
+ } else {
+ VPRINT1
+ ("\nRecovery: Unable to start transaction on clone volume %u.\n",
+ cloneVol);
+ }
+ }
done: /* routine cleanup */
if (fromconn)
afs_int32 ttid = 0, btid = 0;
afs_uint32 backupID;
afs_int32 code = 0, rcode = 0;
+ char vname[VOLSER_MAXVOLNAME + 1];
struct nvldbentry entry, storeEntry;
afs_int32 error = 0;
- int vldblocked = 0, vldbmod = 0;
+ int vldblocked = 0, vldbmod = 0, backexists = 1;
aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
vldbmod = 1;
}
- code = DoVolClone(aconn, avolid, apart, backupVolume, backupID, "backup",
- entry.name, NULL, ".backup", NULL, NULL);
+ /* 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;
}
- /* Mark vldb as backup exists */
+ /* 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;
afs_int32 code = 0, rcode = 0;
char vname[VOLSER_MAXVOLNAME + 1];
afs_int32 error = 0;
+ int backexists = 1;
volEntries volumeInfo;
int type = 0;
free(volumeInfo.volEntries_val);
}
- if (!acloneid) {
- /* Get a clone id */
- VPRINT1("Allocating new volume id for clone of volume %u ...",
- avolid);
- code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &acloneid);
- EGOTO1(bfail, code,
- "Could not get an ID for the clone of volume %u from the VLDB\n",
- avolid);
- VDONE;
+ if (!acloneid) {
+ /* Get a clone id */
+ VPRINT1("Allocating new volume id for clone of volume %u ...",
+ avolid);
+ code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &acloneid);
+ EGOTO1(bfail, code,
+ "Could not get an ID for the clone of volume %u from the VLDB\n",
+ avolid);
+ VDONE;
+ }
+
+ /* Test to see if the clone volume exists by trying to create
+ * a transaction on the clone volume. We've assumed the clone exists.
+ */
+ /* XXX I wonder what happens if the clone has some other parent... */
+ code = AFSVolTransCreate_retry(aconn, acloneid, apart, ITOffline, &btid);
+ if (code) {
+ if (code != VNOVOL) {
+ fprintf(STDERR, "Could not reach the clone volume %lu\n",
+ (unsigned long)acloneid);
+ error = code;
+ goto bfail;
+ }
+ backexists = 0; /* backup volume does not exist */
+ }
+ if (btid) {
+ code = AFSVolEndTrans(aconn, btid, &rcode);
+ btid = 0;
+ if (code || rcode) {
+ fprintf(STDERR,
+ "Could not end transaction on the previous clone volume %lu\n",
+ (unsigned long)acloneid);
+ error = (code ? code : rcode);
+ goto bfail;
+ }
+ }
+
+ /* Now go ahead and try to clone the RW volume.
+ * First start a transaction on the RW volume
+ */
+ code = AFSVolTransCreate_retry(aconn, avolid, apart, ITBusy, &ttid);
+ if (code) {
+ fprintf(STDERR, "Could not start a transaction on the volume %lu\n",
+ (unsigned long)avolid);
+ error = code;
+ goto bfail;
+ }
+
+ /* Clone or reclone the volume, depending on whether the backup
+ * volume exists or not
+ */
+ if (backexists) {
+ VPRINT1("Re-cloning clone volume %u ...", acloneid);
+
+ code = AFSVolReClone(aconn, ttid, acloneid);
+ if (code) {
+ fprintf(STDERR, "Could not re-clone backup volume %lu\n",
+ (unsigned long)acloneid);
+ error = code;
+ goto bfail;
+ }
+ } else {
+ VPRINT1("Creating a new clone %u ...", acloneid);
+
+ if (flags & RV_RWONLY)
+ type = readwriteVolume;
+ else if (flags & RV_RDONLY)
+ type = readonlyVolume;
+ else
+ type = backupVolume;
+
+ code = AFSVolClone(aconn, ttid, 0, type, aname, &acloneid);
+ if (code) {
+ fprintf(STDERR, "Failed to clone the volume %lu\n",
+ (unsigned long)avolid);
+ error = code;
+ goto bfail;
+ }
}
- if (flags & RV_RWONLY)
- type = readwriteVolume;
- else if (flags & RV_RDONLY)
- type = readonlyVolume;
- else
- type = backupVolume;
-
- code = DoVolClone(aconn, avolid, apart, type, acloneid, "clone",
- NULL, ".clone", NULL, NULL, NULL);
- if (code) {
- error = code;
+ /* 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;
}
return error;
}
+static int
+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_retry(conn, vid, part, flags, &tid);
+ if (!acode) { /* It really was there */
+ acode = AFSVolDeleteVolume(conn, tid);
+ if (acode) {
+ fprintf(STDERR, "Failed to delete volume %lu.\n",
+ (unsigned long)vid);
+ PrintError("", acode);
+ }
+ ccode = AFSVolEndTrans(conn, tid, &rcode);
+ if (!ccode)
+ ccode = rcode;
+ if (ccode) {
+ fprintf(STDERR, "Failed to end transaction on volume %lu.\n",
+ (unsigned long)vid);
+ PrintError("", ccode);
+ }
+ }
+
+ return acode;
+}
+
#define ONERROR(ec, ep, es) do { \
if (ec) { \
fprintf(STDERR, (es), (ep)); \
GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
struct rx_connection **connPtr, afs_int32 * transPtr,
afs_uint32 * crtimePtr, afs_uint32 * uptimePtr,
- afs_int32 *origflags, afs_uint32 tmpVolId)
+ afs_int32 *origflags)
{
afs_uint32 volid;
struct volser_status tstatus;
goto fail; /* server is down */
volid = vldbEntryPtr->volumeId[ROVOL];
-
if (volid) {
code =
AFSVolTransCreate_retry(*connPtr, volid,
}
strcpy(volname, vldbEntryPtr->name);
- if (tmpVolId)
- strcat(volname, ".roclone");
- else
- strcat(volname, ".readonly");
+ strcat(volname, ".readonly");
if (verbose) {
fprintf(STDOUT,
"Creating new volume %lu on replication site %s: ",
- tmpVolId?(unsigned long)tmpVolId:(unsigned long)volid,
+ (unsigned long)volid,
noresolve ? afs_inet_ntoa_r(vldbEntryPtr->
serverNumber[index], hoststr) :
hostutil_GetNameByINet(vldbEntryPtr->
}
code =
- AFSVolCreateVolume(*connPtr, vldbEntryPtr->serverPartition[index],
- volname, volser_RO,
- vldbEntryPtr->volumeId[RWVOL],
- tmpVolId?&tmpVolId:&volid,
- transPtr);
+ AFSVolCreateVolume(*connPtr, vldbEntryPtr->serverPartition[index],
+ volname, volser_RO,
+ vldbEntryPtr->volumeId[RWVOL], &volid,
+ transPtr);
if (code) {
PrintError("Failed to create the ro volume: ", code);
goto fail;
code);
goto fail;
}
- if (tmpVolId) {
- code = AFSVolEndTrans(*connPtr, *transPtr, &rcode);
- *transPtr = 0;
- if (!code)
- code = rcode;
- if (!code)
- code = DoVolClone(*connPtr, volid,
- vldbEntryPtr->serverPartition[index],
- readonlyVolume, tmpVolId, "temporary",
- vldbEntryPtr->name, NULL, ".roclone", NULL,
- transPtr);
- if (code)
- goto fail;
- }
*crtimePtr = CLOCKADJ(tstatus.creationDate);
*uptimePtr = CLOCKADJ(tstatus.updateDate);
}
*transPtr = 0;
if (!tcode)
tcode = rcode;
- if (tcode && tcode != ENOENT)
+ if (tcode)
PrintError("Could not end transaction on a ro volume: ", tcode);
}
return 0;
}
-static void
-PutTrans(afs_int32 *vldbindex, struct replica *replicas,
- struct rx_connection **toconns, struct release *times,
- afs_int32 volcount)
-{
- afs_int32 s, code = 0, rcode = 0;
- /* End the transactions and destroy the connections */
- for (s = 0; s < volcount; s++) {
- if (replicas[s].trans) {
- code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode);
-
- replicas[s].trans = 0;
- if (!code)
- code = rcode;
- if (code) {
- if ((s == 0) || (code != ENOENT)) {
- PrintError("Could not end transaction on a ro volume: ",
- code);
- } else {
- PrintError
- ("Transaction timed out on a ro volume. Will retry.\n",
- 0);
- if (times[s].vldbEntryIndex < *vldbindex)
- *vldbindex = times[s].vldbEntryIndex;
- }
- }
- }
- if (toconns[s])
- rx_DestroyConnection(toconns[s]);
- toconns[s] = 0;
- }
-}
-
-static int
-DoVolOnline(struct nvldbentry *vldbEntryPtr, afs_uint32 avolid, int index,
- char *vname, struct rx_connection *connPtr)
-{
- afs_int32 code = 0, rcode = 0, onlinetid = 0;
-
- code =
- AFSVolTransCreate_retry(connPtr, avolid,
- vldbEntryPtr->serverPartition[index],
- ITOffline,
- &onlinetid);
- if (code)
- EPRINT(code, "Could not create transaction on readonly...\n");
-
- else {
- code = AFSVolSetFlags(connPtr, onlinetid, 0);
- if (code)
- EPRINT(code, "Could not set flags on readonly...\n");
- }
-
- if (!code) {
- code =
- AFSVolSetIdsTypes(connPtr, onlinetid, vname,
- ROVOL, vldbEntryPtr->volumeId[RWVOL],
- 0, 0);
- if (code)
- EPRINT(code, "Could not set ids on readonly...\n");
- }
- if (!code)
- code = AFSVolEndTrans(connPtr, onlinetid, &rcode);
- if (!code)
- code = rcode;
- return code;
-}
/* UV_ReleaseVolume()
* Release volume <afromvol> on <afromserver> <afrompart> to all
int
UV_ReleaseVolume(afs_uint32 afromvol, afs_uint32 afromserver,
- afs_int32 afrompart, int forceflag, int stayUp)
+ afs_int32 afrompart, int forceflag)
{
char vname[64];
afs_int32 code = 0;
afs_int32 vcode, rcode, tcode;
- afs_uint32 cloneVolId = 0, roVolId;
+ afs_uint32 cloneVolId, roVolId;
struct replica *replicas = 0;
struct nvldbentry entry, storeEntry;
- int i, volcount = 0, m, fullrelease, vldbindex;
+ int i, volcount, m, fullrelease, vldbindex;
int failure;
struct restoreCookie cookie;
struct rx_connection **toconns = 0;
code = VolumeExists(afromserver, afrompart, cloneVolId);
roexists = ((code == ENODEV) ? 0 : 1);
- /* For stayUp case, if roclone is the only site, bypass special handling */
- if (stayUp && roclone) {
- int e;
- error = 0;
-
- for (e = 0; (e < entry.nServers) && !error; e++) {
- if ((entry.serverFlags[e] & ITSROVOL)) {
- if (!(VLDB_IsSameAddrs(entry.serverNumber[e], afromserver,
- &error)))
- break;
- }
- }
- if (e >= entry.nServers)
- stayUp = 0;
- }
-
- /* If we had a previous release to complete, do so, else: */
- if (stayUp && (cloneVolId == entry.volumeId[ROVOL])) {
- code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &cloneVolId);
- ONERROR(code, afromvol,
- "Cannot get temporary clone id for volume %u\n");
- }
-
fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
if (!fromconn)
ONERROR(-1, afromserver,
* (it was recently added), then also delete it. We do not
* want to "reclone" a temporary RO clone.
*/
- if (stayUp) {
- code = VolumeExists(afromserver, afrompart, cloneVolId);
- if (!code) {
- code = DoVolDelete(fromconn, cloneVolId, afrompart, "previous clone", 0,
- NULL, NULL);
- if (code && (code != VNOVOL))
- ERROREXIT(code);
- VDONE;
- }
- }
- /* clean up any previous tmp clone before starting if staying up */
if (roexists
&& (!roclone || (entry.serverFlags[roindex] & RO_DONTUSE))) {
- code = DoVolDelete(fromconn,
- stayUp ? entry.volumeId[ROVOL] : cloneVolId,
- afrompart, "the", 0, NULL, NULL);
+ code = DelVol(fromconn, cloneVolId, afrompart, ITOffline);
if (code && (code != VNOVOL))
ERROREXIT(code);
roexists = 0;
entry.serverFlags[rwindex] |= NEW_REPSITE;
entry.serverFlags[rwindex] &= ~RO_DONTUSE;
- if (roclone) {
- strcpy(vname, entry.name);
- if (stayUp)
- strcat(vname, ".roclone");
- else
- strcat(vname, ".readonly");
+ /* Begin transaction on RW and mark it busy while we clone it */
+ code =
+ AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
+ &clonetid);
+ ONERROR(code, afromvol, "Failed to start transaction on volume %u\n");
+
+ /* Clone or reclone the volume */
+ if (roexists) {
+ VPRINT1("Recloning RW volume %u...", cloneVolId);
+ code = AFSVolReClone(fromconn, clonetid, cloneVolId);
+ ONERROR(code, afromvol, "Failed to reclone the RW volume %u\n");
+ VDONE;
} else {
- strcpy(vname, "readonly-clone-temp");
- }
-
- code = DoVolClone(fromconn, afromvol, afrompart, readonlyVolume,
- cloneVolId, (roclone && !stayUp)?"permanent RO":
- "temporary RO", NULL, vname, NULL, &volstatus, NULL);
- if (code) {
- error = code;
- goto rfail;
+ if (roclone) {
+ strcpy(vname, entry.name);
+ strcat(vname, ".readonly");
+ VPRINT1("Cloning RW volume %u to permanent RO...", afromvol);
+ } else {
+ strcpy(vname, "readonly-clone-temp");
+ VPRINT1("Cloning RW volume %u to temporary RO...", afromvol);
+ }
+ code =
+ AFSVolClone(fromconn, clonetid, 0, readonlyVolume, vname,
+ &cloneVolId);
+ ONERROR(code, afromvol, "Failed to clone the RW volume %u\n");
+ VDONE;
}
+ /* Get the time the RW was created for future information */
+ VPRINT1("Getting status of RW volume %u...", afromvol);
+ code = AFSVolGetStatus(fromconn, clonetid, &volstatus);
+ ONERROR(code, afromvol,
+ "Failed to get the status of the RW volume %u\n");
+ VDONE;
rwcrdate = volstatus.creationDate;
+ /* End the transaction on the RW volume */
+ VPRINT1("Ending cloning transaction on RW volume %u...", afromvol);
+ code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+ clonetid = 0;
+ ONERROR((code ? code : rcode), afromvol,
+ "Failed to end cloning transaction on RW %u\n");
+ VDONE;
+
/* Remember clone volume ID in case we fail or are interrupted */
entry.cloneId = cloneVolId;
- if (roclone && !stayUp) {
+ if (roclone) {
/* Bring the RO clone online - though not if it's a temporary clone */
VPRINT1("Starting transaction on RO clone volume %u...",
cloneVolId);
*/
strcpy(vname, entry.name);
- if (stayUp)
- strcat(vname, ".roclone");
- else
- strcat(vname, ".readonly");
+ strcat(vname, ".readonly");
memset(&cookie, 0, sizeof(cookie));
strncpy(cookie.name, vname, VOLSER_OLDMAXVOLNAME);
cookie.type = ROVOL;
cookie.parent = entry.volumeId[RWVOL];
cookie.clone = 0;
- /* how many to do at once, excluding clone */
- if (stayUp)
- nservers = entry.nServers; /* can do all, none offline */
- else
- nservers = entry.nServers / 2;
+ nservers = entry.nServers / 2; /* how many to do at once, excluding clone */
replicas =
(struct replica *)malloc(sizeof(struct replica) * nservers + 1);
times = (struct release *)malloc(sizeof(struct release) * nservers + 1);
ONERROR0(code, "Failed to create transaction on the release clone\n");
VDONE;
- /* if we have a clone, treat this as done, for now */
- if (stayUp && !fullrelease) {
- entry.serverFlags[roindex] |= NEW_REPSITE;
- entry.serverFlags[roindex] &= ~RO_DONTUSE;
- entry.flags |= RO_EXISTS;
-
- releasecount++;
- }
-
/* For each index in the VLDB */
for (vldbindex = 0; vldbindex < entry.nServers;) {
- /* Get a transaction on the replicas. Pick replicas which have an old release. */
+
+ /* Get a transaction on the replicas. Pick replacas which have an old release. */
for (volcount = 0;
((volcount < nservers) && (vldbindex < entry.nServers));
vldbindex++) {
- if (!stayUp) {
- /* The first two RO volumes will be released individually.
- * The rest are then released in parallel. This is a hack
- * for clients not recognizing right away when a RO volume
- * comes back on-line.
- */
- if ((volcount == 1) && (releasecount < 2))
- break;
- }
+ /* The first two RO volumes will be released individually.
+ * The rest are then released in parallel. This is a hack
+ * for clients not recognizing right away when a RO volume
+ * comes back on-line.
+ */
+ if ((volcount == 1) && (releasecount < 2))
+ break;
if (vldbindex == roindex)
continue; /* the clone */
&(replicas[volcount].trans),
&(times[volcount].crtime),
&(times[volcount].uptime),
- origflags, stayUp?cloneVolId:0);
+ origflags);
if (code)
continue;
if (verbose) {
fprintf(STDOUT, "Starting ForwardMulti from %lu to %u on %s",
- (unsigned long)cloneVolId, stayUp?
- cloneVolId:entry.volumeId[ROVOL],
+ (unsigned long)cloneVolId, entry.volumeId[ROVOL],
noresolve ? afs_inet_ntoa_r(entry.serverNumber[times[0].
vldbEntryIndex], hoststr) :
hostutil_GetNameByINet(entry.
}
}
- if (!stayUp) {
- PutTrans(&vldbindex, replicas, toconns, times, volcount);
- MapNetworkToHost(&entry, &storeEntry);
- vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0);
- ONERROR(vcode, afromvol,
- " Could not update VLDB entry for volume %u\n");
- }
- } /* for each index in the vldb */
-
- /* for the stayup case, put back at the end */
- if (stayUp) {
- afs_uint32 tmpVol = entry.volumeId[ROVOL];
- strcpy(vname, entry.name);
- strcat(vname, ".readonly");
-
- if (roclone) {
- /* have to clear flags to ensure new vol goes online
- */
- code = AFSVolSetFlags(fromconn, fromtid, 0);
- if (code && (code != ENOENT)) {
- PrintError("Failed to set flags on ro volume: ",
- code);
- }
-
- VPRINT3("%sloning to permanent RO %u on %s...", roexists?"Re-c":"C", tmpVol,
- noresolve ?
- afs_inet_ntoa_r(entry.serverNumber[roindex],
- hoststr) :
- hostutil_GetNameByINet(entry.serverNumber[roindex]));
-
- code = AFSVolClone(fromconn, fromtid, roexists?tmpVol:0,
- readonlyVolume, vname, &tmpVol);
-
- if (!code) {
- VDONE;
- VPRINT("Bringing readonly online...");
- code = DoVolOnline(&entry, tmpVol, roindex, vname,
- fromconn);
- }
- if (code) {
- EPRINT(code, "Failed: ");
- entry.serverFlags[roindex] &= ~NEW_REPSITE;
- entry.serverFlags[roindex] |= RO_DONTUSE;
- } else {
- entry.serverFlags[roindex] |= NEW_REPSITE;
- entry.serverFlags[roindex] &= ~RO_DONTUSE;
- entry.flags |= RO_EXISTS;
- VDONE;
- }
-
- }
+ /* End the transactions and destroy the connections */
for (s = 0; s < volcount; s++) {
- if (replicas[s].trans) {
- vldbindex = times[s].vldbEntryIndex;
-
- /* ok, so now we have to end the previous transaction */
+ if (replicas[s].trans)
code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode);
- if (!code)
- code = rcode;
-
- if (!code) {
- code = AFSVolTransCreate_retry(toconns[s],
- cloneVolId,
- entry.serverPartition[vldbindex],
- ITBusy,
- &(replicas[s].trans));
- if (code) {
- PrintError("Unable to begin transaction on temporary clone: ", code);
- }
- } else {
- PrintError("Unable to end transaction on temporary clone: ", code);
- }
-
- VPRINT3("%sloning to permanent RO %u on %s...", times[s].crtime?"Re-c":"C",
- tmpVol, noresolve ?
- afs_inet_ntoa_r(htonl(replicas[s].server.destHost),
- hoststr) :
- hostutil_GetNameByINet(htonl(replicas[s].server.destHost)));
- if (times[s].crtime)
- code = AFSVolClone(toconns[s], replicas[s].trans, tmpVol,
- readonlyVolume, vname, &tmpVol);
- else
- code = AFSVolClone(toconns[s], replicas[s].trans, 0,
- readonlyVolume, vname, &tmpVol);
-
- if (code) {
- if (!times[s].crtime) {
- entry.serverFlags[vldbindex] |= RO_DONTUSE;
- }
- entry.serverFlags[vldbindex] &= ~NEW_REPSITE;
- PrintError("Failed: ",
+ replicas[s].trans = 0;
+ if (!code)
+ code = rcode;
+ if (code) {
+ if ((s == 0) || (code != ENOENT)) {
+ PrintError("Could not end transaction on a ro volume: ",
code);
- } else
- VDONE;
-
- if (entry.serverFlags[vldbindex] != RO_DONTUSE) {
- /* bring it online (mark it InService) */
- VPRINT1("Bringing readonly online on %s...",
- noresolve ?
- afs_inet_ntoa_r(
- htonl(replicas[s].server.destHost),
- hoststr) :
- hostutil_GetNameByINet(
- htonl(replicas[s].server.destHost)));
-
- code = DoVolOnline(&entry, tmpVol, vldbindex, vname,
- toconns[s]);
- /* needed to come online for cloning */
- if (code) {
- /* technically it's still new, just not online */
- entry.serverFlags[s] &= ~NEW_REPSITE;
- entry.serverFlags[s] |= RO_DONTUSE;
- if (code != ENOENT) {
- PrintError("Failed to set correct names and ids: ",
- code);
- }
- } else
- VDONE;
- }
-
- VPRINT("Marking temporary clone for deletion...\n");
- code = AFSVolSetFlags(toconns[s],
- replicas[s].trans,
- VTDeleteOnSalvage |
- VTOutOfService);
- if (code)
- EPRINT(code, "Failed: ");
- else
- VDONE;
-
- VPRINT("Ending transaction on temporary clone...\n");
- code = AFSVolEndTrans(toconns[s], replicas[s].trans, &rcode);
- if (!code)
- rcode = code;
- if (code)
- PrintError("Failed: ", code);
- else {
- VDONE;
- /* ended successfully */
- replicas[s].trans = 0;
-
- VPRINT2("Deleting temporary clone %u on %s...", cloneVolId,
- noresolve ?
- afs_inet_ntoa_r(htonl(replicas[s].server.destHost),
- hoststr) :
- hostutil_GetNameByINet(htonl(replicas[s].server.destHost)));
- code = DoVolDelete(toconns[s], cloneVolId,
- entry.serverPartition[vldbindex],
- NULL, 0, NULL, NULL);
- if (code) {
- EPRINT(code, "Failed: ");
- } else
- VDONE;
+ } else {
+ PrintError
+ ("Transaction timed out on a ro volume. Will retry.\n",
+ 0);
+ if (times[s].vldbEntryIndex < vldbindex)
+ vldbindex = times[s].vldbEntryIndex;
}
}
+
+ if (toconns[s])
+ rx_DestroyConnection(toconns[s]);
+ toconns[s] = 0;
}
- /* done. put the vldb entry in the success tail case*/
- PutTrans(&vldbindex, replicas, toconns, times, volcount);
- }
+ MapNetworkToHost(&entry, &storeEntry);
+ vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0);
+ ONERROR(vcode, afromvol,
+ " Could not update VLDB entry for volume %u\n");
+ } /* for each index in the vldb */
/* End the transaction on the cloned volume */
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
hostutil_GetNameByINet(entry.serverNumber[i]), pname);
}
}
+
MapNetworkToHost(&entry, &storeEntry);
vcode =
VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry,
ERROREXIT(VOLSERBADRELEASE);
}
- entry.cloneId = 0;
/* All the ROs were release successfully. Remove the temporary clone */
- if (!roclone || stayUp) {
+ if (!roclone) {
if (verbose) {
fprintf(STDOUT, "Deleting the releaseClone %lu ...",
(unsigned long)cloneVolId);
fflush(STDOUT);
}
- code = DoVolDelete(fromconn, cloneVolId, afrompart, NULL, 0, NULL,
- NULL);
+ code = DelVol(fromconn, cloneVolId, afrompart, ITOffline);
ONERROR(code, cloneVolId, "Failed to delete volume %u.\n");
VDONE;
}
+ entry.cloneId = 0;
for (i = 0; i < entry.nServers; i++)
entry.serverFlags[i] &= ~NEW_REPSITE;
&totid);
if (code) {
if (flags & RV_FULLRST) { /* full restore: delete then create anew */
- code = DoVolDelete(toconn, pvolid, topart, "the previous", 0,
- &tstatus, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto refail;
- }
+ VPRINT1("Deleting the previous volume %u ...", pvolid);
+
+ code =
+ AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
+ EGOTO1(refail, code, "Failed to start transaction on %u\n",
+ pvolid);
+
+ code = AFSVolGetStatus(toconn, totid, &tstatus);
+ EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
+ pvolid);
+
+ oldCreateDate = tstatus.creationDate;
+ oldUpdateDate = tstatus.updateDate;
+
+ code =
+ AFSVolSetFlags(toconn, totid,
+ VTDeleteOnSalvage | VTOutOfService);
+ EGOTO1(refail, code, "Could not set flags on volume %u \n",
+ pvolid);
+
+ code = AFSVolDeleteVolume(toconn, totid);
+ EGOTO1(refail, code, "Could not delete volume %u\n", pvolid);
+
+ code = AFSVolEndTrans(toconn, totid, &rcode);
+ totid = 0;
+ if (!code)
+ code = rcode;
+ EGOTO1(refail, code, "Could not end transaction on %u\n", pvolid);
+
+ VDONE;
code =
AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
pvolid);
+ oldCreateDate = tstatus.creationDate;
+ oldUpdateDate = tstatus.updateDate;
}
- oldCreateDate = tstatus.creationDate;
- oldUpdateDate = tstatus.updateDate;
} else {
oldCreateDate = 0;
oldUpdateDate = 0;
noresolve ? afs_inet_ntoa_r(entry.serverNumber[index], hoststr) :
hostutil_GetNameByINet(entry.serverNumber[index]),
apartName);
- code = DoVolDelete(tempconn, pvolid,
- entry.serverPartition[index],
- "the", 0, NULL, NULL);
- if (code && code != VNOVOL) {
- error = code;
- goto refail;
+ code =
+ 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);
}
- MapPartIdIntoName(entry.serverPartition[index],
- partName);
}
}
entry.serverNumber[index] = toserver;
struct volDescription *curPtr;
int curPos;
afs_int32 code = 0;
+ afs_int32 rcode = 0;
afs_int32 success = 1;
+ afs_int32 tid;
aconn = (struct rx_connection *)0;
aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
if (curPtr->volFlags & CLONEVALID) {
curPtr->volFlags &= ~CLONEZAPPED;
success = 1;
-
- code = DoVolDelete(aconn, curPtr->volCloneId, apart,
- "clone", 0, NULL, NULL);
+ code =
+ AFSVolTransCreate_retry(aconn, curPtr->volCloneId, apart, ITOffline,
+ &tid);
if (code)
success = 0;
-
+ else {
+ code = AFSVolDeleteVolume(aconn, tid);
+ if (code)
+ success = 0;
+ code = AFSVolEndTrans(aconn, tid, &rcode);
+ if (code || rcode)
+ success = 0;
+ }
if (success)
curPtr->volFlags |= CLONEZAPPED;
if (!success)
VPRINT2("Clone of %s %u deleted\n", curPtr->volName,
curPtr->volCloneId);
curPos++;
+ tid = 0;
}
}
if (aconn)
int
UV_VolumeZap(afs_uint32 server, afs_int32 part, afs_uint32 volid)
{
- afs_int32 error;
+ afs_int32 rcode, ttid, error, code;
struct rx_connection *aconn;
- aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
- error = DoVolDelete(aconn, volid, part,
- "the", 0, NULL, NULL);
+ code = 0;
+ error = 0;
+ ttid = 0;
+ aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
+ code = AFSVolTransCreate_retry(aconn, volid, part, ITOffline, &ttid);
+ if (code) {
+ fprintf(STDERR, "Could not start transaction on volume %lu\n",
+ (unsigned long)volid);
+ error = code;
+ goto zfail;
+ }
+ code = AFSVolDeleteVolume(aconn, ttid);
+ if (code) {
+ fprintf(STDERR, "Could not delete volume %lu\n",
+ (unsigned long)volid);
+ error = code;
+ goto zfail;
+ }
+ code = AFSVolEndTrans(aconn, ttid, &rcode);
+ ttid = 0;
+ if (!code)
+ code = rcode;
+ if (code) {
+ fprintf(STDERR, "Could not end transaction on volume %lu\n",
+ (unsigned long)volid);
+ error = code;
+ goto zfail;
+ }
+ zfail:
+ if (ttid) {
+ code = AFSVolEndTrans(aconn, ttid, &rcode);
+ if (!code)
+ code = rcode;
+ if (!error)
+ error = code;
+ }
PrintError("", error);
if (aconn)
rx_DestroyConnection(aconn);