]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-syscfg-getifinfo-20080308
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 8 Mar 2008 23:25:08 +0000 (23:25 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 8 Mar 2008 23:25:08 +0000 (23:25 +0000)
LICENSE MIT

syscfg_GetIFInfo() obtains the current list of IP addresses.
Its a really expensive operation.  Call the function once
and cache the data until the next IP address change instead
of calling it everytime we receive a WhoAreYou or construct a
new server object.  Adds a new global rw lock, cm_syscfgLock

(cherry picked from commit 801b670734e254665576dcb71756ea64a123abc9)

src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_daemon.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h

index 940d47ce487c064dc1eb003cc8f542e7a5eb9d05..8e67ed98240084e7857e7b6a413f5303c054d47e 100644 (file)
@@ -579,13 +579,13 @@ SRXAFSCB_Probe(struct rx_call *callp)
 
 extern osi_rwlock_t cm_aclLock;
 extern osi_rwlock_t buf_globalLock;
-extern osi_rwlock_t cm_callbackLock;
 extern osi_rwlock_t cm_cellLock;
 extern osi_rwlock_t cm_connLock;
 extern osi_rwlock_t cm_daemonLock;
 extern osi_rwlock_t cm_dnlcLock;
 extern osi_rwlock_t cm_scacheLock;
 extern osi_rwlock_t cm_serverLock;
+extern osi_rwlock_t cm_syscfgLock;
 extern osi_rwlock_t cm_userLock;
 extern osi_rwlock_t cm_utilsLock;
 extern osi_rwlock_t cm_volumeLock;
@@ -611,6 +611,7 @@ static struct _ltable {
     {"buf_globalLock",   (char*)&buf_globalLock,        LOCKTYPE_RW},
     {"cm_serverLock",    (char*)&cm_serverLock,         LOCKTYPE_RW},
     {"cm_callbackLock",  (char*)&cm_callbackLock,       LOCKTYPE_RW},
+    {"cm_syscfgLock",    (char*)&cm_syscfgLock,         LOCKTYPE_RW},
     {"cm_aclLock",       (char*)&cm_aclLock,            LOCKTYPE_RW},
     {"cm_cellLock",      (char*)&cm_cellLock,           LOCKTYPE_RW},
     {"cm_connLock",      (char*)&cm_connLock,           LOCKTYPE_RW},
@@ -960,11 +961,6 @@ int
 SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
 {
     int i;
-    int cm_noIPAddr;         /* number of client network interfaces */
-    int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
-    int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
-    int cm_NetMtu[CM_MAXINTERFACE_ADDR];    /* client's MTU sizes */
-    int cm_NetFlags[CM_MAXINTERFACE_ADDR];  /* network flags */
     long code;
     struct rx_connection *connp;
     struct rx_peer *peerp;
@@ -976,17 +972,25 @@ SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
         port = rx_PortOf(peerp);
     }
 
-    /* get network related info */
-    cm_noIPAddr = CM_MAXINTERFACE_ADDR;
-    code = syscfg_GetIFInfo(&cm_noIPAddr,
-                             cm_IPAddr, cm_SubnetMask,
-                             cm_NetMtu, cm_NetFlags);
-
-    /* return all network interface addresses */
     osi_Log2(afsd_logp, "SRXAFSCB_WhoAreYou from host 0x%x port %d",
               ntohl(host),
               ntohs(port));
 
+    lock_ObtainRead(&cm_syscfgLock);
+    if (cm_LanAdapterChangeDetected) {
+        lock_ConvertRToW(&cm_syscfgLock);
+        if (cm_LanAdapterChangeDetected) {
+            /* get network related info */
+            cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+            code = syscfg_GetIFInfo(&cm_noIPAddr,
+                                     cm_IPAddr, cm_SubnetMask,
+                                     cm_NetMtu, cm_NetFlags);
+            cm_LanAdapterChangeDetected = 0;
+        }
+        lock_ConvertWToR(&cm_syscfgLock);
+    }
+
+    /* return all network interface addresses */
     addr->numberOfInterfaces = cm_noIPAddr;
     addr->uuid = cm_data.Uuid;
     for ( i=0; i < cm_noIPAddr; i++ ) {
@@ -996,6 +1000,8 @@ SRXAFSCB_WhoAreYou(struct rx_call *callp, struct interfaceAddr* addr)
             cm_NetMtu[i] : rx_mtu;
     }
 
+    lock_ReleaseRead(&cm_syscfgLock);
+
     return 0;
 }
 
@@ -1121,11 +1127,6 @@ SRXAFSCB_TellMeAboutYourself( struct rx_call *callp,
     int i;
     afs_int32 *dataBuffP;
     afs_int32 dataBytes;
-    int cm_noIPAddr;         /* number of client network interfaces */
-    int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
-    int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
-    int cm_NetMtu[CM_MAXINTERFACE_ADDR];    /* client's MTU sizes */
-    int cm_NetFlags[CM_MAXINTERFACE_ADDR];  /* network flags */
     long code;
     struct rx_connection *connp;
     struct rx_peer *peerp;
@@ -1137,16 +1138,24 @@ SRXAFSCB_TellMeAboutYourself( struct rx_call *callp,
         port = rx_PortOf(peerp);
     }
 
-    /* get network related info */
-    cm_noIPAddr = CM_MAXINTERFACE_ADDR;
-    code = syscfg_GetIFInfo(&cm_noIPAddr,
-                             cm_IPAddr, cm_SubnetMask,
-                             cm_NetMtu, cm_NetFlags);
-
     osi_Log2(afsd_logp, "SRXAFSCB_TellMeAboutYourself from host 0x%x port %d",
               ntohl(host),
               ntohs(port));
 
+    lock_ObtainRead(&cm_syscfgLock);
+    if (cm_LanAdapterChangeDetected) {
+        lock_ConvertRToW(&cm_syscfgLock);
+        if (cm_LanAdapterChangeDetected) {
+            /* get network related info */
+            cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+            code = syscfg_GetIFInfo(&cm_noIPAddr,
+                                     cm_IPAddr, cm_SubnetMask,
+                                     cm_NetMtu, cm_NetFlags);
+            cm_LanAdapterChangeDetected = 0;
+        }
+        lock_ConvertWToR(&cm_syscfgLock);
+    }
+
     /* return all network interface addresses */
     addr->numberOfInterfaces = cm_noIPAddr;
     addr->uuid = cm_data.Uuid;
@@ -1156,6 +1165,7 @@ SRXAFSCB_TellMeAboutYourself( struct rx_call *callp,
         addr->mtu[i] = (rx_mtu == -1 || (rx_mtu != -1 && cm_NetMtu[i] < rx_mtu)) ? 
             cm_NetMtu[i] : rx_mtu;
     }
+    lock_ReleaseRead(&cm_syscfgLock);
 
     dataBytes = 1 * sizeof(afs_int32);
     dataBuffP = (afs_int32 *) osi_Alloc(dataBytes);
index e5e0765bf7b32c6deb76e159544bfff2b63851ca..1c94ee235762b9ef4abd3267f31346163adeb925 100644 (file)
@@ -78,6 +78,7 @@ void cm_IpAddrDaemon(long parm)
         if (Result == NO_ERROR && daemon_ShutdownFlag == 0) {
             lastIPAddrChange = osi_Time();
             smb_SetLanAdapterChangeDetected();
+            cm_SetLanAdapterChangeDetected();
             thrd_ResetEvent(cm_IPAddrDaemon_ShutdownEvent);
        }       
     }
index 3f80d1cf5cd0c8a62c34ed2d775f1cfaf91d7eaa..21475e6fb82d4b1f6d1b53f54b1b5291c800bdbc 100644 (file)
@@ -27,6 +27,7 @@
 #include <rx/rx.h>
 
 osi_rwlock_t cm_serverLock;
+osi_rwlock_t cm_syscfgLock;
 
 cm_server_t *cm_allServersp;
 afs_uint32   cm_numFileServers = 0;
@@ -765,10 +766,26 @@ void cm_InitServer(void)
         
     if (osi_Once(&once)) {
         lock_InitializeRWLock(&cm_serverLock, "cm_serverLock");
+        lock_InitializeRWLock(&cm_syscfgLock, "cm_syscfgLock");
         osi_EndOnce(&once);
     }
 }
 
