#include <afs/nfs.h> /* yuck. This is an abomination. */
#include <lwp.h>
#include <rx/rx.h>
-#include <afs/afscbint.h>
+#include <afscbint.h>
#include <afs/afsutil.h>
#include <lock.h>
#include <afs/ihandle.h>
#include <afs/vnode.h>
#include <afs/volume.h>
+#include "viced_prototypes.h"
#include "viced.h"
#include <afs/ptclient.h> /* need definition of prlist for host.h */
#include "host.h"
-
+extern afsUUID FS_HostUUID;
extern int hostCount;
int ShowProblems = 1;
/* max time to break a callback, otherwise client is dead or net is hosed */
#define MAXCBT 25
-#define u_short unsigned short
#define u_byte unsigned char
struct cbcounters cbstuff;
struct cbstruct {
struct host * hp;
- u_short thead;
+ afs_uint32 thead;
} ;
struct FileEntry {
- afs_uint32 vnode; /* XXX This was u_short XXX */
- afs_uint32 unique;
+ afs_uint32 vnode;
+ afs_uint32 unique;
afs_uint32 volid;
- u_short fnext;
- u_short ncbs;
- u_short firstcb;
- u_short spare;
-#if defined(AFS_ALPHA_ENV) || defined(AFS_ALPHA_LINUX20_ENV)
- u_short spare1;
- u_short spare2;
-#endif
+ afs_uint32 fnext;
+ afs_uint32 ncbs;
+ afs_uint32 firstcb;
+ afs_uint32 status;
+ afs_uint32 spare;
} *FE; /* Don't use FE[0] */
+#define FE_LATER 0x1
struct CallBack {
- u_short cnext; /* Next call back entry */
- u_short fhead; /* Head of this call back chain */
+ afs_uint32 cnext; /* Next call back entry */
+ afs_uint32 fhead; /* Head of this call back chain */
u_byte thead; /* Head of timeout chain */
u_byte status; /* Call back status; see definitions, below */
- u_short hhead; /* Head of host table chain */
- u_short tprev, tnext; /* Timeout chain */
- u_short hprev, hnext; /* Chain from host table */
+ afs_uint32 hhead; /* Head of host table chain */
+ afs_uint32 tprev, tnext; /* Timeout chain */
+ afs_uint32 hprev, hnext; /* Chain from host table */
+ unsigned short spare; /* make it a multiple of 32 bits. */
} *CB; /* Don't use CB[0] */
-/* status bits for status field of CallBack structure */
+/* status values for status field of CallBack structure */
#define CB_NORMAL 1 /* Normal call back */
#define CB_DELAYED 2 /* Delayed call back due to rpc problems.
The call back entry will be added back to the
#define ServerBias (3*60)
/* Heads of CB queues; a timeout index is 1+index into this array */
-static u_short timeout[128];
+static afs_uint32 timeout[128];
/* Convert cbtime to timeout queue index */
#define TIndex(cbtime) (((cbtime)&127)+1)
struct VCBParams {
struct cbstruct cba[MAX_CB_HOSTS]; /* re-entrant storage */
unsigned int ncbas;
- unsigned short thead; /* head of timeout queue for youngest callback */
+ afs_uint32 thead; /* head of timeout queue for youngest callback */
struct AFSFid *fid;
};
static int iFreeCB(register struct CallBack *cb, register int *nused);
static struct FileEntry *iGetFE(register int *nused);
static int iFreeFE(register struct FileEntry *fe, register int *nused);
-static int TAdd(register struct CallBack *cb, register u_short *thead);
+static int TAdd(register struct CallBack *cb, register afs_uint32 *thead);
static int TDel(register struct CallBack *cb);
static int HAdd(register struct CallBack *cb, register struct host *host);
static int HDel(register struct CallBack *cb);
-static int CDel(struct CallBack *cb);
-static int CDelPtr(register struct FileEntry *fe, register u_short *cbp);
-static u_short *FindCBPtr(struct FileEntry *fe, struct host *host);
+static int CDel(struct CallBack *cb, int deletefe);
+static int CDelPtr(register struct FileEntry *fe, register afs_uint32 *cbp, int deletefe);
+static afs_uint32 *FindCBPtr(struct FileEntry *fe, struct host *host);
static int FDel(register struct FileEntry *fe);
-static int AddCallBack1_r(struct host *host, AFSFid *fid, u_short *thead, int type, int locked);
+static int AddCallBack1_r(struct host *host, AFSFid *fid, afs_uint32 *thead, int type, int locked);
static void MultiBreakCallBack_r(struct cbstruct cba[], int ncbas, struct AFSCBFids *afidp, struct host *xhost);
-static int MultiBreakVolumeCallBack_r(struct host *host, int isheld, struct VCBParams *parms);
+static int MultiBreakVolumeCallBack_r(struct host *host, int isheld, struct VCBParams *parms, int deletefe);
static int MultiBreakVolumeCallBack(struct host *host, int isheld, struct VCBParams *parms);
+static int MultiBreakVolumeLaterCallBack(struct host *host, int isheld, struct VCBParams *parms);
static int lih_r(register struct host *host, register int held, register struct host *hostp);
static int GetSomeSpace_r(struct host *hostp, int locked);
extern void ShutDown();
#define VHASH 512 /* Power of 2 */
-static u_short HashTable[VHASH]; /* File entry hash table */
+static afs_uint32 HashTable[VHASH]; /* File entry hash table */
#define VHash(volume, unique) (((volume)+(unique))&(VHASH-1))
static struct FileEntry *FindFE (register AFSFid *fid)
}
/* Add cb to end of specified timeout list */
-static int TAdd(register struct CallBack *cb, register u_short *thead)
+static int TAdd(register struct CallBack *cb, register afs_uint32 *thead)
{
if (!*thead) {
(*thead) = cb->tnext = cb->tprev = cbtoi(cb);
/* Delete call back entry from timeout list */
static int TDel(register struct CallBack *cb)
{
- register u_short *thead = itot(cb->thead);
+ register afs_uint32 *thead = itot(cb->thead);
if (*thead == cbtoi(cb))
*thead = (*thead == cb->tnext? 0: cb->tnext);
/* Delete call back entry from host list */
static int HDel(register struct CallBack *cb)
{
- register u_short *hhead = &h_itoh(cb->hhead)->cblist;
+ register afs_uint32 *hhead = &h_itoh(cb->hhead)->cblist;
if (*hhead == cbtoi(cb))
*hhead = (*hhead == cb->hnext? 0: cb->hnext);
/* N.B. This one also deletes the CB, and also possibly parent FE, so
* make sure that it is not on any other list before calling this
* routine */
-static int CDel(struct CallBack *cb)
+static int CDel(struct CallBack *cb, int deletefe)
{
int cbi = cbtoi(cb);
struct FileEntry *fe = itofe(cb->fhead);
- register u_short *cbp;
+ register afs_uint32 *cbp;
register int safety;
for (safety = 0, cbp = &fe->firstcb; *cbp && *cbp != cbi;
ShutDown();
}
}
- CDelPtr(fe, cbp);
+ CDelPtr(fe, cbp, deletefe);
return 0;
}
int Ccdelpt=0, CcdelB=0;
static int CDelPtr(register struct FileEntry *fe,
- register u_short *cbp)
+ register afs_uint32 *cbp, int deletefe)
{
register struct CallBack *cb;
CcdelB++;
*cbp = cb->cnext;
FreeCB(cb);
- if (--fe->ncbs == 0)
+ if (deletefe && (--fe->ncbs == 0))
FDel(fe);
return 0;
}
-static u_short *FindCBPtr(struct FileEntry *fe, struct host *host)
+static afs_uint32 *FindCBPtr(struct FileEntry *fe, struct host *host)
{
register afs_uint32 hostindex = h_htoi(host);
register struct CallBack *cb;
- register u_short *cbp;
+ register afs_uint32 *cbp;
register int safety;
for (safety = 0, cbp = &fe->firstcb; *cbp; cbp = &cb->cnext, safety++) {
static int FDel(register struct FileEntry *fe)
{
register int fei = fetoi(fe);
- register unsigned short *p = &HashTable[VHash(fe->volid, fe->unique)];
+ register afs_uint32 *p = &HashTable[VHash(fe->volid, fe->unique)];
while (*p && *p != fei)
p = &itofe(*p)->fnext;
{
H_LOCK
tfirst = CBtime(FT_ApproxTime());
- /* N.B. FE's, CB's share same free list. If the sizes of either change,
- FE and CB will have to be separated. The "-1", below, is because
+ /* N.B. The "-1", below, is because
FE[0] and CB[0] are not used--and not allocated */
FE = ((struct FileEntry *)(malloc(sizeof(struct FileEntry)*nblks)))-1;
+ if (!FE) {
+ ViceLog(0, ("Failed malloc in InitCallBack\n"));
+ assert(0);
+ }
cbstuff.nFEs = nblks;
while (cbstuff.nFEs)
FreeFE(&FE[cbstuff.nFEs]); /* This is correct */
CB = ((struct CallBack *)(malloc(sizeof(struct CallBack)*nblks)))-1;
+ if (!CB) {
+ ViceLog(0, ("Failed malloc in InitCallBack\n"));
+ assert(0);
+ }
cbstuff.nCBs = nblks;
while (cbstuff.nCBs)
FreeCB(&CB[cbstuff.nCBs]); /* This is correct */
* as well. If so, the host->ResetDone should probably be set to 0,
* and we probably don't want to return a callback promise to the
* cache manager, either. */
-int AddCallBack1(struct host *host, AFSFid *fid, u_short *thead,
+int AddCallBack1(struct host *host, AFSFid *fid, afs_uint32 *thead,
int type, int locked)
{
int retVal;
return retVal;
}
-static int AddCallBack1_r(struct host *host, AFSFid *fid, u_short *thead,
+static int AddCallBack1_r(struct host *host, AFSFid *fid, afs_uint32 *thead,
int type, int locked)
{
struct FileEntry *fe;
struct CallBack *cb = 0, *lastcb = 0;
struct FileEntry *newfe = 0;
afs_uint32 time_out;
- u_short *Thead = thead;
+ afs_uint32 *Thead = thead;
struct CallBack *newcb = 0;
int safety;
multi_Rx(conns, j) {
multi_RXAFSCB_CallBack(afidp, &tc);
if (multi_error) {
- unsigned short idx ;
+ afs_uint32 idx ;
struct host *hp;
char hoststr[16];
ViceLog(7,
("BCB: Failed on file %u.%d.%d, host %s:%d is down\n",
afidp->AFSCBFids_val->Volume, afidp->AFSCBFids_val->Vnode,
- afidp->AFSCBFids_val->Unique, afs_inet_ntoa_r(hp->host,hoststr), hp->port));
+ afidp->AFSCBFids_val->Unique, afs_inet_ntoa_r(hp->host,hoststr), ntohs(hp->port)));
}
H_LOCK
char hoststr[16];
ViceLog(7,("BCB: BreakCallBack(all but %s:%d, (%u,%d,%d))\n",
- afs_inet_ntoa_r(xhost->host,hoststr), xhost->port, fid->Volume, fid->Vnode,
+ afs_inet_ntoa_r(xhost->host,hoststr), ntohs(xhost->port), fid->Volume, fid->Vnode,
fid->Unique));
H_LOCK
}
else if (thishost->hostFlags & VENUSDOWN) {
ViceLog(7,("BCB: %s:%d is down; delaying break call back\n",
- afs_inet_ntoa_r(thishost->host,hoststr), thishost->port));
+ afs_inet_ntoa_r(thishost->host,hoststr), ntohs(thishost->port)));
cb->status = CB_DELAYED;
}
else {
ncbas++;
TDel(cb);
HDel(cb);
- CDel(cb); /* Usually first; so this delete */
- /* is reasonably inexpensive */
+ CDel(cb, 1); /* Usually first; so this delete
+ is reasonably inexpensive */
}
}
}
int DeleteCallBack(struct host *host, AFSFid *fid)
{
register struct FileEntry *fe;
- register u_short *pcb;
+ register afs_uint32 *pcb;
char hoststr[16];
cbstuff.DeleteCallBacks++;
pcb = FindCBPtr(fe, host);
if (!*pcb) {
ViceLog(8,("DCB: No call back for host %s:%d, (%u, %d, %d)\n",
- afs_inet_ntoa_r(host->host,hoststr), host->port, fid->Volume, fid->Vnode, fid->Unique));
+ afs_inet_ntoa_r(host->host,hoststr), ntohs(host->port), fid->Volume, fid->Vnode, fid->Unique));
h_Unlock_r(host);
H_UNLOCK
return 0;
}
HDel(itocb(*pcb));
TDel(itocb(*pcb));
- CDelPtr(fe, pcb);
+ CDelPtr(fe, pcb, 1);
h_Unlock_r(host);
H_UNLOCK
return 0;
/* Delete (do not break) all call backs for host. The host should be
* locked. */
-int DeleteAllCallBacks(struct host *host)
-{
- int retVal;
- H_LOCK
- retVal = DeleteAllCallBacks_r(host);
- H_UNLOCK
- return retVal;
-}
-
-int DeleteAllCallBacks_r(struct host *host)
+int DeleteAllCallBacks_r(struct host *host, int deletefe)
{
register struct CallBack *cb;
register int cbi, first;
cb = itocb(cbi);
cbi = cb->hnext;
TDel(cb);
- CDel(cb);
+ CDel(cb, deletefe);
} while (cbi != first);
host->cblist = 0;
return 0;
return retVal;
}
-extern afsUUID FS_HostUUID;
-
int BreakDelayedCallBacks_r(struct host *host)
{
struct AFSFid fids[AFSCBMAX];
- u_short thead[AFSCBMAX];
+ u_byte thead[AFSCBMAX]; /* This should match thead in struct Callback */
int cbi, first, nfids;
struct CallBack *cb;
struct interfaceAddr interf;
if (ShowProblems) {
ViceLog(0,
("CB: Call back connect back failed (in break delayed) for %s:%d\n",
- afs_inet_ntoa_r(host->host,hoststr), host->port));
+ afs_inet_ntoa_r(host->host,hoststr), ntohs(host->port)));
}
host->hostFlags |= VENUSDOWN;
}
nfids++;
HDel(cb);
TDel(cb);
- CDel(cb);
+ CDel(cb, 1);
}
} while (cbi && cbi != first && nfids < AFSCBMAX);
if (ShowProblems) {
ViceLog(0,
("CB: XCallBackBulk failed, host=%s:%d; callback list follows:\n",
- afs_inet_ntoa_r(host->host,hoststr), host->port));
+ afs_inet_ntoa_r(host->host,hoststr), ntohs(host->port)));
}
for (i = 0; i<nfids; i++) {
if (ShowProblems) {
ViceLog(0,
("CB: Host %s:%d, file %u.%u.%u (part of bulk callback)\n",
- afs_inet_ntoa_r(host->host,hoststr), host->port,
+ afs_inet_ntoa_r(host->host,hoststr), ntohs(host->port),
fids[i].Volume, fids[i].Vnode, fids[i].Unique));
}
/* used to do this:
}
cbstuff.nbreakers--;
+ /* If we succeeded it's always ok to unset HFE_LATER */
+ if (!host->hostFlags & VENUSDOWN)
+ host->hostFlags &= ~HFE_LATER;
return (host->hostFlags & VENUSDOWN);
}
** isheld is 1 if the host is held in BreakVolumeCallBacks
*/
static int MultiBreakVolumeCallBack_r(struct host *host,
- int isheld, struct VCBParams *parms)
+ int isheld, struct VCBParams *parms, int deletefe)
{
char hoststr[16];
return 0; /* Release hold */
}
ViceLog(8,("BVCB: volume call back for host %s:%d failed\n",
- afs_inet_ntoa_r(host->host,hoststr),host->port));
+ afs_inet_ntoa_r(host->host,hoststr),ntohs(host->port)));
if (ShowProblems) {
ViceLog(0, ("CB: volume callback for host %s:%d failed\n",
- afs_inet_ntoa_r(host->host,hoststr), host->port));
+ afs_inet_ntoa_r(host->host,hoststr), ntohs(host->port)));
}
- DeleteAllCallBacks_r(host); /* Delete all callback state rather than
- attempting to selectively remember to
- delete the volume callbacks later */
+ DeleteAllCallBacks_r(host, deletefe); /* Delete all callback state
+ rather than attempting to
+ selectively remember to
+ delete the volume callbacks
+ later */
host->hostFlags &= ~RESETDONE; /* Do InitCallBackState when host returns */
h_Unlock_r(host);
return 0; /* release hold */
{
int retval;
H_LOCK
- retval = MultiBreakVolumeCallBack_r(host, isheld, parms);
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
+ H_UNLOCK
+ return retval;
+}
+
+/*
+** isheld is 0 if the host is held in h_Enumerate
+** isheld is 1 if the host is held in BreakVolumeCallBacks
+*/
+static int MultiBreakVolumeLaterCallBack(struct host *host, int isheld,
+ struct VCBParams *parms)
+{
+ int retval;
+ H_LOCK
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
H_UNLOCK
return retval;
}
{
struct AFSFid fid;
int hash;
- u_short *feip;
+ afs_uint32 *feip;
struct CallBack *cb;
struct FileEntry *fe;
struct host *host;
struct VCBParams henumParms;
- unsigned short tthead = 0; /* zero is illegal value */
+ afs_uint32 tthead = 0; /* zero is illegal value */
H_LOCK
fid.Volume = volume, fid.Vnode = fid.Unique = 0;
return 0;
}
+#ifdef AFS_PTHREAD_ENV
+extern pthread_cond_t fsync_cond;
+#else
+extern char fsync_wait[];
+#endif
+
+int BreakVolumeCallBacksLater(afs_uint32 volume)
+{
+ int hash;
+ afs_int32 *feip;
+ struct FileEntry *fe;
+ struct CallBack *cb;
+ struct host *host;
+ int found = 0;
+
+ ViceLog(25, ("Setting later on volume %d\n", volume));
+ H_LOCK
+ for (hash=0; hash<VHASH; hash++) {
+ for (feip = &HashTable[hash]; fe = itofe(*feip); ) {
+ if (fe->volid == volume) {
+ register struct CallBack *cbnext;
+ for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
+ host = h_itoh(cb->hhead);
+ host->hostFlags |= HFE_LATER;
+ cb->status = CB_DELAYED;
+ cbnext = itocb(cb->cnext);
+ }
+ FSYNC_LOCK
+ fe->status |= FE_LATER;
+ FSYNC_UNLOCK
+ found++;
+ }
+ feip = &fe->fnext;
+ }
+ }
+ H_UNLOCK
+
+ if (!found) {
+ /* didn't find any callbacks, so return right away. */
+ return 0;
+ }
+
+ ViceLog(25, ("Fsync thread wakeup\n"));
+#ifdef AFS_PTHREAD_ENV
+ assert(pthread_cond_broadcast(&fsync_cond) == 0);
+#else
+ LWP_NoYieldSignal(&fsync_wait);
+#endif
+ return 0;
+}
+
+int BreakLaterCallBacks(void)
+{
+ struct AFSFid fid;
+ int hash;
+ afs_int32 *feip;
+ struct CallBack *cb;
+ struct FileEntry *fe = NULL;
+ struct FileEntry *myfe = NULL;
+ struct host *host;
+ struct VCBParams henumParms;
+ unsigned short tthead = 0; /* zero is illegal value */
+
+ /* Unchain first */
+ ViceLog(25, ("Looking for FileEntries to unchain\n"));
+ H_LOCK
+
+ /* Pick the first volume we see to clean up */
+ fid.Volume = fid.Vnode = fid.Unique = 0;
+
+ for (hash=0; hash<VHASH; hash++) {
+ for (feip = &HashTable[hash]; fe = itofe(*feip); ) {
+ if (fe && (fe->status & FE_LATER) &&
+ (fid.Volume == 0 || fid.Volume == fe->volid)) {
+ ViceLog(125, ("Unchaining for %d:%d:%d\n", fe->vnode,
+ fe->unique, fe->volid));
+ fid.Volume = fe->volid;
+ *feip = fe->fnext;
+ /* Works since volid is deeper than the largest pointer */
+ ((struct object *)fe)->next = (struct object *)myfe;
+ myfe = fe;
+ } else
+ feip = &fe->fnext;
+ }
+ }
+
+ if (!myfe) {
+ H_UNLOCK
+ return 0;
+ }
+
+ /* loop over FEs from myfe and free/break */
+ FSYNC_UNLOCK
+ tthead = 0;
+ for (fe = myfe; fe; ) {
+ register struct CallBack *cbnext;
+ for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
+ host = h_itoh(cb->hhead);
+ h_Hold_r(host);
+ cbnext = itocb(cb->cnext);
+ if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
+ tthead = cb->thead;
+ }
+ TDel(cb);
+ HDel(cb);
+ CDel(cb, 0); /* Don't let CDel clean up the fe */
+ /* leave hold for MultiBreakVolumeCallBack to clear */
+ }
+ myfe = fe;
+ (struct object *)fe = ((struct object *)fe)->next;
+ FreeFE(myfe);
+ }
+
+ if (tthead) {
+ ViceLog(125, ("Breaking volume %d\n", fid.Volume));
+ henumParms.ncbas = 0;
+ henumParms.fid = &fid;
+ henumParms.thead = tthead;
+ H_UNLOCK
+ h_Enumerate(MultiBreakVolumeLaterCallBack, (char *) &henumParms);
+ H_LOCK
+
+ if (henumParms.ncbas) { /* do left-overs */
+ struct AFSCBFids tf;
+ tf.AFSCBFids_len = 1;
+ tf.AFSCBFids_val = &fid;
+
+ MultiBreakCallBack_r(henumParms.cba, henumParms.ncbas, &tf, 0 );
+ henumParms.ncbas = 0;
+ }
+ }
+ FSYNC_LOCK
+ H_UNLOCK
+
+ /* Arrange to be called again */
+ return 1;
+}
+
/*
* Delete all timed-out call back entries (to be called periodically by file
* server)
int CleanupTimedOutCallBacks_r(void)
{
afs_uint32 now = CBtime(FT_ApproxTime());
- register u_short *thead;
+ register afs_uint32 *thead;
register struct CallBack *cb;
register int ntimedout = 0;
char hoststr[16];
itofe(cb->fhead)->volid, itofe(cb->fhead)->vnode,
itofe(cb->fhead)->unique));
HDel(cb);
- CDel(cb);
+ CDel(cb, 1);
ntimedout++;
if (ntimedout > cbstuff.nblks) {
ViceLog(0,("CCB: Internal Error -- shutting down...\n"));
*/
cbstuff.GSS5++;
}
- DeleteAllCallBacks_r(hp);
+ DeleteAllCallBacks_r(hp, 1);
if (hp->hostFlags & VENUSDOWN) {
hp->hostFlags &= ~RESETDONE; /* remember that we must do a reset */
} else {
}
if (all || vol) {
register hash;
- register u_short *feip;
+ register afs_uint32 *feip;
register struct CallBack *cb;
register struct FileEntry *fe;
}
}
if (cbi) {
- u_short cfirst = cbi;
+ afs_uint32 cfirst = cbi;
do {
cb = itocb(cbi);
PrintCB(cb,now);
struct FileEntry *fe = itofe(cb->fhead);
time_t expires = TIndexToTime(cb->thead);
- printf("vol=%u vn=%u cbs=%d hi=%d st=%d, exp in %d secs at %s",
+ printf("vol=%u vn=%u cbs=%d hi=%d st=%d fest=%d, exp in %d secs at %s",
fe->volid, fe->vnode, fe->ncbs, cb->hhead, cb->status,
- expires - now, ctime(&expires));
+ fe->status, expires - now, ctime(&expires));
}
#endif
int MultiBreakCallBackAlternateAddress_r(struct host *host, struct AFSCBFids *afidp)
{
int i,j;
- struct rx_connection* conns[AFS_MAX_INTERFACE_ADDR];
+ struct rx_connection** conns;
struct rx_connection* connSuccess = 0;
- afs_int32 addr[AFS_MAX_INTERFACE_ADDR];
+ afs_int32 *addr;
static struct rx_securityClass *sc = 0;
static struct AFSCBs tc = {0,0};
char hoststr[16];
if ( !sc )
sc = rxnull_NewClientSecurityObject();
+ i = host->interface->numberOfInterfaces;
+ addr = malloc(i * sizeof(afs_int32));
+ conns = malloc(i * sizeof(struct rx_connection *));
+ if (!addr || !conns) {
+ ViceLog(0, ("Failed malloc in MultiBreakCallBackAlternateAddress_r\n"));
+ assert(0);
+ }
+
/* initialize alternate rx connections */
for ( i=0,j=0; i < host->interface->numberOfInterfaces; i++)
{
if ( conns[i] != connSuccess )
rx_DestroyConnection(conns[i] );
+ free(addr);
+ free(conns);
+
if ( connSuccess ) return 0; /* success */
else return 1; /* failure */
}
int MultiProbeAlternateAddress_r(struct host *host)
{
int i,j;
- struct rx_connection* conns[AFS_MAX_INTERFACE_ADDR];
+ struct rx_connection** conns;
struct rx_connection* connSuccess = 0;
- afs_int32 addr[AFS_MAX_INTERFACE_ADDR];
+ afs_int32 *addr;
static struct rx_securityClass *sc = 0;
char hoststr[16];
if ( !sc )
sc = rxnull_NewClientSecurityObject();
+ i = host->interface->numberOfInterfaces;
+ addr = malloc(i * sizeof(afs_int32));
+ conns = malloc(i * sizeof(struct rx_connection *));
+ if (!addr || !conns) {
+ ViceLog(0, ("Failed malloc in MultiProbeAlternateAddress_r\n"));
+ assert(0);
+ }
+
/* initialize alternate rx connections */
for ( i=0,j=0; i < host->interface->numberOfInterfaces; i++)
{
if ( conns[i] != connSuccess )
rx_DestroyConnection(conns[i] );
+ free(addr);
+ free(conns);
+
if ( connSuccess ) return 0; /* success */
else return 1; /* failure */
}