From efe393ab416a1e54d3a2a0017ee08db856292046 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 8 Mar 2008 23:25:08 +0000 Subject: [PATCH] DEVEL15-windows-syscfg-getifinfo-20080308 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 | 58 +++++++++++++++++++++--------------- src/WINNT/afsd/cm_daemon.c | 1 + src/WINNT/afsd/cm_server.c | 44 ++++++++++++++++++++------- src/WINNT/afsd/cm_server.h | 11 +++++++ 4 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 940d47ce48..8e67ed9824 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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); diff --git a/src/WINNT/afsd/cm_daemon.c b/src/WINNT/afsd/cm_daemon.c index e5e0765bf7..1c94ee2357 100644 --- a/src/WINNT/afsd/cm_daemon.c +++ b/src/WINNT/afsd/cm_daemon.c @@ -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); } } diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index 3f80d1cf5c..21475e6fb8 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -27,6 +27,7 @@ #include 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; + int writeLock = 0; - /* get network related info */ - cm_noIPAddr = CM_MAXINTERFACE_ADDR; - code = syscfg_GetIFInfo(&cm_noIPAddr, - cm_IPAddr, cm_SubnetMask, - cm_NetMtu, cm_NetFlags); + 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) { diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index 2df50acfbf..affaa6f67c 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -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__ */