Jeffrey Altman e467598d55 STABLE14-windows-vs2005b2-20050706
Visual Studio 2005 Beta 2 has been released.   As part of this
release Microsoft has tightened the rules for their C++ compliance.

* no longer can a variable declared in a for() statement be used
  outside of the associated command block

* no longer can a function or variable be declared implicitly as
  'int'

* several types such as size_t have become 64-bit values on all platforms

* due to type changes the C++ function names in libraries have changed.
  This requires the use of different .DEF file export lists


(cherry picked from commit c6a736486eb2704efd03082ff067858a198ae6d0)
2005-07-07 01:28:59 +00:00

1130 lines
37 KiB
C++

/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
*
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
extern "C" {
#include <afs/param.h>
#include <afs/stds.h>
}
#include "svrmgr.h"
#include "alert.h"
#include "creds.h"
/*
* DEFINITIONS ________________________________________________________________
*
*/
/*
* VARIABLES __________________________________________________________________
*
*/
/*
* PROTOTYPES _________________________________________________________________
*
*/
BOOL Alert_Scout_CheckServer (LPSERVER lpServer);
void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer);
void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer);
void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert);
LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull);
LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
DWORD WINAPI Alert_ScoutProc (LPVOID lp);
void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa);
/*
* ROUTINES ___________________________________________________________________
*
*/
LPOBJECTALERTS Alert_GetObjectAlerts (LPIDENT lpi, BOOL fAlwaysServer, ULONG *pStatus)
{
LPOBJECTALERTS lpoa = NULL;
if (fAlwaysServer || lpi->fIsServer())
{
LPSERVER_PREF lpsp;
if ((lpsp = (LPSERVER_PREF)lpi->GetServer()->GetUserParam()) != NULL)
{
lpoa = &lpsp->oa;
}
}
else if (lpi->fIsService())
{
LPSERVICE_PREF lpsp;
if ((lpsp = (LPSERVICE_PREF)lpi->GetUserParam()) != NULL)
{
lpoa = &lpsp->oa;
}
}
else if (lpi->fIsAggregate())
{
LPAGGREGATE_PREF lpap;
if ((lpap = (LPAGGREGATE_PREF)lpi->GetUserParam()) != NULL)
{
lpoa = &lpap->oa;
}
}
else if (lpi->fIsFileset())
{
LPFILESET_PREF lpfp;
if ((lpfp = (LPFILESET_PREF)lpi->GetUserParam()) != NULL)
{
lpoa = &lpfp->oa;
}
}
return lpoa;
}
void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer)
{
if (lpi->fIsServer())
{
*ppServer = NULL;
}
else
{
*ppServer = lpi->OpenServer();
}
}
void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer)
{
// If we just updated some aggregate, fileset or service, then the
// associated server's secondary alerts are probably out-of-date.
// Update them.
//
if (lpServer != NULL)
{
LPOBJECTALERTS lpoaServer = Alert_GetObjectAlerts (lpServer->GetIdentifier());
LPOBJECTALERTS lpoaChild = Alert_GetObjectAlerts (lpi);
if (lpoaServer)
{
for (size_t iAlert = 0; iAlert < lpoaServer->nAlerts; )
{
if ( (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY) &&
(lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpi) )
{
Alert_RemoveFunc (lpoaServer, iAlert);
}
else
{
++iAlert;
}
}
}
if (lpoaServer && lpoaChild)
{
BOOL fNeedBadCredsWarning = FALSE;
BOOL fHaveBadCredsWarning = FALSE;
size_t iAlert;
for (iAlert = 0; iAlert < lpoaServer->nAlerts; ++iAlert)
{
if (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY)
{
ALERT alert = Alert_GetAlert (lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoaServer->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
if (alert == alertNO_SVRENT)
fNeedBadCredsWarning = TRUE;
}
}
for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
{
if (lpoaChild->aAlerts[ iAlert ].alert == alertNO_SVRENT)
fNeedBadCredsWarning = TRUE;
}
if (lpoaServer->nAlerts &&
lpoaServer->aAlerts[ 0 ].alert == alertBADCREDS)
{
fHaveBadCredsWarning = TRUE;
}
if (fNeedBadCredsWarning)
{
fNeedBadCredsWarning = !CheckCredentials (FALSE);
}
if (fHaveBadCredsWarning && !fNeedBadCredsWarning)
{
Alert_RemoveFunc (lpoaServer, 0);
}
else if (fNeedBadCredsWarning && !fHaveBadCredsWarning)
{
for (iAlert = min( lpoaServer->nAlerts, nAlertsMAX-1 );
iAlert > 0;
--iAlert)
{
memcpy (&lpoaServer->aAlerts[ iAlert ], &lpoaServer->aAlerts[ iAlert-1 ], sizeof(ALERTINFO));
}
lpoaServer->aAlerts[0].alert = alertBADCREDS;
lpoaServer->nAlerts = min( nAlertsMAX, lpoaServer->nAlerts+1 );
}
for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
{
if (lpoaServer->nAlerts < nAlertsMAX)
{
lpoaServer->aAlerts[ lpoaServer->nAlerts ].alert = alertSECONDARY;
lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.lpiSecondary = lpi;
lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.iSecondary = iAlert;
lpoaServer->nAlerts ++;
}
}
}
lpServer->Close();
}
}
void Alert_SetDefaults (LPOBJECTALERTS lpoa)
{
if (lpoa != NULL)
{
memset (lpoa, 0x00, sizeof(OBJECTALERTS));
lpoa->cTickRefresh = DEFAULT_SCOUT_REFRESH_RATE;
}
}
void Alert_Initialize (LPOBJECTALERTS lpoa)
{
if (lpoa != NULL)
{
lpoa->dwTickNextTest = 0;
lpoa->dwTickNextRefresh = 0;
lpoa->nAlerts = 0;
}
}
void Alert_RemoveSecondary (LPIDENT lpiChild)
{
BOOL fChangedAlerts = FALSE;
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpiChild, TRUE)) != NULL)
{
size_t iAlert;
for (iAlert = 0; iAlert < lpoa->nAlerts; )
{
if ( (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY) &&
(lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpiChild) )
{
Alert_RemoveFunc (lpoa, iAlert);
fChangedAlerts = TRUE;
}
else
{
++iAlert;
}
}
BOOL fNeedBadCredsWarning = FALSE;
for (iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
{
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
ALERT alert = Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
if (alert == alertNO_SVRENT)
fNeedBadCredsWarning = TRUE;
}
}
if ( (!fNeedBadCredsWarning) &&
(lpoa->nAlerts && (lpoa->aAlerts[ 0 ].alert == alertBADCREDS)) )
{
Alert_RemoveFunc (lpoa, 0);
fChangedAlerts = TRUE;
}
}
if (fChangedAlerts)
{
PostNotification (evtAlertsChanged, lpiChild->GetServer());
PostNotification (evtAlertsChanged, lpiChild);
}
}
void Alert_Remove (LPIDENT lpi, size_t iAlert)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
{
if (iAlert < lpoa->nAlerts)
{
LPSERVER lpServer;
Alert_BeginUpdate (lpi, &lpServer);
Alert_RemoveFunc (lpoa, iAlert);
Alert_EndUpdate (lpi, lpServer);
}
}
}
void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert)
{
if (iAlert < lpoa->nAlerts-1)
{
memcpy (&lpoa->aAlerts[ iAlert ], &lpoa->aAlerts[ lpoa->nAlerts-1 ], sizeof(ALERTINFO));
}
lpoa->nAlerts --;
}
void Alert_AddPrimary (LPIDENT lpi, LPALERTINFO lpai)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
{
if (lpoa->nAlerts < nAlertsMAX)
{
LPSERVER lpServer;
Alert_BeginUpdate (lpi, &lpServer);
memcpy (&lpoa->aAlerts[ lpoa->nAlerts ], lpai, sizeof(ALERTINFO));
lpoa->nAlerts ++;
Alert_EndUpdate (lpi, lpServer);
}
}
}
void Alert_Scout_ServerStatus (LPIDENT lpi, ULONG status)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
{
BOOL fChanged = FALSE;
for (size_t iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
{
if (lpoa->aAlerts[ iAlert ].alert == alertTIMEOUT)
{
fChanged = TRUE;
Alert_RemoveFunc (lpoa, iAlert);
break;
}
}
if (status != 0)
{
size_t iInsert = 0;
if (lpoa->nAlerts && (lpoa->aAlerts[0].alert == alertBADCREDS))
iInsert = 1;
size_t iHole;
for (iHole = iInsert; iHole < lpoa->nAlerts; ++iHole)
{
if (lpoa->aAlerts[ iHole ].alert == alertINVALID)
break;
}
if (iHole < nAlertsMAX)
{
for (size_t iTarget = iHole; iTarget > iInsert; --iTarget)
{
memcpy (&lpoa->aAlerts[ iTarget ], &lpoa->aAlerts[ iTarget-1 ], sizeof(ALERTINFO));
}
lpoa->nAlerts ++;
lpoa->aAlerts[ iInsert ].alert = alertTIMEOUT;
lpoa->aAlerts[ iInsert ].aiTIMEOUT.status = status;
GetSystemTime (&lpoa->aAlerts[ iInsert ].aiTIMEOUT.stLastAttempt);
fChanged = TRUE;
}
}
if (fChanged)
{
PostNotification (evtAlertsChanged, lpi);
}
}
}
size_t Alert_GetCount (LPIDENT lpi)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return 0;
return lpoa->nAlerts;
}
ALERT Alert_GetAlert (LPIDENT lpi, size_t iAlert)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return alertINVALID;
if (iAlert > lpoa->nAlerts)
return alertINVALID;
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
return Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
}
return lpoa->aAlerts[ iAlert ].alert;
}
LPIDENT Alert_GetIdent (LPIDENT lpi, size_t iAlert)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return NULL;
if (iAlert > lpoa->nAlerts)
return NULL;
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
return lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary;
}
return lpi;
}
LPTSTR Alert_GetQuickDescription (LPIDENT lpi)
{
LPTSTR pszStatus = NULL;
size_t cAlerts;
if ((cAlerts = Alert_GetCount (lpi)) <= 1)
pszStatus = Alert_GetDescription (lpi, 0, FALSE);
else if (lpi->fIsServer())
pszStatus = FormatString (IDS_SERVER_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
else if (lpi->fIsService())
pszStatus = FormatString (IDS_SERVICE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
else if (lpi->fIsAggregate())
pszStatus = FormatString (IDS_AGGREGATE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
else if (lpi->fIsFileset())
pszStatus = FormatString (IDS_FILESET_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
return pszStatus;
}
LPTSTR Alert_GetDescription (LPIDENT lpi, size_t iAlert, BOOL fFull)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return NULL;
if (!lpoa->nAlerts && lpi->fIsServer())
{
LPSERVER_PREF lpsp;
if ((lpsp = (LPSERVER_PREF)lpi->GetUserParam()) != NULL)
{
if (!lpsp->fIsMonitored)
{
TCHAR szName[ cchNAME ];
lpi->GetServerName (szName);
return FormatString (IDS_ALERT_DESCSHORT_UNMONITORED, TEXT("%s"), szName);
}
}
}
if (iAlert >= lpoa->nAlerts)
return NULL;
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
return Alert_GetDescriptionFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
lpi,
fFull);
}
return Alert_GetDescriptionFunc (lpi, iAlert, NULL, fFull);
}
LPTSTR Alert_GetRemedy (LPIDENT lpi, size_t iAlert)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return NULL;
if (iAlert >= lpoa->nAlerts)
return NULL;
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
return Alert_GetRemedyFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
lpi);
}
return Alert_GetRemedyFunc (lpi, iAlert, NULL);
}
LPTSTR Alert_GetButton (LPIDENT lpi, size_t iAlert)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
return NULL;
if (iAlert >= lpoa->nAlerts)
return NULL;
if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
{
return Alert_GetButtonFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
lpi);
}
return Alert_GetButtonFunc (lpi, iAlert, NULL);
}
LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
{
int ids;
TCHAR szServer[ cchRESOURCE ];
TCHAR szService[ cchRESOURCE ];
TCHAR szAggregate[ cchRESOURCE ];
TCHAR szFileset[ cchRESOURCE ];
switch (lpoa->aAlerts[ iAlertPrimary ].alert)
{
case alertTIMEOUT:
ids = (fFull) ? IDS_ALERT_DESCFULL_TIMEOUT : IDS_ALERT_DESCSHORT_TIMEOUT;
lpiPrimary->GetServerName (szServer);
return FormatString (ids, TEXT("%s%t%e"), szServer, &lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.stLastAttempt, lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.status);
case alertFULL:
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
if (lpiPrimary->fIsAggregate())
{
ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_FULL : IDS_ALERT_DESCSHORT_AGG_FULL;
return FormatString (ids, TEXT("%s%s%d%.1B"), szServer, szAggregate, lpoa->aAlerts[ iAlertPrimary ].aiFULL.perWarning, 1024.0 * (double)lpoa->aAlerts[ iAlertPrimary ].aiFULL.ckWarning);
}
else if (lpiPrimary->fIsFileset())
{
ids = (fFull) ? IDS_ALERT_DESCFULL_SET_FULL : IDS_ALERT_DESCSHORT_SET_FULL;
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s%d%.1B"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiFULL.perWarning, 1024.0 * (double)lpoa->aAlerts[ iAlertPrimary ].aiFULL.ckWarning);
}
break;
case alertNO_VLDBENT:
ids = (fFull) ? IDS_ALERT_DESCFULL_NO_VLDBENT : IDS_ALERT_DESCSHORT_NO_VLDBENT;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
case alertNO_SVRENT:
if (lpiPrimary->fIsFileset())
{
ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_SET : IDS_ALERT_DESCSHORT_NO_SVRENT_SET;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
}
else
{
ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_AGG : IDS_ALERT_DESCSHORT_NO_SVRENT_AGG;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
return FormatString (ids, TEXT("%s%s"), szServer, szAggregate);
}
break;
case alertSTOPPED:
ids = (fFull) ? IDS_ALERT_DESCFULL_STOPPED : IDS_ALERT_DESCSHORT_STOPPED;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetServiceName (szService);
return FormatString (ids, TEXT("%s%s%t%t%lu"), szServer, szService, &lpoa->aAlerts[ iAlertPrimary ].aiSTOPPED.stStopped, &lpoa->aAlerts[ iAlertPrimary ].aiSTOPPED.stLastError, lpoa->aAlerts[ iAlertPrimary ].aiSTOPPED.errLastError);
case alertBADCREDS:
ids = (fFull) ? IDS_ALERT_DESCFULL_BADCREDS : IDS_ALERT_DESCSHORT_BADCREDS;
lpiPrimary->GetServerName (szServer);
return FormatString (ids, TEXT("%s"), szServer);
case alertOVERALLOC:
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_ALLOC : IDS_ALERT_DESCSHORT_AGG_ALLOC;
return FormatString (ids, TEXT("%s%s%.1B%.1B"), szServer, szAggregate, 1024.0 * (double)(lpoa->aAlerts[ iAlertPrimary ].aiOVERALLOC.ckCapacity), 1024.0 * (double)(lpoa->aAlerts[ iAlertPrimary ].aiOVERALLOC.ckAllocated));
case alertSTATE_NO_VNODE:
ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_VNODE : IDS_ALERT_DESCSHORT_STATE_NO_VNODE;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
case alertSTATE_NO_SERVICE:
ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_SERVICE : IDS_ALERT_DESCSHORT_STATE_NO_SERVICE;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
case alertSTATE_OFFLINE:
ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_OFFLINE : IDS_ALERT_DESCSHORT_STATE_OFFLINE;
lpiPrimary->GetServerName (szServer);
lpiPrimary->GetAggregateName (szAggregate);
lpiPrimary->GetFilesetName (szFileset);
return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
}
}
return NULL;
}
LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
{
switch (lpoa->aAlerts[ iAlertPrimary ].alert)
{
case alertTIMEOUT:
return FormatString (IDS_ALERT_FIX_TIMEOUT);
case alertFULL:
if (lpiPrimary->fIsAggregate())
return FormatString (IDS_ALERT_FIX_AGG_FULL);
else if (lpiPrimary->fIsFileset())
return FormatString (IDS_ALERT_FIX_SET_FULL);
break;
case alertNO_VLDBENT:
return FormatString (IDS_ALERT_FIX_NO_VLDBENT);
case alertNO_SVRENT:
if (lpiPrimary->fIsFileset())
return FormatString (IDS_ALERT_FIX_NO_SVRENT_SET);
else
return FormatString (IDS_ALERT_FIX_NO_SVRENT_AGG);
break;
case alertSTOPPED:
return FormatString (IDS_ALERT_FIX_STOPPED);
case alertBADCREDS:
return FormatString (IDS_ALERT_FIX_BADCREDS);
case alertOVERALLOC:
return FormatString (IDS_ALERT_FIX_AGG_ALLOC);
case alertSTATE_NO_VNODE:
return FormatString (IDS_ALERT_FIX_STATE_NO_VNODE);
case alertSTATE_NO_SERVICE:
return FormatString (IDS_ALERT_FIX_STATE_NO_SERVICE);
case alertSTATE_OFFLINE:
return FormatString (IDS_ALERT_FIX_STATE_OFFLINE);
}
}
return NULL;
}
LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
{
switch (lpoa->aAlerts[ iAlertPrimary ].alert)
{
case alertTIMEOUT:
return FormatString (IDS_ALERT_BUTTON_TRYAGAIN);
case alertFULL:
return FormatString (IDS_ALERT_BUTTON_WARNINGS);
case alertNO_VLDBENT:
return NULL;
case alertNO_SVRENT:
return NULL;
case alertSTOPPED:
return FormatString (IDS_ALERT_BUTTON_VIEWLOG);
case alertBADCREDS:
return FormatString (IDS_ALERT_BUTTON_GETCREDS);
case alertOVERALLOC:
return NULL;
case alertSTATE_NO_VNODE:
return NULL;
case alertSTATE_NO_SERVICE:
return NULL;
case alertSTATE_OFFLINE:
return NULL;
}
}
return NULL;
}
/*
* SCOUT ______________________________________________________________________
*
* (okay, well, our simulated Scout anyway)
*
*/
static HANDLE hScout = 0; // scout's thread
static HANDLE heScoutWakeup = 0; // scout's wakeup event
BOOL Alert_StartScout (ULONG *pStatus)
{
if (hScout == 0) // create scout?
{
heScoutWakeup = CreateEvent (NULL, FALSE, FALSE, TEXT("AfsSvrMgr Alert Scout Wakeup"));
DWORD dwThreadID;
if ((hScout = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE)Alert_ScoutProc,
NULL, 0,
&dwThreadID)) == NULL)
{
if (pStatus)
*pStatus = GetLastError();
return FALSE;
}
SetThreadPriority (hScout, THREAD_PRIORITY_BELOW_NORMAL);
}
else // or just wake up scout from its slumber?
{
PulseEvent (heScoutWakeup);
}
return TRUE;
}
BOOL Alert_Scout_QueueCheckServer (LPIDENT lpiServer, ULONG *pStatus)
{
Alert_Scout_SetOutOfDate (lpiServer);
return Alert_StartScout (pStatus);
}
DWORD WINAPI Alert_ScoutProc (LPVOID lp)
{
// We'll keep working forever...
//
for (;;)
{
AfsClass_Enter();
LPCELL lpCell = (g.lpiCell == NULL) ? NULL : g.lpiCell->OpenCell();
if (lpCell != NULL)
{
// See if our credentials have expired
//
CheckForExpiredCredentials();
// See if any new servers have arrived, or old servers disappeared.
//
lpCell->RefreshServerList();
// Check all the out-of-date servers we can find.
//
HENUM hEnum;
for (LPSERVER lpServer = lpCell->ServerFindFirst (&hEnum); lpServer; lpServer = lpCell->ServerFindNext (&hEnum))
{
LPIDENT lpiServer = lpServer->GetIdentifier();
LPOBJECTALERTS lpoa;
if ( ((lpoa = Alert_GetObjectAlerts (lpiServer)) != NULL) &&
(lpoa->dwTickNextTest <= GetTickCount()) )
{
// Okay! We've found a server that needs to be tested for
// alert conditions. Do that now, and when we're done, set
// its next query-time to some distance in the future.
//
if (lpoa->dwTickNextRefresh == 0)
{
if (lpoa->cTickRefresh != 0)
lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
}
else if (lpoa->dwTickNextRefresh <= GetTickCount())
{
(void)lpServer->Invalidate();
(void)lpServer->RefreshAll();
lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
}
(void)Alert_Scout_CheckServer (lpServer);
}
lpServer->Close();
}
lpCell->Close();
}
AfsClass_Leave();
// Now that we have completed a pass over the servers in this cell,
// and now that we're not holding any critical sections on which
// other threads would otherwise block, go to sleep for a while.
//
WaitForSingleObjectEx (heScoutWakeup, 45L * cmsec1SECOND, FALSE);
}
return 0;
}
void Alert_Scout_SetOutOfDate (LPIDENT lpi)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpi, TRUE)) != NULL)
{
lpoa->dwTickNextTest = GetTickCount() -1;
}
}
void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa)
{
if (lpoa != NULL)
{
lpoa->dwTickNextTest = GetTickCount() + lpoa->cTickRefresh;
}
}
BOOL Alert_Scout_CheckServer (LPSERVER lpServer)
{
BOOL rc = TRUE;
LPSERVER_PREF lpsp;
if ((lpsp = (LPSERVER_PREF)lpServer->GetUserParam()) != NULL)
{
LPOBJECTALERTS lpoa;
if ((lpoa = Alert_GetObjectAlerts (lpServer->GetIdentifier())) != NULL)
{
PostNotification (evtScoutBegin, lpServer->GetIdentifier());
BOOL fChangedServerAlerts = FALSE;
DWORD dwTickNextTestWhenStarted = lpoa->dwTickNextTest;
// First look through the server's aggregates and filesets, to
// find any which have usages over their warning threshholds.
//
HENUM heAggregate;
for (LPAGGREGATE lpAggregate = lpServer->AggregateFindFirst (&heAggregate); lpAggregate; lpAggregate = lpServer->AggregateFindNext (&heAggregate))
{
BOOL fChangedAggregateAlerts = FALSE;
LPIDENT lpiAggregate = lpAggregate->GetIdentifier();
LPOBJECTALERTS lpoaAggregate;
if ((lpoaAggregate = Alert_GetObjectAlerts (lpAggregate->GetIdentifier())) != NULL)
{
for (size_t iAlert = 0; iAlert < lpoaAggregate->nAlerts; )
{
if ( (lpoaAggregate->aAlerts[ iAlert ].alert == alertFULL) ||
(lpoaAggregate->aAlerts[ iAlert ].alert == alertOVERALLOC) ||
(lpoaAggregate->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
{
fChangedAggregateAlerts = TRUE;
fChangedServerAlerts = TRUE;
Alert_Remove (lpAggregate->GetIdentifier(), iAlert);
}
else
++iAlert;
}
LPAGGREGATE_PREF lpap;
if ((lpap = (LPAGGREGATE_PREF)lpAggregate->GetUserParam()) != NULL)
{
short wGhost = lpAggregate->GetGhostStatus();
if (lpsp->fWarnAggNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY))
{
ALERTINFO ai;
ai.alert = alertNO_SVRENT;
Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
fChangedAggregateAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
if (lpsp->fWarnAggAlloc && lpap->fWarnAggAlloc)
{
AGGREGATESTATUS as;
if (lpAggregate->GetStatus (&as, TRUE))
{
if (as.ckStorageAllocated > as.ckStorageTotal)
{
ALERTINFO ai;
ai.alert = alertOVERALLOC;
ai.aiOVERALLOC.ckAllocated = as.ckStorageAllocated;
ai.aiOVERALLOC.ckCapacity = as.ckStorageTotal;
Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
fChangedAggregateAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
}
}
short perWarnAggFull = lpap->perWarnAggFull;
if (perWarnAggFull == -1)
perWarnAggFull = lpsp->perWarnAggFull;
if (perWarnAggFull != 0)
{
AGGREGATESTATUS as;
if (lpAggregate->GetStatus (&as, TRUE))
{
if (as.ckStorageTotal != 0)
{
short perNow = (short)( (double)(as.ckStorageTotal - as.ckStorageFree) * 100.0 / (double)(as.ckStorageTotal) );
if (perNow > perWarnAggFull)
{
ALERTINFO ai;
ai.alert = alertFULL;
ai.aiFULL.perWarning = perWarnAggFull;
ai.aiFULL.ckWarning = (ULONG)( (double)perWarnAggFull * (double)(as.ckStorageTotal) / 100.0 );
Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
fChangedAggregateAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
}
}
}
}
}
HENUM heFileset;
for (LPFILESET lpFileset = lpAggregate->FilesetFindFirst (&heFileset); lpFileset; lpFileset = lpAggregate->FilesetFindNext (&heFileset))
{
BOOL fChangedFilesetAlerts = FALSE;
LPIDENT lpiFileset = lpFileset->GetIdentifier();
LPOBJECTALERTS lpoaFileset;
if ((lpoaFileset = Alert_GetObjectAlerts (lpFileset->GetIdentifier())) != NULL)
{
for (size_t iAlert = 0; iAlert < lpoaFileset->nAlerts; )
{
if ( (lpoaFileset->aAlerts[ iAlert ].alert == alertFULL) ||
(lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_VNODE) ||
(lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_SERVICE) ||
(lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_OFFLINE) ||
(lpoaFileset->aAlerts[ iAlert ].alert == alertNO_VLDBENT) ||
(lpoaFileset->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
{
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
Alert_Remove (lpFileset->GetIdentifier(), iAlert);
}
else
++iAlert;
}
}
LPFILESET_PREF lpfp;
if ((lpfp = (LPFILESET_PREF)lpFileset->GetUserParam()) != NULL)
{
FILESETSTATUS fs;
if (lpFileset->GetStatus (&fs, TRUE))
{
if (fs.State & fsNO_VNODE)
{
ALERTINFO ai;
ai.alert = alertSTATE_NO_VNODE;
ai.aiSTATE.State = fs.State;
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
else if (fs.State & fsNO_SERVICE)
{
ALERTINFO ai;
ai.alert = alertSTATE_NO_SERVICE;
ai.aiSTATE.State = fs.State;
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
else if (fs.State & fsOFFLINE)
{
ALERTINFO ai;
ai.alert = alertSTATE_OFFLINE;
ai.aiSTATE.State = fs.State;
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
short perWarnSetFull = lpfp->perWarnSetFull;
if (perWarnSetFull == -1)
perWarnSetFull = lpsp->perWarnSetFull;
if (perWarnSetFull != 0)
{
if (fs.Type == ftREADWRITE)
{
if (fs.ckQuota != 0)
{
short perNow = (short)( (double)(fs.ckUsed) * 100.0 / (double)(fs.ckQuota) );
if (perNow > perWarnSetFull)
{
ALERTINFO ai;
ai.alert = alertFULL;
ai.aiFULL.perWarning = perWarnSetFull;
ai.aiFULL.ckWarning = (ULONG)( (double)perWarnSetFull * (double)(fs.ckQuota) / 100.0 );
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
}
}
}
}
short wGhost = lpFileset->GetGhostStatus();
if (lpsp->fWarnSetNoVLDB && !(wGhost & GHOST_HAS_VLDB_ENTRY))
{
ALERTINFO ai;
ai.alert = alertNO_VLDBENT;
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
if (lpsp->fWarnSetNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY) && !(fs.Type == ftREPLICA))
{
ALERTINFO ai;
ai.alert = alertNO_SVRENT;
Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
fChangedFilesetAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
}
lpFileset->Close();
if (fChangedFilesetAlerts)
{
PostNotification (evtAlertsChanged, lpiFileset);
}
}
lpAggregate->Close();
if (fChangedAggregateAlerts)
{
PostNotification (evtAlertsChanged, lpiAggregate);
}
}
// Next look through the server's servces to find any
// which have stopped.
//
HENUM heService;
for (LPSERVICE lpService = lpServer->ServiceFindFirst (&heService); lpService; lpService = lpServer->ServiceFindNext (&heService))
{
BOOL fChangedServiceAlerts = FALSE;
LPIDENT lpiService = lpService->GetIdentifier();
LPOBJECTALERTS lpoaService;
if ((lpoaService = Alert_GetObjectAlerts (lpService->GetIdentifier())) != NULL)
{
for (size_t iAlert = 0; iAlert < lpoaService->nAlerts; )
{
if (lpoaService->aAlerts[ iAlert ].alert == alertSTOPPED)
{
fChangedServiceAlerts = TRUE;
fChangedServerAlerts = TRUE;
Alert_Remove (lpService->GetIdentifier(), iAlert);
}
else
++iAlert;
}
LPSERVICE_PREF lpcp;
if ((lpcp = (LPSERVICE_PREF)lpService->GetUserParam()) != NULL)
{
if (lpcp->fWarnSvcStop && lpsp->fWarnSvcStop)
{
SERVICESTATUS ss;
if (lpService->GetStatus (&ss, TRUE))
{
if (ss.state != SERVICESTATE_RUNNING)
{
ALERTINFO ai;
ai.alert = alertSTOPPED;
memcpy (&ai.aiSTOPPED.stStopped, &ss.timeLastStop, sizeof(SYSTEMTIME));
memcpy (&ai.aiSTOPPED.stLastError, &ss.timeLastFail, sizeof(SYSTEMTIME));
ai.aiSTOPPED.errLastError = ss.dwErrLast;
Alert_AddPrimary (lpService->GetIdentifier(), &ai);
fChangedServiceAlerts = TRUE;
fChangedServerAlerts = TRUE;
}
}
}
}
}
lpService->Close();
if (fChangedServiceAlerts)
{
PostNotification (evtAlertsChanged, lpiService);
}
}
if (rc && (dwTickNextTestWhenStarted == lpoa->dwTickNextTest))
{
Alert_Scout_SetUpToDate (lpoa);
}
if (fChangedServerAlerts)
{
PostNotification (evtAlertsChanged, lpServer->GetIdentifier());
}
PostNotification (evtScoutEnd, lpServer->GetIdentifier());
}
}
return rc;
}