callback-rxcon-move-20040602
authorDerrick Brashear <shadow@dementia.org>
Wed, 2 Jun 2004 09:43:02 +0000 (09:43 +0000)
committerDerrick Brashear <shadow@dementia.org>
Wed, 2 Jun 2004 09:43:02 +0000 (09:43 +0000)
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
src/config/venus.h
src/fsint/afsint.xg
src/venus/fs.c
src/viced/afsfileprocs.c

index f9555d0..d47fce0 100644 (file)
@@ -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;i<NSERVERS;i++) {
+        for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
+            srvAddrCount++;
+        }
+    }
+    
+    addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
+    j = 0;
+    for (i=0;i<NSERVERS;i++) {
+        for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) { 
+            if (j >= srvAddrCount) break;
+            addrs[j++] = sa;
+        }
+    }
+    
+    ReleaseReadLock(&afs_xsrvAddr);     
+    ReleaseReadLock(&afs_xserver);
+    
+    for (i=0; i<j; i++) {
+        sa = addrs[i];
+        ts = sa->server;
+        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;
+}
index c887475..f538026 100644 (file)
@@ -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 */
index bc00cd9..7637d22 100644 (file)
@@ -698,3 +698,7 @@ GiveUpAllCallBacks(
 GetCapabilities(
   Capabilities *capabilities
 ) = 65540;
+
+CallBackRxConnAddr(
+  IN afs_int32 *addr
+) = 65541;
index b309c23..831e401 100644 (file)
@@ -2076,6 +2076,45 @@ ListAliasesCmd(struct cmd_syndesc *as)
 }
 
 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)
 {
     afs_int32 code, linkedstate = 0, size = 0, *lp;
@@ -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;
 }
+
index cf2c9ac..50b90a6 100644 (file)
@@ -7226,6 +7226,82 @@ init_sys_error_to_et(void)
 }
 
 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)
 {
     if (in == 0)