#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
-
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <rx/rxkad.h>
#include <afs/kautils.h>
#include <afs/cmd.h>
+#include <afs/ihandle.h>
+#ifdef AFS_NT40_ENV
+#include <afs/ntops.h>
+#endif
+#include <afs/vnode.h>
+#include <afs/volume.h>
#include <errno.h>
#define ERRCODE_RANGE 8 /* from error_table.h */
#define CLOCKSKEW 2 /* not really skew, but resolution */
#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
#include <setjmp.h>
+#include "volser_internal.h"
#include "volser_prototypes.h"
#include "vsutils_prototypes.h"
#include "lockprocs_prototypes.h"
/* Protos for static routines */
+#if 0
static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn,
afs_int32 apart, afs_uint32 okvol,
afs_uint32 delvol);
+#endif
static int 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 * crtimePtr, afs_int32 * uptimePtr);
+ afs_uint32 * crtimePtr, afs_uint32 * uptimePtr);
static int SimulateForwardMultiple(struct rx_connection *fromconn,
afs_int32 fromtid, afs_int32 fromdate,
manyDests * tr, afs_int32 flags,
int
PrintError(char *msg, afs_int32 errcode)
{
- fprintf(STDERR, msg);
+ fprintf(STDERR, "%s", msg);
/*replace by a big switch statement */
switch (errcode) {
case 0:
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 parent, afs_uint32 *volid, afs_int32 *trans)
{
afs_int32 code;
int retries = 3;
return code;
}
+#if 0
/* if <okvol> is allright(indicated by beibg able to
* start a transaction, delete the <delvol> */
static afs_int32
}
}
+#endif
+
/* called by EmuerateEntry, show vldb entry in a reasonable format */
void
SubEnumerateEntry(struct nvldbentry *entry)
return code;
}
-/* old interface to create volume */
+/* old interface to create volumes */
int
UV_CreateVolume(afs_int32 aserver, afs_int32 apart, char *aname,
afs_uint32 * anewid)
{
afs_int32 code;
+ *anewid = 0;
code = UV_CreateVolume2(aserver, apart, aname, 5000, 0, 0, 0, 0, anewid);
return code;
}
-/* create a volume, given a server, partition number, volume name --> sends
-* back new vol id in <anewid>*/
+/* less old interface to create volumes */
int
UV_CreateVolume2(afs_int32 aserver, afs_int32 apart, char *aname,
afs_int32 aquota, afs_int32 aspare1, afs_int32 aspare2,
afs_int32 aspare3, afs_int32 aspare4, afs_uint32 * anewid)
{
+ afs_uint32 roid = 0, bkid = 0;
+ return UV_CreateVolume3(aserver, apart, aname, aquota, aspare1, aspare2,
+ aspare3, aspare4, anewid, &roid, &bkid);
+}
+
+/**
+ * Create a volume on the given server and partition
+ *
+ * @param aserver server to create volume on
+ * @param spart partition to create volume on
+ * @param aname name of new volume
+ * @param aquota quota for new volume
+ * @param anewid contains the desired volume id for the new volume. If
+ * *anewid == 0, a new id will be chosen, and will be placed
+ * in *anewid when UV_CreateVolume3 returns.
+ * @param aroid contains the desired RO volume id. If NULL, the RO id entry
+ * will be unset. If *aroid == 0, an id will be chosen, and
+ * will be placed in *anewid when UV_CreateVolume3 returns.
+ * @param abkid same as aroid, except for the BK volume id instead of the
+ * RO volume id.
+ * @return 0 on success, error code otherwise.
+ */
+int
+UV_CreateVolume3(afs_int32 aserver, afs_int32 apart, char *aname,
+ afs_int32 aquota, afs_int32 aspare1, afs_int32 aspare2,
+ afs_int32 aspare3, afs_int32 aspare4, afs_uint32 * anewid,
+ afs_uint32 * aroid, afs_uint32 * abkid)
+{
register struct rx_connection *aconn;
afs_int32 tid;
register afs_int32 code;
afs_int32 error;
afs_int32 rcode, vcode;
+ afs_int32 lastid;
struct nvldbentry entry, storeEntry; /*the new vldb entry */
struct volintInfo tstatus;
tstatus.maxquota = aquota;
aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
- /* next the next 3 available ids from the VLDB */
- vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 3, anewid);
- EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
+
+ if (aroid && *aroid) {
+ VPRINT1("Using RO volume ID %d.\n", *aroid);
+ }
+ if (abkid && *abkid) {
+ VPRINT1("Using BK volume ID %d.\n", *abkid);
+ }
+
+ if (*anewid) {
+ vcode = VLDB_GetEntryByID(*anewid, -1, &entry);
+ if (!vcode) {
+ fprintf(STDERR, "Volume ID %d already exists\n", *anewid);
+ return VVOLEXISTS;
+ }
+ VPRINT1("Using volume ID %d.\n", *anewid);
+ } else {
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, anewid);
+ EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n", aname);
+
+ if (aroid && *aroid == 0) {
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, aroid);
+ EGOTO1(cfail, vcode, "Could not get an RO Id for volume %s\n", aname);
+ }
+
+ if (abkid && *abkid == 0) {
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, abkid);
+ EGOTO1(cfail, vcode, "Could not get a BK Id for volume %s\n", aname);
+ }
+ }
+
+ /* rw,ro, bk id are related in the default case */
+ /* If caller specified RW id, but not RO/BK ids, have them be RW+1 and RW+2 */
+ lastid = *anewid;
+ if (aroid && *aroid == 0) {
+ *aroid = ++lastid;
+ }
+ if (abkid && *abkid == 0) {
+ *abkid = ++lastid;
+ }
+
code =
- AFSVolCreateVolume_retry(aconn, apart, aname, volser_RW, 0, anewid, &tid);
+ AFSVolCreateVolume_retry(aconn, apart, aname, volser_RW, 0, anewid, &tid);
EGOTO2(cfail, code, "Failed to create the volume %s %u \n", aname,
*anewid);
EPRINT(code, "Could not change quota, continuing...\n");
code = AFSVolSetFlags(aconn, tid, 0); /* bring it online (mark it InService */
- EGOTO2(cfail, vcode, "Could not bring the volume %s %u online \n", aname,
+ EGOTO2(cfail, code, "Could not bring the volume %s %u online \n", aname,
*anewid);
VPRINT2("Volume %s %u created and brought online\n", aname, *anewid);
entry.flags = RW_EXISTS; /* this records that rw volume exists */
entry.serverFlags[0] = ITSRWVOL; /*this rep site has rw vol */
entry.volumeId[RWVOL] = *anewid;
- entry.volumeId[ROVOL] = *anewid + 1; /* rw,ro, bk id are related in the default case */
- entry.volumeId[BACKVOL] = *anewid + 2;
+ entry.volumeId[ROVOL] = aroid ? *aroid : 0;
+ entry.volumeId[BACKVOL] = abkid ? *abkid : 0;
entry.cloneId = 0;
/*map into right byte order, before passing to xdr, the stuff has to be in host
* byte order. Xdr converts it into network order */
jmp_buf env;
int interrupt = 0;
-void
-sigint_handler(int x)
+static void *
+do_interrupt(void * unused)
{
if (interrupt)
longjmp(env, 0);
fflush(STDOUT);
interrupt = 1;
- (void)signal(SIGINT, sigint_handler);
+ return NULL;
+}
- return;
+static void
+sigint_handler(int x)
+{
+#ifdef AFS_PTHREAD_ENV
+ do_interrupt(NULL);
+#else
+ IOMGR_SoftSig(do_interrupt, 0);
+#endif
+ (void)signal(SIGINT, sigint_handler);
}
/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
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;
+ /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+ * be changing during the move */
+ struct rx_connection * volatile toconn;
+ struct rx_connection * volatile fromconn;
+ afs_int32 volatile fromtid;
+ afs_int32 volatile totid;
+ afs_int32 volatile clonetid;
+ afs_uint32 volatile newVol;
+ afs_uint32 volatile volid;
+ afs_uint32 volatile backupId;
+ int volatile islocked;
+ int volatile pntg;
+
char vname[64];
char *volName = 0;
char tmpName[VOLSER_MAXVOLNAME + 1];
afs_int32 rcode;
afs_int32 fromDate;
+ afs_int32 tmp;
+ afs_uint32 tmpVol;
struct restoreCookie cookie;
register afs_int32 vcode, code;
- afs_uint32 newVol, volid, backupId;
struct volser_status tstatus;
struct destServer destination;
struct nvldbentry entry, storeEntry;
- int i, islocked, pntg;
+ int i;
afs_int32 error;
char in, lf; /* for test code */
int same;
fromtid = 0;
pntg = 1;
+ tmp = fromtid;
code =
AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITOffline,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
if (!code) { /* volume exists - delete it */
VPRINT1("Setting flags on leftover source volume %u ...",
fromtid = 0;
code =
AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
if (!code) { /* backup volume exists - delete it */
VPRINT1("Setting flags on leftover backup volume %u ...",
* ***/
VPRINT1("Starting transaction on source volume %u ...", afromvol);
- code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+ fromtid = tmp;
EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n",
afromvol);
VDONE;
/* Get a clone id */
VPRINT1("Allocating new volume id for clone of volume %u ...",
afromvol);
- newVol = 0;
- vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &newVol);
+ newVol = tmpVol = 0;
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+ newVol = tmpVol;
EGOTO1(mfail, vcode,
"Could not get an ID for the clone of volume %u from the VLDB\n",
afromvol);
VPRINT1("Cloning source volume %u ...", afromvol);
strcpy(vname, "move-clone-temp");
code =
- AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &newVol);
+ AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &tmpVol);
+ newVol = tmpVol;
EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
afromvol);
VDONE;
if (!(flags & RV_NOCLONE)) {
/* All of this is to get the fromDate */
VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
EGOTO1(mfail, code,
"Failed to start a transaction on the cloned volume%u\n",
newVol);
/* create a volume on the target machine */
volid = afromvol;
- code = AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &totid);
+ tmp = totid;
+ code = AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+ totid = tmp;
if (!code) {
/* Delete the existing volume.
* While we are deleting the volume in these steps, the transaction
}
VPRINT1("Creating the destination volume %u ...", volid);
+ tmp = totid;
+ tmpVol = volid;
code =
- AFSVolCreateVolume(toconn, atopart, volName, volser_RW, volid, &volid,
- &totid);
+ AFSVolCreateVolume(toconn, atopart, volName, volser_RW, volid, &tmpVol,
+ &tmp);
+ totid = tmp;
+ volid = tmpVol;
EGOTO1(mfail, code, "Failed to create the destination volume %u\n",
volid);
VDONE;
* ***/
VPRINT1("Starting transaction on source volume %u ...", afromvol);
- code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ tmp = fromtid;
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+ fromtid = tmp;
EGOTO1(mfail, code,
"Failed to create a transaction on the source volume %u\n",
afromvol);
/* 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, &fromtid);
+ AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline, &tmp);
+ fromtid = tmp;
VDONE;
if (!code) {
VPRINT1("Setting flags on backup volume %u on source ...", backupId);
fromtid = 0;
if (!(flags & RV_NOCLONE)) {
VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
EGOTO1(mfail, code,
"Failed to start a transaction on the cloned volume%u\n",
newVol);
VPRINT1
("Recovery: Creating transaction for destination volume %u ...",
volid);
+ tmp = totid;
code =
- AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &totid);
+ AFSVolTransCreate_retry(toconn, volid, atopart, ITOffline, &tmp);
+ totid = tmp;
if (!code) {
VDONE;
if (fromconn) {
VPRINT1("Recovery: Creating transaction on source volume %u ...",
afromvol);
+ tmp = fromtid;
code =
AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
if (!code) {
VDONE;
if (fromconn) {
VPRINT1("Recovery: Creating transaction on backup volume %u ...",
backupId);
+ tmp = fromtid;
code =
AFSVolTransCreate_retry(fromconn, backupId, afrompart, ITOffline,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
if (!code) {
VDONE;
/* delete source volume */
VPRINT1("Recovery: Creating transaction on source volume %u ...",
afromvol);
+ tmp = fromtid;
code =
AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
if (!code) {
VDONE;
if (newVol) {
VPRINT1("Recovery: Creating transaction on clone volume %u ...",
newVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, newVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
if (!code) {
VDONE;
char *atovolname, afs_int32 atoserver, afs_int32 atopart,
afs_uint32 atovolid, int flags)
{
- struct rx_connection *toconn, *fromconn;
- afs_int32 fromtid, totid, clonetid;
+ /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+ * be changing during the copy */
+ int volatile pntg;
+ afs_int32 volatile clonetid;
+ afs_int32 volatile totid;
+ afs_int32 volatile fromtid;
+ struct rx_connection * volatile fromconn;
+ struct rx_connection * volatile toconn;
+ afs_uint32 volatile cloneVol;
+
char vname[64];
afs_int32 rcode;
afs_int32 fromDate, cloneFromDate;
struct restoreCookie cookie;
register afs_int32 vcode, code;
- afs_uint32 cloneVol, newVol;
+ afs_uint32 newVol;
afs_int32 volflag;
struct volser_status tstatus;
struct destServer destination;
-
struct nvldbentry entry, newentry, storeEntry;
- int islocked, pntg;
+ int islocked;
afs_int32 error;
+ afs_int32 tmp;
+ afs_uint32 tmpVol;
int justclone = 0;
islocked = 0;
cloneVol = 0;
if (!(flags & RV_NOCLONE)) {
VPRINT1("Starting transaction on source volume %u ...", afromvol);
+ tmp = fromtid;
code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy,
- &fromtid);
+ &tmp);
+ fromtid = tmp;
EGOTO1(mfail, code, "Failed to create transaction on the volume %u\n",
afromvol);
VDONE;
VPRINT1("Allocating new volume id for clone of volume %u ...",
afromvol);
cloneVol = 0;
- vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &cloneVol);
+ tmpVol = cloneVol;
+ vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+ cloneVol = tmpVol;
EGOTO1(mfail, vcode,
"Could not get an ID for the clone of volume %u from the VLDB\n",
afromvol);
/* Do the clone. Default flags on clone are set to delete on salvage and out of service */
VPRINT1("Cloning source volume %u ...", afromvol);
strcpy(vname, "copy-clone-temp");
+ tmpVol = cloneVol;
code =
AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname,
- &cloneVol);
+ &tmpVol);
+ cloneVol = tmpVol;
EGOTO1(mfail, code, "Failed to clone the source volume %u\n",
afromvol);
VDONE;
if (!(flags & RV_NOCLONE)) {
VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
EGOTO1(mfail, code,
"Failed to start a transaction on the cloned volume%u\n",
cloneVol);
/* create a volume on the target machine */
cloneFromDate = 0;
- code = AFSVolTransCreate_retry(toconn, newVol, atopart, ITOffline, &totid);
+ tmp = totid;
+ code = AFSVolTransCreate_retry(toconn, newVol, atopart, ITOffline, &tmp);
+ totid = tmp;
if (!code) {
if ((flags & RV_CPINCR)) {
VPRINT1("Getting status of pre-existing volume %u ...", newVol);
}
VPRINT1("Creating the destination volume %u ...", newVol);
+ tmp = totid;
code =
AFSVolCreateVolume(toconn, atopart, atovolname,
(flags & RV_RDONLY) ? volser_RO : volser_RW,
- newVol, &newVol, &totid);
+ newVol, &newVol, &tmp);
+ totid = tmp;
EGOTO1(mfail, code, "Failed to create the destination volume %u\n",
newVol);
VDONE;
* ***/
VPRINT1("Starting transaction on source volume %u ...", afromvol);
- code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ tmp = fromtid;
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+ fromtid = tmp;
EGOTO1(mfail, code,
"Failed to create a transaction on the source volume %u\n",
afromvol);
if (!(flags & RV_NOCLONE)) {
VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
EGOTO1(mfail, code,
"Failed to start a transaction on the cloned volume%u\n",
cloneVol);
if (cloneVol) {
VPRINT1("Recovery: Creating transaction on clone volume %u ...",
cloneVol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, cloneVol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
if (!code) {
VDONE;
}
#define ONERROR(ec, ep, es) if (ec) { fprintf(STDERR, (es), (ep)); error = (ec); goto rfail; }
+#define ONERROR0(ec, es) if (ec) { fprintf(STDERR, (es)); error = (ec); goto rfail; }
#define ERROREXIT(ec) { error = (ec); goto rfail; }
/* Get a "transaction" on this replica. Create the volume
static int
GetTrans(struct nvldbentry *vldbEntryPtr, afs_int32 index,
struct rx_connection **connPtr, afs_int32 * transPtr,
- afs_int32 * crtimePtr, afs_int32 * uptimePtr)
+ afs_uint32 * crtimePtr, afs_uint32 * uptimePtr)
{
afs_uint32 volid;
struct volser_status tstatus;
struct volser_status volstatus;
char hoststr[16];
- memset((char *)remembertime, 0, sizeof(remembertime));
- memset((char *)&results, 0, sizeof(results));
+ memset(remembertime, 0, sizeof(remembertime));
+ memset(&results, 0, sizeof(results));
vcode = ubik_VL_SetLock(cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
if (vcode != VL_RERELEASE)
roclone = ((roindex == -1) ? 0 : 1);
rwindex = Lp_GetRwIndex(&entry);
if (rwindex < 0)
- ONERROR(VOLSERNOVOL, 0, "There is no RW volume \n");
+ ONERROR0(VOLSERNOVOL, "There is no RW volume \n");
/* Make sure we have a RO volume id to work with */
if (entry.volumeId[ROVOL] == INVALID_BID) {
results.manyResults_val =
(afs_int32 *) malloc(sizeof(afs_int32) * nservers + 1);
if (!replicas || !times || !!!results.manyResults_val || !toconns)
- ONERROR(ENOMEM, 0,
+ ONERROR0(ENOMEM,
"Failed to create transaction on the release clone\n");
memset(replicas, 0, (sizeof(struct replica) * nservers + 1));
if (!fullrelease && code)
ONERROR(VOLSERNOVOL, afromvol,
"Old clone is inaccessible. Try vos release -f %u.\n");
- ONERROR(code, 0, "Failed to create transaction on the release clone\n");
+ ONERROR0(code, "Failed to create transaction on the release clone\n");
VDONE;
/* For each index in the VLDB */
*/
int
UV_DumpVolume(afs_uint32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
- afs_int32 fromdate, afs_int32(*DumpFunction) (), char *rock,
+ afs_int32 fromdate,
+ afs_int32(*DumpFunction) (struct rx_call *, void *), void *rock,
afs_int32 flags)
{
- struct rx_connection *fromconn = (struct rx_connection *)0;
- struct rx_call *fromcall = (struct rx_call *)0;
- afs_int32 fromtid = 0, rxError = 0, rcode = 0;
- afs_int32 code, error = 0, retry = 0;
+ /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+ * be changing during the dump */
+ struct rx_call * volatile fromcall = NULL;
+ struct rx_connection * volatile fromconn = NULL;
+ afs_int32 volatile fromtid = 0;
+
+ afs_int32 rxError = 0, rcode = 0;
+ afs_int32 code, error = 0;
+ afs_int32 tmp;
time_t tmv = fromdate;
if (setjmp(env))
fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
VEPRINT1("Starting transaction on volume %u...", afromvol);
- code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ tmp = fromtid;
+ code = AFSVolTransCreate_retry(fromconn, afromvol, afrompart, ITBusy, &tmp);
+ fromtid = tmp;
EGOTO1(error_exit, code,
"Could not start transaction on the volume %u to be dumped\n",
afromvol);
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");
VEDONE;
if (fromconn)
rx_DestroyConnection(fromconn);
- if (retry)
- goto retryold;
if (error != RXGEN_OPCODE)
PrintError("", error);
return (error);
int
UV_DumpClonedVolume(afs_uint32 afromvol, afs_int32 afromserver,
afs_int32 afrompart, afs_int32 fromdate,
- afs_int32(*DumpFunction) (), char *rock, afs_int32 flags)
+ afs_int32(*DumpFunction) (struct rx_call *, void *),
+ void *rock, afs_int32 flags)
{
- struct rx_connection *fromconn = (struct rx_connection *)0;
- struct rx_call *fromcall = (struct rx_call *)0;
+ /* declare stuff 'volatile' that may be used from setjmp/longjmp and may
+ * be changing during the dump */
+ struct rx_connection * volatile fromconn = NULL;
+ struct rx_call * volatile fromcall = NULL;
+ afs_int32 volatile clonetid = 0;
+ afs_uint32 volatile clonevol = 0;
+
+ afs_int32 tmp;
afs_int32 fromtid = 0, rxError = 0, rcode = 0;
- afs_int32 clonetid = 0;
- afs_int32 code = 0, vcode = 0, error = 0;
- afs_uint32 clonevol = 0;
+ afs_int32 code = 0, error = 0;
+ afs_uint32 tmpVol;
char vname[64];
time_t tmv = fromdate;
/* Get a clone id */
VEPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
- code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &clonevol);
+ tmpVol = clonevol;
+ code = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &tmpVol);
+ clonevol = tmpVol;
EGOTO1(error_exit, code,
"Could not get an ID for the clone of volume %u from the VLDB\n",
afromvol);
VEPRINT2("Cloning source volume %u to clone volume %u...", afromvol,
clonevol);
strcpy(vname, "dump-clone-temp");
+ tmpVol = clonevol;
code =
- AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol);
+ AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &tmpVol);
+ clonevol = tmpVol;
EGOTO1(error_exit, code, "Failed to clone the source volume %u\n",
afromvol);
VEDONE;
VEPRINT1("Starting transaction on the cloned volume %u ...", clonevol);
+ tmp = clonetid;
code =
AFSVolTransCreate_retry(fromconn, clonevol, afrompart, ITOffline,
- &clonetid);
+ &tmp);
+ clonetid = tmp;
EGOTO1(error_exit, code,
"Failed to start a transaction on the cloned volume%u\n",
clonevol);
int
UV_RestoreVolume2(afs_int32 toserver, afs_int32 topart, afs_uint32 tovolid,
afs_int32 toparentid, char tovolname[], int flags,
- afs_int32(*WriteData) (), char *rock)
+ afs_int32(*WriteData) (struct rx_call *, void *),
+ void *rock)
{
struct rx_connection *toconn, *tempconn;
struct rx_call *tocall;
int
UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_uint32 tovolid,
- char tovolname[], int flags, afs_int32(*WriteData) (),
- char *rock)
+ char tovolname[], int flags,
+ afs_int32(*WriteData) (struct rx_call *, void *),
+ void *rock)
{
return UV_RestoreVolume2(toserver, topart, tovolid, 0, tovolname, flags,
WriteData, rock);
}
+/* old interface to add rosites */
+int
+UV_AddSite(afs_int32 server, afs_int32 part, afs_uint32 volid,
+ afs_int32 valid)
+{
+ return UV_AddSite2(server, part, volid, 0, valid);
+}
+
/*adds <server> and <part> as a readonly replication site for <volid>
*in vldb */
int
-UV_AddSite(afs_int32 server, afs_int32 part, afs_uint32 volid, afs_int32 valid)
+UV_AddSite2(afs_int32 server, afs_int32 part, afs_uint32 volid,
+ afs_uint32 rovolid, afs_int32 valid)
{
int j, nro = 0, islocked = 0;
- struct nvldbentry entry, storeEntry;
+ struct nvldbentry entry, storeEntry, entry2;
afs_int32 vcode, error = 0;
char apartName[10];
goto asfail;
}
+ /* if rovolid == 0, we leave the RO volume id alone. If the volume doesn't
+ * have an RO volid at this point (i.e. entry.volumeId[ROVOL] ==
+ * INVALID_BID) and we leave it alone, it gets an RO volid at release-time.
+ */
+ if (rovolid) {
+ if (entry.volumeId[ROVOL] == INVALID_BID) {
+ vcode = VLDB_GetEntryByID(rovolid, -1, &entry2);
+ if (!vcode) {
+ fprintf(STDERR, "Volume ID %d already exists\n", rovolid);
+ return VVOLEXISTS;
+ }
+ VPRINT1("Using RO volume id %d.\n", rovolid);
+ entry.volumeId[ROVOL] = rovolid;
+ } else {
+ fprintf(STDERR, "Ignoring given RO id %d, since volume already has RO id %d\n",
+ rovolid, entry.volumeId[ROVOL]);
+ }
+ }
+
VPRINT("Adding a new site ...");
entry.serverNumber[entry.nServers] = server;
entry.serverPartition[entry.nServers] = part;