-/* Copyright (C) 1995 Transarc Corporation - All rights reserved */
/*
- * (C) COPYRIGHT IBM CORPORATION 1988
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * 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>
#include <sys/file.h>
#include <netinet/in.h>
#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
#include <lock.h>
#include <afs/voldefs.h>
#include <rx/xdr.h>
#include <afs/procmgmt.h> /* signal(), kill(), wait(), etc. */
#include <setjmp.h>
+#include <volser_prototypes.h>
+
afs_int32 VolumeExists(), CheckVldbRWBK(), CheckVldb();
struct ubik_client *cstruct;
int verbose = 0;
-extern struct rx_securityClass *rxnull_NewClientSecurityObject();
-extern struct rx_connection *rx_NewConnection();
-extern void AFSVolExecuteRequest();
-extern struct rx_securityClass *rxnull_NewServerSecurityObject();
extern int VL_GetNewVolumeId();
extern int VL_SetLock();
extern int VL_ReleaseLock();
extern int VL_DeleteEntry();
+void MapNetworkToHost();
+void MapHostToNetwork();
+
struct release {
afs_int32 time;
afs_int32 vldbEntryIndex;
};
+/* Utility macros used by rest of this source file */
+#define EPRINT(ec, es) \
+ fprintf(STDERR, "\n"); \
+ fprintf(STDERR, (es)); \
+ PrintError(" ",ec);
+
+#define EPRINT1(ec, es, ep1) \
+ fprintf(STDERR, "\n"); \
+ fprintf(STDERR, (es), (ep1)); \
+ PrintError(" ",ec);
+
+#define EPRINT2(ec, es, ep1, ep2) \
+ fprintf(STDERR, "\n"); \
+ fprintf(STDERR, (es), (ep1), (ep2)); \
+ PrintError(" ",ec);
+
+#define EPRINT3(ec, es, ep1, ep2, ep3) \
+ fprintf(STDERR, "\n"); \
+ fprintf(STDERR, (es), (ep1), (ep2), (ep3)); \
+ PrintError(" ",ec);
+
+#define EGOTO(where, ec, es) \
+ if (ec) { \
+ EPRINT((ec),(es)); \
+ error = (ec); \
+ goto where; \
+ }
+
+#define EGOTO1(where, ec, es, ep1) \
+ if (ec) { \
+ EPRINT1((ec),(es),(ep1)); \
+ error = (ec); \
+ goto where; \
+ }
+
+#define EGOTO2(where, ec, es, ep1, ep2) \
+ if (ec) { \
+ EPRINT2((ec),(es),(ep1),(ep2)); \
+ error = (ec); \
+ goto where; \
+ }
+
+#define EGOTO3(where, ec, es, ep1, ep2, ep3) \
+ if (ec) { \
+ EPRINT3((ec),(es),(ep1),(ep2),(ep3)); \
+ error = (ec); \
+ goto where; \
+ }
+
+#define VPRINT(es) \
+ { if (verbose) { fprintf(STDOUT, (es)); fflush(STDOUT); } }
+#define VPRINT1(es, p) \
+ { if (verbose) { fprintf(STDOUT, (es), (p)); fflush(STDOUT); } }
+#define VPRINT2(es, p1, p2) \
+ { if (verbose) { fprintf(STDOUT, (es), (p1), (p2)); fflush(STDOUT); } }
+#define VPRINT3(es, p1, p2, p3) \
+ { if (verbose) { fprintf(STDOUT, (es), (p1), (p2), (p3)); fflush(STDOUT); } }
+#define VDONE \
+ { if (verbose) { fprintf(STDOUT, " done\n"); fflush(STDOUT); } }
+
+
+
+/* getting rid of this */
+#define ERROR_EXIT(code) {error=(code); goto error_exit;}
+
+
+/* Protos for static routines */
+static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn,
+ afs_int32 apart, afs_int32 okvol, afs_int32 delvol);
+static int DelVol (struct rx_connection *conn, afs_int32 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 *timePtr);
+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);
+
+
/*map the partition <partId> into partition name <partName>*/
-MapPartIdIntoName(partId, partName)
-afs_int32 partId;
-char *partName;
+void MapPartIdIntoName(afs_int32 partId, char *partName)
{
if(partId < 26) {/* what if partId > = 26 ? */
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;
}
}
-yesprompt(str)
-char *str;
+int yesprompt(char *str)
{
- char response, c;
+ int response, c;
int code;
fprintf(STDERR, "Do you want to %s? [yn](n): ", str);
}
-PrintError(msg, errcode)
- char *msg;
- afs_int32 errcode;
+int PrintError(char *msg, afs_int32 errcode)
{
fprintf(STDERR,msg);
/*replace by a big switch statement*/
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));
static struct rx_securityClass *uvclass=0;
static int uvindex = -1;
/* called by VLDBClient_Init to set the security module to be used in the RPC */
-UV_SetSecurity(as, aindex)
-register struct rx_securityClass *as;
-afs_int32 aindex; {
+int UV_SetSecurity(register struct rx_securityClass *as, afs_int32 aindex)
+{
uvindex = aindex;
uvclass = as;
}
/* bind to volser on <port> <aserver> */
/* takes server address in network order, port in host order. dumb */
-struct rx_connection *UV_Bind(aserver, port)
-afs_int32 aserver, port;
+struct rx_connection *UV_Bind(afs_int32 aserver, afs_int32 port)
{
register struct rx_connection *tc;
/* if <okvol> is allright(indicated by beibg able to
* start a transaction, delete the <delvol> */
-static afs_int32 CheckAndDeleteVolume(aconn,apart,okvol,delvol)
-struct rx_connection *aconn;
-afs_int32 apart,okvol,delvol;
+static afs_int32 CheckAndDeleteVolume(struct rx_connection *aconn,
+ afs_int32 apart, afs_int32 okvol, afs_int32 delvol)
{
afs_int32 error,code,tid,rcode;
}
/* called by EmuerateEntry, show vldb entry in a reasonable format */
-void SubEnumerateEntry(entry)
-struct nvldbentry *entry;
+void SubEnumerateEntry(struct nvldbentry *entry)
{
int i;
char pname[10];
}
/*enumerate the vldb entry corresponding to <entry> */
-void EnumerateEntry(entry)
-struct nvldbentry *entry;
+void EnumerateEntry(struct nvldbentry *entry)
{
- int i;
- char pname[10];
- int isMixed = 0;
fprintf(STDOUT,"\n");
fprintf(STDOUT,"%s \n",entry->name);
}
/* forcibly remove a volume. Very dangerous call */
-UV_NukeVolume(server, partid, volid)
-afs_int32 server;
-afs_int32 partid, volid; {
+int UV_NukeVolume(afs_int32 server, afs_int32 partid, afs_int32 volid)
+{
register struct rx_connection *tconn;
register afs_int32 code;
}
/* like df. Return usage of <pname> on <server> in <partition> */
-UV_PartitionInfo(server,pname,partition)
-afs_int32 server;
-char *pname;
-struct diskPartition *partition;
+int UV_PartitionInfo(afs_int32 server, char *pname, struct diskPartition *partition)
{
register struct rx_connection *aconn;
afs_int32 code;
}
/* old interface to create volume */
-UV_CreateVolume(aserver, apart, aname, anewid)
-afs_int32 apart, aserver;
-char *aname;
-afs_int32 *anewid;
+int UV_CreateVolume(afs_int32 aserver, afs_int32 apart, char *aname, afs_int32 *anewid)
{
afs_int32 code;
code = UV_CreateVolume2(aserver, apart, aname, 5000, 0, 0, 0, 0, anewid);
/* create a volume, given a server, partition number, volume name --> sends
* back new vol id in <anewid>*/
-UV_CreateVolume2(aserver, apart, aname, aquota, aspare1, aspare2, aspare3, aspare4, anewid)
-afs_int32 apart, aserver;
-afs_int32 aspare1, aspare2, aspare3, aspare4;
-afs_int32 aquota;
-char *aname;
-afs_int32 *anewid;
+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_int32 *anewid)
{
register struct rx_connection *aconn;
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;
aconn = UV_Bind(aserver, AFSCONF_VOLUMEPORT);
/* next the next 3 available ids from the VLDB */
- vcode = ubik_Call(VL_GetNewVolumeId,cstruct, 0, 3, anewid);
- if(vcode) {
- fprintf(STDERR,"Could not get an Id for volume %s\n",aname);
- error = vcode;
- goto cfail;
- }
+ vcode = ubik_Call(VL_GetNewVolumeId, cstruct, 0, 3, anewid);
+ EGOTO1(cfail, vcode, "Could not get an Id for volume %s\n",aname);
+
code = AFSVolCreateVolume(aconn, apart, aname, volser_RW, 0, anewid, &tid);
- if (code) {
- fprintf(STDERR,"Failed to create the volume %s %u \n",aname,*anewid);
- error = code;
- goto cfail;
- }
+ EGOTO2(cfail, vcode, "Failed to create the volume %s %u \n",aname,*anewid);
code = AFSVolSetInfo(aconn, tid, &tstatus);
- if (code) {
- fprintf(STDERR,"Could not change quota (error %d), continuing...\n", code);
- }
+ EPRINT1(code, "Could not change quota (error %d), continuing...\n", code);
code = AFSVolSetFlags(aconn, tid, 0); /* bring it online (mark it InService */
- if (code) {
- fprintf(STDERR,"Could not bring the volume %s %u online \n",aname,*anewid);
- error = code;
- goto cfail;
- }
- if(verbose) fprintf(STDOUT,"Volume %s %u created and brought online\n",aname,*anewid);
+ EGOTO2(cfail, vcode, "Could not bring the volume %s %u online \n",aname,*anewid);
+
+ VPRINT2("Volume %s %u created and brought online\n",aname,*anewid);
+
/* set up the vldb entry for this volume */
strncpy(entry.name, aname,VOLSER_OLDMAXVOLNAME);
entry.nServers = 1;
/* create the vldb entry */
vcode = VLDB_CreateEntry(&storeEntry);
if(vcode) {
- fprintf(STDERR,"Could not create a VLDB entry for the volume %s %u\n", aname,*anewid);
+ fprintf(STDERR,"Could not create a VLDB entry for the volume %s %u\n", aname,*anewid);
/*destroy the created volume*/
- if(verbose) {
- fprintf(STDOUT,"Deleting the newly created volume %u\n",*anewid);
- }
+ VPRINT1("Deleting the newly created volume %u\n",*anewid);
AFSVolDeleteVolume(aconn,tid);
error = vcode;
goto cfail;
}
- if(verbose) fprintf(STDOUT,"Created the VLDB entry for the volume %s %u\n",aname,*anewid);
+ VPRINT2("Created the VLDB entry for the volume %s %u\n",aname,*anewid);
/* volume created, now terminate the transaction and release the connection*/
code = AFSVolEndTrans(aconn, tid, &rcode);/*if it crashes before this
the volume will come online anyway when transaction timesout , so if
}
/* create a volume, given a server, partition number, volume name --> sends
* back new vol id in <anewid>*/
-UV_AddVLDBEntry(aserver, apart, aname, aid)
- afs_int32 apart, aserver;
- char *aname;
- afs_int32 aid;
+int UV_AddVLDBEntry(afs_int32 aserver, afs_int32 apart, char *aname, 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;
error = vcode;
goto cfail;
}
- if(verbose) fprintf(STDOUT,"Created the VLDB entry for the volume %s %u\n",aname,aid);
+ VPRINT2("Created the VLDB entry for the volume %s %u\n",aname,aid);
cfail:
if(aconn) rx_DestroyConnection(aconn);
return error;
}
-#define ERROR_EXIT(code) {error=(code); goto error_exit;}
-
/* Delete the volume <volid>on <aserver> <apart>
* the physical entry gets removed from the vldb only if the ref count
* becomes zero
*/
-UV_DeleteVolume(aserver, apart, avolid)
- afs_int32 aserver, apart, avolid;
+int UV_DeleteVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
{
struct rx_connection *aconn = (struct rx_connection *)0;
afs_int32 ttid = 0;
code = ubik_Call(VL_SetLock, cstruct, 0, avolid, avoltype, VLOP_DELETE);
if (code) {
if (code != VL_NOENT) {
- fprintf(STDERR,"Could not lock VLDB entry for the volume %u\n", avolid);
- ERROR_EXIT(code);
+ EGOTO1(error_exit, code, "Could not lock VLDB entry for the volume %u\n", avolid);
}
notinvldb = 1;
} else {
islocked = 1;
code = VLDB_GetEntryByID(avolid, avoltype, &entry);
- if (code) {
- fprintf(STDERR,"Could not fetch VLDB entry for volume %u\n",avolid);
- ERROR_EXIT(code);
- }
+ EGOTO1(error_exit, code, "Could not fetch VLDB entry for volume %u\n",avolid);
MapHostToNetwork(&entry);
if (verbose)
if (code == VNOVOL) {
notondisk = 1;
} else {
- fprintf(STDERR,"Transaction on volume %u failed\n", avolid);
- ERROR_EXIT(code);
+ EGOTO1(error_exit, code, "Transaction on volume %u failed\n", avolid);
}
}
else {
- if (verbose) {
- fprintf(STDOUT,"Trying to delete the volume %u ...", avolid);
- fflush(STDOUT);
- }
+ VPRINT1("Trying to delete the volume %u ...", avolid);
+
code = AFSVolDeleteVolume(aconn, ttid);
- if (code) {
- fprintf(STDERR,"Could not delete the volume %u \n", avolid);
- ERROR_EXIT(code);
- }
+ EGOTO1(error_exit, code, "Could not delete the volume %u \n", avolid);
+
code = AFSVolEndTrans(aconn, ttid, &rcode);
code = (code ? code : rcode);
ttid = 0;
- if (code) {
- fprintf(STDERR,"Could not end the transaction for the volume %u \n",avolid);
- ERROR_EXIT(code);
- }
- if (verbose)
- fprintf(STDOUT," done\n");
+ EGOTO1(error_exit, code, "Could not end the transaction for the volume %u \n",avolid);
+ VDONE;
}
/* Now update the VLDB entry.
ERROR_EXIT(0);
}
- if (verbose)
- fprintf(STDOUT,"Marking the backup volume %u deleted in the VLDB\n", avolid);
+ VPRINT1("Marking the backup volume %u deleted in the VLDB\n", avolid);
entry.flags &= ~BACK_EXISTS;
vtype = BACKVOL;
fflush(STDOUT);
}
code = AFSVolDeleteVolume(aconn, ttid);
- if (code) {
- fprintf(STDERR,"Could not delete the volume %u \n", entry.volumeId[BACKVOL]);
- ERROR_EXIT(code);
- }
+ 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);
- if (code) {
- fprintf(STDERR,"Could not end the transaction for the volume %u \n",
+ EGOTO1(error_exit, code, "Could not end the transaction for the volume %u \n",
entry.volumeId[BACKVOL]);
- ERROR_EXIT(code);
- }
if (verbose)
fprintf(STDOUT," done\n");
}
if (verbose)
fprintf(STDOUT,"Last reference to the VLDB entry for %u - deleting entry\n", avolid);
code = ubik_Call(VL_DeleteEntry, cstruct, 0, avolid, vtype);
- if (code) {
- fprintf(STDERR,"Could not delete the VLDB entry for the volume %u \n",avolid);
- ERROR_EXIT(code);
- }
+ EGOTO1(error_exit, code, "Could not delete the VLDB entry for the volume %u \n",avolid);
} else {
MapNetworkToHost(&entry, &storeEntry);
code = VLDB_ReplaceEntry(avolid, vtype, &storeEntry,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
- if (code) {
- fprintf(STDERR,"Could not update the VLDB entry for the volume %u \n", avolid);
- ERROR_EXIT(code);
- }
+ EGOTO1(error_exit, code, "Could not update the VLDB entry for the volume %u \n", avolid);
}
islocked = 0;
error_exit:
- if (error) PrintError("", error);
+ if (error) EPRINT(error, "\n");
if (notondisk && notinvldb) {
- fprintf(STDERR,"Volume %u does not exist %s\n",
+ EPRINT2(VOLSERNOVOL,"Volume %u does not exist %s\n",
avolid, ((notinvldb == 2)?"on server and partition":""));
- PrintError("", VOLSERNOVOL);
if (!error) error = VOLSERNOVOL;
}
else if (notondisk) {
code = ubik_Call(VL_ReleaseLock,cstruct, 0, avolid, -1,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
if (code) {
- fprintf(STDERR,"Could not release the lock on the VLDB entry for the volume %u \n",
+ EPRINT1(code, "Could not release the lock on the VLDB entry for the volume %u \n",
avolid);
- PrintError("", code);
if (!error) error = code;
}
}
jmp_buf env;
int interrupt=0;
-void sigint_handler(x)
+void sigint_handler(int x)
{
if(interrupt)
longjmp(env,0);
return;
}
-#define ONERR(ec, es, ep) if (ec) { fprintf(STDERR, (es), (ep)); PrintError(" ",ec); error = (ec); goto mfail; }
-
/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
* <atopart>. The operation is almost idempotent
*/
-UV_MoveVolume(afromvol, afromserver, afrompart, atoserver, atopart)
- afs_int32 afromvol;
- afs_int32 afromserver, atoserver;
- afs_int32 afrompart, atopart;
+int UV_MoveVolume(afs_int32 afromvol, afs_int32 afromserver,
+ afs_int32 afrompart, afs_int32 atoserver, afs_int32 atopart)
{
struct rx_connection *toconn, *fromconn ;
afs_int32 fromtid, totid, clonetid;
}
vcode = VLDB_GetEntryByID(afromvol, -1, &entry);
- ONERR (vcode, "Could not fetch the entry for the volume %u from the VLDB \n", afromvol);
+ EGOTO1(mfail, vcode, "Could not fetch the entry for the volume %u from the VLDB \n", afromvol);
if (entry.volumeId[RWVOL] != afromvol)
{
}
vcode = ubik_Call(VL_SetLock, cstruct, 0,afromvol, RWVOL, VLOP_MOVE);
- ONERR (vcode, "Could not lock entry for volume %u \n", afromvol);
+ EGOTO1(mfail, vcode, "Could not lock entry for volume %u \n", afromvol);
islocked = 1;
vcode = VLDB_GetEntryByID (afromvol, RWVOL, &entry);
- ONERR (vcode, "Could not fetch the entry for the volume %u from the VLDB \n", afromvol);
+ EGOTO1(mfail, vcode, "Could not fetch the entry for the volume %u from the VLDB \n", afromvol);
backupId = entry.volumeId[BACKVOL];
MapHostToNetwork(&entry);
}
vcode = ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
- ONERR (vcode, " Could not release lock on the VLDB entry for the volume %u \n",
+ EGOTO1(mfail, vcode, " Could not release lock on the VLDB entry for the volume %u \n",
afromvol);
return VOLSERVOLMOVED;
code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITOffline, &fromtid);
if (!code)
{ /* volume exists - delete it */
+ VPRINT1("Setting flags on leftover source volume %u ...", afromvol);
code = AFSVolSetFlags(fromconn, fromtid, VTDeleteOnSalvage | VTOutOfService);
- ONERR (code, "Failed to set flags on the volume %u\n", afromvol);
+ 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);
- ONERR (code, "Failed to delete the volume %u\n", afromvol);
+ 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;
- ONERR (code, "Could not end the transaction for the volume %u \n", afromvol);
+ EGOTO1(mfail, code, "Could not end the transaction for the leftover source volume %u \n", afromvol);
+ VDONE;
}
/*delete the backup volume now */
code = AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, &fromtid);
if (!code)
{ /* backup volume exists - delete it */
+ VPRINT1("Setting flags on leftover backup volume %u ...", backupId);
code = AFSVolSetFlags(fromconn, fromtid, VTDeleteOnSalvage | VTOutOfService);
- ONERR (code, "Failed to set flags on the backup volume %u\n", backupId);
+ 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);
- ONERR (code, "Could not delete the backup volume %u\n", backupId);
+ 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;
- ONERR (code,"Could not end the transaction for the backup volume %u \n",backupId);
+ EGOTO1(mfail, code,"Could not end the transaction for the leftover backup volume %u\n",backupId);
+ VDONE;
}
fromtid = 0;
if (afrompart == atopart)
{
same = VLDB_IsSameAddrs (afromserver, atoserver, &error);
- if (error)
+ EGOTO2(mfail, error, "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
+ afromserver, error);
+
+ if ( same )
{
- fprintf(STDERR, "Failed to get info about server's %d address(es) from vlserver (err=%d); aborting call!\n",
- afromserver, error);
- goto mfail;
+ EGOTO1(mfail, VOLSERVOLMOVED, "Warning: Moving volume %u to its home partition ignored!\n", afromvol);
}
- if (same) ONERR (VOLSERVOLMOVED,
- "Warning: Moving volume %u to its home partition ignored!\n", afromvol);
}
pntg = 1;
* clone the read/write volume locally.
* ***/
- if (verbose) fprintf(STDOUT,"Starting transaction on source volume %u ...",afromvol);
- fflush(STDOUT);
+ VPRINT1("Starting transaction on source volume %u ...", afromvol);
code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
- ONERR (code, "Failed to create transaction on the volume %u\n", afromvol);
- if (verbose) fprintf(STDOUT," done\n");
+ 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_Call (VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
- ONERR (vcode, "Could not get an ID for the clone of volume %u from the VLDB\n", afromvol);
+ EGOTO1(mfail, vcode, "Could not get an ID for the clone of volume %u from the VLDB\n", afromvol);
+ VDONE;
/* Do the clone. Default flags on clone are set to delete on salvage and out of service */
- if (verbose) fprintf (STDOUT,"Cloning source volume %u ...", afromvol);
- fflush(STDOUT);
+ VPRINT1("Cloning source volume %u ...", afromvol);
strcpy(vname, "move-clone-temp");
code = AFSVolClone(fromconn, fromtid, 0,readonlyVolume, vname, &newVol);
- ONERR (code, "Failed to clone the source volume %u\n", afromvol);
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to clone the source volume %u\n", afromvol);
+ VDONE;
/* lookup the name of the volume we just cloned */
volid = afromvol;
code = AFSVolGetName(fromconn, fromtid, &volName);
- ONERR (code, "Failed to get the name of the volume %u\n", newVol);
+ EGOTO1(mfail, code, "Failed to get the name of the volume %u\n", newVol);
- if (verbose) fprintf (STDOUT,"Ending the transaction on the source volume %u ...", afromvol);
- fflush(STDOUT);
+ VPRINT1("Ending the transaction on the source volume %u ...", afromvol);
rcode = 0;
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
fromtid = 0;
if (!code) code = rcode;
- ONERR (code, "Failed to end the transaction on the source volume %u\n", afromvol);
- if (verbose) fprintf (STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to end the transaction on the source volume %u\n", afromvol);
+ VDONE;
/* ***
* Create the destination volume
* ***/
- if (verbose) fprintf(STDOUT, "Starting transaction on the cloned volume %u ...", newVol);
- fflush(STDOUT);
+ VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
code = AFSVolTransCreate (fromconn, newVol, afrompart, ITOffline, &clonetid);
- ONERR (code, "Failed to start a transaction on the cloned volume%u\n", newVol);
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to start a transaction on the cloned volume%u\n", newVol);
+ VDONE;
+ VPRINT1("Setting flags on cloned volume %u ...", newVol);
code = AFSVolSetFlags (fromconn, clonetid, VTDeleteOnSalvage|VTOutOfService); /*redundant */
- ONERR (code, "Could not set falgs on the cloned volume %u\n", newVol);
+ EGOTO1(mfail, code, "Could not set falgs on the cloned volume %u\n", newVol);
+ VDONE;
/* remember time from which we've dumped the volume */
+ VPRINT1("Getting status of cloned volume %u ...", newVol);
code = AFSVolGetStatus (fromconn, clonetid, &tstatus);
- ONERR (code, "Failed to get the status of the cloned volume %u\n", newVol);
+ EGOTO1(mfail, code, "Failed to get the status of the cloned volume %u\n", newVol);
+ VDONE;
fromDate = tstatus.creationDate-CLOCKSKEW;
volumeInfo.volEntries_val = (volintInfo *)0;/*this hints the stub to allocate space*/
volumeInfo.volEntries_len = 0;
code = AFSVolListOneVolume(fromconn, afrompart, afromvol, &volumeInfo);
- ONERR (code, "Failed to get the volint Info of the cloned volume %u\n", afromvol);
+ EGOTO1(mfail, code, "Failed to get the volint Info of the cloned volume %u\n", afromvol);
infop = (volintInfo *) volumeInfo.volEntries_val;
infop->maxquota = -1; /* Else it will replace the default quota */
* we started against the cloned volume (clonetid above) will be
* sitting idle. It will get cleaned up after 600 seconds
*/
- if (verbose) fprintf(STDOUT,"Deleting pre-existing volume %u on destination ...",volid);
- fflush(STDOUT);
-
+ VPRINT1("Deleting pre-existing volume %u on destination ...", volid);
code = AFSVolDeleteVolume(toconn, totid);
- ONERR (code, "Could not delete the pre-existing volume %u on destination\n", volid);
+ 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;
- ONERR (code, "Could not end the transaction on pre-existing volume %u on destination\n",
+ EGOTO1(mfail, code, "Could not end the transaction on pre-existing volume %u on destination\n",
volid);
-
- if (verbose) fprintf(STDOUT," done\n");
+ VDONE;
}
- if (verbose) fprintf(STDOUT,"Creating the destination volume %u ...",volid);
- fflush(STDOUT);
+ VPRINT1("Creating the destination volume %u ...", volid);
code = AFSVolCreateVolume (toconn, atopart, volName, volser_RW, volid, &volid, &totid);
- ONERR (code, "Failed to create the destination volume %u\n", volid);
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to create the destination volume %u\n", volid);
+ VDONE;
strncpy(tmpName, volName, VOLSER_OLDMAXVOLNAME);
free(volName);
- volName = (char *) 0;
+ volName = NULL;
+ VPRINT1("Setting volume flags on destination volume %u ...", volid);
code = AFSVolSetFlags (toconn, totid, (VTDeleteOnSalvage | VTOutOfService));
- ONERR(code, "Failed to set the flags on the destination volume %u\n", volid);
+ EGOTO1(mfail, code, "Failed to set the flags on the destination volume %u\n", volid);
+ VDONE;
/***
* Now dump the clone to the new volume
destination.destSSID = 1;
/* Copy the clone to the new volume */
- if (verbose) fprintf(STDOUT, "Dumping from clone %u on source to volume %u on destination ...",
- newVol, afromvol);
- fflush(STDOUT);
+ VPRINT2("Dumping from clone %u on source to volume %u on destination ...", newVol, afromvol);
strncpy(cookie.name,tmpName,VOLSER_OLDMAXVOLNAME);
cookie.type = RWVOL;
cookie.parent = entry.volumeId[RWVOL];
cookie.clone = 0;
code = AFSVolForward(fromconn, clonetid, 0, &destination, totid, &cookie);
- ONERR (code, "Failed to move data for the volume %u\n", volid);
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to move data for the volume %u\n", volid);
+ VDONE;
+ VPRINT1("Ending transaction on cloned volume %u ...", newVol);
code = AFSVolEndTrans(fromconn, clonetid, &rcode);
if (!code) code = rcode;
clonetid = 0;
- ONERR (code, "Failed to end the transaction on the cloned volume %u\n", newVol);
+ EGOTO1(mfail, code, "Failed to end the transaction on the cloned volume %u\n", newVol);
+ VDONE;
/* ***
* reattach to the main-line volume, and incrementally dump it.
* ***/
- if (verbose)
- fprintf(STDOUT,"Doing the incremental dump from source to destination for volume %u ... ",
- afromvol);
- fflush(STDOUT);
-
+ VPRINT1("Starting transaction on source volume %u ...", afromvol);
code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
- ONERR (code, "Failed to create a transaction on the source volume %u\n", afromvol);
+ EGOTO1(mfail, code, "Failed to create a transaction on the source volume %u\n", afromvol);
+ VDONE;
/* now do the incremental */
+ VPRINT1("Doing the incremental dump from source to destination for volume %u ... ", afromvol);
code = AFSVolForward(fromconn, fromtid, fromDate, &destination, totid,&cookie);
- ONERR (code, "Failed to do the incremental dump from rw volume on old site to rw volume on newsite\n", 0);
- if (verbose)fprintf(STDOUT," done\n");
+ EGOTO(mfail, code, "Failed to do the incremental dump from rw volume on old site to rw volume on newsite\n");
+ VDONE;
/* now adjust the flags so that the new volume becomes official */
+ VPRINT1("Setting volume flags on old source volume %u ...", afromvol);
code = AFSVolSetFlags(fromconn, fromtid, VTOutOfService);
- ONERR (code, "Failed to set the flags to make old source volume offline\n", 0);
+ EGOTO(mfail, code, "Failed to set the flags to make old source volume offline\n");
+ VDONE;
+ VPRINT1("Setting volume flags on new source volume %u ...", afromvol);
code = AFSVolSetFlags(toconn, totid, 0);
- ONERR (code, "Failed to set the flags to make new source volume online\n", 0);
+ EGOTO(mfail, code, "Failed to set the flags to make new source volume online\n");
+ VDONE;
#ifdef ENABLE_BUGFIX_1165
+ VPRINT1("Setting volume status on destination volume %u ...", volid);
code = AFSVolSetInfo(toconn, totid, infop);
- ONERR (code, "Failed to set volume status on the destination volume %u\n", volid);
+ EGOTO1(mfail, code, "Failed to set volume status on the destination volume %u\n", volid);
+ VDONE;
#endif
/* put new volume online */
+ VPRINT1("Ending transaction on destination volume %u ...", afromvol);
code = AFSVolEndTrans(toconn, totid, &rcode);
totid = 0;
if (!code) code = rcode;
- ONERR (code, "Failed to end the transaction on the volume %u on the new site\n", afromvol);
+ EGOTO1(mfail, code, "Failed to end the transaction on the volume %u on the new site\n", afromvol);
+ VDONE;
Lp_SetRWValue(&entry, afromserver, afrompart, atoserver, atopart);
MapNetworkToHost(&entry,&storeEntry);
/* or drop through */
}
+ VPRINT1("Releasing lock on VLDB entry for volume %u ...", afromvol);
vcode = VLDB_ReplaceEntry (afromvol, -1, &storeEntry,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
if (vcode)
goto mfail;
}
islocked=0;
+ VDONE;
if (TESTC)
{
if (atoserver != afromserver)
{
/* set forwarding pointer for moved volumes */
+ VPRINT1("Setting forwarding pointer for volume %u ...", afromvol);
code = AFSVolSetForwarding(fromconn, fromtid, atoserver);
- ONERR (code, "Failed to set the forwarding pointer for the volume %u\n", afromvol);
+ EGOTO1(mfail, code, "Failed to set the forwarding pointer for the volume %u\n", afromvol);
+ VDONE;
}
- if (verbose) fprintf(STDOUT,"Deleting old volume %u on source ...", afromvol);
- fflush(STDOUT);
-
+ VPRINT1("Deleting old volume %u on source ...", afromvol);
code = AFSVolDeleteVolume(fromconn,fromtid); /* zap original volume */
- ONERR (code, "Failed to delete the old volume %u on source\n", afromvol);
+ EGOTO1(mfail, code, "Failed to delete the old volume %u on source\n", afromvol);
+ VDONE;
+ VPRINT1("Ending transaction on old volume %u on the source ...", afromvol);
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
fromtid = 0;
if (!code) code = rcode;
- ONERR (code, "Failed to end the transaction on the old volume %u on the source\n", afromvol);
-
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to end the transaction on the old volume %u on the source\n", afromvol);
+ VDONE;
/* Delete the backup volume on the original site */
+ VPRINT1("Creating transaction for backup volume %u on source ...", backupId);
code = AFSVolTransCreate(fromconn, backupId, afrompart, ITOffline, &fromtid);
+ VDONE;
if (!code)
{
- fprintf(STDOUT, "WARNING : Deleting the backup volume %u on the source ...",backupId);
- fflush(STDOUT);
-
+ VPRINT1("Setting flags on backup volume %u on source ...", backupId);
code = AFSVolSetFlags(fromconn, fromtid, VTDeleteOnSalvage | VTOutOfService);
- ONERR (code, "Failed to set the flags on the backup volume on source\n", 0);
+ EGOTO1(mfail, code, "Failed to set the flags on the backup volume %u on the source\n", backupId);
+ VDONE;
+ VPRINT1("Deleting the backup volume %u on the source ...", backupId);
code = AFSVolDeleteVolume(fromconn,fromtid);
- ONERR (code, "Failed to delete the backup volume on source\n", 0);
+ 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;
- ONERR (code, "Failed to end the transaction on the backup volume %u on source\n", 0);
-
- fprintf(STDOUT," done\n");
+ 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 (verbose) fprintf(STDOUT,"Starting transaction on the cloned volume %u ...",newVol);
- fflush(STDOUT);
-
+ VPRINT1("Starting transaction on the cloned volume %u ...", newVol);
code = AFSVolTransCreate(fromconn, newVol, afrompart, ITOffline, &clonetid);
- ONERR (code, "Failed to start a transaction on the cloned volume%u\n", newVol);
-
- if (verbose) fprintf(STDOUT," done\n");
+ EGOTO1(mfail, code, "Failed to start a transaction on the cloned volume%u\n", newVol);
+ VDONE;
/* now delete the clone */
- if (verbose) fprintf(STDOUT,"Deleting the clone %u ...", newVol);
- fflush(STDOUT);
-
+ VPRINT1("Deleting the cloned volume %u ...", newVol);
code = AFSVolDeleteVolume(fromconn, clonetid);
- ONERR (code, "Failed to delete the cloned volume %u\n", newVol);
+ EGOTO1(mfail, code, "Failed to delete the cloned volume %u\n", newVol);
+ VDONE;
- if (verbose) fprintf(STDOUT," done\n");
-
+ VPRINT1("Ending transaction on cloned volume %u ...", newVol);
code = AFSVolEndTrans(fromconn, clonetid, &rcode);
if (!code) code = rcode;
clonetid = 0;
- ONERR (code, "Failed to end the transaction on the cloned volume %u\n", newVol);
+ EGOTO1(mfail, code, "Failed to end the transaction on the cloned volume %u\n", newVol);
+ VDONE;
/* fall through */
/* END OF MOVE */
if (islocked)
{
+ VPRINT1("Cleanup: Releasing VLDB lock on volume %u ...", afromvol);
vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, afromvol, -1,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
if (vcode)
{
+ VPRINT("\n");
fprintf(STDERR," Could not release the lock on the VLDB entry for the volume %u \n",
afromvol);
if (!error) error = vcode;
}
+ VDONE;
}
if (fromtid)
{
+ VPRINT1("Cleanup: Ending transaction on source volume %u ...", afromvol);
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
if (code || rcode)
{
+ VPRINT("\n");
fprintf(STDERR,"Could not end transaction on the source's clone volume %u\n", newVol);
if (!error) error = (code ? code : rcode);
}
+ VDONE;
}
if (clonetid)
{
+ VPRINT1("Cleanup: Ending transaction on clone volume %u ...", newVol);
code = AFSVolEndTrans(fromconn, clonetid, &rcode);
if (code || rcode)
{
+ VPRINT("\n");
fprintf(STDERR,"Could not end transaction on the source's clone volume %u\n",newVol);
if (!error) error = (code ? code : rcode);
}
+ VDONE;
}
if (totid)
{
+ VPRINT1("Cleanup: Ending transaction on destination volume %u ...", afromvol);
code = AFSVolEndTrans(toconn, totid, &rcode);
if (code)
{
+ VPRINT("\n");
fprintf(STDERR,"Could not end transaction on destination volume %u\n",afromvol);
if (!error) error = (code ? code : rcode);
}
+ VDONE;
}
if (volName) free(volName);
#ifdef ENABLE_BUGFIX_1165
/* unlock VLDB entry */
if (islocked)
+ {
+ VPRINT1("Recovery: Releasing VLDB lock on volume %u ...", afromvol);
ubik_Call(VL_ReleaseLock, cstruct, 0, afromvol, -1,
(LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
+ VDONE;
+ }
- if (clonetid) AFSVolEndTrans(fromconn, clonetid, &rcode);
- if (totid) AFSVolEndTrans(toconn, totid, &rcode);
+ if (clonetid)
+ {
+ VPRINT("Recovery: Ending transaction on clone volume ...");
+ AFSVolEndTrans(fromconn, clonetid, &rcode);
+ VDONE;
+ }
+ if (totid)
+ {
+ VPRINT("Recovery: Ending transaction on destination volume ...");
+ AFSVolEndTrans(toconn, totid, &rcode);
+ VDONE;
+ }
if (fromtid)
{ /* put it on-line */
+ VPRINT("Recovery: Setting volume flags on source volume ...");
AFSVolSetFlags(fromconn,fromtid,0);
+ VDONE;
+
+ VPRINT("Recovery: Ending transaction on source volume ...");
AFSVolEndTrans(fromconn, fromtid, &rcode);
+ VDONE;
}
- if (verbose)
- { /* get current VLDB entry */
- fprintf(STDOUT,"access VLDB\n");
- fflush(STDOUT);
- }
+ VPRINT("Recovery: Accessing VLDB.\n");
vcode= VLDB_GetEntryByID (afromvol, -1, &entry);
if (vcode)
{
}
if (volid && toconn) {
+ VPRINT1("Recovery: Creating transaction for destination volume %u ...", volid);
code=AFSVolTransCreate(toconn,volid,atopart, ITOffline,&totid);
+
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) {
+ VPRINT1("Recovery: Creating transaction on source volume %u ...", afromvol);
code=AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Setting flags on source volume %u ...", afromvol);
AFSVolSetFlags(fromconn,fromtid,0);
+ 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);
}
}
}
/* delete backup volume */
if (fromconn) {
+ VPRINT1("Recovery: Creating transaction on backup volume %u ...", backupId);
code=AFSVolTransCreate (fromconn,backupId,afrompart, ITOffline,&fromtid);
if (!code) {
+ VDONE;
+
+ VPRINT1("Recovery: Setting flags on backup volume %u ...", backupId);
AFSVolSetFlags(fromconn,fromtid, VTDeleteOnSalvage | VTOutOfService);
+ VDONE;
+
+ 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);
code=AFSVolTransCreate (fromconn, afromvol, afrompart, ITBusy, &fromtid);
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) {
+ if (newVol) {
+ VPRINT1("Recovery: Creating transaction on clone volume %u ...", newVol);
+ code = AFSVolTransCreate (fromconn, newVol, afrompart, ITOffline, &clonetid);
+ 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 */
+ VPRINT1("Recovery: Releasing lock on VLDB entry for volume %u ...", afromvol);
+ ubik_Call (VL_ReleaseLock, cstruct, 0, afromvol, -1,
+ (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
+ VDONE;
+
+done: /* routine cleanup */
+ if (volName) free(volName);
+#ifdef ENABLE_BUGFIX_1165
+ if (infop) free(infop);
+#endif
+ if (fromconn) rx_DestroyConnection(fromconn);
+ if (toconn) rx_DestroyConnection(toconn);
+
+ if (pntg) {
+ fprintf(STDOUT,"cleanup complete - user verify desired result\n");
+ fflush(STDOUT);
+ }
+ exit(1);
+}
+
+
+/* Move volume <afromvol> on <afromserver> <afrompart> to <atoserver>
+ * <atopart>. The operation is almost idempotent
+ */
+
+int UV_CopyVolume(afs_int32 afromvol, afs_int32 afromserver,
+ afs_int32 afrompart, char *atovolname, afs_int32 atoserver, afs_int32 atopart)
+{
+ struct rx_connection *toconn, *fromconn ;
+ afs_int32 fromtid, totid, clonetid;
+ char vname[64];
+ char tmpName[VOLSER_MAXVOLNAME +1];
+ afs_int32 rcode;
+ afs_int32 fromDate;
+ struct restoreCookie cookie;
+ register afs_int32 vcode, code;
+ afs_int32 cloneVol, newVol;
+ struct volser_status tstatus;
+ struct destServer destination;
+
+ struct nvldbentry entry, newentry, storeEntry;
+ int i, islocked, pntg;
+ afs_int32 error;
+ char in,lf; /* for test code */
+ int same;
+ int justclone = 0;
+
+ islocked = 0;
+ fromconn = (struct rx_connection *)0;
+ toconn = (struct rx_connection *)0;
+ fromtid = 0;
+ totid = 0;
+ clonetid = 0;
+ error = 0;
+ pntg = 0;
+ newVol = 0;
+
+ /* support control-c processing */
+ if (setjmp(env)) goto mfail;
+ (void) signal(SIGINT,sigint_handler);
+
+ vcode = VLDB_GetEntryByID(afromvol, -1, &entry);
+ EGOTO1(mfail, vcode, "Could not fetch the entry for the volume %u from the VLDB \n", afromvol);
+ MapHostToNetwork(&entry);
+
+ pntg = 1;
+ toconn = UV_Bind(atoserver, AFSCONF_VOLUMEPORT); /* get connections to the servers */
+ fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
+ fromtid = totid = 0; /* initialize to uncreated */
+
+
+ /* check if we can shortcut and use a local clone instead of a full copy */
+ if ( afromserver == atoserver && afrompart == atopart )
+ {
+ justclone = 1;
+ }
+
+ /* ***
+ * clone the read/write volume locally.
+ * ***/
+
+ VPRINT1("Starting transaction on source volume %u ...", afromvol);
+ code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ 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_Call (VL_GetNewVolumeId, cstruct, 0, 1, &cloneVol);
+ EGOTO1(mfail, vcode, "Could not get an ID for the clone of volume %u from the VLDB\n", afromvol);
+ VDONE;
+
+ /* Get a new volume id */
+ VPRINT1("Allocating new volume id for copy of volume %u ...", afromvol);
+ newVol = 0;
+ vcode = ubik_Call (VL_GetNewVolumeId, cstruct, 0, 1, &newVol);
+ EGOTO1(mfail, vcode, "Could not get an ID for the copy of volume %u from the VLDB\n", afromvol);
+ VDONE;
+
+ /* 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");
+ code = AFSVolClone(fromconn, fromtid, 0,readonlyVolume, vname, &cloneVol);
+ EGOTO1(mfail, code, "Failed to clone the source volume %u\n", afromvol);
+ VDONE;
+
+ VPRINT1("Ending the transaction on the source volume %u ...", afromvol);
+ rcode = 0;
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code) code = rcode;
+ EGOTO1(mfail, code, "Failed to end the transaction on the source volume %u\n", afromvol);
+ VDONE;
+
+ /* ***
+ * Create the destination volume
+ * ***/
+
+ VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ code = AFSVolTransCreate (fromconn, cloneVol, afrompart, ITOffline, &clonetid);
+ EGOTO1(mfail, code, "Failed to start a transaction on the cloned volume%u\n", cloneVol);
+ VDONE;
+
+ VPRINT1("Setting flags on cloned volume %u ...", cloneVol);
+ code = AFSVolSetFlags (fromconn, clonetid, VTDeleteOnSalvage|VTOutOfService); /*redundant */
+ EGOTO1(mfail, code, "Could not set falgs on the cloned volume %u\n", cloneVol);
+ VDONE;
+
+ /* remember time from which we've dumped the volume */
+ VPRINT1("Getting status of cloned volume %u ...", cloneVol);
+ code = AFSVolGetStatus (fromconn, clonetid, &tstatus);
+ EGOTO1(mfail, code, "Failed to get the status of the cloned volume %u\n", cloneVol);
+ VDONE;
+
+ fromDate = tstatus.creationDate-CLOCKSKEW;
+
+ /* create a volume on the target machine */
+ code = AFSVolTransCreate (toconn, newVol, atopart, ITOffline, &totid);
+ 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 ...", newVol);
+ code = AFSVolDeleteVolume(toconn, totid);
+ EGOTO1(mfail, code, "Could not delete the pre-existing volume %u on destination\n", newVol);
+ VDONE;
+
+ VPRINT1("Ending transaction on pre-existing volume %u on destination ...", newVol);
+ 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",
+ newVol);
+ VDONE;
+ }
+
+ VPRINT1("Creating the destination volume %u ...", newVol);
+ code = AFSVolCreateVolume (toconn, atopart, atovolname, volser_RW, newVol, &newVol, &totid);
+ EGOTO1(mfail, code, "Failed to create the destination volume %u\n", newVol);
+ VDONE;
+
+ strncpy(tmpName, atovolname, VOLSER_OLDMAXVOLNAME);
+
+ VPRINT1("Setting volume flags on destination volume %u ...", newVol);
+ code = AFSVolSetFlags (toconn, totid, (VTDeleteOnSalvage | VTOutOfService));
+ EGOTO1(mfail, code, "Failed to set the flags on the destination volume %u\n", newVol);
+ VDONE;
+
+ /***
+ * Now dump the clone to the new volume
+ ***/
+
+ destination.destHost = ntohl(atoserver);
+ destination.destPort = AFSCONF_VOLUMEPORT;
+ destination.destSSID = 1;
+
+
+/* probably should have some code here that checks to see if we are copying to same server
+and partition - if so, just use a clone to save disk space */
+
+ /* Copy the clone to the new volume */
+ VPRINT2("Dumping from clone %u on source to volume %u on destination ...", cloneVol, newVol);
+ strncpy(cookie.name,tmpName,VOLSER_OLDMAXVOLNAME);
+ cookie.type = RWVOL;
+ cookie.parent = 0;
+ cookie.clone = 0;
+ code = AFSVolForward(fromconn, clonetid, 0, &destination, totid, &cookie);
+ EGOTO1(mfail, code, "Failed to move data for the volume %u\n", newVol);
+ 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;
+
+ /* ***
+ * reattach to the main-line volume, and incrementally dump it.
+ * ***/
+
+ VPRINT1("Starting transaction on source volume %u ...", afromvol);
+ code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ EGOTO1(mfail, code, "Failed to create a transaction on the source volume %u\n", afromvol);
+ VDONE;
+
+ /* now do the incremental */
+ VPRINT1("Doing the incremental dump from source to destination for volume %u ... ", afromvol);
+ code = AFSVolForward(fromconn, fromtid, fromDate, &destination, totid,&cookie);
+ EGOTO(mfail, code, "Failed to do the incremental dump from rw volume on old site to rw volume on newsite\n");
+ VDONE;
+
+ VPRINT1("Setting volume flags on destination volume %u ...", newVol);
+ code = AFSVolSetFlags(toconn, totid, 0);
+ EGOTO(mfail, code, "Failed to set the flags to make destination volume online\n");
+ VDONE;
+
+ /* put new volume online */
+ VPRINT1("Ending transaction on destination volume %u ...", newVol);
+ code = AFSVolEndTrans(toconn, totid, &rcode);
+ totid = 0;
+ if (!code) code = rcode;
+ EGOTO1(mfail, code, "Failed to end the transaction on the destination volume %u\n", newVol);
+ VDONE;
+
+ VPRINT1("Ending transaction on source volume %u ...", afromvol);
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code) code = rcode;
+ EGOTO1(mfail, code, "Failed to end the transaction on the source volume %u\n", afromvol);
+ VDONE;
+
+ fromtid = 0;
+ VPRINT1("Starting transaction on the cloned volume %u ...", cloneVol);
+ code = AFSVolTransCreate(fromconn, cloneVol, afrompart, ITOffline, &clonetid);
+ 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;
+
+ /* create the vldb entry for the copied volume */
+ strncpy(newentry.name, atovolname, VOLSER_OLDMAXVOLNAME);
+ newentry.nServers = 1;
+ newentry.serverNumber[0] = atoserver;
+ newentry.serverPartition[0] = atopart;
+ newentry.flags = RW_EXISTS;/* this records that rw volume exists */
+ newentry.serverFlags[0] = ITSRWVOL; /*this rep site has rw vol */
+ newentry.volumeId[RWVOL] = newVol;
+ newentry.volumeId[ROVOL] = 0;
+ newentry.volumeId[BACKVOL] = 0;
+ newentry.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 */
+ MapNetworkToHost(&newentry,&storeEntry);
+ /* create the vldb entry */
+ vcode = VLDB_CreateEntry(&storeEntry);
+ if(vcode) {
+ fprintf(STDERR,"Could not create a VLDB entry for the volume %s %u\n", atovolname,newVol);
+ /*destroy the created volume*/
+ VPRINT1("Deleting the newly created volume %u\n",newVol);
+ AFSVolDeleteVolume(toconn,totid);
+ error = vcode;
+ goto mfail;
+ }
+ VPRINT2("Created the VLDB entry for the volume %s %u\n",atovolname,newVol);
+
+ /* normal cleanup code */
+
+ if (fromtid)
+ {
+ VPRINT1("Cleanup: Ending transaction on source volume %u ...", afromvol);
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ if (code || rcode)
+ {
+ VPRINT("\n");
+ fprintf(STDERR,"Could not end transaction on the source volume %u\n", afromvol);
+ if (!error) error = (code ? code : rcode);
+ }
+ VDONE;
+ }
+
+ if (clonetid)
+ {
+ VPRINT1("Cleanup: Ending transaction on clone volume %u ...", cloneVol);
+ code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+ if (code || rcode)
+ {
+ VPRINT("\n");
+ fprintf(STDERR,"Could not end transaction on the source's clone volume %u\n",cloneVol);
+ if (!error) error = (code ? code : rcode);
+ }
+ VDONE;
+ }
+
+ if (totid)
+ {
+ VPRINT1("Cleanup: Ending transaction on destination volume %u ...", newVol);
+ code = AFSVolEndTrans(toconn, totid, &rcode);
+ if (code)
+ {
+ VPRINT("\n");
+ fprintf(STDERR,"Could not end transaction on destination volume %u\n", newVol);
+ if (!error) error = (code ? code : rcode);
+ }
+ VDONE;
+ }
+ if (fromconn) rx_DestroyConnection(fromconn);
+ if (toconn) rx_DestroyConnection(toconn);
+ PrintError("",error);
+ return error;
+
+ /* come here only when the sky falls */
+mfail:
+
+ if (pntg)
+ {
+ fprintf(STDOUT,"vos copy: operation interrupted, cleanup in progress...\n");
+ fprintf(STDOUT,"clear transaction contexts\n");
+ fflush(STDOUT);
+ }
+
+ if (clonetid)
+ {
+ VPRINT("Recovery: Ending transaction on clone volume ...");
+ AFSVolEndTrans(fromconn, clonetid, &rcode);
+ VDONE;
+ }
+ if (totid)
+ {
+ VPRINT("Recovery: Ending transaction on destination volume ...");
+ AFSVolEndTrans(toconn, totid, &rcode);
+ VDONE;
+ }
+ if (fromtid)
+ { /* put it on-line */
+ VPRINT("Recovery: Ending transaction on source volume ...");
+ AFSVolEndTrans(fromconn, fromtid, &rcode);
+ VDONE;
+ }
+
+ VPRINT("Recovery: Accessing VLDB.\n");
+ vcode= VLDB_GetEntryByID (afromvol, -1, &entry);
+ if (vcode)
+ {
+ fprintf(STDOUT,"FATAL: VLDB access error: abort cleanup\n");
+ fflush(STDOUT);
+ goto done;
+ }
+ MapHostToNetwork(&entry);
+
+ /* common cleanup - delete local clone */
+ if (cloneVol) {
+ VPRINT1("Recovery: Creating transaction on clone volume %u ...", cloneVol);
code = AFSVolTransCreate (fromconn, newVol, afrompart, ITOffline, &clonetid);
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);
}
}
- /* unlock VLDB entry */
- ubik_Call (VL_ReleaseLock, cstruct, 0, afromvol, -1,
- (LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP));
-
done: /* routine cleanup */
- if (volName) free(volName);
-#ifdef ENABLE_BUGFIX_1165
- if (infop) free(infop);
-#endif
if (fromconn) rx_DestroyConnection(fromconn);
if (toconn) rx_DestroyConnection(toconn);
exit(1);
}
+
+
+
+
/* Make a new backup of volume <avolid> on <aserver> and <apart>
* if one already exists, update it
*/
-UV_BackupVolume(aserver, apart, avolid)
- afs_int32 aserver, apart, avolid;
+int UV_BackupVolume(afs_int32 aserver, afs_int32 apart, afs_int32 avolid)
{
struct rx_connection *aconn = (struct rx_connection *)0;
afs_int32 ttid = 0, btid = 0;
* volume exists or not
*/
if (backexists) {
- if(verbose)
- fprintf(STDOUT,"Re-cloning backup volume %u ...", backupID);
- fflush(STDOUT);
+ VPRINT1("Re-cloning backup volume %u ...", backupID);
code = AFSVolReClone(aconn, ttid, backupID);
if (code) {
}
}
else {
- if (verbose)
- fprintf(STDOUT,"Creating a new backup clone %u ...", backupID);
- fflush(STDOUT);
+ VPRINT1("Creating a new backup clone %u ...", backupID);
strcpy(vname, entry.name);
strcat(vname,".backup");
goto bfail;
}
- if (verbose)
- fprintf(STDOUT,"done\n");
+ VDONE;
/* Will update the vldb below */
return error;
}
-static int DelVol (conn, vid, part, flags)
-struct rx_connection *conn;
-afs_int32 vid, part, flags;
+static int DelVol (struct rx_connection *conn, afs_int32 vid, afs_int32 part, afs_int32 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);
* if necessary. Return the time from which a dump should
* be made (0 if it's a new volume)
*/
-static int GetTrans (vldbEntryPtr, index, connPtr, transPtr, timePtr)
- struct nvldbentry *vldbEntryPtr;
- afs_int32 index;
- struct rx_connection **connPtr;
- afs_int32 *transPtr, *timePtr;
+static int GetTrans (struct nvldbentry *vldbEntryPtr, afs_int32 index, struct rx_connection **connPtr,
+ afs_int32 *transPtr, afs_int32 *timePtr)
{
afs_int32 volid;
struct volser_status tstatus;
}
vldbEntryPtr->volumeId[ROVOL] = volid;
- if (verbose) fprintf(STDOUT,"done.\n");
+ VDONE;
/* The following is a bit redundant, since create sets these flags by default */
code = AFSVolSetFlags(*connPtr, *transPtr, VTDeleteOnSalvage | VTOutOfService);
* latest RO volume on the replication site
*/
else {
- if (verbose) {
- fprintf(STDOUT,"Updating existing ro volume %u on %s ...\n",
- volid, hostutil_GetNameByINet(vldbEntryPtr->serverNumber[index]));
- fflush(STDOUT);
- }
+ VPRINT2("Updating existing ro volume %u on %s ...\n",
+ volid, hostutil_GetNameByINet(vldbEntryPtr->serverNumber[index]));
code = AFSVolGetStatus(*connPtr, *transPtr, &tstatus);
if (code) {
return code;
}
-static int SimulateForwardMultiple(fromconn, fromtid, fromdate, tr,
- flags, cookie, results)
-struct rx_connection *fromconn;
-afs_int32 fromtid, fromdate, flags;
-manyDests *tr;
-void *cookie;
-manyResults *results;
+static int SimulateForwardMultiple(struct rx_connection *fromconn, afs_int32 fromtid,
+ afs_int32 fromdate, manyDests *tr, afs_int32 flags, void *cookie, manyResults *results)
{
int i;
}
-static int rel_compar (r1, r2)
- struct release *r1, *r2;
+static int rel_compar (struct release *r1, struct release *r2)
{
return (r1->time - r2->time);
}
* the time: Influences when we write back the VLDB entry.
*/
-UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
- afs_int32 afromserver;
- afs_int32 afrompart;
- afs_int32 afromvol;
- int forceflag;
+int UV_ReleaseVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart, int forceflag)
{
char vname[64];
afs_int32 code, vcode, rcode, tcode;
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)
/* Clone or reclone the volume */
if (roexists) {
- if (verbose)
- fprintf(STDERR, "Recloning RW volume ...\n");
-
+ VPRINT1("Recloning RW volume %u...", cloneVolId);
code = AFSVolReClone(fromconn, clonetid, cloneVolId);
ONERROR(code, afromvol, "Failed to reclone the RW volume %u\n");
+ VDONE;
} else {
if (roclone) {
strcpy(vname, entry.name);
strcat(vname, ".readonly");
- if (verbose)
- fprintf(STDERR, "Cloning RW volume ...\n");
+ VPRINT("Cloning RW volume %u to permanent RO...");
} else {
strcpy(vname, "readonly-clone-temp");
- if (verbose)
- fprintf(STDERR, "Cloning RW volume to temporary RO ...\n");
+ VPRINT("Cloning RW volume %u to temporary RO...");
}
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...", cloneVolId);
code = AFSVolGetStatus(fromconn, clonetid, &volstatus);
ONERROR(code, cloneVolId, "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...", cloneVolId);
code = AFSVolEndTrans(fromconn, clonetid, &rcode);
clonetid = 0;
ONERROR((code?code:rcode), cloneVolId, "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) {
/* Bring the RO clone online - though not if it's a temporary clone */
+ VPRINT1("Starting transaction on RO clone volume %u...", cloneVolId);
code = AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITOffline, &onlinetid);
ONERROR(code, cloneVolId, "Failed to start transaction on volume %u\n");
+ VDONE;
+ VPRINT1("Setting volume flags for volume %u...", cloneVolId);
tcode = AFSVolSetFlags(fromconn, onlinetid, 0);
+ VDONE;
+ VPRINT1("Ending transaction on volume %u...", cloneVolId);
code = AFSVolEndTrans(fromconn, onlinetid, &rcode);
ONERROR((code?code:rcode), cloneVolId, "Failed to end transaction on RO clone %u\n");
+ VDONE;
ONERROR(tcode, cloneVolId, "Could not bring volume %u on line\n");
* temporarily unavailable.
*/
MapNetworkToHost(&entry, &storeEntry);
+ VPRINT1("Replacing VLDB entry for %s...", entry.name);
vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry, 0);
ONERROR(vcode, entry.name, "Could not update vldb entry for %s.\n");
+ VDONE;
}
}
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 */
+ VPRINT1("Starting transaction on cloned volume %u...", cloneVolId);
code = AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITBusy, &fromtid);
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");
+ VDONE;
/* For each index in the VLDB */
for (vldbindex=0; vldbindex<entry.nServers; ) {
}
code = DelVol (fromconn, cloneVolId, afrompart, ITOffline);
ONERROR (code, cloneVolId, "Failed to delete volume %u.\n");
- if (verbose)
- fprintf(STDOUT," done\n");
+ VDONE;
}
entry.cloneId = 0;
entry.serverFlags[i] &= ~NEW_REPSITE;
/* Update the VLDB */
- if (verbose) {
- fprintf(STDOUT,"updating VLDB ...");
- fflush(STDOUT);
- }
+ VPRINT("updating VLDB ...");
+
MapNetworkToHost(&entry, &storeEntry);
vcode = VLDB_ReplaceEntry(afromvol, RWVOL, &storeEntry,
LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
ONERROR(vcode, afromvol, " Could not update VLDB entry for volume %u\n");
- if (verbose)
- fprintf(STDOUT," done\n");
+ VDONE;
rfail:
if (clonetid) {
}
-void dump_sig_handler(x)
+void dump_sig_handler(int x)
{
fprintf(STDERR,"\nSignal handler: vos dump operation\n");
longjmp(env,0);
* DumpFunction does the real work behind the scenes after
* extracting parameters from the rock
*/
-UV_DumpVolume(afromvol, afromserver, afrompart, fromdate, DumpFunction, rock)
- afs_int32 afromserver;
- afs_int32 afrompart;
- afs_int32 afromvol;
- afs_int32 fromdate;
- afs_int32 (*DumpFunction)();
- char *rock;
+int UV_DumpVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+ afs_int32 fromdate, afs_int32 (*DumpFunction)(), char *rock)
{
struct rx_connection *fromconn = (struct rx_connection *)0;
struct rx_call *fromcall = (struct rx_call *)0;
#endif
(void) signal(SIGINT, dump_sig_handler);
+ if (!fromdate)
+ {
+ VPRINT("Full Dump ...\n");
+ }
+ else
+ {
+ VPRINT1("Incremental Dump (as of %.24s)...\n", ctime((time_t *)&fromdate));
+ }
+
/* get connections to the servers */
fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
- code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
- if (code) {
- fprintf(STDERR,"Could not start transaction on the volume %u to be dumped\n", afromvol);
- ERROR_EXIT(code);
- }
- if (verbose) {
- if (!fromdate)
- fprintf(STDERR,"Full Dump ...");
- else
- fprintf(STDERR,"Incremental Dump (as of %.24s) ...",
- ctime((time_t *)&fromdate));
- fflush(STDERR);
- }
+ VPRINT1("Starting transaction on volume %u...", afromvol);
+ code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ EGOTO1(error_exit, code, "Could not start transaction on the volume %u to be dumped\n", afromvol);
+ VDONE;
fromcall = rx_NewCall(fromconn);
+
+ VPRINT1("Starting volume dump on volume %u...", afromvol);
code = StartAFSVolDump(fromcall, fromtid, fromdate);
- if (code) {
- fprintf(STDERR,"Could not start the dump process \n");
- ERROR_EXIT(code);
- }
- if (code = DumpFunction(fromcall, rock)) {
- fprintf(STDERR,"Error while dumping volume \n");
- ERROR_EXIT(code);
- }
+ EGOTO(error_exit, code, "Could not start the dump process \n");
+ VDONE;
- if (verbose)
- fprintf(STDERR,"completed\n");
+ VPRINT1("Dumping volume %u...", afromvol);
+ code = DumpFunction(fromcall, rock);
+ EGOTO(error_exit, code, "Error while dumping volume \n");
+ VDONE;
error_exit:
if (fromcall) {
}
}
if (fromtid) {
+ VPRINT1("Ending transaction on volume %u...", afromvol);
code = AFSVolEndTrans(fromconn, fromtid, &rcode);
if (code || rcode) {
fprintf(STDERR,"Could not end transaction on the volume %u\n", afromvol);
if (!error) error = (code?code:rcode);
}
+ VDONE;
}
if (fromconn)
rx_DestroyConnection(fromconn);
return(error);
}
+/* Clone the volume <afromvol> on <afromserver> and
+ * <afrompart>, and then dump the clone volume to
+ * <afilename> starting from <fromdate>.
+ * DumpFunction does the real work behind the scenes after
+ * extracting parameters from the rock
+ */
+int UV_DumpClonedVolume(afs_int32 afromvol, afs_int32 afromserver, afs_int32 afrompart,
+ afs_int32 fromdate, afs_int32 (*DumpFunction)(), char *rock)
+{
+ 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 clonetid=0;
+ afs_int32 code=0, vcode=0, error = 0;
+ afs_int32 clonevol=0;
+ char vname[64];
+
+ if (setjmp(env)) ERROR_EXIT(EPIPE);
+#ifndef AFS_NT40_ENV
+ (void) signal(SIGPIPE, dump_sig_handler);
+#endif
+ (void) signal(SIGINT, dump_sig_handler);
+
+ if (!fromdate)
+ {
+ VPRINT("Full Dump ...\n");
+ }
+ else
+ {
+ VPRINT1("Incremental Dump (as of %.24s)...\n", ctime((time_t *)&fromdate));
+ }
+
+ /* get connections to the servers */
+ fromconn = UV_Bind(afromserver, AFSCONF_VOLUMEPORT);
+
+ VPRINT1("Starting transaction on volume %u...", afromvol);
+ code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
+ EGOTO1(error_exit, code, "Could not start transaction on the volume %u to be dumped\n", afromvol);
+ VDONE;
+
+ /* Get a clone id */
+ VPRINT1("Allocating new volume id for clone of volume %u ...", afromvol);
+ code = ubik_Call (VL_GetNewVolumeId, cstruct, 0, 1, &clonevol);
+ EGOTO1(error_exit, code, "Could not get an ID for the clone of volume %u from the VLDB\n", afromvol);
+ VDONE;
+
+ /* Do the clone. Default flags on clone are set to delete on salvage and out of service */
+ VPRINT2("Cloning source volume %u to clone volume %u...", afromvol, clonevol);
+ strcpy(vname, "dump-clone-temp");
+ code = AFSVolClone(fromconn, fromtid, 0, readonlyVolume, vname, &clonevol);
+ EGOTO1(error_exit, code, "Failed to clone the source volume %u\n", afromvol);
+ VDONE;
+
+ VPRINT1("Ending the transaction on the volume %u ...", afromvol);
+ rcode = 0;
+ code = AFSVolEndTrans(fromconn, fromtid, &rcode);
+ fromtid = 0;
+ if (!code) code = rcode;
+ EGOTO1(error_exit, code, "Failed to end the transaction on the volume %u\n", afromvol);
+ VDONE;
+
+
+ VPRINT1("Starting transaction on the cloned volume %u ...", clonevol);
+ code = AFSVolTransCreate (fromconn, clonevol, afrompart, ITOffline, &clonetid);
+ EGOTO1(error_exit, code, "Failed to start a transaction on the cloned volume%u\n", clonevol);
+ VDONE;
+
+ VPRINT1("Setting flags on cloned volume %u ...", clonevol);
+ code = AFSVolSetFlags (fromconn, clonetid, VTDeleteOnSalvage|VTOutOfService); /*redundant */
+ EGOTO1(error_exit, code, "Could not set falgs on the cloned volume %u\n", clonevol);
+ VDONE;
+
+
+ fromcall = rx_NewCall(fromconn);
+
+ VPRINT1("Starting volume dump from cloned volume %u...", clonevol);
+ code = StartAFSVolDump(fromcall, clonetid, fromdate);
+ EGOTO(error_exit, code, "Could not start the dump process \n");
+ VDONE;
+
+ VPRINT1("Dumping volume %u...", afromvol);
+ code = DumpFunction(fromcall, rock);
+ EGOTO(error_exit, code, "Error while dumping volume \n");
+ VDONE;
+
+ error_exit:
+ /* now delete the clone */
+ VPRINT1("Deleting the cloned volume %u ...", clonevol);
+ code = AFSVolDeleteVolume(fromconn, clonetid);
+ if ( code )
+ {
+ fprintf(STDERR,"Failed to delete the cloned volume %u\n", clonevol);
+ }
+ else
+ {
+ VDONE;
+ }
+
+ if (fromcall) {
+ code = rx_EndCall(fromcall, rxError);
+ if (code) {
+ fprintf(STDERR,"Error in rx_EndCall\n");
+ if (!error) error = code;
+ }
+ }
+ if (fromtid) {
+ VPRINT1("Ending transaction on cloned volume %u...", clonevol);
+ code = AFSVolEndTrans(fromconn, clonetid, &rcode);
+ if (code || rcode) {
+ fprintf(STDERR,"Could not end transaction on the cloned volume %u\n", clonevol);
+ if (!error) error = (code?code:rcode);
+ }
+ VDONE;
+ }
+ if (fromconn)
+ rx_DestroyConnection(fromconn);
+
+ PrintError("", error);
+ return(error);
+}
+
+
/*
* Restore a volume <tovolid> <tovolname> on <toserver> <topart> from
* the dump file <afilename>. WriteData does all the real work
* after extracting params from the rock
*/
-UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
- afs_int32 toserver, topart, tovolid;
- char tovolname[];
- int flags;
- afs_int32 (*WriteData)();
- char *rock;
+int UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
+ char tovolname[], int flags, afs_int32 (*WriteData)(), char *rock)
{
struct rx_connection *toconn,*tempconn;
struct rx_call *tocall;
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 */
if(strlen(tovolname) > (VOLSER_OLDMAXVOLNAME - 1)) {
- fprintf(STDERR,"The volume name %s exceeds the maximum limit of (VOLSER_OLDMAXVOLNAME -1 ) bytes\n",tovolname);
- error = VOLSERBADOP;
- goto refail;
+ EGOTO1(refail, VOLSERBADOP, "The volume name %s exceeds the maximum limit of (VOLSER_OLDMAXVOLNAME -1 ) bytes\n",tovolname);
}
MapPartIdIntoName(topart, partName);
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) {
- fprintf(STDOUT,"Deleting the previous volume %u ...",pvolid);
- fflush(STDOUT);
- }
+ VPRINT1("Deleting the previous volume %u ...",pvolid);
+
code = AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
- if (code) {
- fprintf(STDERR,"Failed to start transaction on %u\n",pvolid);
- error = code;
- goto refail;
- }
+ EGOTO1(refail, code, "Failed to start transaction on %u\n",pvolid);
+
code = AFSVolSetFlags(toconn, totid, VTDeleteOnSalvage | VTOutOfService);
- if (code){
- fprintf(STDERR,"Could not set flags on volume %u \n",pvolid);
- error = code;
- goto refail;
- }
+ EGOTO1(refail, code, "Could not set flags on volume %u \n",pvolid);
+
code = AFSVolDeleteVolume(toconn,totid);
- if (code){
- fprintf(STDERR,"Could not delete volume %u\n",pvolid);
- error = code;
- goto refail;
- }
+ EGOTO1(refail, code, "Could not delete volume %u\n",pvolid);
+
code = AFSVolEndTrans(toconn, totid, &rcode);
totid = 0;
if (!code) code = rcode;
- if (code) {
- fprintf(STDERR,"Could not end transaction on %u\n",pvolid);
- error = code;
- goto refail;
- }
- if (verbose) fprintf(STDOUT," done\n");
- code = AFSVolCreateVolume(toconn, topart, tovolname, volser_RW, 0,&pvolid, &totid);
- if (code){
- fprintf(STDERR,"Could not create new volume %u\n",pvolid);
- error = code;
- goto refail;}
+ EGOTO1(refail, code, "Could not end transaction on %u\n",pvolid);
+
+ VDONE;
+
+ code = AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,&pvolid, &totid);
+ EGOTO1(refail, code, "Could not create new volume %u\n",pvolid);
}
else{
-
code = AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
- if (code) {
- fprintf(STDERR,"Failed to start transaction on %u\n",pvolid);
- error = code;
- goto refail;
- }
+ EGOTO1(refail, code, "Failed to start transaction on %u\n",pvolid);
}
}
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;
if (!vcode) MapHostToNetwork(&entry);
if(vcode == VL_NOENT) { /* it doesnot exist already */
/*make the vldb return this indication specifically*/
- if (verbose) fprintf(STDOUT,"------- Creating a new VLDB entry ------- \n");
+ VPRINT("------- Creating a new VLDB entry ------- \n");
strcpy(entry.name, tovolname);
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
* if its different from new site.
*/
same = VLDB_IsSameAddrs(toserver, entry.serverNumber[index], &errcode);
- if (errcode) {
- fprintf(STDERR,"Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
+ EPRINT2(errcode, "Failed to get info about server's %d address(es) from vlserver (err=%d)\n",
toserver, errcode);
- }
if ( (!errcode && !same) || (entry.serverPartition[index] != topart) ) {
tempconn = UV_Bind(entry.serverNumber[index], AFSCONF_VOLUMEPORT);
- if (verbose) {
- MapPartIdIntoName(entry.serverPartition[index], apartName);
- fprintf(STDOUT,"Deleting the previous volume %u on server %s, partition %s ...",
+
+ MapPartIdIntoName(entry.serverPartition[index], apartName);
+ VPRINT3("Deleting the previous volume %u on server %s, partition %s ...",
pvolid,
hostutil_GetNameByINet(entry.serverNumber[index]), apartName);
- fflush(STDOUT);
- }
code = AFSVolTransCreate(tempconn, pvolid, entry.serverPartition[index], ITOffline, &temptid);
if (!code){
code = AFSVolSetFlags(tempconn, temptid, VTDeleteOnSalvage | VTOutOfService);
error = code;
goto refail;
}
- if(verbose) fprintf(STDOUT," done\n");
+ VDONE;
MapPartIdIntoName(entry.serverPartition[index],partName);
}
}
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;
/*unlocks the vldb entry associated with <volid> */
-UV_LockRelease(volid)
-afs_int32 volid;
+int UV_LockRelease(afs_int32 volid)
{
afs_int32 vcode;
- if (verbose) fprintf(STDERR,"Binding to the VLDB server\n");
+ VPRINT("Binding to the VLDB server\n");
vcode = ubik_Call(VL_ReleaseLock,cstruct, 0,volid,-1,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP );
if(vcode) {
fprintf(STDERR,"Could not unlock the entry for volume number %u in VLDB \n",volid);
PrintError("",vcode);
return (vcode);
}
- if (verbose) fprintf(STDERR,"VLDB updated\n");
+ VPRINT("VLDB updated\n");
return 0;
}
/*adds <server> and <part> as a readonly replication site for <volid>
*in vldb */
-UV_AddSite(server, part, volid)
-afs_int32 server, part, volid;
+int UV_AddSite(afs_int32 server, afs_int32 part, afs_int32 volid)
{
int j, nro=0, islocked=0;
struct nvldbentry entry,storeEntry;
goto asfail;
}
- if (verbose) fprintf(STDOUT,"Adding a new site ...");
- fflush(STDOUT);
+ VPRINT("Adding a new site ...");
entry.serverNumber[entry.nServers] = server;
entry.serverPartition[entry.nServers] = part;
entry.serverFlags[entry.nServers] = (ITSROVOL | RO_DONTUSE);
goto asfail;
}
islocked = 0;
- if (verbose) fprintf(STDOUT," done\n");
+ VDONE;
asfail:
if (islocked) {
}
/*removes <server> <part> as read only site for <volid> from the vldb */
-UV_RemoveSite(server, part, volid)
-afs_int32 server, part, volid;
+int UV_RemoveSite(afs_int32 server, afs_int32 part, afs_int32 volid)
{
afs_int32 vcode;
struct nvldbentry entry,storeEntry;
if((entry.nServers == 1) && (entry.flags & RW_EXISTS))
entry.flags &= ~RO_EXISTS;
if(entry.nServers < 1) { /*this is the last ref */
- if(verbose) fprintf(STDOUT,"Deleting the VLDB entry for %u ...",volid);
+ VPRINT1("Deleting the VLDB entry for %u ...",volid);
fflush(STDOUT);
vcode = ubik_Call(VL_DeleteEntry,cstruct, 0,volid, ROVOL);
if(vcode) {
PrintError("",vcode);
return(vcode);
}
- if (verbose) fprintf(STDOUT," done\n");
+ VDONE;
}
MapNetworkToHost(&entry,&storeEntry);
fprintf(STDOUT,"Deleting the replication site for volume %u ...",volid);
ubik_Call(VL_ReleaseLock,cstruct, 0, volid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
return(vcode);
}
- if(verbose) fprintf(STDOUT," done\n");
+ VDONE;
+ }
+ return 0;
+}
+
+/*sets <server> <part> as read/write site for <volid> in the vldb */
+int UV_ChangeLocation(afs_int32 server, afs_int32 part, afs_int32 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);
+ }
+ VDONE;
}
return 0;
}
/*list all the partitions on <aserver> */
-UV_ListPartitions(aserver, ptrPartList, cntp)
- afs_int32 aserver;
- struct partList *ptrPartList;
- afs_int32 *cntp;
+int UV_ListPartitions(afs_int32 aserver, struct partList *ptrPartList, afs_int32 *cntp)
{
struct rx_connection *aconn;
struct pIDs partIds;
aconn = UV_Bind(aserver,AFSCONF_VOLUMEPORT);
partEnts.partEntries_len = 0;
- partEnts.partEntries_val = (afs_int32 *)0;
+ partEnts.partEntries_val = NULL;
code = AFSVolXListPartitions(aconn, &partEnts); /* this is available only on new servers */
if (code == RXGEN_OPCODE)
{
/*zap the list of volumes specified by volPtrArray (the volCloneId field).
This is used by the backup system */
-UV_ZapVolumeClones(aserver,apart,volPtr,arraySize)
-afs_int32 aserver, apart;
-afs_int32 arraySize;
-struct volDescription *volPtr;
+int UV_ZapVolumeClones(afs_int32 aserver, afs_int32 apart, struct volDescription *volPtr, afs_int32 arraySize)
{
struct rx_connection *aconn;
struct volDescription *curPtr;
}
if(success) curPtr->volFlags |= CLONEZAPPED;
if(!success) fprintf(STDERR,"Could not zap volume %u\n",curPtr->volCloneId);
- if(success && verbose) fprintf(STDOUT,"Clone of %s %u deleted\n", curPtr->volName,curPtr->volCloneId);
+ if(success) VPRINT2("Clone of %s %u deleted\n", curPtr->volName,curPtr->volCloneId);
curPos++;
tid = 0;
}
/*return a list of clones of the volumes specified by volPtrArray. Used by the
backup system */
-UV_GenerateVolumeClones(aserver,apart,volPtr,arraySize)
-afs_int32 aserver, apart;
-afs_int32 arraySize;
-struct volDescription *volPtr;
+int UV_GenerateVolumeClones(afs_int32 aserver, afs_int32 apart, struct volDescription *volPtr, afs_int32 arraySize)
{
struct rx_connection *aconn;
struct volDescription *curPtr;
curPtr->volFlags |= CLONEVALID;
/*make a clone of curParentId and record as curPtr->volCloneId */
code = AFSVolTransCreate(aconn, curPtr->volId, apart, ITOffline, &tid);
- if(verbose && code) fprintf(STDERR,"Clone for volume %s %u failed \n",curPtr->volName,curPtr->volId);
+ if(code) VPRINT2("Clone for volume %s %u failed \n",curPtr->volName,curPtr->volId);
if(code) {
curPtr->volFlags &= ~CLONEVALID; /*cant clone */
curPos++;
fprintf(STDERR,"WARNING: could not end transaction\n");
continue;
}
- if(verbose) fprintf(STDOUT,"********** Cloned %s temporary %u\n",cloneName,curPtr->volCloneId);
+ VPRINT2("********** Cloned %s temporary %u\n",cloneName,curPtr->volCloneId);
code = AFSVolEndTrans(aconn, tid, &rcode);
if(code || rcode) {
curPtr->volFlags &= ~CLONEVALID;
/*list all the volumes on <aserver> and <apart>. If all = 1, then all the
* relevant fields of the volume are also returned. This is a heavy weight operation.*/
-UV_ListVolumes(aserver,apart,all,resultPtr,size)
-afs_int32 aserver, apart;
-int all ;
-struct volintInfo **resultPtr;
-afs_int32 *size;
+int UV_ListVolumes(afs_int32 aserver, afs_int32 apart, int all, struct volintInfo **resultPtr, afs_int32 *size)
{
struct rx_connection *aconn;
afs_int32 code = 0;
* As advertised.
*------------------------------------------------------------------------*/
-UV_XListVolumes(a_serverID, a_partID, a_all, a_resultPP, a_numEntsInResultP)
- afs_int32 a_serverID;
- afs_int32 a_partID;
- int a_all;
- struct volintXInfo **a_resultPP;
- afs_int32 *a_numEntsInResultP;
-
-{ /*UV_XListVolumes*/
-
+int UV_XListVolumes(afs_int32 a_serverID, afs_int32 a_partID, int a_all,
+ struct volintXInfo **a_resultPP, afs_int32 *a_numEntsInResultP)
+{
struct rx_connection *rxConnP; /*Ptr to the Rx connection involved*/
afs_int32 code; /*Error code to return*/
volXEntries volumeXInfo; /*Area for returned extended vol info*/
} /*UV_XListVolumes*/
/* get all the information about volume <volid> on <aserver> and <apart> */
-UV_ListOneVolume(aserver,apart,volid,resultPtr)
-afs_int32 aserver, apart;
-afs_int32 volid;
-struct volintInfo **resultPtr;
+int UV_ListOneVolume(afs_int32 aserver, afs_int32 apart, afs_int32 volid, struct volintInfo **resultPtr)
{
struct rx_connection *aconn;
afs_int32 code = 0;
* As advertised.
*------------------------------------------------------------------------*/
-UV_XListOneVolume(a_serverID, a_partID, a_volID, a_resultPP)
- afs_int32 a_serverID;
- afs_int32 a_partID;
- afs_int32 a_volID;
- struct volintXInfo **a_resultPP;
-
-{ /*UV_XListOneVolume*/
+int UV_XListOneVolume(afs_int32 a_serverID, afs_int32 a_partID,
+ afs_int32 a_volID, struct volintXInfo **a_resultPP)
+{
struct rx_connection *rxConnP; /*Rx connection to Volume Server*/
afs_int32 code; /*Error code*/
volXEntries volumeXInfo; /*Area for returned info*/
PrintError("",code);
return code;
-} /*UV_XListOneVolume*/
+}
/* CheckVolume()
* Given a volume we read from a partition, check if it is
* VLDB entries are locked only when a change needs to be done.
* Output changed to look a lot like the "vos syncserv" otuput.
*/
-static afs_int32 CheckVolume(volumeinfo, aserver, apart, modentry, maxvolid)
- volintInfo *volumeinfo;
- afs_int32 aserver, apart;
- afs_int32 *modentry;
- afs_uint32 *maxvolid;
+static afs_int32 CheckVolume(volintInfo *volumeinfo, afs_int32 aserver, afs_int32 apart,
+ afs_int32 *modentry, afs_uint32 *maxvolid)
{
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;
if (entry.serverFlags[j] & ITSROVOL) {
/* Verify this volume exists and print message we are orphaning it */
if (pass == 1) {
- MapPartIdIntoName(apart, entry.serverPartition[j]);
+ MapPartIdIntoName(apart, pname);
fprintf(STDERR,"*** Warning: Orphaned RO volume %u exists on %s %s\n",
entry.volumeId[ROVOL],
hostutil_GetNameByINet(entry.serverNumber[j]), pname);
}
error_exit:
- if (verbose) {
- fprintf(STDOUT,"\n_______________________________\n");
- }
+ VPRINT("\n_______________________________\n");
return(error);
}
-int sortVolumes(v1, v2)
- volintInfo *v1, *v2;
+int sortVolumes(const void *a, const void *b)
{
+ volintInfo *v1 = (volintInfo *)a;
+ volintInfo *v2 = (volintInfo *)b;
afs_int32 rwvolid1, rwvolid2;
rwvolid1 = ((v1->type == RWVOL) ? v1->volid : v1->parentID);
* Checks the VLDB entry (similar to syncserv) as well as checks
* if the volume exists on specified servers (similar to syncvldb).
*/
-UV_SyncVolume(aserver, apart, avolname, flags)
- afs_int32 aserver, apart;
- char *avolname;
- int flags;
+int UV_SyncVolume(afs_int32 aserver, afs_int32 apart, char *avolname, int flags)
{
struct rx_connection *aconn = 0;
afs_int32 j, k, code, vcode, error = 0;
aconn = UV_Bind(aserver,AFSCONF_VOLUMEPORT);
/* If a volume ID were given, search for it on each partition */
- if (volumeid = atol(avolname)) {
+ if ((volumeid = atol(avolname))) {
for (j=0; j<pcnt; j++) {
code = AFSVolListOneVolume(aconn, PartList.partId[j], volumeid, &volumeInfo);
if (code) {
if (modified && (code == VL_NOENT)) {
fprintf(STDOUT,"\n**entry deleted**\n");
} else if (modified) {
- EnumerateEntry(vldbentry);
+ EnumerateEntry(&vldbentry);
} else {
fprintf(STDOUT,"\n**no change**\n");
}
* Synchronise vldb with the file server <aserver> and,
* optionally, <apart>.
*/
-UV_SyncVldb(aserver, apart, flags, force)
- afs_int32 aserver, apart;
- int flags, force;
+int UV_SyncVldb(afs_int32 aserver, afs_int32 apart, int flags, int force)
{
struct rx_connection *aconn;
afs_int32 code, error=0;
pcnt = 1;
}
- if (verbose) {
- fprintf(STDOUT,"Processing volume entries ...\n");
- fflush(STDOUT);
- }
-
+ VPRINT("Processing volume entries ...\n");
+
/* Step through the array of partitions */
for (i = 0; i < pcnt; i++) {
apart = PartList.partId[i];
}/* thru all partitions */
- if (verbose) {
- fprintf(STDOUT, "Total entries: %u, Failed to process %d, Changed %d\n",
+ VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n",
tentries, failures, modifications);
- }
error_exit:
/* Now check if the maxvolid is larger than that stored in the VLDB */
* Some error codes mean the volume is unavailable but
* still exists - so we catch these error codes.
*/
-afs_int32 VolumeExists(server, partition, volumeid)
- afs_int32 server, partition, volumeid;
+afs_int32 VolumeExists(afs_int32 server, afs_int32 partition, afs_int32 volumeid)
{
struct rx_connection *conn=(struct rx_connection *)0;
afs_int32 code = -1;
/* CheckVldbRWBK()
*
*/
-afs_int32 CheckVldbRWBK(entry, modified)
- struct nvldbentry *entry;
- afs_int32 *modified;
+afs_int32 CheckVldbRWBK(struct nvldbentry *entry, afs_int32 *modified)
{
int modentry = 0;
int idx;
return(error);
}
-CheckVldbRO(entry, modified)
- struct nvldbentry *entry;
- afs_int32 *modified;
+int CheckVldbRO(struct nvldbentry *entry, afs_int32 *modified)
{
int idx;
int foundro = 0, modentry = 0;
/* CheckVldb()
* Ensure that <entry> matches with the info on file servers
*/
-afs_int32 CheckVldb(entry, modified)
- struct nvldbentry *entry;
- afs_int32 *modified;
+afs_int32 CheckVldb(struct nvldbentry *entry, 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) {
}
error_exit:
- if (verbose) {
- fprintf(STDOUT,"\n_______________________________\n");
- }
+ VPRINT("\n_______________________________\n");
if (islocked) {
code = ubik_Call(VL_ReleaseLock, cstruct, 0, entry->volumeId[RWVOL], RWVOL,
/* UV_SyncServer()
* Synchronise <aserver> <apart>(if flags = 1) with the VLDB.
*/
-UV_SyncServer(aserver, apart, flags, force)
- afs_int32 aserver, apart;
- int flags, force;
+int UV_SyncServer(afs_int32 aserver, afs_int32 apart, int flags, int force)
{
struct rx_connection *aconn;
afs_int32 code, error = 0;
attributes.Mask |= VLLIST_PARTITION;
}
- if (verbose) {
- fprintf(STDOUT,"Processing VLDB entries ...\n");
- fflush(STDOUT);
- }
+ VPRINT("Processing VLDB entries ...\n");
/* 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,
vlentry = &arrayEntries.nbulkentries_val[j];
MapHostToNetwork(vlentry);
- if (verbose) {
- fprintf(STDOUT,"Processing VLDB entry %d ...\n", j+1);
- fflush(STDOUT);
- }
+ VPRINT1("Processing VLDB entry %d ...\n", j+1);
code = CheckVldb(vlentry, &modified);
if (code) {
}
}
- if (verbose) {
- fprintf(STDOUT,"Total entries: %u, Failed to process %d, Changed %d\n",
+ VPRINT3("Total entries: %u, Failed to process %d, Changed %d\n",
tentries, failures, modifications);
- }
error_exit:
if (aconn)
*readonly and backup volumes. This operation is also idempotent.
*salvager is capable of recovering from rename operation stopping halfway.
*to recover run syncserver on the affected machines,it will force renaming to completion. name clashes should have been detected before calling this proc */
-UV_RenameVolume(entry,oldname,newname)
-struct nvldbentry *entry;
-char oldname[],newname[];
+int UV_RenameVolume(struct nvldbentry *entry, char oldname[], char newname[])
{
struct nvldbentry storeEntry;
afs_int32 vcode,code,rcode,error;
error = vcode;
goto rvfail;
}
- if(verbose) fprintf(STDOUT,"Recorded the new name %s in VLDB\n",newname);
+ VPRINT1("Recorded the new name %s in VLDB\n",newname);
/*at this stage the intent to rename is recorded in the vldb, as far as the vldb
is concerned, oldname is lost */
if(entry->flags & RW_EXISTS) {
code = AFSVolSetIdsTypes(aconn, tid, newname,RWVOL, entry->volumeId[RWVOL],entry->volumeId[ROVOL],entry->volumeId[BACKVOL]);
if(!code) {
- if(verbose) printf("Renamed rw volume %s to %s\n",oldname,newname);
+ VPRINT2("Renamed rw volume %s to %s\n",oldname,newname);
code = AFSVolEndTrans(aconn, tid, &rcode);
tid = 0;
if(code) {
code = AFSVolSetIdsTypes(aconn, tid,nameBuffer ,BACKVOL, entry->volumeId[RWVOL],0,0);
if(!code) {
- if(verbose) fprintf(STDOUT,"Renamed backup volume to %s \n",nameBuffer);
+ VPRINT1("Renamed backup volume to %s \n",nameBuffer);
code = AFSVolEndTrans(aconn, tid, &rcode);
tid = 0;
if(code) {
}
code = AFSVolSetIdsTypes(aconn, tid, nameBuffer,ROVOL, entry->volumeId[RWVOL],0,0);
if(!code) {
- if(verbose) fprintf(STDOUT,"Renamed RO volume %s on host %s\n",
+ VPRINT2("Renamed RO volume %s on host %s\n",
nameBuffer,
hostutil_GetNameByINet(entry->serverNumber[i]));
code = AFSVolEndTrans(aconn, tid, &rcode);
}
/*report on all the active transactions on volser */
-UV_VolserStatus(server,rpntr,rcount)
-afs_int32 server;
-transDebugInfo **rpntr;
-afs_int32 *rcount;
+int UV_VolserStatus(afs_int32 server, transDebugInfo **rpntr, afs_int32 *rcount)
{
struct rx_connection *aconn;
transDebugEntries transInfo;
}
-/*delete the volume without interacting with the vldb */
-UV_VolumeZap(server,part,volid)
-afs_int32 volid,server,part;
+/*delete the volume without interacting with the vldb */
+int UV_VolumeZap(afs_int32 server, afs_int32 part, afs_int32 volid)
{
afs_int32 rcode,ttid,error,code;
struct rx_connection *aconn;
return error;
}
-UV_SetVolume(server, partition, volid, transflag, setflag, sleeptime)
- afs_int32 server, partition, volid, transflag, setflag;
+int UV_SetVolume(afs_int32 server, afs_int32 partition, afs_int32 volid, afs_int32 transflag, afs_int32 setflag, int sleeptime)
{
struct rx_connection *conn = 0;
afs_int32 tid=0;
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);
}
+int UV_SetVolumeInfo(afs_int32 server, afs_int32 partition, afs_int32 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 )*/
-MapNetworkToHost(old, new)
-struct nvldbentry *old, *new;
+void MapNetworkToHost(struct nvldbentry *old, struct nvldbentry *new)
{
int i,count;
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 */
-MapHostToNetwork(entry)
-struct nvldbentry *entry;
+void MapHostToNetwork(struct nvldbentry *entry)
{
int i,count;