}
}
- /* volume must be inaccessible during this process */
- code = UV_SetVolume(server, partition, volid, ITOffline, VTOutOfService, 0);
- if (code != 0) {
- fprintf(STDERR, "Taking RO volume %u offline failed with code %d.\n",
- volid, code);
- goto error_exit;
- }
-
aconn = UV_Bind(server, AFSCONF_VOLUMEPORT);
code = AFSVolConvertROtoRWvolume(aconn, partition, volid);
if (code) {
PrintError("convertROtoRW ", code);
goto error_exit;
}
-
- /*
- * Since the inService flag is copied from the RO volume, the new RW copy is
- * offline. Change the status of this RW volume to online.
- */
- code = UV_SetVolume(server, partition, entry->volumeId[RWVOL], ITOffline,
- 0 /* online */, 0);
- if (code != 0) {
- fprintf(STDERR, "Warning: Attempt to set RW volume %u as online failed "
- "with code %d.\n", entry->volumeId[RWVOL], code);
- }
-
/* Update the VLDB to match what we did on disk as much as possible. */
/* If the converted RO was in the VLDB, make it look like the new RW. */
if (roserver) {
if (entry.volumeId[ROVOL] == INVALID_BID) {
/* need to get a new RO volume id */
vcode = ubik_VL_GetNewVolumeId(cstruct, 0, 1, &roVolId);
- ONERROR(vcode, entry.name, "Cant allocate ID for RO volume of %s\n");
+ ONERROR(vcode, entry.name, "Can't allocate ID for RO volume of %s\n");
entry.volumeId[ROVOL] = roVolId;
MapNetworkToHost(&entry, &storeEntry);
goto refail;
}
reuseID = 0;
+ } else if (vcode) {
+ fprintf(STDERR, "Could not fetch the VLDB entry for the volume %s\n",
+ tovolname);
+ error = vcode;
+ goto refail;
} else if (flags & RV_RDONLY) {
+ /* -readonly restore is prohibited if an RW already exists */
if (entry.flags & VLF_RWEXISTS) {
fprintf(STDERR,
"Entry for ReadWrite volume %s already exists!\n",
noresolve ? afs_inet_ntoa_r(toserver, hoststr) :
hostutil_GetNameByINet(toserver), partName);
fflush(STDOUT);
- code =
- AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid, &pvolid,
- &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;
- }
- code =
- AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
- &pvolid, &totid);
+ /*
+ * Obtain a transaction and get the status of the target volume. Create a new
+ * volume if the target volume does not already exist.
+ */
+ memset(&tstatus, 0, sizeof(tstatus));
+ if ((flags & RV_FULLRST) != 0) {
+ /* Full restore: Delete existing volume then create anew. */
+ code = DoVolDelete(toconn, pvolid, topart, "the previous", 0, &tstatus, NULL);
+ if (code && code != VNOVOL) {
+ error = code;
+ goto refail;
+ }
+ code = AFSVolCreateVolume(toconn, topart, tovolreal, volsertype, pparentid,
+ &pvolid, &totid);
+ EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
+ } else {
+ /* Incremental restore: Obtain a transaction on the existing volume. */
+ code = AFSVolTransCreate_retry(toconn, pvolid, topart, ITOffline, &totid);
+ if (code == 0) {
+ code = AFSVolGetStatus(toconn, totid, &tstatus);
+ EGOTO1(refail, code, "Could not get timestamp from volume %u\n", pvolid);
+ } else if (code == VNOVOL) {
+ code = AFSVolCreateVolume(toconn, topart, tovolreal, volsertype,
+ pparentid, &pvolid, &totid);
EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
} else {
- 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);
-
+ EGOTO1(refail, code, "Failed to start transaction on %u\n", pvolid);
}
- oldCreateDate = tstatus.creationDate;
- oldUpdateDate = tstatus.updateDate;
- oldCloneId = tstatus.cloneID;
- oldBackupId = tstatus.backupID;
- } else {
- oldCreateDate = 0;
- oldUpdateDate = 0;
}
+ oldCreateDate = tstatus.creationDate;
+ oldUpdateDate = tstatus.updateDate;
+ oldCloneId = tstatus.cloneID;
+ oldBackupId = tstatus.backupID;
cookie.parent = pparentid;
cookie.type = voltype;
LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
return (vcode);
}
- VDONE;
+ fprintf(STDOUT, " done\n");
+ fflush(STDOUT);
}
return 0;
}
VPRINT2("Clone for volume %s %u failed \n", curPtr->volName,
curPtr->volId);
if (code) {
- curPtr->volFlags &= ~CLONEVALID; /*cant clone */
+ curPtr->volFlags &= ~CLONEVALID; /* can't clone */
curPos++;
continue;
}
goto rvfail;
}
islocked = 1;
+
+ /*
+ * Match the flags we just set via SetLock,
+ * so we don't invalidate our compare below.
+ */
+ entry->flags &= ~VLOP_ALLOPERS;
+ entry->flags |= VLOP_ADDSITE;
+
+ /*
+ * Now get the entry again (under lock) and
+ * verify the volume hasn't otherwise changed.
+ */
+ vcode = VLDB_GetEntryByID(entry->volumeId[RWVOL], RWVOL, &storeEntry);
+ if (vcode) {
+ fprintf(STDERR,
+ "Could not obtain the VLDB entry for the volume %u\n",
+ entry->volumeId[RWVOL]);
+ error = vcode;
+ goto rvfail;
+ }
+ /* Convert to net order to match entry, which was passed in net order. */
+ MapHostToNetwork(&storeEntry);
+ if (memcmp(entry, &storeEntry, sizeof(*entry)) != 0) {
+ fprintf(STDERR,
+ "VLDB entry for volume %u has changed; "
+ "please reissue the command.\n",
+ entry->volumeId[RWVOL]);
+ error = VL_BADENTRY; /* an arbitrary choice, but closest to the truth */
+ goto rvfail;
+ }
+
strncpy(entry->name, newname, VOLSER_OLDMAXVOLNAME);
+ /* Note that we are reusing storeEntry. */
MapNetworkToHost(entry, &storeEntry);
vcode = VLDB_ReplaceEntry(entry->volumeId[RWVOL], RWVOL, &storeEntry, 0);
if (vcode) {