+/* Protected by cm_syscfgLock (rw) */
+int cm_noIPAddr;         /* number of client network interfaces */
+int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
+int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
+int cm_NetMtu[CM_MAXINTERFACE_ADDR];    /* client's MTU sizes */
+int cm_NetFlags[CM_MAXINTERFACE_ADDR];  /* network flags */
+int cm_LanAdapterChangeDetected = 1;
+
+void cm_SetLanAdapterChangeDetected(void)
+{
+    lock_ObtainWrite(&cm_syscfgLock);
+    cm_LanAdapterChangeDetected = 1;
+    lock_ReleaseWrite(&cm_syscfgLock);
+}
+
 void cm_GetServer(cm_server_t *serverp)
 {
     lock_ObtainRead(&cm_serverLock);
@@ -822,19 +839,23 @@ void cm_SetServerPrefs(cm_server_t * serverp)
     unsigned long      myAddr, myNet, mySubnet;/* in host byte order */
     unsigned long      netMask;
     int                i;
-
-    int cm_noIPAddr;         /* number of client network interfaces */
-    int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
-    int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
-    int cm_NetMtu[CM_MAXINTERFACE_ADDR];    /* client's MTU sizes */
-    int cm_NetFlags[CM_MAXINTERFACE_ADDR];  /* network flags */
     long code;
-
-    /* get network related info */
-    cm_noIPAddr = CM_MAXINTERFACE_ADDR;
-    code = syscfg_GetIFInfo(&cm_noIPAddr,
-                           cm_IPAddr, cm_SubnetMask,
-                           cm_NetMtu, cm_NetFlags);
+    int writeLock = 0;
+
+    lock_ObtainRead(&cm_syscfgLock);
+    if (cm_LanAdapterChangeDetected) {
+        lock_ConvertRToW(&cm_syscfgLock);
+        writeLock = 1;
+        if (cm_LanAdapterChangeDetected) {
+            /* get network related info */
+            cm_noIPAddr = CM_MAXINTERFACE_ADDR;
+            code = syscfg_GetIFInfo(&cm_noIPAddr,
+                                     cm_IPAddr, cm_SubnetMask,
+                                     cm_NetMtu, cm_NetFlags);
+            cm_LanAdapterChangeDetected = 0;
+        }
+        lock_ConvertWToR(&cm_syscfgLock);
+    }
 
     serverAddr = ntohl(serverp->addr.sin_addr.s_addr);
     serverp->ipRank  = CM_IPRANK_LOW;  /* default setings */
@@ -873,6 +894,7 @@ void cm_SetServerPrefs(cm_server_t * serverp)
        /* random between 0..15*/
        serverp->ipRank += min(serverp->ipRank, rand() % 0x000f);
     } /* and of for loop */
