int verbose = 0;
struct release {
- afs_int32 time;
+ afs_int32 crtime;
+ afs_int32 uptime;
afs_int32 vldbEntryIndex;
};
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);
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;
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");
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);
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 */
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;
struct volser_status tstatus;
int code, rcode, tcode;
*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);
code);
goto fail;
}
- *timePtr = tstatus.creationDate - CLOCKSKEW;
+ *crtimePtr = tstatus.creationDate - CLOCKSKEW;
+ *uptimePtr = tstatus.updateDate - CLOCKSKEW;
}
return 0;
}
-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
manyDests tr;
manyResults results;
int rwindex, roindex, roclone, roexists;
- afs_int32 rwcrdate, clcrdate;
+ afs_int32 rwcrdate, rwupdate, clcrdate;
struct rtime {
int validtime;
- afs_uint32 time;
+ afs_uint32 uptime;
} remembertime[NMAXNSERVERS];
int releasecount = 0;
struct volser_status volstatus;
}
/* 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 */
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 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 */
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;
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 (fromdate == 0)
fprintf(STDOUT, " (full release)");
+ else
+ fprintf(STDOUT, " (as of %.24s)", ctime((time_t *)&fromdate));
fprintf(STDOUT, ".\n");
fflush(STDOUT);
}
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;
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];
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);
AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,
&pvolid, &totid);
EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
-
- newDate = 0;
} else {
code =
AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
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.type = voltype;
cookie.clone = 0;
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 '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 date on %lu\n",
- (unsigned long)pvolid);
+ fprintf(STDERR, "Could not set the 'last updated' date on %u\n",
+ pvolid);
error = code;
goto refail;
}