From 4f26bcfdb3c6a47d17f825e99f9d5a1bc97eba45 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 21 Oct 2006 21:46:17 +0000 Subject: [PATCH] windows-misc-20061021 * don't DebugBreak unless a debugger is attached * replace afsdcell.ini with CellServDB in error message * do not NetBIOS Reset adapters when checking to see if only the loopback is in use because doing so breaks the existing LANA bind * remove a deadlock in smb3.c * do not retry dirty buffer writes when flushing in response to a suspend * do not flush in response to a suspend when only the loopback is present --- src/WINNT/afsd/afsd_init.c | 5 ++++- src/WINNT/afsd/afsd_service.c | 18 ++++++++++----- src/WINNT/afsd/cm_buf.c | 13 ++++++++--- src/WINNT/afsd/cm_cell.c | 2 +- src/WINNT/afsd/cm_cell.h | 4 ++-- src/WINNT/afsd/cm_conn.h | 2 +- src/WINNT/afsd/cm_scache.h | 2 +- src/WINNT/afsd/lanahelper.cpp | 41 ++++++++++++++++++++--------------- src/WINNT/afsd/lanahelper.h | 2 +- src/WINNT/afsd/smb3.c | 15 ++++++++----- 10 files changed, 65 insertions(+), 39 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 252712f62b..1dc22c6d42 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -1205,7 +1205,7 @@ int afsd_InitCM(char **reasonP) code, cm_freelanceEnabled, (code ? "" : rootCellName)); if (code != 0 && !cm_freelanceEnabled) { - *reasonP = "can't find root cell name in afsd.ini"; + *reasonP = "can't find root cell name in CellServDB"; return -1; } else if (cm_freelanceEnabled) @@ -1518,6 +1518,9 @@ OpenDumpFile(void) void GenerateMiniDump(PEXCEPTION_POINTERS ep) { + if (IsDebuggerPresent()) + return; + if (ep == NULL) { // Generate exception to get proper context in dump diff --git a/src/WINNT/afsd/afsd_service.c b/src/WINNT/afsd/afsd_service.c index ac9826f763..d755f5e8cc 100644 --- a/src/WINNT/afsd/afsd_service.c +++ b/src/WINNT/afsd/afsd_service.c @@ -9,6 +9,7 @@ #include #include "afsd.h" #include "afsd_init.h" +#include "lanahelper.h" #include #include #include @@ -83,7 +84,8 @@ static void afsd_notifier(char *msgp, char *filep, long line) afsi_log("--- end dump ---"); #ifdef DEBUG - DebugBreak(); + if (IsDebuggerPresent()) + DebugBreak(); #endif SetEvent(WaitToTerminate); @@ -174,7 +176,8 @@ afsd_ServiceControlHandler(DWORD ctrlCode) afsi_log("SERVICE_CONTROL_SHUTDOWN"); /* Write all dirty buffers back to server */ - buf_CleanAndReset(); + if ( !lana_OnlyLoopback() ) + buf_CleanAndReset(); /* Force trace if requested */ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, @@ -242,7 +245,8 @@ afsd_ServiceControlHandlerEx( SetServiceStatus(StatusHandle, &ServiceStatus); /* Write all dirty buffers back to server */ - buf_CleanAndReset(); + if ( !lana_OnlyLoopback() ) + buf_CleanAndReset(); /* Force trace if requested */ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, @@ -298,13 +302,17 @@ afsd_ServiceControlHandlerEx( case PBT_APMQUERYSUSPEND: afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND"); /* Write all dirty buffers back to server */ - buf_CleanAndReset(); + if ( !lana_OnlyLoopback() ) + buf_CleanAndReset(); + afsi_log("SERVICE_CONTROL_APMQUERYSUSPEND buf_CleanAndReset complete"); dwRet = NO_ERROR; break; case PBT_APMQUERYSTANDBY: afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY"); /* Write all dirty buffers back to server */ - buf_CleanAndReset(); + if ( !lana_OnlyLoopback() ) + buf_CleanAndReset(); + afsi_log("SERVICE_CONTROL_APMQUERYSTANDBY buf_CleanAndReset complete"); dwRet = NO_ERROR; break; diff --git a/src/WINNT/afsd/cm_buf.c b/src/WINNT/afsd/cm_buf.c index a5da85778e..2052d3e561 100644 --- a/src/WINNT/afsd/cm_buf.c +++ b/src/WINNT/afsd/cm_buf.c @@ -169,9 +169,7 @@ void buf_IncrSyncer(long parm) * a log page at any given instant. */ cm_InitReq(&req); -#ifdef NO_BKG_RETRIES req.flags |= CM_REQ_NORETRY; -#endif wasDirty |= buf_CleanAsync(bp, &req); /* now advance to the next buffer; the allp chain never changes, @@ -535,7 +533,7 @@ cm_buf_t *buf_Find(struct cm_scache *scp, osi_hyper_t *offsetp) * at any given time, and also ensures that the log is forced sufficiently far, * if this buffer contains logged data. * - * Returns one if the buffer was dirty. + * Returns non-zero if the buffer was dirty. */ long buf_CleanAsyncLocked(cm_buf_t *bp, cm_req_t *reqp) { @@ -582,6 +580,13 @@ long buf_CleanAsyncLocked(cm_buf_t *bp, cm_req_t *reqp) /* write buffer to disk cache (synchronous for now) */ diskcache_Update(bp->dcp, bp->datap, cm_data.buf_blockSize, bp->dataVersion); #endif /* DISKCACHE95 */ + + /* if we get here and retries are not permitted + * then we need to exit this loop regardless of + * whether or not we were able to clear the dirty bit + */ + if (reqp->flags & CM_REQ_NORETRY) + break; }; /* do logging after call to GetLastError, or else */ @@ -1150,6 +1155,8 @@ long buf_CleanAndReset(void) /* now no locks are held; clean buffer and go on */ cm_InitReq(&req); + req.flags |= CM_REQ_NORETRY; + buf_CleanAsync(bp, &req); buf_CleanWait(NULL, bp); diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 23114b3816..8f76acc311 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -206,7 +206,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags) return cp; } -cm_cell_t *cm_FindCellByID(long cellID) +cm_cell_t *cm_FindCellByID(afs_int32 cellID) { cm_cell_t *cp; diff --git a/src/WINNT/afsd/cm_cell.h b/src/WINNT/afsd/cm_cell.h index 7c949b54f0..fd750a057d 100644 --- a/src/WINNT/afsd/cm_cell.h +++ b/src/WINNT/afsd/cm_cell.h @@ -19,7 +19,7 @@ /* a cell structure */ typedef struct cm_cell { afs_uint32 magic; - long cellID; /* cell ID */ + afs_int32 cellID; /* cell ID */ struct cm_cell *nextp; /* locked by cm_cellLock */ char name[CELL_MAXNAMELEN]; /* cell name; never changes */ cm_serverRef_t *vlServersp; /* locked by cm_serverLock */ @@ -44,7 +44,7 @@ extern cm_cell_t *cm_GetCell(char *namep, long flags); extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags); -extern cm_cell_t *cm_FindCellByID(long cellID); +extern cm_cell_t *cm_FindCellByID(afs_int32 cellID); extern void cm_ChangeRankCellVLServer(cm_server_t *tsp); diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index d0cf8ada6e..383e0e3271 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -24,7 +24,7 @@ typedef struct cm_conn { struct rx_connection *callp; /* locked by mx */ struct cm_user *userp; /* locked by mx; a held reference */ osi_mutex_t mx; /* mutex for some of these fields */ - unsigned long refCount; /* locked by cm_connLock */ + unsigned long refCount; /* locked by cm_connLock */ int ucgen; /* ucellp's generation number */ long flags; /* locked by mx */ int cryptlevel; /* encrytion status */ diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index 71810a7c24..fa791f0409 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -139,7 +139,7 @@ typedef struct cm_scache { /* callback info */ struct cm_server *cbServerp; /* server granting callback */ - time_t cbExpires; /* time callback expires */ + time_t cbExpires; /* time callback expires */ /* access cache */ long anyAccess; /* anonymous user's access */ diff --git a/src/WINNT/afsd/lanahelper.cpp b/src/WINNT/afsd/lanahelper.cpp index c4495e9c88..2ac048c1e9 100644 --- a/src/WINNT/afsd/lanahelper.cpp +++ b/src/WINNT/afsd/lanahelper.cpp @@ -382,7 +382,7 @@ extern "C" lana_number_t lana_FindLoopback(void) return LANA_INVALID; } for (i = 0; i < lana_list.length; i++) { - if (lana_IsLoopback(lana_list.lana[i])) { + if (lana_IsLoopback(lana_list.lana[i],TRUE)) { // Found one, return it. #ifndef NOLOGGING afsi_log("lana_FindLoopback: Found LAN adapter %d", @@ -415,7 +415,7 @@ extern "C" BOOL lana_OnlyLoopback(void) return FALSE; } for (i = 0; i < lana_list.length; i++) { - if (!lana_IsLoopback(lana_list.lana[i])) { + if (!lana_IsLoopback(lana_list.lana[i],FALSE)) { // Found one non-Loopback adapter return FALSE; } @@ -427,7 +427,8 @@ extern "C" BOOL lana_OnlyLoopback(void) // Is the given lana a Windows Loopback Adapter? // TODO: implement a better check for loopback // TODO: also check for proper bindings (IPv4) -extern "C" BOOL lana_IsLoopback(lana_number_t lana) +// For VMWare we only check the first five octets since the last one may vary +extern "C" BOOL lana_IsLoopback(lana_number_t lana, BOOL reset) { NCB ncb; struct { @@ -436,6 +437,7 @@ extern "C" BOOL lana_IsLoopback(lana_number_t lana) } astat; unsigned char kWLA_MAC[6] = { 0x02, 0x00, 0x4c, 0x4f, 0x4f, 0x50 }; unsigned char kVista_WLA_MAC[6] = { 0x7F, 0x00, 0x00, 0x01, 0x4f, 0x50 }; + unsigned char kVMWare_MAC[5] = { 0x00, 0x50, 0x56, 0xC0, 0x00 }; int status; HKEY hkConfig; LONG rv; @@ -451,21 +453,23 @@ extern "C" BOOL lana_IsLoopback(lana_number_t lana) return TRUE; } - // Reset the adapter: in Win32, this is required for every process, and - // acts as an init call, not as a real hardware reset. - memset(&ncb, 0, sizeof(ncb)); - ncb.ncb_command = NCBRESET; - ncb.ncb_callname[0] = 100; - ncb.ncb_callname[2] = 100; - ncb.ncb_lana_num = lana; - status = Netbios(&ncb); - if (status == 0) - status = ncb.ncb_retcode; - if (status != 0) { + if (reset) { + // Reset the adapter: in Win32, this is required for every process, and + // acts as an init call, not as a real hardware reset. + memset(&ncb, 0, sizeof(ncb)); + ncb.ncb_command = NCBRESET; + ncb.ncb_callname[0] = 100; + ncb.ncb_callname[2] = 100; + ncb.ncb_lana_num = lana; + status = Netbios(&ncb); + if (status == 0) + status = ncb.ncb_retcode; + if (status != 0) { #ifndef NOLOGGING - afsi_log("NCBRESET failed: lana %u, status %ld", lana, status); + afsi_log("NCBRESET failed: lana %u, status %ld", lana, status); #endif - return FALSE; + return FALSE; + } } // Use the NCBASTAT command to get the adapter address. @@ -485,7 +489,8 @@ extern "C" BOOL lana_IsLoopback(lana_number_t lana) return FALSE; } return (memcmp(astat.status.adapter_address, kWLA_MAC, 6) == 0 || - memcmp(astat.status.adapter_address, kVista_WLA_MAC, 6) == 0); + memcmp(astat.status.adapter_address, kVista_WLA_MAC, 6) == 0 || + memcmp(astat.status.adapter_address, kVMWare_MAC, 5) == 0); } // Get the netbios named used/to-be-used by the AFS SMB server. @@ -588,7 +593,7 @@ extern "C" long lana_GetUncServerNameEx(char *buffer, lana_number_t * pLana, int } if(regNbName[0] && - (regLana >=0 && lana_IsLoopback((lana_number_t) regLana))) { + (regLana >=0 && lana_IsLoopback((lana_number_t) regLana,FALSE))) { strncpy(nbName,regNbName,15); nbName[16] = 0; strupr(nbName); diff --git a/src/WINNT/afsd/lanahelper.h b/src/WINNT/afsd/lanahelper.h index 502472828a..1979b3e9b5 100644 --- a/src/WINNT/afsd/lanahelper.h +++ b/src/WINNT/afsd/lanahelper.h @@ -59,7 +59,7 @@ extern "C" { BOOL lana_OnlyLoopback(void); - BOOL lana_IsLoopback(lana_number_t lana); + BOOL lana_IsLoopback(lana_number_t lana, BOOL reset); long lana_GetUncServerNameEx(char *buffer, lana_number_t * pLana, int * pIsGateway, int flags); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 676748a164..04a8535a94 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2861,12 +2861,6 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { smb_fid_t *fidp = smb_FindFIDByScache(vcp, scp); - if (fidp) { - lock_ObtainMutex(&fidp->mx); - delonclose = fidp->flags & SMB_FID_DELONCLOSE; - lock_ReleaseMutex(&fidp->mx); - smb_ReleaseFID(fidp); - } qpi.u.QPfileStandardInfo.allocationSize = scp->length; qpi.u.QPfileStandardInfo.endOfFile = scp->length; @@ -2877,6 +2871,15 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t scp->fileType == CM_SCACHETYPE_MOUNTPOINT || scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); qpi.u.QPfileStandardInfo.reserved = 0; + + if (fidp) { + lock_ReleaseMutex(&scp->mx); + lock_ObtainMutex(&fidp->mx); + lock_ObtainMutex(&scp->mx); + delonclose = fidp->flags & SMB_FID_DELONCLOSE; + lock_ReleaseMutex(&fidp->mx); + smb_ReleaseFID(fidp); + } } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { qpi.u.QPfileEaInfo.eaSize = 0;