Now agent will start even when failed to open log. Added params: agent.logfile and...
authorzev <zev@radensolutions.com>
Mon, 6 Jun 2016 15:33:32 +0000 (18:33 +0300)
committerzev <zev@radensolutions.com>
Mon, 6 Jun 2016 15:33:32 +0000 (18:33 +0300)
14 files changed:
include/netxmsdb.h
include/nms_agent.h
include/nxevent.h
src/agent/core/dbupgrade.cpp
src/agent/core/localdb.cpp
src/agent/core/localdb.h
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/policy.cpp
src/agent/core/session.cpp
src/agent/subagents/logwatch/logwatch.cpp
src/agent/subagents/winperf/winperf.cpp
src/server/core/node.cpp
src/server/tools/nxdbmgr/upgrade.cpp

index b2b0457..a559432 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _netxmsdb_h
 #define _netxmsdb_h
 
-#define DB_FORMAT_VERSION   404
+#define DB_FORMAT_VERSION   405
 
 #endif
index 880cf0d..dae9859 100644 (file)
@@ -74,6 +74,7 @@
  * Agent log parser policy folder
  */
 #define LOGPARSER_AP_FOLDER _T("logparser_ap")
+#define CONFIG_AP_FOLDER _T("config_ap")
 
 /**
  * Error codes
index 2b31350..7b138a0 100644 (file)
 #define EVENT_MAINTENANCE_MODE_ENTERED    78
 #define EVENT_MAINTENANCE_MODE_LEFT       79
 #define EVENT_LDAP_SYNC_ERROR             80
+#define EVENT_AGENT_LOG_FAIL              81
+#define EVENT_AGENT_LOCAL_DATABASE_FAIL   82
 
 #define EVENT_SNMP_UNMATCHED_TRAP         500
 #define EVENT_SNMP_COLD_START             501
index 7486905..b32807a 100644 (file)
@@ -21,6 +21,7 @@
 **/
 
 #include "nxagentd.h"
+#include <nxstat.h>
 
 /**
  * Execute with error check
@@ -37,6 +38,81 @@ bool g_ignoreAgentDbErrors = FALSE;
 static DB_HANDLE s_db = NULL;
 
 /**
+ * Upgrade from V2 to V3
+ */
+static BOOL H_UpgradeFromV2(int currVersion, int newVersion)
+{
+   //This upgrade procedure moves config policy from old folder to a new one that is specially created form this purposes
+   DB_RESULT hResult = DBSelect(s_db, _T("SELECT guid FROM agent_policy WHERE type=1"));
+   if (hResult != NULL)
+   {
+      for(int row = 0; row < DBGetNumRows(hResult); row++)
+      {
+         uuid guid = DBGetFieldGUID(hResult, row, 0);
+         TCHAR oldPath[MAX_PATH], newPath[MAX_PATH], name[64], tail;
+
+         tail = g_szConfigPolicyDir[_tcslen(g_szConfigPolicyDir) - 1];
+         _sntprintf(newPath, MAX_PATH, _T("%s%s%s.conf"), g_szConfigPolicyDir,
+                    ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+                    guid.toString(name));
+         tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
+         _sntprintf(oldPath, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
+                  ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+               guid.toString(name));
+
+         //check that file exists and move it to other folder
+         NX_STAT_STRUCT st;
+
+         if (CALL_STAT(oldPath, &st) != 0)
+         {
+            continue;
+         }
+
+#ifdef _WIN32
+         MoveFileEx(oldPath, newPath, MOVEFILE_COPY_ALLOWED);
+#else
+         if (_trename(oldPath, newPath) != 0)
+         {
+            int oldFile = _topen(oldPath, O_RDONLY | O_BINARY);
+            bool success = true;
+            if (oldFile == -1)
+               continue;
+
+            int newFile = _topen(newPath, O_CREAT | O_BINARY | O_WRONLY, st.st_mode); // should be copied with the same acess rights
+            if (newFile == -1)
+            {
+               close(oldFile);
+               continue;
+            }
+
+            int size = 16384, in, out;
+            BYTE *bytes = (BYTE *)malloc(size);
+
+            while((in = read(oldFile, bytes, size)) > 0)
+            {
+               out = write(newFile, bytes, (ssize_t)in);
+               if (out != in)
+               {
+                  break;
+               }
+            }
+
+            close(oldFile);
+            close(newFile);
+            free(bytes);
+            if(success)
+               _tremove(oldPath);
+         }
+#endif /* _WIN32 */
+      }
+      DBFreeResult(hResult);
+   }
+
+   CHK_EXEC(WriteMetadata(_T("SchemaVersion"), 3));
+   return TRUE;
+}
+
+/**
  * Upgrade from V1 to V2
  */
 static BOOL H_UpgradeFromV1(int currVersion, int newVersion)
@@ -192,6 +268,7 @@ static struct
 } m_dbUpgradeMap[] =
 {
    { 1, 2, H_UpgradeFromV1 },
+   { 2, 3, H_UpgradeFromV2 },
    { 0, 0, NULL }
 };
 
index 53fd49d..df40eec 100644 (file)
@@ -142,11 +142,13 @@ bool OpenLocalDatabase()
    if (s_db == NULL)
    {
       DebugPrintf(INVALID_INDEX, 1, _T("Local database open error: %s"), errorText);
+          g_failFlags = FAIL_OPEN_DATABASE;
       return false;
    }
 
    if (!CheckDatabaseStructure() || !UpgradeDatabase())
    {
+          g_failFlags = FIAL_UPGRADE_DATABASE;
       DBDisconnect(s_db);
       s_db = NULL;
       return false;
index b12af6f..fd13dfd 100644 (file)
@@ -27,7 +27,7 @@
 /**
  * Database schema version
  */
-#define DB_SCHEMA_VERSION     2
+#define DB_SCHEMA_VERSION     3
 
 bool OpenLocalDatabase();
 void CloseLocalDatabase();
index f0cd887..37dc55e 100644 (file)
@@ -79,6 +79,8 @@ void DestroySessionList();
 
 BOOL RegisterOnServer(const TCHAR *pszServer);
 
+void UpdatePolicyInventory();
+
 #if !defined(_WIN32)
 void InitStaticSubagents();
 #endif
@@ -136,6 +138,7 @@ extern const TCHAR *g_szMessages[];
  * Global variables
  */
 UINT32 g_dwFlags = AF_ENABLE_ACTIONS | AF_ENABLE_AUTOLOAD;
+UINT32 g_failFlags = 0;
 TCHAR g_szLogFile[MAX_PATH] = AGENT_DEFAULT_LOG;
 TCHAR g_szSharedSecret[MAX_SECRET_LENGTH] = _T("admin");
 TCHAR g_szConfigFile[MAX_PATH] = AGENT_DEFAULT_CONFIG;
@@ -146,6 +149,7 @@ TCHAR g_szConfigServer[MAX_DB_STRING] = _T("not_set");
 TCHAR g_szRegistrar[MAX_DB_STRING] = _T("not_set");
 TCHAR g_szListenAddress[MAX_PATH] = _T("*");
 TCHAR g_szConfigIncludeDir[MAX_PATH] = AGENT_DEFAULT_CONFIG_D;
+TCHAR g_szConfigPolicyDir[MAX_PATH] = AGENT_DEFAULT_CONFIG_D;
 TCHAR g_szLogParserDirectory[MAX_PATH] = _T("");
 TCHAR g_masterAgent[MAX_PATH] = _T("not_set");
 TCHAR g_szSNMPTrapListenAddress[MAX_PATH] = _T("*");
@@ -523,6 +527,27 @@ static LONG H_RestartAgent(const TCHAR *action, StringList *args, const TCHAR *d
 #endif
 }
 
+static LONG H_FailStatusProvider(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
+{
+   UINT32 result = 0;
+   switch(*pArg)
+   {
+      case 'D':
+         if((g_failFlags & FAIL_OPEN_DATABASE) > 0)
+            result++;
+         if((g_failFlags & FIAL_UPGRADE_DATABASE) > 0)
+            result++;
+         break;
+      case 'L':
+         if((g_failFlags & FAIL_OPEN_LOG) > 0)
+            result++;
+         break;
+   }
+
+   ret_int(pValue, result);
+   return SYSINFO_RC_SUCCESS;
+}
+
 /**
  * This function writes message from subagent to agent's log
  */
@@ -663,13 +688,17 @@ BOOL Initialize()
       GetNetXMSDirectory(nxDirData, g_szDataDirectory);
    }
 
+   //Initialize config policy folder
+   TCHAR tail = g_szDataDirectory[_tcslen(g_szDataDirectory) - 1];
+       _sntprintf(g_szConfigPolicyDir, MAX_PATH, _T("%s%s%s"), g_szDataDirectory,
+                  ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+              CONFIG_AP_FOLDER FS_PATH_SEPARATOR);
+       CreateFolder(g_szConfigPolicyDir);
+       //load configuration
+   g_config->loadConfigDirectory(g_szConfigPolicyDir, _T("agent"));
+       g_config->parseTemplate(_T("agent"), m_cfgTemplate);
+
    // Open log file
-       if (!(g_dwFlags & AF_USE_SYSLOG))
-       {
-               if (!nxlog_set_rotation_policy((int)s_logRotationMode, (int)s_maxLogSize, (int)s_logHistorySize, s_dailyLogFileSuffix))
-                       if (!(g_dwFlags & AF_DAEMON))
-                               _tprintf(_T("WARNING: cannot set log rotation policy; using default values\n"));
-       }
    if (!nxlog_open((g_dwFlags & AF_USE_SYSLOG) ? NXAGENTD_SYSLOG_NAME : g_szLogFile,
                        ((g_dwFlags & AF_USE_SYSLOG) ? NXLOG_USE_SYSLOG : 0) |
                        ((g_dwFlags & AF_BACKGROUND_LOG_WRITER) ? NXLOG_BACKGROUND_WRITER : 0) |
@@ -681,9 +710,30 @@ BOOL Initialize()
                        g_dwNumMessages, g_szMessages, MSG_DEBUG))
 #endif
        {
-               _ftprintf(stderr, _T("FATAL ERROR: Cannot open log file\n"));
-               return FALSE;
+          //TODO: set flag that log have been opened with errors
+          s_debugLevel = 1;
+          g_failFlags = FAIL_OPEN_LOG;
+      nxlog_open(NXAGENTD_SYSLOG_NAME, NXLOG_USE_SYSLOG |
+                      ((g_dwFlags & AF_BACKGROUND_LOG_WRITER) ? NXLOG_BACKGROUND_WRITER : 0) |
+                  ((g_dwFlags & AF_DAEMON) ? 0 : NXLOG_PRINT_TO_STDOUT),
+                      _T("NXAGENTD.EXE"),
+#ifdef _WIN32
+                      0, NULL, MSG_DEBUG);
+#else
+                      g_dwNumMessages, g_szMessages, MSG_DEBUG);
+#endif
+               _ftprintf(stderr, _T("ERROR: Cannot open log file, logs will be written to syslog with debug level 1\n"));
+
        }
+       else
+   {
+      if (!(g_dwFlags & AF_USE_SYSLOG))
+      {
+         if (!nxlog_set_rotation_policy((int)s_logRotationMode, (int)s_maxLogSize, (int)s_logHistorySize, s_dailyLogFileSuffix))
+            if (!(g_dwFlags & AF_DAEMON))
+               _tprintf(_T("WARNING: cannot set log rotation policy; using default values\n"));
+      }
+   }
        nxlog_write(MSG_USE_CONFIG_D, NXLOG_INFO, "s", g_szConfigIncludeDir);
        nxlog_write(MSG_DEBUG_LEVEL, NXLOG_INFO, "d", s_debugLevel);
        nxlog_set_debug_level(s_debugLevel);
@@ -698,12 +748,13 @@ BOOL Initialize()
    CreateFolder(g_szDataDirectory);
 
    //Initialize log parser policy folder
-   TCHAR tail = g_szDataDirectory[_tcslen(g_szDataDirectory) - 1];
+   tail = g_szDataDirectory[_tcslen(g_szDataDirectory) - 1];
        _sntprintf(g_szLogParserDirectory, MAX_PATH, _T("%s%s%s"), g_szDataDirectory,
                   ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
               LOGPARSER_AP_FOLDER FS_PATH_SEPARATOR);
    DebugPrintf(INVALID_INDEX, 6, _T("Log parser policy directory: %s"), g_szLogParserDirectory);
        CreateFolder(g_szLogParserDirectory);
+   DebugPrintf(INVALID_INDEX, 6, _T("Configuration policy directory: %s"), g_szConfigPolicyDir);
    CreateFolder(g_szFileStore);
 
 #ifdef _WIN32
@@ -766,6 +817,9 @@ BOOL Initialize()
 
                // Add built-in actions
                AddAction(_T("Agent.Restart"), AGENT_ACTION_SUBAGENT, NULL, H_RestartAgent, _T("CORE"), _T("Restart agent"));
+               //Add build-in DCIs
+      AddParameter(_T("Agent.LogFile"), H_FailStatusProvider, _T("L"), DCI_DT_UINT, _T("Get log status"));
+      AddParameter(_T("Agent.LocalDatabase"), H_FailStatusProvider, _T("D"), DCI_DT_UINT, _T("Get database status"));
 
           // Load platform subagents
 #if !defined(_WIN32)
@@ -999,6 +1053,9 @@ BOOL Initialize()
       DeleteRegistryEntry(_T("upgrade.file"));
        }
 
+       //Update policy inventory according to files that exist on file system
+   UpdatePolicyInventory();
+
    return TRUE;
 }
 
index e3ddea2..67eab4f 100644 (file)
 #define AF_ENABLE_SNMP_TRAP_PROXY   0x00200000
 #define AF_BACKGROUND_LOG_WRITER    0x00400000
 
+//Flags for errors while loading
+#define FAIL_OPEN_LOG               0x00000001
+#define FAIL_OPEN_DATABASE          0x00000002
+#define FIAL_UPGRADE_DATABASE       0x00000003
 
 #ifdef _WIN32
 
@@ -611,6 +615,7 @@ TCHAR *GetPdhErrorText(UINT32 dwError, TCHAR *pszBuffer, int iBufSize);
  * Global variables
  */
 extern UINT32 g_dwFlags;
+extern UINT32 g_failFlags;
 extern TCHAR g_szLogFile[];
 extern TCHAR g_szSharedSecret[];
 extern TCHAR g_szConfigFile[];
@@ -619,6 +624,7 @@ extern TCHAR g_szConfigServer[];
 extern TCHAR g_szRegistrar[];
 extern TCHAR g_szListenAddress[];
 extern TCHAR g_szConfigIncludeDir[];
+extern TCHAR g_szConfigPolicyDir[];
 extern TCHAR g_szLogParserDirectory[];
 extern TCHAR g_szDataDirectory[];
 extern TCHAR g_masterAgent[];
index 90d8e2a..fd7e413 100644 (file)
@@ -27,7 +27,7 @@
 #define close _close
 #endif
 
-#define POLICY_REGISTRY_PATH _T("/policyRegistry")
+#include <nxstat.h>
 
 /**
  * Register policy in persistent storage
@@ -134,8 +134,8 @@ static UINT32 DeployConfig(UINT32 session, const uuid& guid, NXCPMessage *msg)
        int fh;
        UINT32 rcc;
 
-       tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
-       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
+       tail = g_szConfigPolicyDir[_tcslen(g_szConfigPolicyDir) - 1];
+       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigPolicyDir,
                   ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
               guid.toString(name));
 
@@ -257,8 +257,8 @@ static UINT32 RemoveConfig(UINT32 session, const uuid& guid, NXCPMessage *msg)
        TCHAR path[MAX_PATH], name[64], tail;
        UINT32 rcc;
 
-       tail = g_szConfigIncludeDir[_tcslen(g_szConfigIncludeDir) - 1];
-       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigIncludeDir,
+       tail = g_szConfigPolicyDir[_tcslen(g_szConfigPolicyDir) - 1];
+       _sntprintf(path, MAX_PATH, _T("%s%s%s.conf"), g_szConfigPolicyDir,
                   ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
               guid.toString(name));
 
@@ -368,3 +368,44 @@ UINT32 GetPolicyInventory(CommSession *session, NXCPMessage *msg)
 
        return success;
 }
+
+void UpdatePolicyInventory()
+{
+       DB_HANDLE hdb = GetLocalDatabaseHandle();
+       if(hdb != NULL)
+   {
+      DB_RESULT hResult = DBSelect(hdb, _T("SELECT guid,type FROM agent_policy"));
+      if (hResult != NULL)
+      {
+         for(int row = 0; row < DBGetNumRows(hResult); row++)
+         {
+            uuid guid = DBGetFieldGUID(hResult, row, 0);
+            int type = DBGetFieldULong(hResult, row, 1);
+            TCHAR filePath[MAX_PATH], name[64], tail;
+
+            switch(type)
+            {
+               case AGENT_POLICY_CONFIG:
+                  tail = g_szConfigPolicyDir[_tcslen(g_szConfigPolicyDir) - 1];
+                  _sntprintf(filePath, MAX_PATH, _T("%s%s%s.conf"), g_szConfigPolicyDir,
+                             ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""),
+                             guid.toString(name));
+                  break;
+               case AGENT_POLICY_LOG_PARSER:
+                  _sntprintf(filePath, MAX_PATH, _T("%s%s.xml"), g_szLogParserDirectory, guid.toString(name));
+                  break;
+               default:
+                  continue;
+                  break;
+            }
+
+            NX_STAT_STRUCT st;
+            if (CALL_STAT(filePath, &st) == 0)
+            {
+               continue;
+            }
+            UnregisterPolicy(guid);
+         }
+      }
+   }
+}
index 8c803f1..8cb2ec0 100644 (file)
@@ -34,6 +34,7 @@ void UnregisterSession(UINT32 dwIndex);
 UINT32 DeployPolicy(CommSession *session, NXCPMessage *request);
 UINT32 UninstallPolicy(CommSession *session, NXCPMessage *request);
 UINT32 GetPolicyInventory(CommSession *session, NXCPMessage *msg);
+void UpdatePolicyInventory();
 void ClearDataCollectionConfiguration();
 
 /**
index 7dbaf22..f67b766 100644 (file)
@@ -248,7 +248,6 @@ static void AddLogwatchPolicyFiles()
 
          TCHAR fullName[MAX_PATH];
          _tcscpy(fullName, policyFolder);
-         _tcscat(fullName, FS_PATH_SEPARATOR);
          _tcscat(fullName, d->d_name);
 
          NX_STAT_STRUCT st;
index caed33e..643d198 100644 (file)
@@ -608,7 +608,7 @@ DECLARE_SUBAGENT_ENTRY_POINT(WINPERF)
    {
       AgentWriteDebugLog(4, _T("WinPerf: \"\\Memory\\Free & Zero Page List Bytes\" is supported"));
       AddParameter(_T("System.Memory.Physical.Free"), H_CounterAlias, (TCHAR *)counter, DCI_DT_UINT64, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE);
-      AddParameter(_T("System.Memory.Physical.FreePerc"), H_FreeMemoryPct, (TCHAR *)counter, DCI_DT_UINT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE_PCT);
+      AddParameter(_T("System.Memory.Physical.FreePerc"), H_FreeMemoryPct, (TCHAR *)counter, DCI_DT_INT, DCIDESC_SYSTEM_MEMORY_PHYSICAL_FREE_PCT);
    }
    else
    {
index f2185b3..efc0cc8 100644 (file)
@@ -1641,6 +1641,38 @@ restart_agent_check:
       }
    }
 
+   //Get Agent log and agent localDatabase statuses
+   if (!(m_dwDynamicFlags & NDF_UNREACHABLE))
+   {
+      TCHAR buffer[MAX_RESULT_LENGTH];
+      if (getItemFromAgent(_T("Agent.LogFile"), MAX_RESULT_LENGTH, buffer) == DCE_SUCCESS)
+      {
+         UINT32 status = _tcstol(buffer, NULL, 0);
+         if(status != 0)
+            PostEvent(EVENT_AGENT_LOG_FAIL, m_id, "ds", status, _T("could not open"));
+      }
+      else
+      {
+         DbgPrintf(5, _T("StatusPoll(%s [%d]): unable to get agent log status"), m_name, m_id);
+      }
+
+      if (getItemFromAgent(_T("Agent.LocalDatabase"), MAX_RESULT_LENGTH, buffer) == DCE_SUCCESS)
+      {
+         UINT32 status = _tcstol(buffer, NULL, 0);
+         const TCHAR *statusDescription[3]= {
+                                       _T("normal"),
+                                       _T("could not open database"),
+                                       _T("could not update database"),
+                                       };
+         if(status != 0)
+            PostEvent(EVENT_AGENT_LOCAL_DATABASE_FAIL, m_id, "ds", status, statusDescription[status]);
+      }
+      else
+      {
+         DbgPrintf(5, _T("StatusPoll(%s [%d]): unable to get agent local database status"), m_name, m_id);
+      }
+   }
+
    // Send delayed events and destroy delayed event queue
        if (pQueue != NULL)
        {
@@ -1881,11 +1913,11 @@ void Node::checkAgentPolicyBinding(AgentConnection *conn)
                ServerJob *job = new PolicyDeploymentJob(this, (AgentPolicy *)m_pParentList[i], 0); //TODO: change to system user
                                        if (AddJob(job))
                                        {
-                  DbgPrintf(5, _T("ConfPoll(%s): \"%s\" policy deploy scheduled for \"%s\" node"), m_pParentList[i]->getName(), m_name);
+                  DbgPrintf(5, _T("ConfPoll(%s): \"%s\" policy deploy scheduled for \"%s\" node"), m_name, m_pParentList[i]->getName(), m_name );
                                        }
                                        else
                                        {
-                  DbgPrintf(5, _T("ConfPoll(%s): \"%s\" policy deploy is not possible to scheduled for \"%s\" node"), m_pParentList[i]->getName(), m_name);
+                  DbgPrintf(5, _T("ConfPoll(%s): \"%s\" policy deploy is not possible to scheduled for \"%s\" node"), m_name, m_pParentList[i]->getName(), m_name);
                                                delete job;
                   unbindList[unbindListSize++] = m_pParentList[i];
                                        }
index 2aaeb62..bbbd771 100644 (file)
@@ -674,6 +674,46 @@ static int NextFreeEPPruleID()
 }
 
 /**
+ * Upgrade from V404 to V405
+ */
+static BOOL H_UpgradeFromV404(int currVersion, int newVersion)
+{
+   CHK_EXEC(CreateEventTemplate(EVENT_AGENT_LOG_FAIL, _T("SYS_AGENT_LOG_FAIL"),
+            SEVERITY_MAJOR, EF_LOG, _T("262057ca-357a-4a4d-9b78-42ae96e490a1"),
+      _T("Problem with agent log: %2"),
+      _T("Generated on status poll if agent reposts log open problem.\r\n")
+      _T("Parameters:\r\n")
+      _T("    1) Status\r\n")
+      _T("    2) Description")));
+   CHK_EXEC(CreateEventTemplate(EVENT_AGENT_LOCAL_DATABASE_FAIL, _T("SYS_AGENT_LOCAL_DATABASE_FAIL"),
+            SEVERITY_MAJOR, EF_LOG, _T("d02b63f1-1151-429e-adb9-1dfbb3a31b32"),
+      _T("Problem with agent local database: %2"),
+      _T("Generated on status poll if agent reposts local database problem.\r\n")
+      _T("Parameters:\r\n")
+      _T("    1) Status\r\n")
+      _T("    2) Description")));
+
+       int ruleId = NextFreeEPPruleID();
+   TCHAR query[1024];
+       _sntprintf(query, 1024, _T("INSERT INTO event_policy (rule_id,rule_guid,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance) ")
+                           _T("VALUES (%d,'19bd89ba-8bb2-4915-8546-a1ecc650dedd',7944,'Generate an alarm when there is problem with log on agent','%%m',5,'SYS_AGENT_LOG_FAIL_%%1','',0,%d,0,'')"),
+                           ruleId, EVENT_ALARM_TIMEOUT);
+   CHK_EXEC(SQLQuery(query));
+   _sntprintf(query, 1024, _T("INSERT INTO policy_event_list (rule_id,event_code) VALUES (%d,%d)"), ruleId, EVENT_AGENT_LOG_FAIL);
+   CHK_EXEC(SQLQuery(query));
+       ruleId = NextFreeEPPruleID();
+       _sntprintf(query, 1024, _T("INSERT INTO event_policy (rule_id,rule_guid,flags,comments,alarm_message,alarm_severity,alarm_key,script,alarm_timeout,alarm_timeout_event,situation_id,situation_instance) ")
+                           _T("VALUES (%d,'cff7fe6b-2ad1-4c18-8a8f-4d397d44fe04',7944,'Generate an alarm when  there is problem with local database on agent','%%m',5,'SYS_AGENT_LOCAL_DATABASE_FAIL_%%1','',0,%d,0,'')"),
+                           ruleId, EVENT_ALARM_TIMEOUT);
+   CHK_EXEC(SQLQuery(query));
+   _sntprintf(query, 1024, _T("INSERT INTO policy_event_list (rule_id,event_code) VALUES (%d,%d)"), ruleId, EVENT_AGENT_LOCAL_DATABASE_FAIL);
+   CHK_EXEC(SQLQuery(query));
+
+   CHK_EXEC(SQLQuery(_T("UPDATE metadata SET var_value='405' WHERE var_name='SchemaVersion'")));
+   return TRUE;
+}
+
+/**
  * Upgrade from V403 to V404
  */
 static BOOL H_UpgradeFromV403(int currVersion, int newVersion)
@@ -10192,6 +10232,7 @@ static struct
    { 401, 402, H_UpgradeFromV401 },
    { 402, 403, H_UpgradeFromV402 },
    { 403, 404, H_UpgradeFromV403 },
+   { 404, 405, H_UpgradeFromV404 },
    { 0, 0, NULL }
 };