From b0161198cfbe35fd2663ad849d0ebe33c057c289 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Wed, 2 Jun 2004 09:43:02 +0000 Subject: [PATCH] callback-rxcon-move-20040602 FIXES 4891 apply it disabled in the fileserver, but provide mech for client to suggest a particular IP address to the fileserver ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== FIXES 4891 apply it disabled in the fileserver, but provide mech for client to suggest a pa rticular IP address to the fileserver ==================== FIXES 4891 apply it disabled in the fileserver, but provide mech for client to suggest a pa rticular IP address to the fileserver ==================== FIXES 4891 apply it disabled in the fileserver, but provide mech for client to suggest a pa rticular IP address to the fileserver --- src/afs/afs_pioctl.c | 96 ++++++++++++++++++++++++++++++++++++++++ src/config/venus.h | 1 + src/fsint/afsint.xg | 4 ++ src/venus/fs.c | 43 ++++++++++++++++++ src/viced/afsfileprocs.c | 76 +++++++++++++++++++++++++++++++ 5 files changed, 220 insertions(+) diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index f9555d02a..d47fce0be 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -88,6 +88,7 @@ DECL_PIOCTL(PRxStatProc); DECL_PIOCTL(PRxStatPeer); DECL_PIOCTL(PPrefetchFromTape); DECL_PIOCTL(PResidencyCmd); +DECL_PIOCTL(PCallBackAddr); /* * A macro that says whether we're going to need HandleClientContext(). @@ -188,6 +189,7 @@ static int (*(CpioctlSw[])) () = { PBogus, /* 0 */ PNewAlias, /* 1 -- create new cell alias */ PListAliases, /* 2 -- list cell aliases */ + PCallBackAddr, /* 3 -- request addr for callback rxcon */ }; #define PSetClientContext 99 /* Special pioctl to setup caller's creds */ @@ -3744,3 +3746,97 @@ DECL_PIOCTL(PResidencyCmd) } return code; } + +DECL_PIOCTL(PCallBackAddr) +{ +#ifndef UKERNEL + afs_uint32 addr, code; + int srvAddrCount; + struct server *ts; + struct srvAddr *sa; + struct conn *tc; + afs_int32 i, j; + struct unixuser *tu; + struct srvAddr **addrs; + + /*AFS_STATCNT(PCallBackAddr);*/ + if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */ + return EIO; /* Inappropriate ioctl for device */ + + if (!afs_osi_suser(acred)) + return EACCES; + + if ( ainSize < sizeof(afs_int32) ) + return EINVAL; + + memcpy(&addr, ain, sizeof(afs_int32)); + + ObtainReadLock(&afs_xinterface); + for ( i=0; (unsigned short)i < afs_cb_interface.numberOfInterfaces; i++) { + if (afs_cb_interface.addr_in[i] == addr) break; + } + + ReleaseWriteLock(&afs_xinterface); + + if (afs_cb_interface.addr_in[i] != addr) return EINVAL; + + ObtainReadLock(&afs_xserver); /* Necessary? */ + ObtainReadLock(&afs_xsrvAddr); + + srvAddrCount = 0; + for (i=0;inext_bkt) { + srvAddrCount++; + } + } + + addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs)); + j = 0; + for (i=0;inext_bkt) { + if (j >= srvAddrCount) break; + addrs[j++] = sa; + } + } + + ReleaseReadLock(&afs_xsrvAddr); + ReleaseReadLock(&afs_xserver); + + for (i=0; iserver; + if (!ts) + continue; + + /* vlserver has no callback conn */ + if (sa->sa_portal == AFS_VLPORT) { + continue; + } + + if (!ts->cell) /* not really an active server, anyway, it must */ + continue; /* have just been added by setsprefs */ + + /* get a connection, even if host is down; bumps conn ref count */ + tu = afs_GetUser(areq->uid, ts->cell->cellNum, SHARED_LOCK); + tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cellNum, tu, 1/*force*/, 1/*create*/, SHARED_LOCK); + afs_PutUser(tu, SHARED_LOCK); + if (!tc) continue; + + if ((sa->sa_flags & SRVADDR_ISDOWN) || HaveCallBacksFrom(ts)) { + if (sa->sa_flags & SRVADDR_ISDOWN) { + rx_SetConnDeadTime(tc->id, 3); + } + +#ifdef RX_ENABLE_LOCKS + AFS_GUNLOCK(); +#endif /* RX_ENABLE_LOCKS */ + code = RXAFS_CallBackRxConnAddr(tc->id, &addr); +#ifdef RX_ENABLE_LOCKS + AFS_GLOCK(); +#endif /* RX_ENABLE_LOCKS */ + } + afs_PutConn(tc, SHARED_LOCK); /* done with it now */ + } /* Outer loop over addrs */ +#endif /* UKERNEL */ + return 0; +} diff --git a/src/config/venus.h b/src/config/venus.h index c887475fa..f5380264f 100644 --- a/src/config/venus.h +++ b/src/config/venus.h @@ -179,5 +179,6 @@ struct cm_initparams { /* Coordinated 'C' pioctl's */ #define VIOC_NEWALIAS _CVICEIOCTL(1) /* create new cell alias */ #define VIOC_GETALIAS _CVICEIOCTL(2) /* get alias info */ +#define VIOC_CBADDR _CVICEIOCTL(3) /* push callback addr */ #endif /* AFS_VENUS_H */ diff --git a/src/fsint/afsint.xg b/src/fsint/afsint.xg index bc00cd9c7..7637d22f4 100644 --- a/src/fsint/afsint.xg +++ b/src/fsint/afsint.xg @@ -698,3 +698,7 @@ GiveUpAllCallBacks( GetCapabilities( Capabilities *capabilities ) = 65540; + +CallBackRxConnAddr( + IN afs_int32 *addr +) = 65541; diff --git a/src/venus/fs.c b/src/venus/fs.c index b309c23cd..831e40194 100644 --- a/src/venus/fs.c +++ b/src/venus/fs.c @@ -2075,6 +2075,45 @@ ListAliasesCmd(struct cmd_syndesc *as) return 0; } +static int +CallBackRxConnCmd(struct cmd_syndesc *as) +{ + afs_int32 code; + struct ViceIoctl blob; + struct cmd_item *ti; + afs_int32 hostAddr; + struct hostent *thp; + char *tp; + int setp; + + ti = as->parms[0].items; + setp = 1; + if (ti) { + thp = hostutil_GetHostByName(ti->data); + if (!thp) { + fprintf(stderr, "host %s not found in host table.\n", ti->data); + return 1; + } + else memcpy(&hostAddr, thp->h_addr, sizeof(afs_int32)); + } else { + hostAddr = 0; /* means don't set host */ + setp = 0; /* aren't setting host */ + } + + /* now do operation */ + blob.in_size = sizeof(afs_int32); + blob.out_size = sizeof(afs_int32); + blob.in = (char *) &hostAddr; + blob.out = (char *) &hostAddr; + + code = pioctl(0, VIOC_CBADDR, &blob, 1); + if (code < 0) { + Die(errno, 0); + return 1; + } + return 0; +} + static int NewCellCmd(struct cmd_syndesc *as) { @@ -3417,6 +3456,9 @@ defect 3069 cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "Disable RX stats"); cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, "Clear RX stats"); + ts = cmd_CreateSyntax("setcbaddr", CallBackRxConnCmd, 0, "configure callback connection address"); + cmd_AddParm(ts, "-addr", CMD_SINGLE, CMD_OPTIONAL, "host name or address"); + code = cmd_Dispatch(argc, argv); if (rxInitDone) rx_Finalize(); @@ -3773,3 +3815,4 @@ RxStatPeerCmd(struct cmd_syndesc *as) return 0; } + diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index cf2c9ac02..50b90a65f 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -7225,6 +7225,82 @@ init_sys_error_to_et(void) sys2et[EMEDIUMTYPE] = UAEMEDIUMTYPE; } +afs_int32 +SRXAFS_CallBackRxConnAddr (struct rx_call * acall, afs_int32 *addr) +{ + Error errorCode = 0; + struct host *thost; + struct client *tclient; + static struct rx_securityClass *sc = 0; + int i,j; + struct rx_connection *tcon; + struct rx_connection *conn; + + if (errorCode = CallPreamble(acall, ACTIVECALL, &tcon)) + goto Bad_CallBackRxConnAddr1; + +#ifndef __EXPERIMENTAL_CALLBACK_CONN_MOVING + errorCode = 1; +#else + + H_LOCK + tclient = h_FindClient_r(tcon); + thost = tclient->host; + + /* nothing more can be done */ + if ( !thost->interface ) + goto Bad_CallBackRxConnAddr; + + assert(thost->interface->numberOfInterfaces > 0 ); + + /* the only address is the primary interface */ + /* can't change when there's only 1 address, anyway */ + if ( thost->interface->numberOfInterfaces == 1 ) + goto Bad_CallBackRxConnAddr; + + /* initialise a security object only once */ + if ( !sc ) + sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject(); + + for ( i=0; i < thost->interface->numberOfInterfaces; i++) + { + if ( *addr == thost->interface->addr[i] ) { + break; + } + } + + if ( *addr != thost->interface->addr[i] ) + goto Bad_CallBackRxConnAddr; + + conn = rx_NewConnection (thost->interface->addr[i], + thost->port, 1, sc, 0); + rx_SetConnDeadTime(conn, 2); + rx_SetConnHardDeadTime(conn, AFS_HARDDEADTIME); + H_UNLOCK + errorCode = RXAFSCB_Probe(conn); + H_LOCK + if (!errorCode) { + if ( thost->callback_rxcon ) + rx_DestroyConnection(thost->callback_rxcon); + thost->callback_rxcon = conn; + thost->host = addr; + rx_SetConnDeadTime(thost->callback_rxcon, 50); + rx_SetConnHardDeadTime(thost->callback_rxcon, AFS_HARDDEADTIME); + H_UNLOCK; + errorCode = CallPostamble(tcon, errorCode); + return errorCode; + } else { + rx_DestroyConnection(conn); + } +#endif + + Bad_CallBackRxConnAddr: + H_UNLOCK; + errorCode = CallPostamble(tcon, errorCode); + Bad_CallBackRxConnAddr1: + return errorCode; /* failure */ +} + afs_int32 sys_error_to_et(afs_int32 in) { -- 2.39.5