+    lock_ReleaseRead(&cm_syscfgLock);
 }
 
 cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cellp, afs_uint32 flags) {
index 2df50acfbf8bb116acf5a7d92a252f5adfeb4a07..affaa6f67cc497f79135ee93ccbdc51dde815912 100644 (file)
@@ -100,6 +100,8 @@ extern cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type);
 
 extern osi_rwlock_t cm_serverLock;
 
+extern osi_rwlock_t cm_syscfgLock;
+
 extern void cm_InitServer(void);
 
 extern void cm_CheckServers(afs_uint32 flags, struct cm_cell *cellp);
@@ -128,4 +130,13 @@ extern void cm_SetServerNoInlineBulk(cm_server_t * serverp, int no);
 
 extern cm_server_t * cm_FindServerByIP(afs_uint32 addr, int type);
 
+extern void cm_SetLanAdapterChangeDetected(void);
+
+/* Protected by cm_syscfgLock (rw) */
+extern int cm_noIPAddr;         /* number of client network interfaces */
+extern int cm_IPAddr[CM_MAXINTERFACE_ADDR];    /* client's IP address in host order */
+extern int cm_SubnetMask[CM_MAXINTERFACE_ADDR];/* client's subnet mask in host order*/
+extern int cm_NetMtu[CM_MAXINTERFACE_ADDR];    /* client's MTU sizes */
+extern int cm_NetFlags[CM_MAXINTERFACE_ADDR];  /* network flags */
+extern int cm_LanAdapterChangeDetected;
 #endif /*  __CM_SERVER_H_ENV__ */