2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afsconfig.h>
15 #include <afs/param.h>
25 * DEFINITIONS ________________________________________________________________
31 * VARIABLES __________________________________________________________________
37 * PROTOTYPES _________________________________________________________________
41 BOOL Alert_Scout_CheckServer (LPSERVER lpServer);
43 void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer);
44 void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer);
46 void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert);
47 LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull);
48 LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
49 LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
51 DWORD WINAPI Alert_ScoutProc (LPVOID lp);
52 void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa);
56 * ROUTINES ___________________________________________________________________
60 LPOBJECTALERTS Alert_GetObjectAlerts (LPIDENT lpi, BOOL fAlwaysServer, ULONG *pStatus)
62 LPOBJECTALERTS lpoa = NULL;
64 if (fAlwaysServer || lpi->fIsServer())
67 if ((lpsp = (LPSERVER_PREF)lpi->GetServer()->GetUserParam()) != NULL)
72 else if (lpi->fIsService())
75 if ((lpsp = (LPSERVICE_PREF)lpi->GetUserParam()) != NULL)
80 else if (lpi->fIsAggregate())
82 LPAGGREGATE_PREF lpap;
83 if ((lpap = (LPAGGREGATE_PREF)lpi->GetUserParam()) != NULL)
88 else if (lpi->fIsFileset())
91 if ((lpfp = (LPFILESET_PREF)lpi->GetUserParam()) != NULL)
101 void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer)
103 if (lpi->fIsServer())
109 *ppServer = lpi->OpenServer();
114 void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer)
116 // If we just updated some aggregate, fileset or service, then the
117 // associated server's secondary alerts are probably out-of-date.
120 if (lpServer != NULL)
122 LPOBJECTALERTS lpoaServer = Alert_GetObjectAlerts (lpServer->GetIdentifier());
123 LPOBJECTALERTS lpoaChild = Alert_GetObjectAlerts (lpi);
127 for (size_t iAlert = 0; iAlert < lpoaServer->nAlerts; )
129 if ( (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY) &&
130 (lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpi) )
132 Alert_RemoveFunc (lpoaServer, iAlert);
141 if (lpoaServer && lpoaChild)
143 BOOL fNeedBadCredsWarning = FALSE;
144 BOOL fHaveBadCredsWarning = FALSE;
147 for (iAlert = 0; iAlert < lpoaServer->nAlerts; ++iAlert)
149 if (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY)
151 ALERT alert = Alert_GetAlert (lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
152 lpoaServer->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
153 if (alert == alertNO_SVRENT)
154 fNeedBadCredsWarning = TRUE;
157 for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
159 if (lpoaChild->aAlerts[ iAlert ].alert == alertNO_SVRENT)
160 fNeedBadCredsWarning = TRUE;
162 if (lpoaServer->nAlerts &&
163 lpoaServer->aAlerts[ 0 ].alert == alertBADCREDS)
165 fHaveBadCredsWarning = TRUE;
168 if (fNeedBadCredsWarning)
170 fNeedBadCredsWarning = !CheckCredentials (FALSE);
173 if (fHaveBadCredsWarning && !fNeedBadCredsWarning)
175 Alert_RemoveFunc (lpoaServer, 0);
177 else if (fNeedBadCredsWarning && !fHaveBadCredsWarning)
179 for (iAlert = min( lpoaServer->nAlerts, nAlertsMAX-1 );
183 memcpy (&lpoaServer->aAlerts[ iAlert ], &lpoaServer->aAlerts[ iAlert-1 ], sizeof(ALERTINFO));
185 lpoaServer->aAlerts[0].alert = alertBADCREDS;
186 lpoaServer->nAlerts = min( nAlertsMAX, lpoaServer->nAlerts+1 );
189 for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
191 if (lpoaServer->nAlerts < nAlertsMAX)
193 lpoaServer->aAlerts[ lpoaServer->nAlerts ].alert = alertSECONDARY;
194 lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.lpiSecondary = lpi;
195 lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.iSecondary = iAlert;
196 lpoaServer->nAlerts ++;
206 void Alert_SetDefaults (LPOBJECTALERTS lpoa)
210 memset (lpoa, 0x00, sizeof(OBJECTALERTS));
211 lpoa->cTickRefresh = DEFAULT_SCOUT_REFRESH_RATE;
216 void Alert_Initialize (LPOBJECTALERTS lpoa)
220 lpoa->dwTickNextTest = 0;
221 lpoa->dwTickNextRefresh = 0;
227 void Alert_RemoveSecondary (LPIDENT lpiChild)
229 BOOL fChangedAlerts = FALSE;
232 if ((lpoa = Alert_GetObjectAlerts (lpiChild, TRUE)) != NULL)
235 for (iAlert = 0; iAlert < lpoa->nAlerts; )
237 if ( (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY) &&
238 (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpiChild) )
240 Alert_RemoveFunc (lpoa, iAlert);
241 fChangedAlerts = TRUE;
250 BOOL fNeedBadCredsWarning = FALSE;
252 for (iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
254 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
256 ALERT alert = Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
257 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
258 if (alert == alertNO_SVRENT)
259 fNeedBadCredsWarning = TRUE;
263 if ( (!fNeedBadCredsWarning) &&
264 (lpoa->nAlerts && (lpoa->aAlerts[ 0 ].alert == alertBADCREDS)) )
266 Alert_RemoveFunc (lpoa, 0);
267 fChangedAlerts = TRUE;
273 PostNotification (evtAlertsChanged, lpiChild->GetServer());
274 PostNotification (evtAlertsChanged, lpiChild);
279 void Alert_Remove (LPIDENT lpi, size_t iAlert)
283 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
285 if (iAlert < lpoa->nAlerts)
288 Alert_BeginUpdate (lpi, &lpServer);
290 Alert_RemoveFunc (lpoa, iAlert);
292 Alert_EndUpdate (lpi, lpServer);
298 void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert)
300 if (iAlert < lpoa->nAlerts-1)
302 memcpy (&lpoa->aAlerts[ iAlert ], &lpoa->aAlerts[ lpoa->nAlerts-1 ], sizeof(ALERTINFO));
308 void Alert_AddPrimary (LPIDENT lpi, LPALERTINFO lpai)
312 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
314 if (lpoa->nAlerts < nAlertsMAX)
317 Alert_BeginUpdate (lpi, &lpServer);
319 memcpy (&lpoa->aAlerts[ lpoa->nAlerts ], lpai, sizeof(ALERTINFO));
322 Alert_EndUpdate (lpi, lpServer);
328 void Alert_Scout_ServerStatus (LPIDENT lpi, ULONG status)
331 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
333 BOOL fChanged = FALSE;
335 for (size_t iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
337 if (lpoa->aAlerts[ iAlert ].alert == alertTIMEOUT)
340 Alert_RemoveFunc (lpoa, iAlert);
348 if (lpoa->nAlerts && (lpoa->aAlerts[0].alert == alertBADCREDS))
352 for (iHole = iInsert; iHole < lpoa->nAlerts; ++iHole)
354 if (lpoa->aAlerts[ iHole ].alert == alertINVALID)
357 if (iHole < nAlertsMAX)
359 for (size_t iTarget = iHole; iTarget > iInsert; --iTarget)
361 memcpy (&lpoa->aAlerts[ iTarget ], &lpoa->aAlerts[ iTarget-1 ], sizeof(ALERTINFO));
365 lpoa->aAlerts[ iInsert ].alert = alertTIMEOUT;
366 lpoa->aAlerts[ iInsert ].aiTIMEOUT.status = status;
367 GetSystemTime (&lpoa->aAlerts[ iInsert ].aiTIMEOUT.stLastAttempt);
375 PostNotification (evtAlertsChanged, lpi);
381 size_t Alert_GetCount (LPIDENT lpi)
385 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
388 return lpoa->nAlerts;
392 ALERT Alert_GetAlert (LPIDENT lpi, size_t iAlert)
396 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
399 if (iAlert > lpoa->nAlerts)
402 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
404 return Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
405 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
408 return lpoa->aAlerts[ iAlert ].alert;
412 LPIDENT Alert_GetIdent (LPIDENT lpi, size_t iAlert)
416 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
419 if (iAlert > lpoa->nAlerts)
422 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
424 return lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary;
431 LPTSTR Alert_GetQuickDescription (LPIDENT lpi)
433 LPTSTR pszStatus = NULL;
436 if ((cAlerts = Alert_GetCount (lpi)) <= 1)
437 pszStatus = Alert_GetDescription (lpi, 0, FALSE);
438 else if (lpi->fIsServer())
439 pszStatus = FormatString (IDS_SERVER_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
440 else if (lpi->fIsService())
441 pszStatus = FormatString (IDS_SERVICE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
442 else if (lpi->fIsAggregate())
443 pszStatus = FormatString (IDS_AGGREGATE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
444 else if (lpi->fIsFileset())
445 pszStatus = FormatString (IDS_FILESET_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
451 LPTSTR Alert_GetDescription (LPIDENT lpi, size_t iAlert, BOOL fFull)
455 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
458 if (!lpoa->nAlerts && lpi->fIsServer())
461 if ((lpsp = (LPSERVER_PREF)lpi->GetUserParam()) != NULL)
463 if (!lpsp->fIsMonitored)
465 TCHAR szName[ cchNAME ];
466 lpi->GetServerName (szName);
467 return FormatString (IDS_ALERT_DESCSHORT_UNMONITORED, TEXT("%s"), szName);
472 if (iAlert >= lpoa->nAlerts)
475 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
477 return Alert_GetDescriptionFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
478 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
483 return Alert_GetDescriptionFunc (lpi, iAlert, NULL, fFull);
487 LPTSTR Alert_GetRemedy (LPIDENT lpi, size_t iAlert)
491 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
494 if (iAlert >= lpoa->nAlerts)
497 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
499 return Alert_GetRemedyFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
500 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
504 return Alert_GetRemedyFunc (lpi, iAlert, NULL);
508 LPTSTR Alert_GetButton (LPIDENT lpi, size_t iAlert)
512 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
515 if (iAlert >= lpoa->nAlerts)
518 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
520 return Alert_GetButtonFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
521 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
525 return Alert_GetButtonFunc (lpi, iAlert, NULL);
529 LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull)
532 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
535 TCHAR szServer[ cchRESOURCE ];
536 TCHAR szService[ cchRESOURCE ];
537 TCHAR szAggregate[ cchRESOURCE ];
538 TCHAR szFileset[ cchRESOURCE ];
540 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
543 ids = (fFull) ? IDS_ALERT_DESCFULL_TIMEOUT : IDS_ALERT_DESCSHORT_TIMEOUT;
544 lpiPrimary->GetServerName (szServer);
545 return FormatString (ids, TEXT("%s%t%e"), szServer, &lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.stLastAttempt, lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.status);
548 lpiPrimary->GetServerName (szServer);
549 lpiPrimary->GetAggregateName (szAggregate);
550 if (lpiPrimary->fIsAggregate())
552 ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_FULL : IDS_ALERT_DESCSHORT_AGG_FULL;
553 return FormatString (ids, TEXT("%s%s%d%.1B"), szServer, szAggregate, lpoa->aAlerts[ iAlertPrimary ].aiFULL.perWarning, 1024.0 * (double)lpoa->aAlerts[ iAlertPrimary ].aiFULL.ckWarning);
555 else if (lpiPrimary->fIsFileset())
557 ids = (fFull) ? IDS_ALERT_DESCFULL_SET_FULL : IDS_ALERT_DESCSHORT_SET_FULL;
558 lpiPrimary->GetFilesetName (szFileset);
559 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);
563 case alertNO_VLDBENT:
564 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_VLDBENT : IDS_ALERT_DESCSHORT_NO_VLDBENT;
565 lpiPrimary->GetServerName (szServer);
566 lpiPrimary->GetAggregateName (szAggregate);
567 lpiPrimary->GetFilesetName (szFileset);
568 return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
571 if (lpiPrimary->fIsFileset())
573 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_SET : IDS_ALERT_DESCSHORT_NO_SVRENT_SET;
574 lpiPrimary->GetServerName (szServer);
575 lpiPrimary->GetAggregateName (szAggregate);
576 lpiPrimary->GetFilesetName (szFileset);
577 return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
581 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_AGG : IDS_ALERT_DESCSHORT_NO_SVRENT_AGG;
582 lpiPrimary->GetServerName (szServer);
583 lpiPrimary->GetAggregateName (szAggregate);
584 return FormatString (ids, TEXT("%s%s"), szServer, szAggregate);
589 ids = (fFull) ? IDS_ALERT_DESCFULL_STOPPED : IDS_ALERT_DESCSHORT_STOPPED;
590 lpiPrimary->GetServerName (szServer);
591 lpiPrimary->GetServiceName (szService);
592 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);
595 ids = (fFull) ? IDS_ALERT_DESCFULL_BADCREDS : IDS_ALERT_DESCSHORT_BADCREDS;
596 lpiPrimary->GetServerName (szServer);
597 return FormatString (ids, TEXT("%s"), szServer);
600 lpiPrimary->GetServerName (szServer);
601 lpiPrimary->GetAggregateName (szAggregate);
602 ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_ALLOC : IDS_ALERT_DESCSHORT_AGG_ALLOC;
603 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));
605 case alertSTATE_NO_VNODE:
606 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_VNODE : IDS_ALERT_DESCSHORT_STATE_NO_VNODE;
607 lpiPrimary->GetServerName (szServer);
608 lpiPrimary->GetAggregateName (szAggregate);
609 lpiPrimary->GetFilesetName (szFileset);
610 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
612 case alertSTATE_NO_SERVICE:
613 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_SERVICE : IDS_ALERT_DESCSHORT_STATE_NO_SERVICE;
614 lpiPrimary->GetServerName (szServer);
615 lpiPrimary->GetAggregateName (szAggregate);
616 lpiPrimary->GetFilesetName (szFileset);
617 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
619 case alertSTATE_OFFLINE:
620 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_OFFLINE : IDS_ALERT_DESCSHORT_STATE_OFFLINE;
621 lpiPrimary->GetServerName (szServer);
622 lpiPrimary->GetAggregateName (szAggregate);
623 lpiPrimary->GetFilesetName (szFileset);
624 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
632 LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
635 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
637 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
640 return FormatString (IDS_ALERT_FIX_TIMEOUT);
642 if (lpiPrimary->fIsAggregate())
643 return FormatString (IDS_ALERT_FIX_AGG_FULL);
644 else if (lpiPrimary->fIsFileset())
645 return FormatString (IDS_ALERT_FIX_SET_FULL);
647 case alertNO_VLDBENT:
648 return FormatString (IDS_ALERT_FIX_NO_VLDBENT);
650 if (lpiPrimary->fIsFileset())
651 return FormatString (IDS_ALERT_FIX_NO_SVRENT_SET);
653 return FormatString (IDS_ALERT_FIX_NO_SVRENT_AGG);
656 return FormatString (IDS_ALERT_FIX_STOPPED);
658 return FormatString (IDS_ALERT_FIX_BADCREDS);
660 return FormatString (IDS_ALERT_FIX_AGG_ALLOC);
661 case alertSTATE_NO_VNODE:
662 return FormatString (IDS_ALERT_FIX_STATE_NO_VNODE);
663 case alertSTATE_NO_SERVICE:
664 return FormatString (IDS_ALERT_FIX_STATE_NO_SERVICE);
665 case alertSTATE_OFFLINE:
666 return FormatString (IDS_ALERT_FIX_STATE_OFFLINE);
674 LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
677 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
679 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
682 return FormatString (IDS_ALERT_BUTTON_TRYAGAIN);
684 return FormatString (IDS_ALERT_BUTTON_WARNINGS);
685 case alertNO_VLDBENT:
690 return FormatString (IDS_ALERT_BUTTON_VIEWLOG);
692 return FormatString (IDS_ALERT_BUTTON_GETCREDS);
695 case alertSTATE_NO_VNODE:
697 case alertSTATE_NO_SERVICE:
699 case alertSTATE_OFFLINE:
709 * SCOUT ______________________________________________________________________
711 * (okay, well, our simulated Scout anyway)
715 static HANDLE hScout = 0; // scout's thread
716 static HANDLE heScoutWakeup = 0; // scout's wakeup event
718 BOOL Alert_StartScout (ULONG *pStatus)
720 if (hScout == 0) // create scout?
722 heScoutWakeup = CreateEvent (NULL, FALSE, FALSE, TEXT("AfsSvrMgr Alert Scout Wakeup"));
725 if ((hScout = CreateThread (NULL, 0,
726 (LPTHREAD_START_ROUTINE)Alert_ScoutProc,
728 &dwThreadID)) == NULL)
731 *pStatus = GetLastError();
735 SetThreadPriority (hScout, THREAD_PRIORITY_BELOW_NORMAL);
737 else // or just wake up scout from its slumber?
739 PulseEvent (heScoutWakeup);
746 BOOL Alert_Scout_QueueCheckServer (LPIDENT lpiServer, ULONG *pStatus)
748 Alert_Scout_SetOutOfDate (lpiServer);
749 return Alert_StartScout (pStatus);
753 DWORD WINAPI Alert_ScoutProc (LPVOID lp)
755 // We'll keep working forever...
761 LPCELL lpCell = (g.lpiCell == NULL) ? NULL : g.lpiCell->OpenCell();
764 // See if our credentials have expired
766 CheckForExpiredCredentials();
768 // See if any new servers have arrived, or old servers disappeared.
770 lpCell->RefreshServerList();
772 // Check all the out-of-date servers we can find.
775 for (LPSERVER lpServer = lpCell->ServerFindFirst (&hEnum); lpServer; lpServer = lpCell->ServerFindNext (&hEnum))
777 LPIDENT lpiServer = lpServer->GetIdentifier();
780 if ( ((lpoa = Alert_GetObjectAlerts (lpiServer)) != NULL) &&
781 (lpoa->dwTickNextTest <= GetTickCount()) )
784 // Okay! We've found a server that needs to be tested for
785 // alert conditions. Do that now, and when we're done, set
786 // its next query-time to some distance in the future.
788 if (lpoa->dwTickNextRefresh == 0)
790 if (lpoa->cTickRefresh != 0)
791 lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
793 else if (lpoa->dwTickNextRefresh <= GetTickCount())
795 (void)lpServer->Invalidate();
796 (void)lpServer->RefreshAll();
797 lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
800 (void)Alert_Scout_CheckServer (lpServer);
811 // Now that we have completed a pass over the servers in this cell,
812 // and now that we're not holding any critical sections on which
813 // other threads would otherwise block, go to sleep for a while.
815 WaitForSingleObjectEx (heScoutWakeup, 45L * cmsec1SECOND, FALSE);
822 void Alert_Scout_SetOutOfDate (LPIDENT lpi)
825 if ((lpoa = Alert_GetObjectAlerts (lpi, TRUE)) != NULL)
827 lpoa->dwTickNextTest = GetTickCount() -1;
832 void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa)
836 lpoa->dwTickNextTest = GetTickCount() + lpoa->cTickRefresh;
841 BOOL Alert_Scout_CheckServer (LPSERVER lpServer)
846 if ((lpsp = (LPSERVER_PREF)lpServer->GetUserParam()) != NULL)
849 if ((lpoa = Alert_GetObjectAlerts (lpServer->GetIdentifier())) != NULL)
851 PostNotification (evtScoutBegin, lpServer->GetIdentifier());
853 BOOL fChangedServerAlerts = FALSE;
855 DWORD dwTickNextTestWhenStarted = lpoa->dwTickNextTest;
857 // First look through the server's aggregates and filesets, to
858 // find any which have usages over their warning threshholds.
861 for (LPAGGREGATE lpAggregate = lpServer->AggregateFindFirst (&heAggregate); lpAggregate; lpAggregate = lpServer->AggregateFindNext (&heAggregate))
863 BOOL fChangedAggregateAlerts = FALSE;
864 LPIDENT lpiAggregate = lpAggregate->GetIdentifier();
866 LPOBJECTALERTS lpoaAggregate;
867 if ((lpoaAggregate = Alert_GetObjectAlerts (lpAggregate->GetIdentifier())) != NULL)
869 for (size_t iAlert = 0; iAlert < lpoaAggregate->nAlerts; )
871 if ( (lpoaAggregate->aAlerts[ iAlert ].alert == alertFULL) ||
872 (lpoaAggregate->aAlerts[ iAlert ].alert == alertOVERALLOC) ||
873 (lpoaAggregate->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
875 fChangedAggregateAlerts = TRUE;
876 fChangedServerAlerts = TRUE;
877 Alert_Remove (lpAggregate->GetIdentifier(), iAlert);
883 LPAGGREGATE_PREF lpap;
884 if ((lpap = (LPAGGREGATE_PREF)lpAggregate->GetUserParam()) != NULL)
886 short wGhost = lpAggregate->GetGhostStatus();
887 if (lpsp->fWarnAggNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY))
890 ai.alert = alertNO_SVRENT;
891 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
892 fChangedAggregateAlerts = TRUE;
893 fChangedServerAlerts = TRUE;
896 if (lpsp->fWarnAggAlloc && lpap->fWarnAggAlloc)
899 if (lpAggregate->GetStatus (&as, TRUE))
901 if (as.ckStorageAllocated > as.ckStorageTotal)
904 ai.alert = alertOVERALLOC;
905 ai.aiOVERALLOC.ckAllocated = as.ckStorageAllocated;
906 ai.aiOVERALLOC.ckCapacity = as.ckStorageTotal;
907 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
908 fChangedAggregateAlerts = TRUE;
909 fChangedServerAlerts = TRUE;
914 short perWarnAggFull = lpap->perWarnAggFull;
915 if (perWarnAggFull == -1)
916 perWarnAggFull = lpsp->perWarnAggFull;
917 if (perWarnAggFull != 0)
920 if (lpAggregate->GetStatus (&as, TRUE))
922 if (as.ckStorageTotal != 0)
924 short perNow = (short)( (double)(as.ckStorageTotal - as.ckStorageFree) * 100.0 / (double)(as.ckStorageTotal) );
926 if (perNow > perWarnAggFull)
929 ai.alert = alertFULL;
930 ai.aiFULL.perWarning = perWarnAggFull;
931 ai.aiFULL.ckWarning = (ULONG)( (double)perWarnAggFull * (double)(as.ckStorageTotal) / 100.0 );
932 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
933 fChangedAggregateAlerts = TRUE;
934 fChangedServerAlerts = TRUE;
943 for (LPFILESET lpFileset = lpAggregate->FilesetFindFirst (&heFileset); lpFileset; lpFileset = lpAggregate->FilesetFindNext (&heFileset))
945 BOOL fChangedFilesetAlerts = FALSE;
946 LPIDENT lpiFileset = lpFileset->GetIdentifier();
948 LPOBJECTALERTS lpoaFileset;
949 if ((lpoaFileset = Alert_GetObjectAlerts (lpFileset->GetIdentifier())) != NULL)
951 for (size_t iAlert = 0; iAlert < lpoaFileset->nAlerts; )
953 if ( (lpoaFileset->aAlerts[ iAlert ].alert == alertFULL) ||
954 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_VNODE) ||
955 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_SERVICE) ||
956 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_OFFLINE) ||
957 (lpoaFileset->aAlerts[ iAlert ].alert == alertNO_VLDBENT) ||
958 (lpoaFileset->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
960 fChangedFilesetAlerts = TRUE;
961 fChangedServerAlerts = TRUE;
962 Alert_Remove (lpFileset->GetIdentifier(), iAlert);
970 if ((lpfp = (LPFILESET_PREF)lpFileset->GetUserParam()) != NULL)
973 if (lpFileset->GetStatus (&fs, TRUE))
975 if (fs.State & fsNO_VNODE)
978 ai.alert = alertSTATE_NO_VNODE;
979 ai.aiSTATE.State = fs.State;
980 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
981 fChangedFilesetAlerts = TRUE;
982 fChangedServerAlerts = TRUE;
984 else if (fs.State & fsNO_SERVICE)
987 ai.alert = alertSTATE_NO_SERVICE;
988 ai.aiSTATE.State = fs.State;
989 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
990 fChangedFilesetAlerts = TRUE;
991 fChangedServerAlerts = TRUE;
993 else if (fs.State & fsOFFLINE)
996 ai.alert = alertSTATE_OFFLINE;
997 ai.aiSTATE.State = fs.State;
998 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
999 fChangedFilesetAlerts = TRUE;
1000 fChangedServerAlerts = TRUE;
1003 short perWarnSetFull = lpfp->perWarnSetFull;
1004 if (perWarnSetFull == -1)
1005 perWarnSetFull = lpsp->perWarnSetFull;
1006 if (perWarnSetFull != 0)
1008 if (fs.Type == ftREADWRITE)
1010 if (fs.ckQuota != 0)
1012 short perNow = (short)( (double)(fs.ckUsed) * 100.0 / (double)(fs.ckQuota) );
1014 if (perNow > perWarnSetFull)
1017 ai.alert = alertFULL;
1018 ai.aiFULL.perWarning = perWarnSetFull;
1019 ai.aiFULL.ckWarning = (ULONG)( (double)perWarnSetFull * (double)(fs.ckQuota) / 100.0 );
1020 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1021 fChangedFilesetAlerts = TRUE;
1022 fChangedServerAlerts = TRUE;
1029 short wGhost = lpFileset->GetGhostStatus();
1030 if (lpsp->fWarnSetNoVLDB && !(wGhost & GHOST_HAS_VLDB_ENTRY))
1033 ai.alert = alertNO_VLDBENT;
1034 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1035 fChangedFilesetAlerts = TRUE;
1036 fChangedServerAlerts = TRUE;
1038 if (lpsp->fWarnSetNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY) && !(fs.Type == ftREPLICA))
1041 ai.alert = alertNO_SVRENT;
1042 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1043 fChangedFilesetAlerts = TRUE;
1044 fChangedServerAlerts = TRUE;
1049 if (fChangedFilesetAlerts)
1051 PostNotification (evtAlertsChanged, lpiFileset);
1055 lpAggregate->Close();
1056 if (fChangedAggregateAlerts)
1058 PostNotification (evtAlertsChanged, lpiAggregate);
1062 // Next look through the server's servces to find any
1063 // which have stopped.
1066 for (LPSERVICE lpService = lpServer->ServiceFindFirst (&heService); lpService; lpService = lpServer->ServiceFindNext (&heService))
1068 BOOL fChangedServiceAlerts = FALSE;
1069 LPIDENT lpiService = lpService->GetIdentifier();
1071 LPOBJECTALERTS lpoaService;
1072 if ((lpoaService = Alert_GetObjectAlerts (lpService->GetIdentifier())) != NULL)
1074 for (size_t iAlert = 0; iAlert < lpoaService->nAlerts; )
1076 if (lpoaService->aAlerts[ iAlert ].alert == alertSTOPPED)
1078 fChangedServiceAlerts = TRUE;
1079 fChangedServerAlerts = TRUE;
1080 Alert_Remove (lpService->GetIdentifier(), iAlert);
1086 LPSERVICE_PREF lpcp;
1087 if ((lpcp = (LPSERVICE_PREF)lpService->GetUserParam()) != NULL)
1089 if (lpcp->fWarnSvcStop && lpsp->fWarnSvcStop)
1092 if (lpService->GetStatus (&ss, TRUE))
1094 if (ss.state != SERVICESTATE_RUNNING)
1097 ai.alert = alertSTOPPED;
1098 memcpy (&ai.aiSTOPPED.stStopped, &ss.timeLastStop, sizeof(SYSTEMTIME));
1099 memcpy (&ai.aiSTOPPED.stLastError, &ss.timeLastFail, sizeof(SYSTEMTIME));
1100 ai.aiSTOPPED.errLastError = ss.dwErrLast;
1101 Alert_AddPrimary (lpService->GetIdentifier(), &ai);
1102 fChangedServiceAlerts = TRUE;
1103 fChangedServerAlerts = TRUE;
1111 if (fChangedServiceAlerts)
1113 PostNotification (evtAlertsChanged, lpiService);
1117 if (rc && (dwTickNextTestWhenStarted == lpoa->dwTickNextTest))
1119 Alert_Scout_SetUpToDate (lpoa);
1122 if (fChangedServerAlerts)
1124 PostNotification (evtAlertsChanged, lpServer->GetIdentifier());
1127 PostNotification (evtScoutEnd, lpServer->GetIdentifier());