* directory or online at http://www.openafs.org/dl/license10.html
*/
+#include <afsconfig.h>
#include <afs/param.h>
+
+RCSID("$Header$");
+
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
extern int VL_ReleaseLock();
extern int VL_DeleteEntry();
+void MapNetworkToHost();
+void MapHostToNetwork();
+
struct release {
afs_int32 time;
afs_int32 vldbEntryIndex;
};
/*map the partition <partId> into partition name <partName>*/
+void
MapPartIdIntoName(partId, partName)
afs_int32 partId;
char *partName;
strcpy(partName,"/vicep");
partName[6] = partId + 'a';
partName[7] = '\0';
- return 0;
+ return;
} else if (partId < VOLMAXPARTS) {
strcpy(partName,"/vicep");
partId -= 26;
partName[6] = 'a' + (partId/26);
partName[7] = 'a' + (partId%26);
partName[8] = '\0';
- return 0;
+ return;
}
}
afs_int32 offset;
- initialize_ka_error_table();
- initialize_rxk_error_table();
- initialize_ktc_error_table();
- initialize_acfg_error_table();
- initialize_cmd_error_table();
- initialize_vl_error_table();
+ initialize_KA_error_table();
+ initialize_RXK_error_table();
+ initialize_KTC_error_table();
+ initialize_ACFG_error_table();
+ initialize_CMD_error_table();
+ initialize_VL_error_table();
offset = errcode & ((1<<ERRCODE_RANGE)-1);
fprintf(STDERR,"%s: %s\n",error_table_name (errcode), error_message (errcode));
void EnumerateEntry(entry)
struct nvldbentry *entry;
{
- int i;
- char pname[10];
- int isMixed = 0;
fprintf(STDOUT,"\n");
fprintf(STDOUT,"%s \n",entry->name);
tid = 0;
aconn = (struct rx_connection *)0;
error = 0;
- bzero (&tstatus, sizeof(struct volintInfo));
+ memset(&tstatus, 0, sizeof(struct volintInfo));
tstatus.dayUse = -1;
tstatus.maxquota = aquota;
afs_int32 aid;
{
register struct rx_connection *aconn;
- register afs_int32 code;
afs_int32 error;
- afs_int32 rcode,vcode;
+ afs_int32 vcode;
struct nvldbentry entry,storeEntry;/*the new vldb entry */
aconn = (struct rx_connection *)0;
* clone the read/write volume locally.
* ***/
- if (verbose) fprintf(STDOUT,"Starting transaction on source volume %u ...",afromvol);
+ if (verbose) fprintf(STDOUT,"Starting transaction on source volume %u ...",afromvol);
fflush(STDOUT);
code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
ONERR (code, "Failed to create transaction on the volume %u\n", afromvol);
struct rx_connection *conn;
afs_int32 vid, part, flags;
{
- afs_int32 acode, bcode, ccode, rcode, tid;
+ afs_int32 acode, ccode, rcode, tid;
ccode = rcode = tid = 0;
acode = AFSVolTransCreate(conn, vid, part, flags, &tid);
afs_int32 cloneVolId, roVolId;
struct replica *replicas=0;
struct nvldbentry entry,storeEntry;
- int i, volcount, k, m, n, fullrelease, vldbindex;
+ int i, volcount, m, fullrelease, vldbindex;
int failure;
struct restoreCookie cookie;
struct rx_connection **toconns=0;
afs_int32 clonetid=0, onlinetid;
afs_int32 fromtid=0;
afs_uint32 fromdate, thisdate;
- int ix, si, s;
+ int s;
manyDests tr;
manyResults results;
int rwindex, roindex, roclone, roexists;
int releasecount = 0;
struct volser_status volstatus;
- bzero((char *)remembertime, sizeof(remembertime));
- bzero((char *)&results, sizeof(results));
+ memset((char *)remembertime, 0, sizeof(remembertime));
+ memset((char *)&results, 0, sizeof(results));
vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
if (vcode != VL_RERELEASE)
strcpy(vname, entry.name);
strcat(vname, ".readonly");
- bzero(&cookie,sizeof(cookie));
+ memset(&cookie, 0, sizeof(cookie));
strncpy(cookie.name, vname, VOLSER_OLDMAXVOLNAME);
cookie.type = ROVOL;
cookie.parent = entry.volumeId[RWVOL];
if ( !replicas || !times || !! !results.manyResults_val || !toconns )
ONERROR(ENOMEM, 0, "Failed to create transaction on the release clone\n");
- bzero (replicas, (sizeof(struct replica)*nservers+1));
- bzero (times, (sizeof(struct release)*nservers+1));
- bzero (toconns, (sizeof(struct rx_connection *)*nservers+1));
- bzero (results.manyResults_val, (sizeof(afs_int32)*nservers+1));
+ memset(replicas, 0, (sizeof(struct replica)*nservers+1));
+ memset(times, 0, (sizeof(struct release)*nservers+1));
+ memset(toconns, 0, (sizeof(struct rx_connection *)*nservers+1));
+ memset(results.manyResults_val, 0, (sizeof(afs_int32)*nservers+1));
/* Create a transaction on the cloned volume */
code = AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITBusy, &fromtid);
int islocked;
struct restoreCookie cookie;
int reuseID;
- afs_int32 newDate, volflag;
+ afs_int32 newDate, volflag, voltype, volsertype;
int index, same, errcode;
char apartName[10];
- bzero(&cookie,sizeof(cookie));
+ memset(&cookie, 0, sizeof(cookie));
islocked = 0;
success = 0;
error = 0;
totid = 0;
temptid = 0;
+ if (flags & RV_RDONLY) {
+ voltype = ROVOL;
+ volsertype = volser_RO;
+ } else {
+ voltype = RWVOL;
+ volsertype = volser_RW;
+ }
+
pvolid = tovolid;
toconn = UV_Bind(toserver, AFSCONF_VOLUMEPORT);
if(pvolid == 0) {/*alot a new id if needed */
goto refail;
}
reuseID = 0;
- }
- else{
+ } else if (flags & RV_RDONLY) {
+ if (entry.flags & RW_EXISTS) {
+ fprintf(STDERR,"Entry for ReadWrite volume %s already exists!\n",entry.name);
+ error = VOLSERBADOP;
+ goto refail;
+ }
+ if (!entry.volumeId[ROVOL]) {
+ fprintf(STDERR,"Existing entry for volume %s has no ReadOnly ID\n",tovolname);
+ error = VOLSERBADOP;
+ goto refail;
+ }
+ pvolid = entry.volumeId[ROVOL];
+ } else {
pvolid = entry.volumeId[RWVOL];
}
}/* at this point we have a volume id to use/reuse for the volume to be restored */
fprintf(STDOUT,"Restoring volume %s Id %u on server %s partition %s ..", tovolname,
pvolid, hostutil_GetNameByINet(toserver), partName);
fflush(STDOUT);
- /*what should the volume be restored as ? rw or ro or bk ?
- right now the default is rw always */
- code = AFSVolCreateVolume(toconn, topart, tovolname, volser_RW, 0,&pvolid, &totid);
+ code = AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,&pvolid, &totid);
if (code){
if (flags & RV_FULLRST) { /* full restore: delete then create anew */
if(verbose) {
goto refail;
}
if (verbose) fprintf(STDOUT," done\n");
- code = AFSVolCreateVolume(toconn, topart, tovolname, volser_RW, 0,&pvolid, &totid);
+ code = AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,&pvolid, &totid);
if (code){
fprintf(STDERR,"Could not create new volume %u\n",pvolid);
error = code;
}
}
cookie.parent = pvolid;
- cookie.type = RWVOL;
+ cookie.type = voltype;
cookie.clone = 0;
strncpy(cookie.name,tovolname,VOLSER_OLDMAXVOLNAME);
}
code = AFSVolGetStatus(toconn,totid, &tstatus);
if(code) {
- fprintf(STDERR,"Could not get status information about the volume %u\n",tovolid);
+ fprintf(STDERR,"Could not get status information about the volume %u\n",pvolid);
error = code;
goto refail;
}
- code = AFSVolSetIdsTypes(toconn,totid, tovolname, RWVOL, pvolid,0,0);
+ code = AFSVolSetIdsTypes(toconn,totid, tovolname, voltype, pvolid,0,0);
if(code) {
fprintf(STDERR,"Could not set the right type and ID on %u\n",pvolid);
error = code;
/* Volume was restored on the file server, update the
* VLDB to reflect the change.
*/
- vcode = VLDB_GetEntryByID(pvolid,RWVOL, &entry);
+ vcode = VLDB_GetEntryByID(pvolid,voltype, &entry);
if(vcode && vcode != VL_NOENT && vcode != VL_ENTDELETED) {
fprintf(STDERR,"Could not fetch the entry for volume number %u from VLDB \n",pvolid);
error = vcode;
entry.nServers = 1;
entry.serverNumber[0] = toserver;/*should be indirect */
entry.serverPartition[0] = topart;
- entry.serverFlags[0] = ITSRWVOL;
- entry.flags = RW_EXISTS;
- if(tstatus.cloneID != 0){
+ entry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
+ entry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
+ if (flags & RV_RDONLY)
+ entry.volumeId[ROVOL] = pvolid;
+ else if(tstatus.cloneID != 0){
entry.volumeId[ROVOL] = tstatus.cloneID;/*this should come from status info on the volume if non zero */
}
else
EnumerateEntry(&entry);
fprintf(STDOUT,"------- New entry -------\n");
}
- vcode = ubik_Call(VL_SetLock,cstruct, 0, pvolid, RWVOL, VLOP_RESTORE);
+ vcode = ubik_Call(VL_SetLock,cstruct, 0, pvolid, voltype, VLOP_RESTORE);
if(vcode) {
fprintf(STDERR,"Could not lock the entry for volume number %u \n",pvolid);
error = vcode;
strcpy(entry.name, tovolname);
/* Update the vlentry with the new information */
- index = Lp_GetRwIndex(&entry);
+ if (flags & RV_RDONLY)
+ index = Lp_ROMatch(toserver, topart, &entry) - 1;
+ else
+ index = Lp_GetRwIndex(&entry);
if (index == -1) {
- /* Add the rw site for the volume being restored */
+ /* Add the new site for the volume being restored */
entry.serverNumber[entry.nServers] = toserver;
entry.serverPartition[entry.nServers] = topart;
- entry.serverFlags[entry.nServers] = ITSRWVOL;
+ entry.serverFlags[entry.nServers] =
+ (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
entry.nServers++;
} else {
/* This volume should be deleted on the old site
entry.serverPartition[index] = topart;
}
- entry.flags |= RW_EXISTS;
+ entry.flags |= (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
MapNetworkToHost(&entry,&storeEntry);
- vcode = VLDB_ReplaceEntry(pvolid,RWVOL, &storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP );
+ vcode = VLDB_ReplaceEntry(pvolid,voltype, &storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP );
if(vcode) {
fprintf(STDERR,"Could not update the entry for volume number %u \n",pvolid);
error = vcode;
if (!error) error = code;
}
if(islocked) {
- vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, pvolid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+ vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, pvolid, voltype, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
if(vcode) {
fprintf(STDERR,"Could not release lock on the VLDB entry for the volume %u\n",pvolid);
if(!error) error = vcode;
return 0;
}
+/*sets <server> <part> as read/write site for <volid> in the vldb */
+UV_ChangeLocation(server, part, volid)
+afs_int32 server, part, volid;
+{
+ afs_int32 vcode;
+ struct nvldbentry entry,storeEntry;
+ int index;
+
+ vcode = ubik_Call(VL_SetLock,cstruct, 0,volid,RWVOL, VLOP_ADDSITE);
+ if(vcode) {
+ fprintf(STDERR," Could not lock the VLDB entry for volume %u \n", volid);
+ PrintError("",vcode);
+ return(vcode);
+ }
+ vcode = VLDB_GetEntryByID(volid,RWVOL, &entry);
+ if(vcode) {
+ fprintf(STDERR,"Could not fetch the entry for volume number %u from VLDB \n",volid);
+ PrintError("",vcode);
+ return (vcode);
+ }
+ MapHostToNetwork(&entry);
+ index = Lp_GetRwIndex(&entry);
+ if (index < 0) {
+ /* no RW site exists */
+ fprintf(STDERR,"No existing RW site for volume %u", volid);
+ vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+ if(vcode) {
+ fprintf(STDERR,"Could not release lock on entry for volume %u \n",volid);
+ PrintError("",vcode);
+ return(vcode);
+ }
+ return VOLSERBADOP;
+ }
+ else { /* change the RW site */
+ entry.serverNumber[index] = server;
+ entry.serverPartition[index] = part;
+ MapNetworkToHost(&entry,&storeEntry);
+ vcode = VLDB_ReplaceEntry(volid,RWVOL,&storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+ if(vcode){
+ fprintf(STDERR,"Could not update entry for volume %u \n",volid);
+ PrintError("",vcode);
+ ubik_Call(VL_ReleaseLock,cstruct, 0, volid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+ return(vcode);
+ }
+ if(verbose) fprintf(STDOUT," done\n");
+ }
+ return 0;
+}
+
/*list all the partitions on <aserver> */
UV_ListPartitions(aserver, ptrPartList, cntp)
afs_int32 aserver;
int idx, j;
afs_int32 code, error = 0;
struct nvldbentry entry, storeEntry;
- int sameserver;
char pname[10];
int pass=0, islocked=0, createentry, addvolume, modified, mod;
afs_int32 rwvolid;
ERROR_EXIT(code);
}
- bzero(&entry, sizeof(entry));
+ memset(&entry, 0, sizeof(entry));
vsu_ExtractName(entry.name, volumeinfo->name); /* Store name of RW */
createentry = 1;
afs_int32 *modified;
{
afs_int32 code, error=0;
- int idx;
struct nvldbentry storeEntry;
int islocked=0, mod, modentry, delentry=0;
- int foundro, pass=0;
+ int pass=0;
if (modified) *modified = 0;
if (verbose) {
/* While we need to collect more VLDB entries */
for (si=0; si != -1; si=nsi) {
- bzero(&arrayEntries, sizeof(arrayEntries));
+ memset(&arrayEntries, 0, sizeof(arrayEntries));
/* Collect set of VLDB entries */
code = VLDB_ListAttributesN2(&attributes, 0, si,
error_exit:
if (tid) {
rcode = 0;
- code = AFSVolEndTrans(conn, tid, &code);
+ code = AFSVolEndTrans(conn, tid, &rcode);
if (code || rcode) {
fprintf(STDERR, "SetVolumeStatus: EndTrans Failed\n");
if (!error) error = (code ? code : rcode);
return(error);
}
+UV_SetVolumeInfo(server, partition, volid, infop)
+ afs_int32 server, partition, volid;
+ volintInfo *infop;
+{
+ struct rx_connection *conn = 0;
+ afs_int32 tid=0;
+ afs_int32 code, error=0, rcode;
+
+ conn = UV_Bind(server, AFSCONF_VOLUMEPORT);
+ if (!conn) {
+ fprintf(STDERR, "SetVolumeInfo: Bind Failed");
+ ERROR_EXIT(-1);
+ }
+
+ code = AFSVolTransCreate(conn, volid, partition, ITOffline, &tid);
+ if (code) {
+ fprintf(STDERR, "SetVolumeInfo: TransCreate Failed\n");
+ ERROR_EXIT(code);
+ }
+
+ code = AFSVolSetInfo(conn, tid, infop);
+ if (code) {
+ fprintf(STDERR, "SetVolumeInfo: SetInfo Failed\n");
+ ERROR_EXIT(code);
+ }
+
+ error_exit:
+ if (tid) {
+ rcode = 0;
+ code = AFSVolEndTrans(conn, tid, &rcode);
+ if (code || rcode) {
+ fprintf(STDERR, "SetVolumeInfo: EndTrans Failed\n");
+ if (!error) error = (code ? code : rcode);
+ }
+ }
+
+ if (conn) rx_DestroyConnection(conn);
+ return(error);
+}
+
/*maps the host addresses in <old > (present in network byte order) to
that in< new> (present in host byte order )*/
+void
MapNetworkToHost(old, new)
struct nvldbentry *old, *new;
{
new->volumeId[BACKVOL] = old->volumeId[BACKVOL];
new->cloneId = old->cloneId;
new->flags = old->flags;
-
}
/*maps the host entries in <entry> which are present in host byte order to network byte order */
+void
MapHostToNetwork(entry)
struct nvldbentry *entry;
{