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 <afs/param.h>
24 * DEFINITIONS ________________________________________________________________
30 * VARIABLES __________________________________________________________________
36 * PROTOTYPES _________________________________________________________________
40 BOOL Alert_Scout_CheckServer (LPSERVER lpServer);
42 void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer);
43 void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer);
45 void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert);
46 LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull);
47 LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
48 LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer);
50 DWORD WINAPI Alert_ScoutProc (LPVOID lp);
51 void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa);
55 * ROUTINES ___________________________________________________________________
59 LPOBJECTALERTS Alert_GetObjectAlerts (LPIDENT lpi, BOOL fAlwaysServer, ULONG *pStatus)
61 LPOBJECTALERTS lpoa = NULL;
63 if (fAlwaysServer || lpi->fIsServer())
66 if ((lpsp = (LPSERVER_PREF)lpi->GetServer()->GetUserParam()) != NULL)
71 else if (lpi->fIsService())
74 if ((lpsp = (LPSERVICE_PREF)lpi->GetUserParam()) != NULL)
79 else if (lpi->fIsAggregate())
81 LPAGGREGATE_PREF lpap;
82 if ((lpap = (LPAGGREGATE_PREF)lpi->GetUserParam()) != NULL)
87 else if (lpi->fIsFileset())
90 if ((lpfp = (LPFILESET_PREF)lpi->GetUserParam()) != NULL)
100 void Alert_BeginUpdate (LPIDENT lpi, LPSERVER *ppServer)
102 if (lpi->fIsServer())
108 *ppServer = lpi->OpenServer();
113 void Alert_EndUpdate (LPIDENT lpi, LPSERVER lpServer)
115 // If we just updated some aggregate, fileset or service, then the
116 // associated server's secondary alerts are probably out-of-date.
119 if (lpServer != NULL)
121 LPOBJECTALERTS lpoaServer = Alert_GetObjectAlerts (lpServer->GetIdentifier());
122 LPOBJECTALERTS lpoaChild = Alert_GetObjectAlerts (lpi);
126 for (size_t iAlert = 0; iAlert < lpoaServer->nAlerts; )
128 if ( (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY) &&
129 (lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpi) )
131 Alert_RemoveFunc (lpoaServer, iAlert);
140 if (lpoaServer && lpoaChild)
142 BOOL fNeedBadCredsWarning = FALSE;
143 BOOL fHaveBadCredsWarning = FALSE;
146 for (iAlert = 0; iAlert < lpoaServer->nAlerts; ++iAlert)
148 if (lpoaServer->aAlerts[ iAlert ].alert == alertSECONDARY)
150 ALERT alert = Alert_GetAlert (lpoaServer->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
151 lpoaServer->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
152 if (alert == alertNO_SVRENT)
153 fNeedBadCredsWarning = TRUE;
156 for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
158 if (lpoaChild->aAlerts[ iAlert ].alert == alertNO_SVRENT)
159 fNeedBadCredsWarning = TRUE;
161 if (lpoaServer->nAlerts &&
162 lpoaServer->aAlerts[ 0 ].alert == alertBADCREDS)
164 fHaveBadCredsWarning = TRUE;
167 if (fNeedBadCredsWarning)
169 fNeedBadCredsWarning = !CheckCredentials (FALSE);
172 if (fHaveBadCredsWarning && !fNeedBadCredsWarning)
174 Alert_RemoveFunc (lpoaServer, 0);
176 else if (fNeedBadCredsWarning && !fHaveBadCredsWarning)
178 for (iAlert = min( lpoaServer->nAlerts, nAlertsMAX-1 );
182 memcpy (&lpoaServer->aAlerts[ iAlert ], &lpoaServer->aAlerts[ iAlert-1 ], sizeof(ALERTINFO));
184 lpoaServer->aAlerts[0].alert = alertBADCREDS;
185 lpoaServer->nAlerts = min( nAlertsMAX, lpoaServer->nAlerts+1 );
188 for (iAlert = 0; iAlert < lpoaChild->nAlerts; ++iAlert)
190 if (lpoaServer->nAlerts < nAlertsMAX)
192 lpoaServer->aAlerts[ lpoaServer->nAlerts ].alert = alertSECONDARY;
193 lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.lpiSecondary = lpi;
194 lpoaServer->aAlerts[ lpoaServer->nAlerts ].aiSECONDARY.iSecondary = iAlert;
195 lpoaServer->nAlerts ++;
205 void Alert_SetDefaults (LPOBJECTALERTS lpoa)
209 memset (lpoa, 0x00, sizeof(OBJECTALERTS));
210 lpoa->cTickRefresh = DEFAULT_SCOUT_REFRESH_RATE;
215 void Alert_Initialize (LPOBJECTALERTS lpoa)
219 lpoa->dwTickNextTest = 0;
220 lpoa->dwTickNextRefresh = 0;
226 void Alert_RemoveSecondary (LPIDENT lpiChild)
228 BOOL fChangedAlerts = FALSE;
231 if ((lpoa = Alert_GetObjectAlerts (lpiChild, TRUE)) != NULL)
234 for (iAlert = 0; iAlert < lpoa->nAlerts; )
236 if ( (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY) &&
237 (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary == lpiChild) )
239 Alert_RemoveFunc (lpoa, iAlert);
240 fChangedAlerts = TRUE;
249 BOOL fNeedBadCredsWarning = FALSE;
251 for (iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
253 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
255 ALERT alert = Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
256 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
257 if (alert == alertNO_SVRENT)
258 fNeedBadCredsWarning = TRUE;
262 if ( (!fNeedBadCredsWarning) &&
263 (lpoa->nAlerts && (lpoa->aAlerts[ 0 ].alert == alertBADCREDS)) )
265 Alert_RemoveFunc (lpoa, 0);
266 fChangedAlerts = TRUE;
272 PostNotification (evtAlertsChanged, lpiChild->GetServer());
273 PostNotification (evtAlertsChanged, lpiChild);
278 void Alert_Remove (LPIDENT lpi, size_t iAlert)
282 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
284 if (iAlert < lpoa->nAlerts)
287 Alert_BeginUpdate (lpi, &lpServer);
289 Alert_RemoveFunc (lpoa, iAlert);
291 Alert_EndUpdate (lpi, lpServer);
297 void Alert_RemoveFunc (LPOBJECTALERTS lpoa, size_t iAlert)
299 if (iAlert < lpoa->nAlerts-1)
301 memcpy (&lpoa->aAlerts[ iAlert ], &lpoa->aAlerts[ lpoa->nAlerts-1 ], sizeof(ALERTINFO));
307 void Alert_AddPrimary (LPIDENT lpi, LPALERTINFO lpai)
311 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
313 if (lpoa->nAlerts < nAlertsMAX)
316 Alert_BeginUpdate (lpi, &lpServer);
318 memcpy (&lpoa->aAlerts[ lpoa->nAlerts ], lpai, sizeof(ALERTINFO));
321 Alert_EndUpdate (lpi, lpServer);
327 void Alert_Scout_ServerStatus (LPIDENT lpi, ULONG status)
330 if ((lpoa = Alert_GetObjectAlerts (lpi)) != NULL)
332 BOOL fChanged = FALSE;
334 for (size_t iAlert = 0; iAlert < lpoa->nAlerts; ++iAlert)
336 if (lpoa->aAlerts[ iAlert ].alert == alertTIMEOUT)
339 Alert_RemoveFunc (lpoa, iAlert);
347 if (lpoa->nAlerts && (lpoa->aAlerts[0].alert == alertBADCREDS))
351 for (iHole = iInsert; iHole < lpoa->nAlerts; ++iHole)
353 if (lpoa->aAlerts[ iHole ].alert == alertINVALID)
356 if (iHole < nAlertsMAX)
358 for (size_t iTarget = iHole; iTarget > iInsert; --iTarget)
360 memcpy (&lpoa->aAlerts[ iTarget ], &lpoa->aAlerts[ iTarget-1 ], sizeof(ALERTINFO));
364 lpoa->aAlerts[ iInsert ].alert = alertTIMEOUT;
365 lpoa->aAlerts[ iInsert ].aiTIMEOUT.status = status;
366 GetSystemTime (&lpoa->aAlerts[ iInsert ].aiTIMEOUT.stLastAttempt);
374 PostNotification (evtAlertsChanged, lpi);
380 size_t Alert_GetCount (LPIDENT lpi)
384 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
387 return lpoa->nAlerts;
391 ALERT Alert_GetAlert (LPIDENT lpi, size_t iAlert)
395 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
398 if (iAlert > lpoa->nAlerts)
401 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
403 return Alert_GetAlert (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
404 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary);
407 return lpoa->aAlerts[ iAlert ].alert;
411 LPIDENT Alert_GetIdent (LPIDENT lpi, size_t iAlert)
415 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
418 if (iAlert > lpoa->nAlerts)
421 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
423 return lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary;
430 LPTSTR Alert_GetQuickDescription (LPIDENT lpi)
432 LPTSTR pszStatus = NULL;
435 if ((cAlerts = Alert_GetCount (lpi)) <= 1)
436 pszStatus = Alert_GetDescription (lpi, 0, FALSE);
437 else if (lpi->fIsServer())
438 pszStatus = FormatString (IDS_SERVER_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
439 else if (lpi->fIsService())
440 pszStatus = FormatString (IDS_SERVICE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
441 else if (lpi->fIsAggregate())
442 pszStatus = FormatString (IDS_AGGREGATE_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
443 else if (lpi->fIsFileset())
444 pszStatus = FormatString (IDS_FILESET_MULTIPLE_PROBLEMS, TEXT("%lu"), cAlerts);
450 LPTSTR Alert_GetDescription (LPIDENT lpi, size_t iAlert, BOOL fFull)
454 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
457 if (!lpoa->nAlerts && lpi->fIsServer())
460 if ((lpsp = (LPSERVER_PREF)lpi->GetUserParam()) != NULL)
462 if (!lpsp->fIsMonitored)
464 TCHAR szName[ cchNAME ];
465 lpi->GetServerName (szName);
466 return FormatString (IDS_ALERT_DESCSHORT_UNMONITORED, TEXT("%s"), szName);
471 if (iAlert >= lpoa->nAlerts)
474 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
476 return Alert_GetDescriptionFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
477 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
482 return Alert_GetDescriptionFunc (lpi, iAlert, NULL, fFull);
486 LPTSTR Alert_GetRemedy (LPIDENT lpi, size_t iAlert)
490 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
493 if (iAlert >= lpoa->nAlerts)
496 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
498 return Alert_GetRemedyFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
499 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
503 return Alert_GetRemedyFunc (lpi, iAlert, NULL);
507 LPTSTR Alert_GetButton (LPIDENT lpi, size_t iAlert)
511 if ((lpoa = Alert_GetObjectAlerts (lpi)) == NULL)
514 if (iAlert >= lpoa->nAlerts)
517 if (lpoa->aAlerts[ iAlert ].alert == alertSECONDARY)
519 return Alert_GetButtonFunc (lpoa->aAlerts[ iAlert ].aiSECONDARY.lpiSecondary,
520 lpoa->aAlerts[ iAlert ].aiSECONDARY.iSecondary,
524 return Alert_GetButtonFunc (lpi, iAlert, NULL);
528 LPTSTR Alert_GetDescriptionFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer, BOOL fFull)
531 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
534 TCHAR szServer[ cchRESOURCE ];
535 TCHAR szService[ cchRESOURCE ];
536 TCHAR szAggregate[ cchRESOURCE ];
537 TCHAR szFileset[ cchRESOURCE ];
539 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
542 ids = (fFull) ? IDS_ALERT_DESCFULL_TIMEOUT : IDS_ALERT_DESCSHORT_TIMEOUT;
543 lpiPrimary->GetServerName (szServer);
544 return FormatString (ids, TEXT("%s%t%e"), szServer, &lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.stLastAttempt, lpoa->aAlerts[ iAlertPrimary ].aiTIMEOUT.status);
547 lpiPrimary->GetServerName (szServer);
548 lpiPrimary->GetAggregateName (szAggregate);
549 if (lpiPrimary->fIsAggregate())
551 ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_FULL : IDS_ALERT_DESCSHORT_AGG_FULL;
552 return FormatString (ids, TEXT("%s%s%d%.1B"), szServer, szAggregate, lpoa->aAlerts[ iAlertPrimary ].aiFULL.perWarning, 1024.0 * (double)lpoa->aAlerts[ iAlertPrimary ].aiFULL.ckWarning);
554 else if (lpiPrimary->fIsFileset())
556 ids = (fFull) ? IDS_ALERT_DESCFULL_SET_FULL : IDS_ALERT_DESCSHORT_SET_FULL;
557 lpiPrimary->GetFilesetName (szFileset);
558 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);
562 case alertNO_VLDBENT:
563 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_VLDBENT : IDS_ALERT_DESCSHORT_NO_VLDBENT;
564 lpiPrimary->GetServerName (szServer);
565 lpiPrimary->GetAggregateName (szAggregate);
566 lpiPrimary->GetFilesetName (szFileset);
567 return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
570 if (lpiPrimary->fIsFileset())
572 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_SET : IDS_ALERT_DESCSHORT_NO_SVRENT_SET;
573 lpiPrimary->GetServerName (szServer);
574 lpiPrimary->GetAggregateName (szAggregate);
575 lpiPrimary->GetFilesetName (szFileset);
576 return FormatString (ids, TEXT("%s%s%s"), szServer, szAggregate, szFileset);
580 ids = (fFull) ? IDS_ALERT_DESCFULL_NO_SVRENT_AGG : IDS_ALERT_DESCSHORT_NO_SVRENT_AGG;
581 lpiPrimary->GetServerName (szServer);
582 lpiPrimary->GetAggregateName (szAggregate);
583 return FormatString (ids, TEXT("%s%s"), szServer, szAggregate);
588 ids = (fFull) ? IDS_ALERT_DESCFULL_STOPPED : IDS_ALERT_DESCSHORT_STOPPED;
589 lpiPrimary->GetServerName (szServer);
590 lpiPrimary->GetServiceName (szService);
591 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);
594 ids = (fFull) ? IDS_ALERT_DESCFULL_BADCREDS : IDS_ALERT_DESCSHORT_BADCREDS;
595 lpiPrimary->GetServerName (szServer);
596 return FormatString (ids, TEXT("%s"), szServer);
599 lpiPrimary->GetServerName (szServer);
600 lpiPrimary->GetAggregateName (szAggregate);
601 ids = (fFull) ? IDS_ALERT_DESCFULL_AGG_ALLOC : IDS_ALERT_DESCSHORT_AGG_ALLOC;
602 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));
604 case alertSTATE_NO_VNODE:
605 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_VNODE : IDS_ALERT_DESCSHORT_STATE_NO_VNODE;
606 lpiPrimary->GetServerName (szServer);
607 lpiPrimary->GetAggregateName (szAggregate);
608 lpiPrimary->GetFilesetName (szFileset);
609 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
611 case alertSTATE_NO_SERVICE:
612 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_NO_SERVICE : IDS_ALERT_DESCSHORT_STATE_NO_SERVICE;
613 lpiPrimary->GetServerName (szServer);
614 lpiPrimary->GetAggregateName (szAggregate);
615 lpiPrimary->GetFilesetName (szFileset);
616 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
618 case alertSTATE_OFFLINE:
619 ids = (fFull) ? IDS_ALERT_DESCFULL_STATE_OFFLINE : IDS_ALERT_DESCSHORT_STATE_OFFLINE;
620 lpiPrimary->GetServerName (szServer);
621 lpiPrimary->GetAggregateName (szAggregate);
622 lpiPrimary->GetFilesetName (szFileset);
623 return FormatString (ids, TEXT("%s%s%s%08lX"), szServer, szAggregate, szFileset, lpoa->aAlerts[ iAlertPrimary ].aiSTATE.State);
631 LPTSTR Alert_GetRemedyFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
634 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
636 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
639 return FormatString (IDS_ALERT_FIX_TIMEOUT);
641 if (lpiPrimary->fIsAggregate())
642 return FormatString (IDS_ALERT_FIX_AGG_FULL);
643 else if (lpiPrimary->fIsFileset())
644 return FormatString (IDS_ALERT_FIX_SET_FULL);
646 case alertNO_VLDBENT:
647 return FormatString (IDS_ALERT_FIX_NO_VLDBENT);
649 if (lpiPrimary->fIsFileset())
650 return FormatString (IDS_ALERT_FIX_NO_SVRENT_SET);
652 return FormatString (IDS_ALERT_FIX_NO_SVRENT_AGG);
655 return FormatString (IDS_ALERT_FIX_STOPPED);
657 return FormatString (IDS_ALERT_FIX_BADCREDS);
659 return FormatString (IDS_ALERT_FIX_AGG_ALLOC);
660 case alertSTATE_NO_VNODE:
661 return FormatString (IDS_ALERT_FIX_STATE_NO_VNODE);
662 case alertSTATE_NO_SERVICE:
663 return FormatString (IDS_ALERT_FIX_STATE_NO_SERVICE);
664 case alertSTATE_OFFLINE:
665 return FormatString (IDS_ALERT_FIX_STATE_OFFLINE);
673 LPTSTR Alert_GetButtonFunc (LPIDENT lpiPrimary, size_t iAlertPrimary, LPIDENT lpiServer)
676 if ((lpoa = Alert_GetObjectAlerts (lpiPrimary)) != NULL)
678 switch (lpoa->aAlerts[ iAlertPrimary ].alert)
681 return FormatString (IDS_ALERT_BUTTON_TRYAGAIN);
683 return FormatString (IDS_ALERT_BUTTON_WARNINGS);
684 case alertNO_VLDBENT:
689 return FormatString (IDS_ALERT_BUTTON_VIEWLOG);
691 return FormatString (IDS_ALERT_BUTTON_GETCREDS);
694 case alertSTATE_NO_VNODE:
696 case alertSTATE_NO_SERVICE:
698 case alertSTATE_OFFLINE:
708 * SCOUT ______________________________________________________________________
710 * (okay, well, our simulated Scout anyway)
714 static HANDLE hScout = 0; // scout's thread
715 static HANDLE heScoutWakeup = 0; // scout's wakeup event
717 BOOL Alert_StartScout (ULONG *pStatus)
719 if (hScout == 0) // create scout?
721 heScoutWakeup = CreateEvent (NULL, FALSE, FALSE, TEXT("AfsSvrMgr Alert Scout Wakeup"));
724 if ((hScout = CreateThread (NULL, 0,
725 (LPTHREAD_START_ROUTINE)Alert_ScoutProc,
727 &dwThreadID)) == NULL)
730 *pStatus = GetLastError();
734 SetThreadPriority (hScout, THREAD_PRIORITY_BELOW_NORMAL);
736 else // or just wake up scout from its slumber?
738 PulseEvent (heScoutWakeup);
745 BOOL Alert_Scout_QueueCheckServer (LPIDENT lpiServer, ULONG *pStatus)
747 Alert_Scout_SetOutOfDate (lpiServer);
748 return Alert_StartScout (pStatus);
752 DWORD WINAPI Alert_ScoutProc (LPVOID lp)
754 // We'll keep working forever...
760 LPCELL lpCell = (g.lpiCell == NULL) ? NULL : g.lpiCell->OpenCell();
763 // See if our credentials have expired
765 CheckForExpiredCredentials();
767 // See if any new servers have arrived, or old servers disappeared.
769 lpCell->RefreshServerList();
771 // Check all the out-of-date servers we can find.
774 for (LPSERVER lpServer = lpCell->ServerFindFirst (&hEnum); lpServer; lpServer = lpCell->ServerFindNext (&hEnum))
776 LPIDENT lpiServer = lpServer->GetIdentifier();
779 if ( ((lpoa = Alert_GetObjectAlerts (lpiServer)) != NULL) &&
780 (lpoa->dwTickNextTest <= GetTickCount()) )
783 // Okay! We've found a server that needs to be tested for
784 // alert conditions. Do that now, and when we're done, set
785 // its next query-time to some distance in the future.
787 if (lpoa->dwTickNextRefresh == 0)
789 if (lpoa->cTickRefresh != 0)
790 lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
792 else if (lpoa->dwTickNextRefresh <= GetTickCount())
794 (void)lpServer->Invalidate();
795 (void)lpServer->RefreshAll();
796 lpoa->dwTickNextRefresh = lpoa->cTickRefresh + GetTickCount();
799 (void)Alert_Scout_CheckServer (lpServer);
810 // Now that we have completed a pass over the servers in this cell,
811 // and now that we're not holding any critical sections on which
812 // other threads would otherwise block, go to sleep for a while.
814 WaitForSingleObjectEx (heScoutWakeup, 45L * cmsec1SECOND, FALSE);
821 void Alert_Scout_SetOutOfDate (LPIDENT lpi)
824 if ((lpoa = Alert_GetObjectAlerts (lpi, TRUE)) != NULL)
826 lpoa->dwTickNextTest = GetTickCount() -1;
831 void Alert_Scout_SetUpToDate (LPOBJECTALERTS lpoa)
835 lpoa->dwTickNextTest = GetTickCount() + lpoa->cTickRefresh;
840 BOOL Alert_Scout_CheckServer (LPSERVER lpServer)
845 if ((lpsp = (LPSERVER_PREF)lpServer->GetUserParam()) != NULL)
848 if ((lpoa = Alert_GetObjectAlerts (lpServer->GetIdentifier())) != NULL)
850 PostNotification (evtScoutBegin, lpServer->GetIdentifier());
852 BOOL fChangedServerAlerts = FALSE;
854 DWORD dwTickNextTestWhenStarted = lpoa->dwTickNextTest;
856 // First look through the server's aggregates and filesets, to
857 // find any which have usages over their warning threshholds.
860 for (LPAGGREGATE lpAggregate = lpServer->AggregateFindFirst (&heAggregate); lpAggregate; lpAggregate = lpServer->AggregateFindNext (&heAggregate))
862 BOOL fChangedAggregateAlerts = FALSE;
863 LPIDENT lpiAggregate = lpAggregate->GetIdentifier();
865 LPOBJECTALERTS lpoaAggregate;
866 if ((lpoaAggregate = Alert_GetObjectAlerts (lpAggregate->GetIdentifier())) != NULL)
868 for (size_t iAlert = 0; iAlert < lpoaAggregate->nAlerts; )
870 if ( (lpoaAggregate->aAlerts[ iAlert ].alert == alertFULL) ||
871 (lpoaAggregate->aAlerts[ iAlert ].alert == alertOVERALLOC) ||
872 (lpoaAggregate->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
874 fChangedAggregateAlerts = TRUE;
875 fChangedServerAlerts = TRUE;
876 Alert_Remove (lpAggregate->GetIdentifier(), iAlert);
882 LPAGGREGATE_PREF lpap;
883 if ((lpap = (LPAGGREGATE_PREF)lpAggregate->GetUserParam()) != NULL)
885 short wGhost = lpAggregate->GetGhostStatus();
886 if (lpsp->fWarnAggNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY))
889 ai.alert = alertNO_SVRENT;
890 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
891 fChangedAggregateAlerts = TRUE;
892 fChangedServerAlerts = TRUE;
895 if (lpsp->fWarnAggAlloc && lpap->fWarnAggAlloc)
898 if (lpAggregate->GetStatus (&as, TRUE))
900 if (as.ckStorageAllocated > as.ckStorageTotal)
903 ai.alert = alertOVERALLOC;
904 ai.aiOVERALLOC.ckAllocated = as.ckStorageAllocated;
905 ai.aiOVERALLOC.ckCapacity = as.ckStorageTotal;
906 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
907 fChangedAggregateAlerts = TRUE;
908 fChangedServerAlerts = TRUE;
913 short perWarnAggFull = lpap->perWarnAggFull;
914 if (perWarnAggFull == -1)
915 perWarnAggFull = lpsp->perWarnAggFull;
916 if (perWarnAggFull != 0)
919 if (lpAggregate->GetStatus (&as, TRUE))
921 if (as.ckStorageTotal != 0)
923 short perNow = (short)( (double)(as.ckStorageTotal - as.ckStorageFree) * 100.0 / (double)(as.ckStorageTotal) );
925 if (perNow > perWarnAggFull)
928 ai.alert = alertFULL;
929 ai.aiFULL.perWarning = perWarnAggFull;
930 ai.aiFULL.ckWarning = (ULONG)( (double)perWarnAggFull * (double)(as.ckStorageTotal) / 100.0 );
931 Alert_AddPrimary (lpAggregate->GetIdentifier(), &ai);
932 fChangedAggregateAlerts = TRUE;
933 fChangedServerAlerts = TRUE;
942 for (LPFILESET lpFileset = lpAggregate->FilesetFindFirst (&heFileset); lpFileset; lpFileset = lpAggregate->FilesetFindNext (&heFileset))
944 BOOL fChangedFilesetAlerts = FALSE;
945 LPIDENT lpiFileset = lpFileset->GetIdentifier();
947 LPOBJECTALERTS lpoaFileset;
948 if ((lpoaFileset = Alert_GetObjectAlerts (lpFileset->GetIdentifier())) != NULL)
950 for (size_t iAlert = 0; iAlert < lpoaFileset->nAlerts; )
952 if ( (lpoaFileset->aAlerts[ iAlert ].alert == alertFULL) ||
953 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_VNODE) ||
954 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_NO_SERVICE) ||
955 (lpoaFileset->aAlerts[ iAlert ].alert == alertSTATE_OFFLINE) ||
956 (lpoaFileset->aAlerts[ iAlert ].alert == alertNO_VLDBENT) ||
957 (lpoaFileset->aAlerts[ iAlert ].alert == alertNO_SVRENT) )
959 fChangedFilesetAlerts = TRUE;
960 fChangedServerAlerts = TRUE;
961 Alert_Remove (lpFileset->GetIdentifier(), iAlert);
969 if ((lpfp = (LPFILESET_PREF)lpFileset->GetUserParam()) != NULL)
972 if (lpFileset->GetStatus (&fs, TRUE))
974 if (fs.State & fsNO_VNODE)
977 ai.alert = alertSTATE_NO_VNODE;
978 ai.aiSTATE.State = fs.State;
979 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
980 fChangedFilesetAlerts = TRUE;
981 fChangedServerAlerts = TRUE;
983 else if (fs.State & fsNO_SERVICE)
986 ai.alert = alertSTATE_NO_SERVICE;
987 ai.aiSTATE.State = fs.State;
988 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
989 fChangedFilesetAlerts = TRUE;
990 fChangedServerAlerts = TRUE;
992 else if (fs.State & fsOFFLINE)
995 ai.alert = alertSTATE_OFFLINE;
996 ai.aiSTATE.State = fs.State;
997 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
998 fChangedFilesetAlerts = TRUE;
999 fChangedServerAlerts = TRUE;
1002 short perWarnSetFull = lpfp->perWarnSetFull;
1003 if (perWarnSetFull == -1)
1004 perWarnSetFull = lpsp->perWarnSetFull;
1005 if (perWarnSetFull != 0)
1007 if (fs.Type == ftREADWRITE)
1009 if (fs.ckQuota != 0)
1011 short perNow = (short)( (double)(fs.ckUsed) * 100.0 / (double)(fs.ckQuota) );
1013 if (perNow > perWarnSetFull)
1016 ai.alert = alertFULL;
1017 ai.aiFULL.perWarning = perWarnSetFull;
1018 ai.aiFULL.ckWarning = (ULONG)( (double)perWarnSetFull * (double)(fs.ckQuota) / 100.0 );
1019 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1020 fChangedFilesetAlerts = TRUE;
1021 fChangedServerAlerts = TRUE;
1028 short wGhost = lpFileset->GetGhostStatus();
1029 if (lpsp->fWarnSetNoVLDB && !(wGhost & GHOST_HAS_VLDB_ENTRY))
1032 ai.alert = alertNO_VLDBENT;
1033 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1034 fChangedFilesetAlerts = TRUE;
1035 fChangedServerAlerts = TRUE;
1037 if (lpsp->fWarnSetNoServ && !(wGhost & GHOST_HAS_SERVER_ENTRY) && !(fs.Type == ftREPLICA))
1040 ai.alert = alertNO_SVRENT;
1041 Alert_AddPrimary (lpFileset->GetIdentifier(), &ai);
1042 fChangedFilesetAlerts = TRUE;
1043 fChangedServerAlerts = TRUE;
1048 if (fChangedFilesetAlerts)
1050 PostNotification (evtAlertsChanged, lpiFileset);
1054 lpAggregate->Close();
1055 if (fChangedAggregateAlerts)
1057 PostNotification (evtAlertsChanged, lpiAggregate);
1061 // Next look through the server's servces to find any
1062 // which have stopped.
1065 for (LPSERVICE lpService = lpServer->ServiceFindFirst (&heService); lpService; lpService = lpServer->ServiceFindNext (&heService))
1067 BOOL fChangedServiceAlerts = FALSE;
1068 LPIDENT lpiService = lpService->GetIdentifier();
1070 LPOBJECTALERTS lpoaService;
1071 if ((lpoaService = Alert_GetObjectAlerts (lpService->GetIdentifier())) != NULL)
1073 for (size_t iAlert = 0; iAlert < lpoaService->nAlerts; )
1075 if (lpoaService->aAlerts[ iAlert ].alert == alertSTOPPED)
1077 fChangedServiceAlerts = TRUE;
1078 fChangedServerAlerts = TRUE;
1079 Alert_Remove (lpService->GetIdentifier(), iAlert);
1085 LPSERVICE_PREF lpcp;
1086 if ((lpcp = (LPSERVICE_PREF)lpService->GetUserParam()) != NULL)
1088 if (lpcp->fWarnSvcStop && lpsp->fWarnSvcStop)
1091 if (lpService->GetStatus (&ss, TRUE))
1093 if (ss.state != SERVICESTATE_RUNNING)
1096 ai.alert = alertSTOPPED;
1097 memcpy (&ai.aiSTOPPED.stStopped, &ss.timeLastStop, sizeof(SYSTEMTIME));
1098 memcpy (&ai.aiSTOPPED.stLastError, &ss.timeLastFail, sizeof(SYSTEMTIME));
1099 ai.aiSTOPPED.errLastError = ss.dwErrLast;
1100 Alert_AddPrimary (lpService->GetIdentifier(), &ai);
1101 fChangedServiceAlerts = TRUE;
1102 fChangedServerAlerts = TRUE;
1110 if (fChangedServiceAlerts)
1112 PostNotification (evtAlertsChanged, lpiService);
1116 if (rc && (dwTickNextTestWhenStarted == lpoa->dwTickNextTest))
1118 Alert_Scout_SetUpToDate (lpoa);
1121 if (fChangedServerAlerts)
1123 PostNotification (evtAlertsChanged, lpServer->GetIdentifier());
1126 PostNotification (evtScoutEnd, lpServer->GetIdentifier());