alarm.c

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         ALARM.C
00004   Created by:   Stefan Ritt
00005 
00006   Contents:     MIDAS alarm functions
00007 
00008   $Id: alarm.c 4738 2010-06-08 11:35:08Z ritt $
00009 
00010 \********************************************************************/
00011 
00012 #include "midas.h"
00013 #include "msystem.h"
00014 #include "strlcpy.h"
00015 #include <assert.h>
00016 
00017 /**dox***************************************************************/
00018 /** @file alarm.c
00019 The Midas Alarm file
00020 */
00021 
00022 /** @defgroup alfunctioncode Midas Alarm Functions (al_xxx)
00023  */
00024 
00025 /**dox***************************************************************/
00026 /** @addtogroup alfunctioncode
00027  *
00028  *  @{  */
00029 
00030 /**dox***************************************************************/
00031 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00032 
00033 /********************************************************************\
00034 *                                                                    *
00035 *                     Alarm functions                                *
00036 *                                                                    *
00037 \********************************************************************/
00038 
00039 /********************************************************************/
00040 BOOL al_evaluate_condition(const char *condition, char *value)
00041 {
00042    HNDLE hDB, hkey;
00043    int i, j, idx1, idx2, idx, size;
00044    KEY key;
00045    double value1, value2;
00046    char value1_str[256], value2_str[256], str[256], op[3], function[80];
00047    char data[10000];
00048    DWORD dtime;
00049 
00050    strcpy(str, condition);
00051    op[1] = op[2] = 0;
00052    value1 = value2 = 0;
00053    idx1 = idx2 = 0;
00054 
00055    /* find value and operator */
00056    for (i = strlen(str) - 1; i > 0; i--)
00057       if (strchr("<>=!&", str[i]) != NULL)
00058          break;
00059    op[0] = str[i];
00060    for (j = 1; str[i + j] == ' '; j++);
00061    strlcpy(value2_str, str + i + j, sizeof(value2_str));
00062    value2 = atof(value2_str);
00063    str[i] = 0;
00064 
00065    if (i > 0 && strchr("<>=!&", str[i - 1])) {
00066       op[1] = op[0];
00067       op[0] = str[--i];
00068       str[i] = 0;
00069    }
00070 
00071    i--;
00072    while (i > 0 && str[i] == ' ')
00073       i--;
00074    str[i + 1] = 0;
00075 
00076    /* check if function */
00077    function[0] = 0;
00078    if (str[i] == ')') {
00079       str[i--] = 0;
00080       if (strchr(str, '(')) {
00081          *strchr(str, '(') = 0;
00082          strcpy(function, str);
00083          for (i = strlen(str) + 1, j = 0; str[i]; i++, j++)
00084             str[j] = str[i];
00085          str[j] = 0;
00086          i = j - 1;
00087       }
00088    }
00089 
00090    /* find key */
00091    if (str[i] == ']') {
00092       str[i--] = 0;
00093       if (str[i] == '*') {
00094          idx1 = -1;
00095          while (i > 0 && str[i] != '[')
00096             i--;
00097          str[i] = 0;
00098       } else if (strchr(str, '[') &&
00099                  strchr(strchr(str, '['), '-')) {
00100          while (i > 0 && isdigit(str[i]))
00101             i--;
00102          idx2 = atoi(str + i + 1);
00103          while (i > 0 && str[i] != '[')
00104             i--;
00105          idx1 = atoi(str + i + 1);
00106          str[i] = 0;
00107       } else {
00108          while (i > 0 && isdigit(str[i]))
00109             i--;
00110          idx1 = idx2 = atoi(str + i + 1);
00111          str[i] = 0;
00112       }
00113    }
00114 
00115    cm_get_experiment_database(&hDB, NULL);
00116    db_find_key(hDB, 0, str, &hkey);
00117    if (!hkey) {
00118       cm_msg(MERROR, "al_evaluate_condition", "Cannot find key %s to evaluate alarm condition", str);
00119       if (value)
00120          strcpy(value, "unknown");
00121       return FALSE;
00122    }
00123    db_get_key(hDB, hkey, &key);
00124 
00125    if (idx1 < 0) {
00126       idx1 = 0;
00127       idx2 = key.num_values-1;
00128    }
00129 
00130    for (idx=idx1; idx<=idx2 ; idx++) {
00131       
00132       if (equal_ustring(function, "access")) {
00133          /* check key access time */
00134          db_get_key_time(hDB, hkey, &dtime);
00135          sprintf(value1_str, "%d", dtime);
00136          value1 = atof(value1_str);
00137       } else {
00138          /* get key data and convert to double */
00139          db_get_key(hDB, hkey, &key);
00140          size = sizeof(data);
00141          db_get_data_index(hDB, hkey, data, &size, idx, key.type);
00142          db_sprintf(value1_str, data, size, 0, key.type);
00143          value1 = atof(value1_str);
00144       }
00145 
00146       /* convert boolean values to integers */
00147       if (key.type == TID_BOOL) {
00148          value1 = (value1_str[0] == 'Y' || value1_str[0] == 'y' || value1_str[0] == '1');
00149          value2 = (value2_str[0] == 'Y' || value2_str[0] == 'y' || value2_str[0] == '1');
00150       }
00151 
00152       /* return value */
00153       if (value)
00154          strcpy(value, value1_str);
00155 
00156       /* now do logical operation */
00157       if (strcmp(op, "=") == 0)
00158          if (value1 == value2) return TRUE;
00159       if (strcmp(op, "==") == 0)
00160          if (value1 == value2) return TRUE;
00161       if (strcmp(op, "!=") == 0)
00162          if (value1 != value2) return TRUE;
00163       if (strcmp(op, "<") == 0)
00164          if (value1 < value2) return TRUE;
00165       if (strcmp(op, ">") == 0)
00166          if (value1 > value2) return TRUE;
00167       if (strcmp(op, "<=") == 0)
00168          if (value1 <= value2) return TRUE;
00169       if (strcmp(op, ">=") == 0)
00170          if (value1 >= value2) return TRUE;
00171       if (strcmp(op, "&") == 0)
00172          if (((unsigned int)value1 & (unsigned int)value2) > 0) return TRUE;
00173    }
00174 
00175    return FALSE;
00176 }
00177 
00178 /**dox***************************************************************/
00179 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00180 
00181 /********************************************************************/
00182 /**
00183 Trigger a certain alarm.
00184 \code  ...
00185   lazy.alarm[0] = 0;
00186   size = sizeof(lazy.alarm);
00187   db_get_value(hDB, pLch->hKey, "Settings/Alarm Class", lazy.alarm, &size, TID_STRING, TRUE);
00188 
00189   // trigger alarm if defined
00190   if (lazy.alarm[0])
00191     al_trigger_alarm("Tape", "Tape full...load new one!", lazy.alarm, "Tape full", AT_INTERNAL);
00192   ...
00193 \endcode
00194 @param alarm_name Alarm name, defined in /alarms/alarms
00195 @param alarm_message Optional message which goes with alarm
00196 @param default_class If alarm is not yet defined under
00197                     /alarms/alarms/<alarm_name>, a new one
00198                     is created and this default class is used.
00199 @param cond_str String displayed in alarm condition
00200 @param type Alarm type, one of AT_xxx
00201 @return AL_SUCCESS, AL_INVALID_NAME
00202 */
00203 INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
00204 {
00205    if (rpc_is_remote())
00206       return rpc_call(RPC_AL_TRIGGER_ALARM, alarm_name, alarm_message, default_class, cond_str, type);
00207 
00208 #ifdef LOCAL_ROUTINES
00209    {
00210       int status, size;
00211       HNDLE hDB, hkeyalarm;
00212       char str[256];
00213       ALARM a;
00214       BOOL flag;
00215       ALARM_ODB_STR(alarm_odb_str);
00216 
00217       cm_get_experiment_database(&hDB, NULL);
00218 
00219       /* check online mode */
00220       flag = TRUE;
00221       size = sizeof(flag);
00222       db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
00223       if (!flag)
00224          return AL_SUCCESS;
00225 
00226       /* find alarm */
00227       sprintf(str, "/Alarms/Alarms/%s", alarm_name);
00228       db_find_key(hDB, 0, str, &hkeyalarm);
00229       if (!hkeyalarm) {
00230          /* alarm must be an internal analyzer alarm, so create a default alarm */
00231          status = db_create_record(hDB, 0, str, strcomb(alarm_odb_str));
00232          db_find_key(hDB, 0, str, &hkeyalarm);
00233          if (!hkeyalarm) {
00234             cm_msg(MERROR, "al_trigger_alarm", "Cannot create alarm record");
00235             return AL_ERROR_ODB;
00236          }
00237 
00238          if (default_class && default_class[0])
00239             db_set_value(hDB, hkeyalarm, "Alarm Class", default_class, 32, 1, TID_STRING);
00240          status = TRUE;
00241          db_set_value(hDB, hkeyalarm, "Active", &status, sizeof(status), 1, TID_BOOL);
00242       }
00243 
00244       /* set parameters for internal alarms */
00245       if (type != AT_EVALUATED && type != AT_PERIODIC) {
00246          db_set_value(hDB, hkeyalarm, "Type", &type, sizeof(INT), 1, TID_INT);
00247          strcpy(str, cond_str);
00248          db_set_value(hDB, hkeyalarm, "Condition", str, 256, 1, TID_STRING);
00249       }
00250 
00251       size = sizeof(a);
00252       status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00253       if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00254          /* make sure alarm record has right structure */
00255          db_check_record(hDB, hkeyalarm, "", strcomb(alarm_odb_str), TRUE);
00256 
00257          size = sizeof(a);
00258          status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00259          if (status != DB_SUCCESS) {
00260             cm_msg(MERROR, "al_trigger_alarm", "Cannot get alarm record");
00261             return AL_ERROR_ODB;
00262          }
00263       }
00264 
00265       /* if internal alarm, check if active and check interval */
00266       if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
00267          /* check global alarm flag */
00268          flag = TRUE;
00269          size = sizeof(flag);
00270          db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
00271          if (!flag)
00272             return AL_SUCCESS;
00273 
00274          if (!a.active)
00275             return AL_SUCCESS;
00276 
00277          if ((INT) ss_time() - (INT) a.checked_last < a.check_interval)
00278             return AL_SUCCESS;
00279 
00280          /* now the alarm will be triggered, so save time */
00281          a.checked_last = ss_time();
00282       }
00283 
00284       /* write back alarm message for internal alarms */
00285       if (a.type != AT_EVALUATED && a.type != AT_PERIODIC) {
00286          strncpy(a.alarm_message, alarm_message, 79);
00287          a.alarm_message[79] = 0;
00288       }
00289 
00290       /* now trigger alarm class defined in this alarm */
00291       if (a.alarm_class[0])
00292          al_trigger_class(a.alarm_class, alarm_message, a.triggered > 0);
00293 
00294       /* signal alarm being triggered */
00295       cm_asctime(str, sizeof(str));
00296 
00297       if (!a.triggered)
00298          strcpy(a.time_triggered_first, str);
00299 
00300       a.triggered++;
00301       strcpy(a.time_triggered_last, str);
00302 
00303       a.checked_last = ss_time();
00304 
00305       status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
00306       if (status != DB_SUCCESS) {
00307          cm_msg(MERROR, "al_trigger_alarm", "Cannot update alarm record");
00308          return AL_ERROR_ODB;
00309       }
00310 
00311    }
00312 #endif                          /* LOCAL_ROUTINES */
00313 
00314    return AL_SUCCESS;
00315 }
00316 
00317 /**dox***************************************************************/
00318 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00319 
00320 /********************************************************************/
00321 INT al_trigger_class(const char *alarm_class, const char *alarm_message, BOOL first)
00322 /********************************************************************\
00323 
00324   Routine: al_trigger_class
00325 
00326   Purpose: Trigger a certain alarm class
00327 
00328   Input:
00329     char   *alarm_class     Alarm class, must be defined in
00330                             /alarms/classes
00331     char   *alarm_message   Optional message which goes with alarm
00332     BOOL   first            TRUE if alarm is triggered first time
00333                             (used for elog)
00334 
00335   Output:
00336 
00337   Function value:
00338     AL_INVALID_NAME         Alarm class not defined
00339     AL_SUCCESS              Successful completion
00340 
00341 \********************************************************************/
00342 {
00343    int status, size, state;
00344    HNDLE hDB, hkeyclass;
00345    char str[256], command[256], tag[32], url[256];
00346    ALARM_CLASS ac;
00347    DWORD now = ss_time();
00348 
00349    cm_get_experiment_database(&hDB, NULL);
00350 
00351    /* get alarm class */
00352    sprintf(str, "/Alarms/Classes/%s", alarm_class);
00353    db_find_key(hDB, 0, str, &hkeyclass);
00354    if (!hkeyclass) {
00355       cm_msg(MERROR, "al_trigger_class", "Alarm class %s not found in ODB", alarm_class);
00356       return AL_INVALID_NAME;
00357    }
00358 
00359    size = sizeof(ac);
00360    status = db_get_record(hDB, hkeyclass, &ac, &size, 0);
00361    if (status != DB_SUCCESS) {
00362       cm_msg(MERROR, "al_trigger_class", "Cannot get alarm class record");
00363       return AL_ERROR_ODB;
00364    }
00365 
00366    /* write system message */
00367    if (ac.write_system_message && (now - ac.system_message_last >= (DWORD)ac.system_message_interval)) {
00368       sprintf(str, "%s: %s", alarm_class, alarm_message);
00369       cm_msg(MTALK, "al_trigger_class", str);
00370       ac.system_message_last = now;
00371    }
00372 
00373    /* write elog message on first trigger if using internal ELOG */
00374    size = sizeof(url);
00375    if (ac.write_elog_message && first &&
00376        db_get_value(hDB, 0, "/Elog/URL", url, &size, TID_STRING, FALSE) != DB_SUCCESS)
00377       el_submit(0, "Alarm system", "Alarm", "General", alarm_class, str,
00378                 "", "plain", "", "", 0, "", "", 0, "", "", 0, tag, 32);
00379 
00380    /* execute command */
00381    if (ac.execute_command[0] &&
00382        ac.execute_interval > 0 && (INT) ss_time() - (INT) ac.execute_last > ac.execute_interval) {
00383       sprintf(str, "%s: %s", alarm_class, alarm_message);
00384       sprintf(command, ac.execute_command, str);
00385       cm_msg(MINFO, "al_trigger_class", "Execute: %s", command);
00386       ss_system(command);
00387       ac.execute_last = ss_time();
00388    }
00389 
00390    /* stop run */
00391    if (ac.stop_run) {
00392       state = STATE_STOPPED;
00393       size = sizeof(state);
00394       db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
00395       if (state != STATE_STOPPED) {
00396          cm_msg(MINFO, "al_trigger_class", "Stopping the run from alarm class \'%s\', message \'%s\'", alarm_class, alarm_message);
00397          cm_transition(TR_STOP, 0, NULL, 0, DETACH, FALSE);
00398       }
00399    }
00400 
00401    status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
00402    if (status != DB_SUCCESS) {
00403       cm_msg(MERROR, "al_trigger_class", "Cannot update alarm class record");
00404       return AL_ERROR_ODB;
00405    }
00406 
00407    return AL_SUCCESS;
00408 }
00409 
00410 /**dox***************************************************************/
00411 #endif                          /* DOXYGEN_SHOULD_SKIP_THIS */
00412 
00413 /********************************************************************/
00414 /**
00415 Reset (acknoledge) alarm.
00416 
00417 @param alarm_name Alarm name, defined in /alarms/alarms
00418 @return AL_SUCCESS, AL_RESETE, AL_INVALID_NAME
00419 */
00420 INT al_reset_alarm(const char *alarm_name)
00421 {
00422    int status, size, i;
00423    HNDLE hDB, hkeyalarm, hkeyclass, hsubkey;
00424    KEY key;
00425    char str[256];
00426    ALARM a;
00427    ALARM_CLASS ac;
00428 
00429    cm_get_experiment_database(&hDB, NULL);
00430 
00431    if (alarm_name == NULL) {
00432       /* reset all alarms */
00433       db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyalarm);
00434       if (hkeyalarm) {
00435          for (i = 0;; i++) {
00436             db_enum_link(hDB, hkeyalarm, i, &hsubkey);
00437 
00438             if (!hsubkey)
00439                break;
00440 
00441             db_get_key(hDB, hsubkey, &key);
00442             al_reset_alarm(key.name);
00443          }
00444       }
00445       return AL_SUCCESS;
00446    }
00447 
00448    /* find alarm and alarm class */
00449    sprintf(str, "/Alarms/Alarms/%s", alarm_name);
00450    db_find_key(hDB, 0, str, &hkeyalarm);
00451    if (!hkeyalarm) {
00452       /*cm_msg(MERROR, "al_reset_alarm", "Alarm %s not found in ODB", alarm_name);*/
00453       return AL_INVALID_NAME;
00454    }
00455 
00456    size = sizeof(a);
00457    status = db_get_record(hDB, hkeyalarm, &a, &size, 0);
00458    if (status != DB_SUCCESS) {
00459       cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm record");
00460       return AL_ERROR_ODB;
00461    }
00462 
00463    sprintf(str, "/Alarms/Classes/%s", a.alarm_class);
00464    db_find_key(hDB, 0, str, &hkeyclass);
00465    if (!hkeyclass) {
00466       cm_msg(MERROR, "al_reset_alarm", "Alarm class %s not found in ODB", a.alarm_class);
00467       return AL_INVALID_NAME;
00468    }
00469 
00470    size = sizeof(ac);
00471    status = db_get_record(hDB, hkeyclass, &ac, &size, 0);
00472    if (status != DB_SUCCESS) {
00473       cm_msg(MERROR, "al_reset_alarm", "Cannot get alarm class record");
00474       return AL_ERROR_ODB;
00475    }
00476 
00477    if (a.triggered) {
00478       a.triggered = 0;
00479       a.time_triggered_first[0] = 0;
00480       a.time_triggered_last[0] = 0;
00481       a.checked_last = 0;
00482 
00483       ac.system_message_last = 0;
00484       ac.execute_last = 0;
00485 
00486       status = db_set_record(hDB, hkeyalarm, &a, sizeof(a), 0);
00487       if (status != DB_SUCCESS) {
00488          cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm record");
00489          return AL_ERROR_ODB;
00490       }
00491       status = db_set_record(hDB, hkeyclass, &ac, sizeof(ac), 0);
00492       if (status != DB_SUCCESS) {
00493          cm_msg(MERROR, "al_reset_alarm", "Cannot update alarm class record");
00494          return AL_ERROR_ODB;
00495       }
00496       return AL_RESET;
00497    }
00498 
00499    return AL_SUCCESS;
00500 }
00501 
00502 
00503 /********************************************************************/
00504 /**
00505 Scan ODB for alarms.
00506 @return AL_SUCCESS
00507 */
00508 INT al_check()
00509 {
00510    if (rpc_is_remote())
00511       return rpc_call(RPC_AL_CHECK);
00512 
00513 #ifdef LOCAL_ROUTINES
00514    {
00515       INT i, status, size, semaphore;
00516       HNDLE hDB, hkeyroot, hkey;
00517       KEY key;
00518       ALARM a;
00519       char str[256], value[256];
00520       time_t now;
00521       PROGRAM_INFO program_info;
00522       BOOL flag;
00523 
00524       ALARM_CLASS_STR(alarm_class_str);
00525       ALARM_ODB_STR(alarm_odb_str);
00526       ALARM_PERIODIC_STR(alarm_periodic_str);
00527 
00528       cm_get_experiment_database(&hDB, NULL);
00529 
00530       if (hDB == 0)
00531          return AL_SUCCESS;     /* called from server not yet connected */
00532 
00533       /* check online mode */
00534       flag = TRUE;
00535       size = sizeof(flag);
00536       db_get_value(hDB, 0, "/Runinfo/Online Mode", &flag, &size, TID_INT, TRUE);
00537       if (!flag)
00538          return AL_SUCCESS;
00539 
00540       /* check global alarm flag */
00541       flag = TRUE;
00542       size = sizeof(flag);
00543       db_get_value(hDB, 0, "/Alarms/Alarm system active", &flag, &size, TID_BOOL, TRUE);
00544       if (!flag)
00545          return AL_SUCCESS;
00546 
00547       /* request semaphore */
00548       cm_get_experiment_semaphore(&semaphore, NULL, NULL, NULL);
00549       status = ss_semaphore_wait_for(semaphore, 100);
00550       if (status != SS_SUCCESS)
00551          return SUCCESS;        /* someone else is doing alarm business */
00552 
00553       /* check ODB alarms */
00554       db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00555       if (!hkeyroot) {
00556          /* create default ODB alarm */
00557          status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo ODB", strcomb(alarm_odb_str));
00558          db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00559          if (!hkeyroot) {
00560             ss_semaphore_release(semaphore);
00561             return SUCCESS;
00562          }
00563 
00564          status = db_create_record(hDB, 0, "/Alarms/Alarms/Demo periodic", strcomb(alarm_periodic_str));
00565          db_find_key(hDB, 0, "/Alarms/Alarms", &hkeyroot);
00566          if (!hkeyroot) {
00567             ss_semaphore_release(semaphore);
00568             return SUCCESS;
00569          }
00570 
00571          /* create default alarm classes */
00572          status = db_create_record(hDB, 0, "/Alarms/Classes/Alarm", strcomb(alarm_class_str));
00573          status = db_create_record(hDB, 0, "/Alarms/Classes/Warning", strcomb(alarm_class_str));
00574          if (status != DB_SUCCESS) {
00575             ss_semaphore_release(semaphore);
00576             return SUCCESS;
00577          }
00578       }
00579 
00580       for (i = 0;; i++) {
00581          status = db_enum_key(hDB, hkeyroot, i, &hkey);
00582          if (status == DB_NO_MORE_SUBKEYS)
00583             break;
00584 
00585          db_get_key(hDB, hkey, &key);
00586 
00587          size = sizeof(a);
00588          status = db_get_record(hDB, hkey, &a, &size, 0);
00589          if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00590             /* make sure alarm record has right structure */
00591             db_check_record(hDB, hkey, "", strcomb(alarm_odb_str), TRUE);
00592             size = sizeof(a);
00593             status = db_get_record(hDB, hkey, &a, &size, 0);
00594             if (status != DB_SUCCESS || a.type < 1 || a.type > AT_LAST) {
00595                cm_msg(MERROR, "al_check", "Cannot get alarm record");
00596                continue;
00597             }
00598          }
00599 
00600          /* check periodic alarm only when active */
00601          if (a.active &&
00602              a.type == AT_PERIODIC &&
00603              a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
00604             /* if checked_last has not been set, set it to current time */
00605             if (a.checked_last == 0) {
00606                a.checked_last = ss_time();
00607                db_set_record(hDB, hkey, &a, size, 0);
00608             } else
00609                al_trigger_alarm(key.name, a.alarm_message, a.alarm_class, "", AT_PERIODIC);
00610          }
00611 
00612          /* check alarm only when active and not internal */
00613          if (a.active &&
00614              a.type == AT_EVALUATED &&
00615              a.check_interval > 0 && (INT) ss_time() - (INT) a.checked_last > a.check_interval) {
00616             /* if condition is true, trigger alarm */
00617             if (al_evaluate_condition(a.condition, value)) {
00618                sprintf(str, a.alarm_message, value);
00619                al_trigger_alarm(key.name, str, a.alarm_class, "", AT_EVALUATED);
00620             } else {
00621                a.checked_last = ss_time();
00622                status = db_set_record(hDB, hkey, &a, sizeof(a), 0);
00623                if (status != DB_SUCCESS) {
00624                   cm_msg(MERROR, "al_check", "Cannot write back alarm record");
00625                   continue;
00626                }
00627             }
00628          }
00629       }
00630 
00631       /* check /programs alarms */
00632       db_find_key(hDB, 0, "/Programs", &hkeyroot);
00633       if (hkeyroot) {
00634          for (i = 0;; i++) {
00635             status = db_enum_key(hDB, hkeyroot, i, &hkey);
00636             if (status == DB_NO_MORE_SUBKEYS)
00637                break;
00638 
00639             db_get_key(hDB, hkey, &key);
00640 
00641             /* don't check "execute on xxx" */
00642             if (key.type != TID_KEY)
00643                continue;
00644 
00645             size = sizeof(program_info);
00646             status = db_get_record(hDB, hkey, &program_info, &size, 0);
00647             if (status != DB_SUCCESS) {
00648                cm_msg(MERROR, "al_check", "Cannot get program info record");
00649                continue;
00650             }
00651 
00652             now = ss_time();
00653 
00654             rpc_get_name(str);
00655             str[strlen(key.name)] = 0;
00656             if (!equal_ustring(str, key.name) && cm_exist(key.name, FALSE) == CM_NO_CLIENT) {
00657                if (program_info.first_failed == 0)
00658                   program_info.first_failed = (DWORD) now;
00659 
00660                /* fire alarm when not running for more than what specified in check interval */
00661                if (now - program_info.first_failed >= program_info.check_interval / 1000) {
00662                   /* if not running and alarm calss defined, trigger alarm */
00663                   if (program_info.alarm_class[0]) {
00664                      sprintf(str, "Program %s is not running", key.name);
00665                      al_trigger_alarm(key.name, str, program_info.alarm_class,
00666                                       "Program not running", AT_PROGRAM);
00667                   }
00668 
00669                   /* auto restart program */
00670                   if (program_info.auto_restart && program_info.start_command[0]) {
00671                      ss_system(program_info.start_command);
00672                      program_info.first_failed = 0;
00673                      cm_msg(MTALK, "al_check", "Program %s restarted", key.name);
00674                   }
00675                }
00676             } else
00677                program_info.first_failed = 0;
00678 
00679             db_set_record(hDB, hkey, &program_info, sizeof(program_info), 0);
00680          }
00681       }
00682 
00683       ss_semaphore_release(semaphore);
00684    }
00685 #endif                          /* LOCAL_COUTINES */
00686 
00687    return SUCCESS;
00688 }
00689 
00690 
00691 /**dox***************************************************************/
00692 /** @} *//* end of alfunctioncode */
00693 

Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk