2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2016 Raden Solutions
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <netxms_mt.h>
28 #if !defined(_WIN32) && HAVE_READLINE_READLINE_H && HAVE_READLINE && !defined(UNICODE)
29 #include <readline/readline.h>
30 #include <readline/history.h>
31 #define USE_READLINE 1
51 * Format string to show value of global flag
53 #define SHOW_FLAG_VALUE(x) _T(" %-38s = %d\n"), _T(#x), (g_flags & x) ? 1 : 0
56 * Messages generated by mc.pl (for UNIX version only)
59 extern unsigned int g_dwNumMessages
;
60 extern const TCHAR
*g_szMessages
[];
66 #define SHUTDOWN_DEFAULT 0
67 #define SHUTDOWN_FROM_CONSOLE 1
68 #define SHUTDOWN_BY_SIGNAL 2
73 extern Queue g_nodePollerQueue
;
74 extern Queue g_dataCollectionQueue
;
75 extern Queue g_dciCacheLoaderQueue
;
76 extern Queue g_syslogProcessingQueue
;
77 extern Queue g_syslogWriteQueue
;
78 extern ThreadPool
*g_pollerThreadPool
;
79 extern ThreadPool
*g_schedulerThreadPool
;
81 void InitClientListeners();
82 void InitMobileDeviceListeners();
83 void InitCertificates();
86 void LoadPerfDataStorageDrivers();
87 void ImportLocalConfiguration();
89 void ExecuteScheduledScript(const ScheduledTaskParameters
*param
);
90 void MaintenanceModeEnter(const ScheduledTaskParameters
*params
);
91 void MaintenanceModeLeave(const ScheduledTaskParameters
*params
);
94 void StartXMPPConnector();
95 void StopXMPPConnector();
99 * Syslog server control
101 void StartSyslogServer();
102 void StopSyslogServer();
105 * Housekeeper control
107 void StartHouseKeeper();
108 void StopHouseKeeper();
109 void RunHouseKeeper();
114 THREAD_RESULT THREAD_CALL
Syncer(void *);
115 THREAD_RESULT THREAD_CALL
NodePoller(void *);
116 THREAD_RESULT THREAD_CALL
PollManager(void *);
117 THREAD_RESULT THREAD_CALL
EventProcessor(void *);
118 THREAD_RESULT THREAD_CALL
WatchdogThread(void *);
119 THREAD_RESULT THREAD_CALL
ClientListener(void *);
120 THREAD_RESULT THREAD_CALL
ClientListenerIPv6(void *);
121 THREAD_RESULT THREAD_CALL
MobileDeviceListener(void *);
122 THREAD_RESULT THREAD_CALL
MobileDeviceListenerIPv6(void *);
123 THREAD_RESULT THREAD_CALL
ISCListener(void *);
124 THREAD_RESULT THREAD_CALL
LocalAdminListener(void *);
125 THREAD_RESULT THREAD_CALL
SNMPTrapReceiver(void *);
126 THREAD_RESULT THREAD_CALL
BeaconPoller(void *);
127 THREAD_RESULT THREAD_CALL
JobManagerThread(void *);
128 THREAD_RESULT THREAD_CALL
UptimeCalculator(void *);
129 THREAD_RESULT THREAD_CALL
ReportingServerConnector(void *);
134 TCHAR NXCORE_EXPORTABLE g_szConfigFile
[MAX_PATH
] = _T("{search}");
135 TCHAR NXCORE_EXPORTABLE g_szLogFile
[MAX_PATH
] = DEFAULT_LOG_FILE
;
136 UINT32 g_dwLogRotationMode
= NXLOG_ROTATION_BY_SIZE
;
137 UINT32 g_dwMaxLogSize
= 16384 * 1024;
138 UINT32 g_dwLogHistorySize
= 4;
139 TCHAR g_szDailyLogFileSuffix
[64] = _T("");
140 TCHAR NXCORE_EXPORTABLE g_szDumpDir
[MAX_PATH
] = DEFAULT_DUMP_DIR
;
141 char g_szCodePage
[256] = ICONV_DEFAULT_CODEPAGE
;
142 TCHAR NXCORE_EXPORTABLE g_szListenAddress
[MAX_PATH
] = _T("*");
144 TCHAR NXCORE_EXPORTABLE g_szPIDFile
[MAX_PATH
] = _T("/var/run/netxmsd.pid");
146 UINT32 g_dwDiscoveryPollingInterval
;
147 UINT32 g_dwStatusPollingInterval
;
148 UINT32 g_dwConfigurationPollingInterval
;
149 UINT32 g_dwRoutingTableUpdateInterval
;
150 UINT32 g_dwTopologyPollingInterval
;
151 UINT32 g_dwConditionPollingInterval
;
152 UINT32 g_instancePollingInterval
;
153 UINT32 g_icmpPingSize
;
154 UINT32 g_icmpPingTimeout
= 1500; // ICMP ping timeout (milliseconds)
156 UINT32 g_slmPollingInterval
;
157 TCHAR NXCORE_EXPORTABLE g_netxmsdDataDir
[MAX_PATH
] = _T("");
158 TCHAR NXCORE_EXPORTABLE g_netxmsdLibDir
[MAX_PATH
] = _T("");
159 int g_dbSyntax
= DB_SYNTAX_UNKNOWN
;
160 UINT32 NXCORE_EXPORTABLE g_processAffinityMask
= DEFAULT_AFFINITY_MASK
;
161 UINT64 g_serverId
= 0;
162 RSA
*g_pServerKey
= NULL
;
163 time_t g_serverStartTime
= 0;
164 UINT32 g_lockTimeout
= 60000; // Default timeout for acquiring mutex
165 UINT32 g_agentCommandTimeout
= 4000; // Default timeout for requests to agent
166 UINT32 g_thresholdRepeatInterval
= 0; // Disabled by default
167 int g_requiredPolls
= 1;
168 DB_DRIVER g_dbDriver
= NULL
;
169 ThreadPool
*g_mainThreadPool
= NULL
;
170 INT16 g_defaultAgentCacheMode
= AGENT_CACHE_OFF
;
175 static CONDITION m_condShutdown
= INVALID_CONDITION_HANDLE
;
176 static THREAD m_thPollManager
= INVALID_THREAD_HANDLE
;
177 static THREAD m_thSyncer
= INVALID_THREAD_HANDLE
;
178 static int m_nShutdownReason
= SHUTDOWN_DEFAULT
;
181 static pthread_t m_signalHandlerThread
;
185 * Sleep for specified number of seconds or until system shutdown arrives
186 * Function will return TRUE if shutdown event occurs
188 * @param seconds seconds to sleep
189 * @return true if server is shutting down
191 bool NXCORE_EXPORTABLE
SleepAndCheckForShutdown(int seconds
)
193 return ConditionWait(m_condShutdown
, seconds
* 1000);
197 * Disconnect from database (exportable function for startup module)
199 void NXCORE_EXPORTABLE
ShutdownDB()
201 DBConnectionPoolShutdown();
202 DBUnloadDriver(g_dbDriver
);
206 * Check data directory for existence
208 static BOOL
CheckDataDir()
210 TCHAR szBuffer
[MAX_PATH
];
212 if (_tchdir(g_netxmsdDataDir
) == -1)
214 nxlog_write(MSG_INVALID_DATA_DIR
, EVENTLOG_ERROR_TYPE
, "s", g_netxmsdDataDir
);
219 #define MKDIR(name) _tmkdir(name)
221 #define MKDIR(name) _tmkdir(name, 0700)
224 // Create directory for package files if it doesn't exist
225 _tcscpy(szBuffer
, g_netxmsdDataDir
);
226 _tcscat(szBuffer
, DDIR_PACKAGES
);
227 if (MKDIR(szBuffer
) == -1)
230 nxlog_write(MSG_ERROR_CREATING_DATA_DIR
, EVENTLOG_ERROR_TYPE
, "s", szBuffer
);
234 // Create directory for map background images if it doesn't exist
235 _tcscpy(szBuffer
, g_netxmsdDataDir
);
236 _tcscat(szBuffer
, DDIR_BACKGROUNDS
);
237 if (MKDIR(szBuffer
) == -1)
240 nxlog_write(MSG_ERROR_CREATING_DATA_DIR
, EVENTLOG_ERROR_TYPE
, "s", szBuffer
);
244 // Create directory for image library is if does't exists
245 _tcscpy(szBuffer
, g_netxmsdDataDir
);
246 _tcscat(szBuffer
, DDIR_IMAGES
);
247 if (MKDIR(szBuffer
) == -1)
251 nxlog_write(MSG_ERROR_CREATING_DATA_DIR
, EVENTLOG_ERROR_TYPE
, "s", szBuffer
);
256 // Create directory for file store if does't exists
257 _tcscpy(szBuffer
, g_netxmsdDataDir
);
258 _tcscat(szBuffer
, DDIR_FILES
);
259 if (MKDIR(szBuffer
) == -1)
263 nxlog_write(MSG_ERROR_CREATING_DATA_DIR
, EVENTLOG_ERROR_TYPE
, "s", szBuffer
);
274 * Load global configuration parameters
276 static void LoadGlobalConfig()
278 g_dwDiscoveryPollingInterval
= ConfigReadInt(_T("DiscoveryPollingInterval"), 900);
279 g_dwStatusPollingInterval
= ConfigReadInt(_T("StatusPollingInterval"), 60);
280 g_dwConfigurationPollingInterval
= ConfigReadInt(_T("ConfigurationPollingInterval"), 3600);
281 g_instancePollingInterval
= ConfigReadInt(_T("InstancePollingInterval"), 600);
282 g_dwRoutingTableUpdateInterval
= ConfigReadInt(_T("RoutingTableUpdateInterval"), 300);
283 g_dwTopologyPollingInterval
= ConfigReadInt(_T("TopologyPollingInterval"), 1800);
284 g_dwConditionPollingInterval
= ConfigReadInt(_T("ConditionPollingInterval"), 60);
285 g_slmPollingInterval
= ConfigReadInt(_T("SlmPollingInterval"), 60);
286 DCObject::m_defaultPollingInterval
= ConfigReadInt(_T("DefaultDCIPollingInterval"), 60);
287 DCObject::m_defaultRetentionTime
= ConfigReadInt(_T("DefaultDCIRetentionTime"), 30);
288 g_defaultAgentCacheMode
= (INT16
)ConfigReadInt(_T("DefaultAgentCacheMode"), AGENT_CACHE_OFF
);
289 if ((g_defaultAgentCacheMode
!= AGENT_CACHE_ON
) && (g_defaultAgentCacheMode
!= AGENT_CACHE_OFF
))
291 DbgPrintf(1, _T("Invalid value %d of DefaultAgentCacheMode: reset to %d (OFF)"), g_defaultAgentCacheMode
, AGENT_CACHE_OFF
);
292 ConfigWriteInt(_T("DefaultAgentCacheMode"), AGENT_CACHE_OFF
, true, true, true);
293 g_defaultAgentCacheMode
= AGENT_CACHE_OFF
;
295 if (ConfigReadInt(_T("DeleteEmptySubnets"), 1))
296 g_flags
|= AF_DELETE_EMPTY_SUBNETS
;
297 if (ConfigReadInt(_T("EnableSNMPTraps"), 1))
298 g_flags
|= AF_ENABLE_SNMP_TRAPD
;
299 if (ConfigReadInt(_T("ProcessTrapsFromUnmanagedNodes"), 0))
300 g_flags
|= AF_TRAPS_FROM_UNMANAGED_NODES
;
301 if (ConfigReadInt(_T("EnableZoning"), 0))
302 g_flags
|= AF_ENABLE_ZONING
;
303 if (ConfigReadInt(_T("EnableObjectTransactions"), 0))
304 g_flags
|= AF_ENABLE_OBJECT_TRANSACTIONS
;
305 if (ConfigReadInt(_T("RunNetworkDiscovery"), 0))
306 g_flags
|= AF_ENABLE_NETWORK_DISCOVERY
;
307 if (ConfigReadInt(_T("ActiveNetworkDiscovery"), 0))
308 g_flags
|= AF_ACTIVE_NETWORK_DISCOVERY
;
309 if (ConfigReadInt(_T("UseSNMPTrapsForDiscovery"), 0))
310 g_flags
|= AF_SNMP_TRAP_DISCOVERY
;
311 if (ConfigReadInt(_T("ResolveNodeNames"), 1))
312 g_flags
|= AF_RESOLVE_NODE_NAMES
;
313 if (ConfigReadInt(_T("SyncNodeNamesWithDNS"), 0))
314 g_flags
|= AF_SYNC_NODE_NAMES_WITH_DNS
;
315 if (ConfigReadInt(_T("CheckTrustedNodes"), 1))
316 g_flags
|= AF_CHECK_TRUSTED_NODES
;
317 if (ConfigReadInt(_T("EnableNXSLContainerFunctions"), 1))
318 g_flags
|= AF_ENABLE_NXSL_CONTAINER_FUNCS
;
319 if (ConfigReadInt(_T("UseFQDNForNodeNames"), 1))
320 g_flags
|= AF_USE_FQDN_FOR_NODE_NAMES
;
321 if (ConfigReadInt(_T("ApplyDCIFromTemplateToDisabledDCI"), 1))
322 g_flags
|= AF_APPLY_TO_DISABLED_DCI_FROM_TEMPLATE
;
323 if (ConfigReadInt(_T("ResolveDNSToIPOnStatusPoll"), 0))
324 g_flags
|= AF_RESOLVE_IP_FOR_EACH_STATUS_POLL
;
325 if (ConfigReadInt(_T("CaseInsensitiveLoginNames"), 0))
326 g_flags
|= AF_CASE_INSENSITIVE_LOGINS
;
327 if (ConfigReadInt(_T("TrapSourcesInAllZones"), 0))
328 g_flags
|= AF_TRAP_SOURCES_IN_ALL_ZONES
;
330 if (g_netxmsdDataDir
[0] == 0)
332 GetNetXMSDirectory(nxDirData
, g_netxmsdDataDir
);
333 DbgPrintf(1, _T("Data directory set to %s"), g_netxmsdDataDir
);
337 DbgPrintf(1, _T("Using data directory %s"), g_netxmsdDataDir
);
340 g_icmpPingTimeout
= ConfigReadInt(_T("IcmpPingTimeout"), 1500);
341 g_icmpPingSize
= ConfigReadInt(_T("IcmpPingSize"), 46);
342 g_lockTimeout
= ConfigReadInt(_T("LockTimeout"), 60000);
343 g_agentCommandTimeout
= ConfigReadInt(_T("AgentCommandTimeout"), 4000);
344 g_thresholdRepeatInterval
= ConfigReadInt(_T("ThresholdRepeatInterval"), 0);
345 g_requiredPolls
= ConfigReadInt(_T("PollCountForStatusChange"), 1);
347 UINT32 snmpTimeout
= ConfigReadInt(_T("SNMPRequestTimeout"), 1500);
348 SnmpSetDefaultTimeout(snmpTimeout
);
352 * Initialize cryptografic functions
354 static BOOL
InitCryptografy()
356 #ifdef _WITH_ENCRYPTION
357 TCHAR szKeyFile
[MAX_PATH
];
358 BOOL bResult
= FALSE
;
361 BYTE
*pBufPos
, *pKeyBuffer
, hash
[SHA1_DIGEST_SIZE
];
363 if (!InitCryptoLib(ConfigReadULong(_T("AllowedCiphers"), 0x7F)))
365 nxlog_debug(4, _T("Supported ciphers: %s"), (const TCHAR
*)NXCPGetSupportedCiphersAsText());
368 SSL_load_error_strings();
370 _tcscpy(szKeyFile
, g_netxmsdDataDir
);
371 _tcscat(szKeyFile
, DFILE_KEYS
);
372 fd
= _topen(szKeyFile
, O_RDONLY
| O_BINARY
);
373 g_pServerKey
= LoadRSAKeys(szKeyFile
);
374 if (g_pServerKey
== NULL
)
376 nxlog_debug(1, _T("Generating RSA key pair..."));
377 g_pServerKey
= RSA_generate_key(NETXMS_RSA_KEYLEN
, 17, NULL
, 0);
378 if (g_pServerKey
!= NULL
)
380 fd
= _topen(szKeyFile
, O_WRONLY
| O_BINARY
| O_CREAT
| O_TRUNC
, 0600);
383 dwLen
= i2d_RSAPublicKey(g_pServerKey
, NULL
);
384 dwLen
+= i2d_RSAPrivateKey(g_pServerKey
, NULL
);
385 pKeyBuffer
= (BYTE
*)malloc(dwLen
);
387 pBufPos
= pKeyBuffer
;
388 i2d_RSAPublicKey(g_pServerKey
, &pBufPos
);
389 i2d_RSAPrivateKey(g_pServerKey
, &pBufPos
);
390 write(fd
, &dwLen
, sizeof(UINT32
));
391 write(fd
, pKeyBuffer
, dwLen
);
393 CalculateSHA1Hash(pKeyBuffer
, dwLen
, hash
);
394 write(fd
, hash
, SHA1_DIGEST_SIZE
);
402 nxlog_debug(0, _T("Failed to open %s for writing"), szKeyFile
);
407 nxlog_debug(0, _T("Failed to generate RSA key"));
415 iPolicy
= ConfigReadInt(_T("DefaultEncryptionPolicy"), 1);
416 if ((iPolicy
< 0) || (iPolicy
> 3))
418 SetAgentDEP(iPolicy
);
427 * Check if process with given PID exists and is a NetXMS server process
429 static BOOL
IsNetxmsdProcess(UINT32 dwPID
)
433 TCHAR szExtModule
[MAX_PATH
], szIntModule
[MAX_PATH
];
436 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, dwPID
);
437 if (hProcess
!= NULL
)
439 if ((GetModuleBaseName(hProcess
, NULL
, szExtModule
, MAX_PATH
) > 0) &&
440 (GetModuleBaseName(GetCurrentProcess(), NULL
, szIntModule
, MAX_PATH
) > 0))
442 bRet
= !_tcsicmp(szExtModule
, szIntModule
);
446 // Cannot read process name, for safety assume that it's a server process
449 CloseHandle(hProcess
);
453 return (kill((pid_t
)dwPID
, 0) != -1);
458 * Database event handler
460 static void DBEventHandler(DWORD dwEvent
, const WCHAR
*pszArg1
, const WCHAR
*pszArg2
, bool connLost
, void *userArg
)
462 if (!(g_flags
& AF_SERVER_INITIALIZED
))
463 return; // Don't try to do anything if server is not ready yet
467 case DBEVENT_CONNECTION_LOST
:
468 PostEvent(EVENT_DB_CONNECTION_LOST
, g_dwMgmtNode
, NULL
);
469 g_flags
|= AF_DB_CONNECTION_LOST
;
470 NotifyClientSessions(NX_NOTIFY_DBCONN_STATUS
, FALSE
);
472 case DBEVENT_CONNECTION_RESTORED
:
473 PostEvent(EVENT_DB_CONNECTION_RESTORED
, g_dwMgmtNode
, NULL
);
474 g_flags
&= ~AF_DB_CONNECTION_LOST
;
475 NotifyClientSessions(NX_NOTIFY_DBCONN_STATUS
, TRUE
);
477 case DBEVENT_QUERY_FAILED
:
478 PostEvent(EVENT_DB_QUERY_FAILED
, g_dwMgmtNode
, "uud", pszArg1
, pszArg2
, connLost
? 1 : 0);
486 * Send console message to session with open console
488 static void SendConsoleMessage(ClientSession
*session
, void *arg
)
490 if (session
->isConsoleOpen())
494 msg
.setCode(CMD_ADM_MESSAGE
);
495 msg
.setField(VID_MESSAGE
, (TCHAR
*)arg
);
496 session
->postMessage(&msg
);
503 static void LogConsoleWriter(const TCHAR
*format
, ...)
508 va_start(args
, format
);
509 _vsntprintf(buffer
, 8192, format
, args
);
513 WriteToTerminal(buffer
);
515 EnumerateClientSessions(SendConsoleMessage
, buffer
);
519 * Oracle session init callback
521 static void OracleSessionInitCallback(DB_HANDLE hdb
)
523 DBQuery(hdb
, _T("ALTER SESSION SET DDL_LOCK_TIMEOUT = 60"));
527 * Server initialization
529 BOOL NXCORE_EXPORTABLE
Initialize()
534 g_serverStartTime
= time(NULL
);
535 srand((unsigned int)g_serverStartTime
);
537 if (!(g_flags
& AF_USE_SYSLOG
))
539 if (!nxlog_set_rotation_policy((int)g_dwLogRotationMode
, (int)g_dwMaxLogSize
, (int)g_dwLogHistorySize
, g_szDailyLogFileSuffix
))
540 if (!(g_flags
& AF_DAEMON
))
541 _tprintf(_T("WARNING: cannot set log rotation policy; using default values\n"));
543 if (!nxlog_open((g_flags
& AF_USE_SYSLOG
) ? NETXMSD_SYSLOG_NAME
: g_szLogFile
,
544 ((g_flags
& AF_USE_SYSLOG
) ? NXLOG_USE_SYSLOG
: 0) |
545 ((g_flags
& AF_BACKGROUND_LOG_WRITER
) ? NXLOG_BACKGROUND_WRITER
: 0) |
546 ((g_flags
& AF_DAEMON
) ? 0 : NXLOG_PRINT_TO_STDOUT
),
551 g_dwNumMessages
, g_szMessages
, MSG_DEBUG
))
554 _ftprintf(stderr
, _T("FATAL ERROR: Cannot open log file\n"));
557 nxlog_set_console_writer(LogConsoleWriter
);
559 if (g_netxmsdLibDir
[0] == 0)
561 GetNetXMSDirectory(nxDirLib
, g_netxmsdLibDir
);
562 nxlog_debug(1, _T("LIB directory set to %s"), g_netxmsdLibDir
);
567 if (SetDefaultCodepage(g_szCodePage
))
569 DbgPrintf(1, _T("Code page set to %hs"), g_szCodePage
);
573 nxlog_write(MSG_CODEPAGE_ERROR
, EVENTLOG_WARNING_TYPE
, "m", g_szCodePage
);
577 // Set process affinity mask
578 if (g_processAffinityMask
!= DEFAULT_AFFINITY_MASK
)
581 if (SetProcessAffinityMask(GetCurrentProcess(), g_processAffinityMask
))
582 nxlog_debug(1, _T("Process affinity mask set to 0x%08X"), g_processAffinityMask
);
584 nxlog_write(MSG_SET_PROCESS_AFFINITY_NOT_SUPPORTED
, EVENTLOG_WARNING_TYPE
, NULL
);
590 int wrc
= WSAStartup(MAKEWORD(2, 2), &wsaData
);
593 nxlog_write(MSG_WSASTARTUP_FAILED
, EVENTLOG_ERROR_TYPE
, "e", wrc
);
599 SnmpSetMessageIds(MSG_OID_PARSE_ERROR
, MSG_SNMP_UNKNOWN_TYPE
, MSG_SNMP_GET_ERROR
);
601 // Create queue for delayed SQL queries
602 g_dbWriterQueue
= new Queue(256, 64);
603 g_dciDataWriterQueue
= new Queue(1024, 1024);
604 g_dciRawDataWriterQueue
= new Queue(1024, 1024);
606 // Initialize database driver and connect to database
607 if (!DBInit(MSG_OTHER
, (g_flags
& AF_LOG_SQL_ERRORS
) ? MSG_SQL_ERROR
: 0))
609 g_dbDriver
= DBLoadDriver(g_szDbDriver
, g_szDbDrvParams
, (nxlog_get_debug_level() >= 9), DBEventHandler
, NULL
);
610 if (g_dbDriver
== NULL
)
613 // Connect to database
614 DB_HANDLE hdbBootstrap
= NULL
;
615 TCHAR errorText
[DBDRV_MAX_ERROR_TEXT
];
618 hdbBootstrap
= DBConnect(g_dbDriver
, g_szDbServer
, g_szDbName
, g_szDbLogin
, g_szDbPassword
, g_szDbSchema
, errorText
);
619 if ((hdbBootstrap
!= NULL
) || (i
== 5))
623 if (hdbBootstrap
== NULL
)
625 nxlog_write(MSG_DB_CONNFAIL
, EVENTLOG_ERROR_TYPE
, "s", errorText
);
628 nxlog_debug(1, _T("Successfully connected to database %s@%s"), g_szDbName
, g_szDbServer
);
630 // Check database version
631 iDBVersion
= DBGetSchemaVersion(hdbBootstrap
);
632 if (iDBVersion
!= DB_FORMAT_VERSION
)
634 nxlog_write(MSG_WRONG_DB_VERSION
, EVENTLOG_ERROR_TYPE
, "dd", iDBVersion
, DB_FORMAT_VERSION
);
635 DBDisconnect(hdbBootstrap
);
639 // Read database syntax
640 g_dbSyntax
= DBGetSyntax(hdbBootstrap
);
641 if (g_dbSyntax
== DB_SYNTAX_ORACLE
)
643 DBSetSessionInitCallback(OracleSessionInitCallback
);
646 int baseSize
= ConfigReadIntEx(hdbBootstrap
, _T("DBConnectionPoolBaseSize"), 10);
647 int maxSize
= ConfigReadIntEx(hdbBootstrap
, _T("DBConnectionPoolMaxSize"), 30);
648 int cooldownTime
= ConfigReadIntEx(hdbBootstrap
, _T("DBConnectionPoolCooldownTime"), 300);
649 int ttl
= ConfigReadIntEx(hdbBootstrap
, _T("DBConnectionPoolMaxLifetime"), 14400);
651 DBDisconnect(hdbBootstrap
);
653 if (!DBConnectionPoolStartup(g_dbDriver
, g_szDbServer
, g_szDbName
, g_szDbLogin
, g_szDbPassword
, g_szDbSchema
, baseSize
, maxSize
, cooldownTime
, ttl
))
655 nxlog_write(MSG_DBCONNPOOL_INIT_FAILED
, EVENTLOG_ERROR_TYPE
, NULL
);
659 UINT32 lrt
= ConfigReadULong(_T("LongRunningQueryThreshold"), 0);
661 DBSetLongRunningThreshold(lrt
);
664 MetaDataReadStr(_T("ServerID"), szInfo
, 256, _T(""));
668 g_serverId
= _tcstoull(szInfo
, NULL
, 16);
673 g_serverId
= ((UINT64
)time(NULL
) << 31) | (UINT64
)((UINT32
)rand() & 0x7FFFFFFF);
674 _sntprintf(szInfo
, 256, UINT64X_FMT(_T("016")), g_serverId
);
675 MetaDataWriteStr(_T("ServerID"), szInfo
);
677 nxlog_debug(1, _T("Server ID ") UINT64X_FMT(_T("016")), g_serverId
);
682 if (!InitLocks(&addr
, szInfo
))
684 if (!addr
.isValid()) // Some SQL problems
686 nxlog_write(MSG_INIT_LOCKS_FAILED
, EVENTLOG_ERROR_TYPE
, NULL
);
688 else // Database already locked by another server instance
690 // Check for lock from crashed/terminated local process
691 if (GetLocalIpAddr().equals(addr
))
695 dwPID
= ConfigReadULong(_T("DBLockPID"), 0);
696 if (!IsNetxmsdProcess(dwPID
) || (dwPID
== GetCurrentProcessId()))
699 nxlog_write(MSG_DB_LOCK_REMOVED
, EVENTLOG_INFORMATION_TYPE
, NULL
);
703 nxlog_write(MSG_DB_LOCKED
, EVENTLOG_ERROR_TYPE
, "As", &addr
, szInfo
);
707 g_flags
|= AF_DB_LOCKED
;
709 // Load global configuration parameters
712 nxlog_debug(1, _T("Global configuration loaded"));
714 // Check data directory
718 // Initialize cryptografy
719 if (!InitCryptografy())
721 nxlog_write(MSG_INIT_CRYPTO_FAILED
, EVENTLOG_ERROR_TYPE
, NULL
);
725 // Initialize certificate store and CA
728 // Create synchronization stuff
729 m_condShutdown
= ConditionCreate(TRUE
);
731 // Create thread pools
732 nxlog_debug(2, _T("Creating thread pools"));
733 g_mainThreadPool
= ThreadPoolCreate(8, 256, _T("MAIN"));
734 g_agentConnectionThreadPool
= ThreadPoolCreate(4, 256, _T("AGENT"));
736 // Setup unique identifiers table
739 nxlog_debug(2, _T("ID table created"));
741 // Update status for unfinished jobs in job history
742 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
743 DBQuery(hdb
, _T("UPDATE job_history SET status=4,failure_message='Aborted due to server shutdown or crash' WHERE status NOT IN (3,4,5)"));
744 DBConnectionPoolReleaseConnection(hdb
);
746 // Load and compile scripts
749 // Initialize watchdog
753 if (!LoadNetXMSModules())
754 return FALSE
; // Mandatory module not loaded
756 // Initialize mailer and SMS sender
760 // Load users from database
764 nxlog_write(MSG_ERROR_LOADING_USERS
, EVENTLOG_ERROR_TYPE
, NULL
);
767 nxlog_debug(2, _T("User accounts loaded"));
772 // Initialize event handling subsystem
773 if (!InitEventSubsystem())
777 if (!InitAlarmManager())
780 // Initialize objects infrastructure and load objects from database
781 LoadNetworkDeviceDrivers();
785 nxlog_debug(1, _T("Objects loaded and initialized"));
787 // Initialize situations
788 if (!SituationsInit())
790 nxlog_debug(1, _T("Situations loaded and initialized"));
792 // Initialize and load event actions
795 nxlog_write(MSG_ACTION_INIT_ERROR
, EVENTLOG_ERROR_TYPE
, NULL
);
799 // Initialize helpdesk link
800 SetHDLinkEntryPoints(ResolveAlarmByHDRef
, TerminateAlarmByHDRef
);
803 // Initialize data collection subsystem
804 LoadPerfDataStorageDrivers();
805 if (!InitDataCollector())
809 FileUploadJob::init();
812 InitClientListeners();
813 if (ConfigReadInt(_T("ImportConfigurationOnStartup"), 1))
814 ImportLocalConfiguration();
816 // Check if management node object presented in database
818 if (g_dwMgmtNode
== 0)
820 nxlog_write(MSG_CANNOT_FIND_SELF
, EVENTLOG_ERROR_TYPE
, NULL
);
825 ThreadCreate(WatchdogThread
, 0, NULL
);
826 ThreadCreate(NodePoller
, 0, NULL
);
827 ThreadCreate(JobManagerThread
, 0, NULL
);
828 m_thSyncer
= ThreadCreateEx(Syncer
, 0, NULL
);
829 m_thPollManager
= ThreadCreateEx(PollManager
, 0, NULL
);
833 // Start event processor
834 ThreadCreate(EventProcessor
, 0, NULL
);
836 // Start SNMP trapper
838 if (ConfigReadInt(_T("EnableSNMPTraps"), 1))
839 ThreadCreate(SNMPTrapReceiver
, 0, NULL
);
841 // Start built-in syslog daemon
842 if (ConfigReadInt(_T("EnableSyslogDaemon"), 0))
845 // Start database _T("lazy") write thread
848 // Start local administartive interface listener if required
849 if (ConfigReadInt(_T("EnableAdminInterface"), 1))
850 ThreadCreate(LocalAdminListener
, 0, NULL
);
852 // Start beacon host poller
853 ThreadCreate(BeaconPoller
, 0, NULL
);
855 // Start inter-server communication listener
856 if (ConfigReadInt(_T("EnableISCListener"), 0))
857 ThreadCreate(ISCListener
, 0, NULL
);
859 // Start reporting server connector
860 if (ConfigReadInt(_T("EnableReportingServer"), 0))
861 ThreadCreate(ReportingServerConnector
, 0, NULL
);
863 //Start ldap synchronization
864 if (ConfigReadInt(_T("LdapSyncInterval"), 0))
865 ThreadCreate(SyncLDAPUsers
, 0, NULL
);
867 RegisterSchedulerTaskHandler(_T("Execute.Script"), ExecuteScheduledScript
, SYSTEM_ACCESS_SCHEDULE_SCRIPT
);
868 RegisterSchedulerTaskHandler(_T("Maintenance.Enter"), MaintenanceModeEnter
, SYSTEM_ACCESS_SCHEDULE_MAINTENANCE
);
869 RegisterSchedulerTaskHandler(_T("Maintenance.Leave"), MaintenanceModeLeave
, SYSTEM_ACCESS_SCHEDULE_MAINTENANCE
);
870 InitializeTaskScheduler();
872 // Allow clients to connect
873 ThreadCreate(ClientListener
, 0, NULL
);
875 ThreadCreate(ClientListenerIPv6
, 0, NULL
);
878 // Allow mobile devices to connect
879 InitMobileDeviceListeners();
880 ThreadCreate(MobileDeviceListener
, 0, NULL
);
882 ThreadCreate(MobileDeviceListenerIPv6
, 0, NULL
);
885 // Start uptime calculator for SLM
886 ThreadCreate(UptimeCalculator
, 0, NULL
);
888 nxlog_debug(2, _T("LIBDIR: %s"), g_netxmsdLibDir
);
890 // Call startup functions for the modules
891 CALL_ALL_MODULES(pfServerStarted
, ());
894 if (ConfigReadInt(_T("EnableXMPPConnector"), 1))
896 StartXMPPConnector();
904 g_flags
|= AF_SERVER_INITIALIZED
;
905 nxlog_debug(1, _T("Server initialization completed"));
912 void NXCORE_EXPORTABLE
Shutdown()
915 NotifyClientSessions(NX_NOTIFY_SHUTDOWN
, 0);
917 nxlog_write(MSG_SERVER_STOPPED
, EVENTLOG_INFORMATION_TYPE
, NULL
);
918 g_flags
|= AF_SHUTDOWN
; // Set shutdown flag
919 ConditionSet(m_condShutdown
);
921 CloseTaskScheduler();
923 // Stop DCI cache loading thread
924 g_dciCacheLoaderQueue
.setShutdownMode();
934 g_pEventQueue
->clear();
935 g_pEventQueue
->put(INVALID_POINTER_VALUE
);
940 ThreadSleep(1); // Give other threads a chance to terminate in a safe way
941 nxlog_debug(2, _T("All threads was notified, continue with shutdown"));
946 // Wait for critical threads
947 ThreadJoin(m_thPollManager
);
948 ThreadJoin(m_thSyncer
);
950 // Call shutdown functions for the modules
951 // CALL_ALL_MODULES cannot be used here because it checks for shutdown flag
952 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
954 if (g_pModuleList
[i
].pfShutdown
!= NULL
)
955 g_pModuleList
[i
].pfShutdown();
958 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
960 nxlog_debug(2, _T("All objects saved to database"));
962 nxlog_debug(2, _T("All users saved to database"));
963 DBConnectionPoolReleaseConnection(hdb
);
966 nxlog_debug(1, _T("Database writer stopped"));
970 // Remove database lock
973 DBConnectionPoolShutdown();
974 DBUnloadDriver(g_dbDriver
);
975 nxlog_debug(1, _T("Database driver unloaded"));
978 ShutdownEventSubsystem();
979 ShutdownAlarmManager();
980 nxlog_debug(1, _T("Event processing stopped"));
982 ThreadPoolDestroy(g_agentConnectionThreadPool
);
983 ThreadPoolDestroy(g_mainThreadPool
);
984 MsgWaitQueue::shutdown();
986 delete g_pScriptLibrary
;
988 nxlog_debug(1, _T("Server shutdown complete"));
993 _tremove(g_szPIDFile
);
998 if (!(g_flags
& AF_DAEMON
))
1006 * Fast server shutdown - normally called only by Windows service on system shutdown
1008 void NXCORE_EXPORTABLE
FastShutdown()
1010 DbgPrintf(1, _T("Using fast shutdown procedure"));
1012 g_flags
|= AF_SHUTDOWN
; // Set shutdown flag
1013 ConditionSet(m_condShutdown
);
1015 DB_HANDLE hdb
= DBConnectionPoolAcquireConnection();
1017 DbgPrintf(2, _T("All objects saved to database"));
1019 DbgPrintf(2, _T("All users saved to database"));
1020 DBConnectionPoolReleaseConnection(hdb
);
1022 // Remove database lock first, because we have a chance to lose DB connection
1025 // Stop database writers
1027 DbgPrintf(1, _T("Database writer stopped"));
1029 DbgPrintf(1, _T("Server shutdown complete"));
1034 * Compare given string to command template with abbreviation possibility
1036 static bool IsCommand(const TCHAR
*cmdTemplate
, TCHAR
*pszString
, int iMinChars
)
1040 // Convert given string to uppercase
1043 for(i
= 0; pszString
[i
] != 0; i
++)
1044 if (pszString
[i
] != cmdTemplate
[i
])
1052 * Dump index callback (by IP address)
1054 static void DumpIndexCallbackByInetAddr(const InetAddress
& addr
, NetObj
*object
, void *data
)
1057 ConsolePrintf((CONSOLE_CTX
)data
, _T("%-40s %p %s [%d]\n"), addr
.toString(buffer
), object
, object
->getName(), (int)object
->getId());
1061 * Dump index (by IP address)
1063 static void DumpIndex(CONSOLE_CTX pCtx
, InetAddressIndex
*index
)
1065 index
->forEach(DumpIndexCallbackByInetAddr
, pCtx
);
1069 * Dump index callback (by ID)
1071 static void DumpIndexCallbackById(NetObj
*object
, void *data
)
1073 ConsolePrintf((CONSOLE_CTX
)data
, _T("%08X %p %s\n"), object
->getId(), object
, object
->getName());
1077 * Dump index (by ID)
1079 static void DumpIndex(CONSOLE_CTX pCtx
, ObjectIndex
*index
)
1081 index
->forEach(DumpIndexCallbackById
, pCtx
);
1085 * Process command entered from command line in standalone mode
1086 * Return TRUE if command was _T("down")
1088 int ProcessConsoleCommand(const TCHAR
*pszCmdLine
, CONSOLE_CTX pCtx
)
1091 TCHAR szBuffer
[256], *eptr
;
1092 int nExitCode
= CMD_EXIT_CONTINUE
;
1095 pArg
= ExtractWord(pszCmdLine
, szBuffer
);
1097 if (IsCommand(_T("AT"), szBuffer
, 2))
1099 pArg
= ExtractWord(pArg
, szBuffer
);
1100 if (szBuffer
[0] == _T('+'))
1102 int offset
= _tcstoul(&szBuffer
[1], NULL
, 0);
1103 AddOneTimeScheduledTask(_T("Execute.Script"), time(NULL
) + offset
, pArg
, 0, 0, SYSTEM_ACCESS_FULL
);//TODO: change to correct user
1107 AddScheduledTask(_T("Execute.Script"), szBuffer
, pArg
, 0, 0, SYSTEM_ACCESS_FULL
); //TODO: change to correct user
1110 if (IsCommand(_T("DEBUG"), szBuffer
, 2))
1113 pArg
= ExtractWord(pArg
, szBuffer
);
1114 int level
= (int)_tcstol(szBuffer
, &eptr
, 0);
1115 if ((*eptr
== 0) && (level
>= 0) && (level
<= 9))
1117 nxlog_set_debug_level(level
);
1118 ConsolePrintf(pCtx
, (level
== 0) ? _T("Debug mode turned off\n") : _T("Debug level set to %d\n"), level
);
1120 else if (IsCommand(_T("OFF"), szBuffer
, 2))
1122 nxlog_set_debug_level(0);
1123 ConsoleWrite(pCtx
, _T("Debug mode turned off\n"));
1127 if (szBuffer
[0] == 0)
1128 ConsoleWrite(pCtx
, _T("ERROR: Missing argument\n\n"));
1130 ConsoleWrite(pCtx
, _T("ERROR: Invalid debug level\n\n"));
1133 else if (IsCommand(_T("DOWN"), szBuffer
, 4))
1135 ConsoleWrite(pCtx
, _T("Proceeding with server shutdown...\n"));
1136 nExitCode
= CMD_EXIT_SHUTDOWN
;
1138 else if (IsCommand(_T("DUMP"), szBuffer
, 4))
1142 else if (IsCommand(_T("GET"), szBuffer
, 3))
1144 pArg
= ExtractWord(pArg
, szBuffer
);
1145 if (szBuffer
[0] != 0)
1147 TCHAR value
[MAX_CONFIG_VALUE
];
1148 ConfigReadStr(szBuffer
, value
, MAX_CONFIG_VALUE
, _T(""));
1149 ConsolePrintf(pCtx
, _T("%s = %s\n"), szBuffer
, value
);
1153 ConsoleWrite(pCtx
, _T("Variable name missing\n"));
1156 else if (IsCommand(_T("HKRUN"), szBuffer
, 2))
1158 ConsoleWrite(pCtx
, _T("Starting housekeeper\n"));
1161 else if (IsCommand(_T("LDAPSYNC"), szBuffer
, 4))
1163 LDAPConnection conn
;
1166 else if (IsCommand(_T("LOG"), szBuffer
, 3))
1168 while(_istspace(*pArg
))
1171 DbgPrintf(0, _T("%s"), pArg
);
1173 else if (IsCommand(_T("LOGMARK"), szBuffer
, 4))
1175 DbgPrintf(0, _T("******* MARK *******"));
1177 else if (IsCommand(_T("RAISE"), szBuffer
, 5))
1180 pArg
= ExtractWord(pArg
, szBuffer
);
1182 if (IsCommand(_T("ACCESS"), szBuffer
, 6))
1184 ConsoleWrite(pCtx
, _T("Raising exception...\n"));
1188 else if (IsCommand(_T("BREAKPOINT"), szBuffer
, 5))
1191 ConsoleWrite(pCtx
, _T("Raising exception...\n"));
1192 RaiseException(EXCEPTION_BREAKPOINT
, 0, 0, NULL
);
1194 ConsoleWrite(pCtx
, _T("ERROR: Not supported on current platform\n"));
1199 ConsoleWrite(pCtx
, _T("Invalid exception name; possible names are:\nACCESS BREAKPOINT\n"));
1202 else if (IsCommand(_T("EXIT"), szBuffer
, 4))
1204 if ((pCtx
->hSocket
!= -1) || (pCtx
->session
!= NULL
))
1206 ConsoleWrite(pCtx
, _T("Closing session...\n"));
1207 nExitCode
= CMD_EXIT_CLOSE_SESSION
;
1211 ConsoleWrite(pCtx
, _T("Cannot exit from local server console\n"));
1214 else if (IsCommand(_T("KILL"), szBuffer
, 4))
1216 pArg
= ExtractWord(pArg
, szBuffer
);
1217 if (szBuffer
[0] != 0)
1219 int id
= _tcstol(szBuffer
, &eptr
, 10);
1222 if (KillClientSession(id
))
1224 ConsoleWrite(pCtx
, _T("Session killed\n"));
1228 ConsoleWrite(pCtx
, _T("Invalid session ID\n"));
1233 ConsoleWrite(pCtx
, _T("Invalid session ID\n"));
1238 ConsoleWrite(pCtx
, _T("Session ID missing\n"));
1241 else if (IsCommand(_T("PING"), szBuffer
, 4))
1243 pArg
= ExtractWord(pArg
, szBuffer
);
1244 if (szBuffer
[0] != 0)
1246 InetAddress addr
= InetAddress::parse(szBuffer
);
1250 UINT32 rc
= IcmpPing(addr
, 1, 2000, &rtt
, 128);
1254 ConsolePrintf(pCtx
, _T("Success, RTT = %d ms\n"), (int)rtt
);
1256 case ICMP_UNREACHEABLE
:
1257 ConsolePrintf(pCtx
, _T("Destination unreachable\n"));
1260 ConsolePrintf(pCtx
, _T("Request timeout\n"));
1262 case ICMP_RAW_SOCK_FAILED
:
1263 ConsolePrintf(pCtx
, _T("Cannot create raw socket\n"));
1265 case ICMP_API_ERROR
:
1266 ConsolePrintf(pCtx
, _T("API error\n"));
1269 ConsolePrintf(pCtx
, _T("ERROR %d\n"), (int)rc
);
1275 ConsoleWrite(pCtx
, _T("Invalid IP address\n"));
1280 ConsoleWrite(pCtx
, _T("Usage: PING <address>\n"));
1283 else if (IsCommand(_T("POLL"), szBuffer
, 2))
1285 pArg
= ExtractWord(pArg
, szBuffer
);
1286 if (szBuffer
[0] != 0)
1289 if (IsCommand(_T("CONFIGURATION"), szBuffer
, 1))
1293 else if (IsCommand(_T("STATUS"), szBuffer
, 1))
1297 else if (IsCommand(_T("TOPOLOGY"), szBuffer
, 1))
1308 pArg
= ExtractWord(pArg
, szBuffer
);
1309 UINT32 id
= _tcstoul(szBuffer
, NULL
, 0);
1312 Node
*node
= (Node
*)FindObjectById(id
, OBJECT_NODE
);
1318 node
->lockForConfigurationPoll();
1319 ThreadPoolExecute(g_pollerThreadPool
, node
, &Node::configurationPoll
, RegisterPoller(POLLER_TYPE_CONFIGURATION
, node
));
1322 node
->lockForStatusPoll();
1323 ThreadPoolExecute(g_pollerThreadPool
, node
, &Node::statusPoll
, RegisterPoller(POLLER_TYPE_STATUS
, node
));
1326 node
->lockForTopologyPoll();
1327 ThreadPoolExecute(g_pollerThreadPool
, node
, &Node::topologyPoll
, RegisterPoller(POLLER_TYPE_TOPOLOGY
, node
));
1333 ConsolePrintf(pCtx
, _T("ERROR: Node with ID %d does not exist\n\n"), id
);
1338 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
1343 ConsoleWrite(pCtx
, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY] <node>\n"));
1348 ConsoleWrite(pCtx
, _T("Usage POLL [CONFIGURATION|STATUS|TOPOLOGY] <node>\n"));
1351 else if (IsCommand(_T("SET"), szBuffer
, 3))
1353 pArg
= ExtractWord(pArg
, szBuffer
);
1354 if (szBuffer
[0] != 0)
1357 pArg
= ExtractWord(pArg
, value
);
1358 if (ConfigWriteStr(szBuffer
, value
, TRUE
, TRUE
, TRUE
))
1360 ConsolePrintf(pCtx
, _T("Configuration variable %s updated\n"), szBuffer
);
1364 ConsolePrintf(pCtx
, _T("ERROR: cannot update configuration variable %s\n"), szBuffer
);
1369 ConsolePrintf(pCtx
, _T("Variable name missing\n"));
1372 else if (IsCommand(_T("SHOW"), szBuffer
, 2))
1375 pArg
= ExtractWord(pArg
, szBuffer
);
1377 if (IsCommand(_T("COMPONENTS"), szBuffer
, 1))
1380 pArg
= ExtractWord(pArg
, szBuffer
);
1381 UINT32 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
1384 NetObj
*pObject
= FindObjectById(dwNode
);
1385 if (pObject
!= NULL
)
1387 if (pObject
->getObjectClass() == OBJECT_NODE
)
1389 ComponentTree
*components
= ((Node
*)pObject
)->getComponents();
1390 if (components
!= NULL
)
1392 components
->print(pCtx
);
1393 components
->decRefCount();
1397 ConsoleWrite(pCtx
, _T("ERROR: Node does not have physical component information\n\n"));
1402 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
1407 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
1412 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
1415 else if (IsCommand(_T("DBCP"), szBuffer
, 4))
1417 ObjectArray
<PoolConnectionInfo
> *list
= DBConnectionPoolGetConnectionList();
1418 for(int i
= 0; i
< list
->size(); i
++)
1420 PoolConnectionInfo
*c
= list
->get(i
);
1421 TCHAR accessTime
[64];
1422 struct tm
*ltm
= localtime(&c
->lastAccessTime
);
1423 _tcsftime(accessTime
, 64, _T("%d.%b.%Y %H:%M:%S"), ltm
);
1424 ConsolePrintf(pCtx
, _T("%p %s %hs:%d\n"), c
->handle
, accessTime
, c
->srcFile
, c
->srcLine
);
1426 ConsolePrintf(pCtx
, _T("%d database connections in use\n\n"), list
->size());
1429 else if (IsCommand(_T("DBSTATS"), szBuffer
, 3))
1431 LIBNXDB_PERF_COUNTERS counters
;
1432 DBGetPerfCounters(&counters
);
1433 ConsolePrintf(pCtx
, _T("SQL query counters:\n"));
1434 ConsolePrintf(pCtx
, _T(" Total .......... ") INT64_FMT
_T("\n"), counters
.totalQueries
);
1435 ConsolePrintf(pCtx
, _T(" SELECT ......... ") INT64_FMT
_T("\n"), counters
.selectQueries
);
1436 ConsolePrintf(pCtx
, _T(" Non-SELECT ..... ") INT64_FMT
_T("\n"), counters
.nonSelectQueries
);
1437 ConsolePrintf(pCtx
, _T(" Long running ... ") INT64_FMT
_T("\n"), counters
.longRunningQueries
);
1438 ConsolePrintf(pCtx
, _T(" Failed ......... ") INT64_FMT
_T("\n"), counters
.failedQueries
);
1440 ConsolePrintf(pCtx
, _T("Background writer requests:\n"));
1441 ConsolePrintf(pCtx
, _T(" DCI data ....... ") INT64_FMT
_T("\n"), g_idataWriteRequests
);
1442 ConsolePrintf(pCtx
, _T(" DCI raw data ... ") INT64_FMT
_T("\n"), g_rawDataWriteRequests
);
1443 ConsolePrintf(pCtx
, _T(" Others ......... ") INT64_FMT
_T("\n"), g_otherWriteRequests
);
1445 else if (IsCommand(_T("FDB"), szBuffer
, 3))
1448 pArg
= ExtractWord(pArg
, szBuffer
);
1449 UINT32 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
1452 NetObj
*pObject
= FindObjectById(dwNode
);
1453 if (pObject
!= NULL
)
1455 if (pObject
->getObjectClass() == OBJECT_NODE
)
1457 ForwardingDatabase
*fdb
= ((Node
*)pObject
)->getSwitchForwardingDatabase();
1460 fdb
->print(pCtx
, (Node
*)pObject
);
1465 ConsoleWrite(pCtx
, _T("ERROR: Node does not have forwarding database information\n\n"));
1470 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
1475 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
1480 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
1483 else if (IsCommand(_T("FLAGS"), szBuffer
, 1))
1485 ConsolePrintf(pCtx
, _T("Flags: 0x") UINT64X_FMT(_T("016")) _T("\n"), g_flags
);
1486 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_DAEMON
));
1487 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_USE_SYSLOG
));
1488 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ENABLE_NETWORK_DISCOVERY
));
1489 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ACTIVE_NETWORK_DISCOVERY
));
1490 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_LOG_SQL_ERRORS
));
1491 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_DELETE_EMPTY_SUBNETS
));
1492 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ENABLE_SNMP_TRAPD
));
1493 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ENABLE_ZONING
));
1494 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_SYNC_NODE_NAMES_WITH_DNS
));
1495 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_CHECK_TRUSTED_NODES
));
1496 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ENABLE_NXSL_CONTAINER_FUNCS
));
1497 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_USE_FQDN_FOR_NODE_NAMES
));
1498 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_APPLY_TO_DISABLED_DCI_FROM_TEMPLATE
));
1499 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_DEBUG_CONSOLE_DISABLED
));
1500 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_ENABLE_OBJECT_TRANSACTIONS
));
1501 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_WRITE_FULL_DUMP
));
1502 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_RESOLVE_NODE_NAMES
));
1503 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_CATCH_EXCEPTIONS
));
1504 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_HELPDESK_LINK_ACTIVE
));
1505 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_DB_LOCKED
));
1506 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_DB_CONNECTION_LOST
));
1507 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_NO_NETWORK_CONNECTIVITY
));
1508 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_EVENT_STORM_DETECTED
));
1509 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_SNMP_TRAP_DISCOVERY
));
1510 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_TRAPS_FROM_UNMANAGED_NODES
));
1511 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_RESOLVE_IP_FOR_EACH_STATUS_POLL
));
1512 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_PERFDATA_STORAGE_DRIVER_LOADED
));
1513 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_BACKGROUND_LOG_WRITER
));
1514 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_CASE_INSENSITIVE_LOGINS
));
1515 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_TRAP_SOURCES_IN_ALL_ZONES
));
1516 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_SERVER_INITIALIZED
));
1517 ConsolePrintf(pCtx
, SHOW_FLAG_VALUE(AF_SHUTDOWN
));
1518 ConsolePrintf(pCtx
, _T("\n"));
1520 else if (IsCommand(_T("HEAP"), szBuffer
, 1))
1522 TCHAR
*text
= GetHeapInfo();
1525 ConsoleWrite(pCtx
, text
);
1526 ConsoleWrite(pCtx
, _T("\n"));
1531 ConsoleWrite(pCtx
, _T("Error reading heap information\n"));
1534 else if (IsCommand(_T("INDEX"), szBuffer
, 1))
1537 pArg
= ExtractWord(pArg
, szBuffer
);
1539 if (IsCommand(_T("CONDITION"), szBuffer
, 1))
1541 DumpIndex(pCtx
, &g_idxConditionById
);
1543 else if (IsCommand(_T("ID"), szBuffer
, 2))
1545 DumpIndex(pCtx
, &g_idxObjectById
);
1547 else if (IsCommand(_T("INTERFACE"), szBuffer
, 2))
1549 DumpIndex(pCtx
, &g_idxInterfaceByAddr
);
1551 else if (IsCommand(_T("NODEADDR"), szBuffer
, 5))
1553 DumpIndex(pCtx
, &g_idxNodeByAddr
);
1555 else if (IsCommand(_T("NODEID"), szBuffer
, 5))
1557 DumpIndex(pCtx
, &g_idxNodeById
);
1559 else if (IsCommand(_T("SUBNET"), szBuffer
, 1))
1561 DumpIndex(pCtx
, &g_idxSubnetByAddr
);
1563 else if (IsCommand(_T("ZONE"), szBuffer
, 1))
1565 DumpIndex(pCtx
, &g_idxZoneByGUID
);
1569 if (szBuffer
[0] == 0)
1570 ConsoleWrite(pCtx
, _T("ERROR: Missing index name\n")
1571 _T("Valid names are: CONDITION, ID, INTERFACE, NODEADDR, NODEID, SUBNET, ZONE\n\n"));
1573 ConsoleWrite(pCtx
, _T("ERROR: Invalid index name\n\n"));
1576 else if (IsCommand(_T("MODULES"), szBuffer
, 3))
1578 ConsoleWrite(pCtx
, _T("Loaded server modules:\n"));
1579 for(UINT32 i
= 0; i
< g_dwNumModules
; i
++)
1581 ConsolePrintf(pCtx
, _T(" %s\n"), g_pModuleList
[i
].szName
);
1583 ConsolePrintf(pCtx
, _T("%d modules loaded\n"), g_dwNumModules
);
1585 else if (IsCommand(_T("MSGWQ"), szBuffer
, 2))
1587 String text
= MsgWaitQueue::getDiagInfo();
1588 ConsoleWrite(pCtx
, text
);
1589 ConsoleWrite(pCtx
, _T("\n"));
1591 else if (IsCommand(_T("OBJECTS"), szBuffer
, 1))
1594 pArg
= ExtractWord(pArg
, szBuffer
);
1596 DumpObjects(pCtx
, (szBuffer
[0] != 0) ? szBuffer
: NULL
);
1598 else if (IsCommand(_T("POLLERS"), szBuffer
, 1))
1602 else if (IsCommand(_T("QUEUES"), szBuffer
, 1))
1604 ShowQueueStats(pCtx
, &g_dataCollectionQueue
, _T("Data collector"));
1605 ShowQueueStats(pCtx
, &g_dciCacheLoaderQueue
, _T("DCI cache loader"));
1606 ShowQueueStats(pCtx
, g_dbWriterQueue
, _T("Database writer"));
1607 ShowQueueStats(pCtx
, g_dciDataWriterQueue
, _T("Database writer (IData)"));
1608 ShowQueueStats(pCtx
, g_dciRawDataWriterQueue
, _T("Database writer (raw DCI values)"));
1609 ShowQueueStats(pCtx
, g_pEventQueue
, _T("Event processor"));
1610 ShowQueueStats(pCtx
, &g_nodePollerQueue
, _T("Node poller"));
1611 ShowQueueStats(pCtx
, &g_syslogProcessingQueue
, _T("Syslog processing"));
1612 ShowQueueStats(pCtx
, &g_syslogWriteQueue
, _T("Syslog writer"));
1613 ConsolePrintf(pCtx
, _T("\n"));
1615 else if (IsCommand(_T("ROUTING-TABLE"), szBuffer
, 1))
1620 pArg
= ExtractWord(pArg
, szBuffer
);
1621 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
1624 pObject
= FindObjectById(dwNode
);
1625 if (pObject
!= NULL
)
1627 if (pObject
->getObjectClass() == OBJECT_NODE
)
1633 ConsolePrintf(pCtx
, _T("Routing table for node %s:\n\n"), pObject
->getName());
1634 pRT
= ((Node
*)pObject
)->getCachedRoutingTable();
1637 for(i
= 0; i
< pRT
->iNumEntries
; i
++)
1639 _sntprintf(szBuffer
, 256, _T("%s/%d"), IpToStr(pRT
->pRoutes
[i
].dwDestAddr
, szIpAddr
),
1640 BitsInMask(pRT
->pRoutes
[i
].dwDestMask
));
1641 ConsolePrintf(pCtx
, _T("%-18s %-15s %-6d %d\n"), szBuffer
,
1642 IpToStr(pRT
->pRoutes
[i
].dwNextHop
, szIpAddr
),
1643 pRT
->pRoutes
[i
].dwIfIndex
, pRT
->pRoutes
[i
].dwRouteType
);
1645 ConsoleWrite(pCtx
, _T("\n"));
1649 ConsoleWrite(pCtx
, _T("Node doesn't have cached routing table\n\n"));
1654 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
1659 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode
);
1664 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
1667 else if (IsCommand(_T("SESSIONS"), szBuffer
, 2))
1669 ConsoleWrite(pCtx
, _T("\x1b[1mCLIENT SESSIONS\x1b[0m\n============================================================\n"));
1670 DumpClientSessions(pCtx
);
1671 ConsoleWrite(pCtx
, _T("\n\x1b[1mMOBILE DEVICE SESSIONS\x1b[0m\n============================================================\n"));
1672 DumpMobileDeviceSessions(pCtx
);
1674 else if (IsCommand(_T("STATS"), szBuffer
, 2))
1676 ShowServerStats(pCtx
);
1678 else if (IsCommand(_T("THREADS"), szBuffer
, 2))
1680 ShowThreadPool(pCtx
, g_mainThreadPool
);
1681 ShowThreadPool(pCtx
, g_pollerThreadPool
);
1682 ShowThreadPool(pCtx
, g_schedulerThreadPool
);
1683 ShowThreadPool(pCtx
, g_agentConnectionThreadPool
);
1685 else if (IsCommand(_T("TOPOLOGY"), szBuffer
, 1))
1687 pArg
= ExtractWord(pArg
, szBuffer
);
1688 UINT32 nodeId
= _tcstoul(szBuffer
, NULL
, 0);
1691 Node
*node
= (Node
*)FindObjectById(nodeId
, OBJECT_NODE
);
1694 LinkLayerNeighbors
*nbs
= BuildLinkLayerNeighborList(node
);
1697 ConsolePrintf(pCtx
, _T("Proto | PtP | ifLocal | ifRemote | Peer\n")
1698 _T("--------+-----+---------+----------+------------------------------------\n"));
1699 for(int i
= 0; i
< nbs
->size(); i
++)
1701 LL_NEIGHBOR_INFO
*ni
= nbs
->getConnection(i
);
1703 if (ni
->objectId
!= 0)
1705 NetObj
*object
= FindObjectById(ni
->objectId
);
1707 _sntprintf(peer
, 256, _T("%s [%d]"), object
->getName(), ni
->objectId
);
1709 _sntprintf(peer
, 256, _T("[%d]"), ni
->objectId
);
1715 ConsolePrintf(pCtx
, _T("%-7s | %c | %7d | %7d | %s\n"),
1716 GetLinkLayerProtocolName(ni
->protocol
), ni
->isPtToPt
? _T('Y') : _T('N'), ni
->ifLocal
, ni
->ifRemote
, peer
);
1722 ConsoleWrite(pCtx
, _T("ERROR: call to BuildLinkLayerNeighborList failed\n\n"));
1727 ConsolePrintf(pCtx
, _T("ERROR: Node with ID %d does not exist\n\n"), nodeId
);
1732 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node ID\n\n"));
1735 else if (IsCommand(_T("USERS"), szBuffer
, 1))
1739 else if (IsCommand(_T("VLANS"), szBuffer
, 1))
1744 pArg
= ExtractWord(pArg
, szBuffer
);
1745 dwNode
= _tcstoul(szBuffer
, NULL
, 0);
1748 pObject
= FindObjectById(dwNode
);
1749 if (pObject
!= NULL
)
1751 if (pObject
->getObjectClass() == OBJECT_NODE
)
1753 VlanList
*vlans
= ((Node
*)pObject
)->getVlans();
1756 ConsoleWrite(pCtx
, _T("\x1b[1mVLAN\x1b[0m | \x1b[1mName\x1b[0m | \x1b[1mPorts\x1b[0m\n")
1757 _T("-----+------------------+-----------------------------------------------------------------\n"));
1758 for(int i
= 0; i
< vlans
->size(); i
++)
1760 VlanInfo
*vlan
= vlans
->get(i
);
1761 ConsolePrintf(pCtx
, _T("%4d | %-16s |"), vlan
->getVlanId(), vlan
->getName());
1762 for(int j
= 0; j
< vlan
->getNumPorts(); j
++)
1763 ConsolePrintf(pCtx
, _T(" %d.%d"), (int)(vlan
->getPorts()[j
] >> 16), (int)(vlan
->getPorts()[j
] & 0xFFFF));
1764 ConsolePrintf(pCtx
, _T("\n"));
1766 ConsolePrintf(pCtx
, _T("\n"));
1767 vlans
->decRefCount();
1771 ConsoleWrite(pCtx
, _T("\x1b[31mNode doesn't have VLAN information\x1b[0m\n\n"));
1776 ConsoleWrite(pCtx
, _T("\x1b[31mERROR: Object is not a node\x1b[0m\n\n"));
1781 ConsolePrintf(pCtx
, _T("\x1b[31mERROR: Object with ID %d does not exist\x1b[0m\n\n"), dwNode
);
1786 ConsoleWrite(pCtx
, _T("\x1b[31mERROR: Invalid or missing node ID\x1b[0m\n\n"));
1789 else if (IsCommand(_T("WATCHDOG"), szBuffer
, 1))
1791 WatchdogPrintStatus(pCtx
);
1792 ConsoleWrite(pCtx
, _T("\n"));
1796 if (szBuffer
[0] == 0)
1797 ConsoleWrite(pCtx
, _T("ERROR: Missing subcommand\n\n"));
1799 ConsoleWrite(pCtx
, _T("ERROR: Invalid SHOW subcommand\n\n"));
1802 else if (IsCommand(_T("EXEC"), szBuffer
, 3))
1804 pArg
= ExtractWord(pArg
, szBuffer
);
1806 bool libraryLocked
= true;
1807 bool destroyCompiledScript
= false;
1808 g_pScriptLibrary
->lock();
1810 NXSL_Program
*compiledScript
= g_pScriptLibrary
->findScript(szBuffer
);
1811 if (compiledScript
== NULL
)
1813 g_pScriptLibrary
->unlock();
1814 libraryLocked
= false;
1815 destroyCompiledScript
= true;
1818 if ((script
= (char *)LoadFile(szBuffer
, &fileSize
)) != NULL
)
1820 const int errorMsgLen
= 512;
1821 TCHAR errorMsg
[errorMsgLen
];
1823 WCHAR
*wscript
= WideStringFromMBString(script
);
1824 compiledScript
= NXSLCompile(wscript
, errorMsg
, errorMsgLen
, NULL
);
1827 compiledScript
= NXSLCompile(script
, errorMsg
, errorMsgLen
, NULL
);
1830 if (compiledScript
== NULL
)
1832 ConsolePrintf(pCtx
, _T("ERROR: Script compilation error: %s\n\n"), errorMsg
);
1837 ConsolePrintf(pCtx
, _T("ERROR: Script \"%s\" not found\n\n"), szBuffer
);
1841 if (compiledScript
!= NULL
)
1843 NXSL_ServerEnv
*pEnv
= new NXSL_ServerEnv
;
1844 pEnv
->setConsole(pCtx
);
1846 NXSL_VM
*vm
= new NXSL_VM(pEnv
);
1847 if (vm
->load(compiledScript
))
1851 g_pScriptLibrary
->unlock();
1852 libraryLocked
= false;
1855 NXSL_Value
*argv
[32];
1859 pArg
= ExtractWord(pArg
, szBuffer
);
1860 if (szBuffer
[0] == 0)
1862 argv
[argc
++] = new NXSL_Value(szBuffer
);
1865 if (vm
->run(argc
, argv
))
1867 NXSL_Value
*pValue
= vm
->getResult();
1868 int retCode
= pValue
->getValueAsInt32();
1869 ConsolePrintf(pCtx
, _T("INFO: Script finished with rc=%d\n\n"), retCode
);
1873 ConsolePrintf(pCtx
, _T("ERROR: Script finished with error: %s\n\n"), vm
->getErrorText());
1878 ConsolePrintf(pCtx
, _T("ERROR: VM creation failed: %s\n\n"), vm
->getErrorText());
1881 if (destroyCompiledScript
)
1882 delete compiledScript
;
1885 g_pScriptLibrary
->unlock();
1887 else if (IsCommand(_T("TRACE"), szBuffer
, 1))
1889 UINT32 dwNode1
, dwNode2
;
1890 NetObj
*pObject1
, *pObject2
;
1891 NetworkPath
*pTrace
;
1892 TCHAR szNextHop
[16];
1896 pArg
= ExtractWord(pArg
, szBuffer
);
1897 dwNode1
= _tcstoul(szBuffer
, NULL
, 0);
1899 pArg
= ExtractWord(pArg
, szBuffer
);
1900 dwNode2
= _tcstoul(szBuffer
, NULL
, 0);
1902 if ((dwNode1
!= 0) && (dwNode2
!= 0))
1904 pObject1
= FindObjectById(dwNode1
);
1905 if (pObject1
== NULL
)
1907 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode1
);
1911 pObject2
= FindObjectById(dwNode2
);
1912 if (pObject2
== NULL
)
1914 ConsolePrintf(pCtx
, _T("ERROR: Object with ID %d does not exist\n\n"), dwNode2
);
1918 if ((pObject1
->getObjectClass() == OBJECT_NODE
) && (pObject2
->getObjectClass() == OBJECT_NODE
))
1920 pTrace
= TraceRoute((Node
*)pObject1
, (Node
*)pObject2
);
1924 ConsolePrintf(pCtx
, _T("Trace from %s to %s (%d hops, %s, source IP %s):\n"),
1925 pObject1
->getName(), pObject2
->getName(), pTrace
->getHopCount(),
1926 pTrace
->isComplete() ? _T("complete") : _T("incomplete"),
1927 pTrace
->getSourceAddress().toString(sourceIp
));
1928 for(i
= 0; i
< pTrace
->getHopCount(); i
++)
1930 HOP_INFO
*hop
= pTrace
->getHopInfo(i
);
1931 ConsolePrintf(pCtx
, _T("[%d] %s %s %s %d\n"),
1932 hop
->object
->getId(),
1933 hop
->object
->getName(),
1934 hop
->nextHop
.toString(szNextHop
),
1935 hop
->isVpn
? _T("VPN Connector ID:") : _T("Interface Index: "),
1939 ConsolePrintf(pCtx
, _T("\n"));
1943 ConsoleWrite(pCtx
, _T("ERROR: Call to TraceRoute() failed\n\n"));
1948 ConsoleWrite(pCtx
, _T("ERROR: Object is not a node\n\n"));
1955 ConsoleWrite(pCtx
, _T("ERROR: Invalid or missing node id(s)\n\n"));
1958 else if (IsCommand(_T("HELP"), szBuffer
, 2) || IsCommand(_T("?"), szBuffer
, 1))
1961 _T("Valid commands are:\n")
1962 _T(" at +<seconds>|<schedule> <script> [<parameters>]\n")
1963 _T(" - Schedule script execution task\n")
1964 _T(" debug [<level>|off] - Set debug level (valid range is 0..9)\n")
1965 _T(" down - Shutdown NetXMS server\n")
1966 _T(" exec <script> [<params>] - Executes NXSL script from script library\n")
1967 _T(" exit - Exit from remote session\n")
1968 _T(" kill <session> - Kill client session\n")
1969 _T(" get <variable> - Get value of server configuration variable\n")
1970 _T(" help - Display this help\n")
1971 _T(" hkrun - Run housekeeper immediately\n")
1972 _T(" ldapsync - Synchronize ldap users with local user database\n")
1973 _T(" log <text> - Write given text to server log file\n")
1974 _T(" logmark - Write marker ******* MARK ******* to server log file\n")
1975 _T(" ping <address> - Send ICMP echo request to given IP address\n")
1976 _T(" poll <type> <node> - Initiate node poll\n")
1977 _T(" raise <exception> - Raise exception\n")
1978 _T(" set <variable> <value> - Set value of server configuration variable\n")
1979 _T(" show components <node> - Show physical components of given node\n")
1980 _T(" show dbcp - Show active sessions in database connection pool\n")
1981 _T(" show dbstats - Show DB library statistics\n")
1982 _T(" show fdb <node> - Show forwarding database for node\n")
1983 _T(" show flags - Show internal server flags\n")
1984 _T(" show heap - Show heap information\n")
1985 _T(" show index <index> - Show internal index\n")
1986 _T(" show modules - Show loaded server modules\n")
1987 _T(" show msgwq - Show message wait queues information\n")
1988 _T(" show objects [<filter>] - Dump network objects to screen\n")
1989 _T(" show pollers - Show poller threads state information\n")
1990 _T(" show queues - Show internal queues statistics\n")
1991 _T(" show routing-table <node> - Show cached routing table for node\n")
1992 _T(" show sessions - Show active client sessions\n")
1993 _T(" show stats - Show server statistics\n")
1994 _T(" show topology <node> - Collect and show link layer topology for node\n")
1995 _T(" show users - Show users\n")
1996 _T(" show vlans <node> - Show cached VLAN information for node\n")
1997 _T(" show watchdog - Display watchdog information\n")
1998 _T(" trace <node1> <node2> - Show network path trace between two nodes\n")
1999 _T("\nAlmost all commands can be abbreviated to 2 or 3 characters\n")
2004 ConsoleWrite(pCtx
, _T("UNKNOWN COMMAND\n\n"));
2011 * Signal handler for UNIX platforms
2015 void SignalHandlerStub(int nSignal
)
2017 // should be unused, but JIC...
2018 if (nSignal
== SIGCHLD
)
2020 while (waitpid(-1, NULL
, WNOHANG
) > 0)
2025 THREAD_RESULT NXCORE_EXPORTABLE THREAD_CALL
SignalHandler(void *pArg
)
2030 m_signalHandlerThread
= pthread_self();
2032 // default for SIGCHLD: ignore
2033 signal(SIGCHLD
, &SignalHandlerStub
);
2035 sigemptyset(&signals
);
2036 sigaddset(&signals
, SIGTERM
);
2037 sigaddset(&signals
, SIGINT
);
2038 sigaddset(&signals
, SIGSEGV
);
2039 sigaddset(&signals
, SIGCHLD
);
2040 sigaddset(&signals
, SIGHUP
);
2041 sigaddset(&signals
, SIGUSR1
);
2042 sigaddset(&signals
, SIGUSR2
);
2043 #if !defined(__sun) && !defined(_AIX) && !defined(__hpux)
2044 sigaddset(&signals
, SIGPIPE
);
2047 sigprocmask(SIG_BLOCK
, &signals
, NULL
);
2051 if (sigwait(&signals
, &nSignal
) == 0)
2057 // avoid repeat Shutdown() call
2058 if (!(g_flags
& AF_SHUTDOWN
))
2060 m_nShutdownReason
= SHUTDOWN_BY_SIGNAL
;
2062 Shutdown(); // will never return
2064 ConditionSet(m_condShutdown
);
2071 while (waitpid(-1, NULL
, WNOHANG
) > 0)
2075 if (g_flags
& AF_SHUTDOWN
)
2089 sigprocmask(SIG_UNBLOCK
, &signals
, NULL
);
2098 THREAD_RESULT NXCORE_EXPORTABLE THREAD_CALL
Main(void *pArg
)
2100 nxlog_write(MSG_SERVER_STARTED
, EVENTLOG_INFORMATION_TYPE
, NULL
);
2104 if (!(g_flags
& AF_DEBUG_CONSOLE_DISABLED
))
2106 char *ptr
, szCommand
[256];
2107 struct __console_ctx ctx
;
2109 WCHAR wcCommand
[256];
2113 ctx
.socketMutex
= INVALID_MUTEX_HANDLE
;
2117 WriteToTerminal(_T("\nNetXMS Server V") NETXMS_VERSION_STRING
_T(" Build ") NETXMS_VERSION_BUILD_STRING IS_UNICODE_BUILD_STRING
_T(" Ready\n")
2118 _T("Enter \"\x1b[1mhelp\x1b[0m\" for command list or \"\x1b[1mdown\x1b[0m\" for server shutdown\n")
2119 _T("System Console\n\n"));
2122 // Initialize readline library if we use it
2123 rl_bind_key('\t', RL_INSERT_CAST rl_insert
);
2129 ptr
= readline("\x1b[33mnetxmsd:\x1b[0m ");
2131 WriteToTerminal(_T("\x1b[33mnetxmsd:\x1b[0m "));
2133 if (fgets(szCommand
, 255, stdin
) == NULL
)
2134 break; // Error reading stdin
2135 ptr
= strchr(szCommand
, '\n');
2145 mbstowcs(wcCommand
, ptr
, 255);
2147 MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, ptr
, -1, wcCommand
, 256);
2150 StrStrip(wcCommand
);
2151 if (wcCommand
[0] != 0)
2153 if (ProcessConsoleCommand(wcCommand
, &ctx
) == CMD_EXIT_SHUTDOWN
)
2158 if (ProcessConsoleCommand(ptr
, &ctx
) == CMD_EXIT_SHUTDOWN
)
2178 if (!(g_flags
& AF_SHUTDOWN
))
2180 m_nShutdownReason
= SHUTDOWN_FROM_CONSOLE
;
2186 // standalone with debug console disabled
2188 _tprintf(_T("Server running. Press ESC to shutdown.\n"));
2194 _tprintf(_T("Server shutting down...\n"));
2197 _tprintf(_T("Server running. Press Ctrl+C to shutdown.\n"));
2198 // Shutdown will be called from signal handler
2199 ConditionWait(m_condShutdown
, INFINITE
);
2205 ConditionWait(m_condShutdown
, INFINITE
);
2206 // On Win32, Shutdown() will be called by service control handler
2215 * Initiate server shutdown
2217 void InitiateShutdown()
2228 pthread_kill(m_signalHandlerThread
, SIGTERM
);
2238 BOOL WINAPI
DllMain(HINSTANCE hInstance
, DWORD dwReason
, LPVOID lpReserved
)
2240 if (dwReason
== DLL_PROCESS_ATTACH
)
2241 DisableThreadLibraryCalls(hInstance
);