diff --git a/conf.d/heartbeat.conf.sample b/conf.d/heartbeat.conf.sample index 2090f16e..d28ba674 100644 --- a/conf.d/heartbeat.conf.sample +++ b/conf.d/heartbeat.conf.sample @@ -4,7 +4,7 @@ ; enabled: bool: Enable operation of this module ;enabled=true -; node: string: Name of this cluster node, must be set to enable module +; node: string: Name of this cluster node, default to engine's node name ;node= ; host: ipaddress: IP address to send heartbeat packets to, must be set diff --git a/conf.d/yate.conf.sample b/conf.d/yate.conf.sample index 75ecadae..ae68de2b 100644 --- a/conf.d/yate.conf.sample +++ b/conf.d/yate.conf.sample @@ -16,6 +16,9 @@ ; Note that you MUST NOT add a path separator at the end ;extrapath= +; nodename: string: Name of this node in a cluster +;nodename= + ; maxworkers: int: Maximum number of worker threads the engine can create ;maxworkers=10 diff --git a/docs/man/yate.8 b/docs/man/yate.8 index 4e444b8f..bb41b26e 100644 --- a/docs/man/yate.8 +++ b/docs/man/yate.8 @@ -73,6 +73,9 @@ Relative path to extra modules directory (can be repeated) .TP .B \-w \fIdirectory\fR Change working directory +.TP +.B \-N \fInodename\fR +Set the name of the node in a cluster .SS Debugging options (may not be compiled in) .TP .B \-C diff --git a/engine/Engine.cpp b/engine/Engine.cpp index 1886e972..14f91a9f 100644 --- a/engine/Engine.cpp +++ b/engine/Engine.cpp @@ -101,6 +101,10 @@ using namespace TelEngine; #define INIT_SANITY 30 #define MAX_LOGBUFF 4096 +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + static u_int64_t s_nextinit = 0; static u_int64_t s_restarts = 0; static bool s_makeworker = true; @@ -136,6 +140,7 @@ static void sighandler(int signal) } } +String Engine::s_node; String Engine::s_shrpath(SHR_PATH); String Engine::s_cfgpath(CFG_PATH); String Engine::s_cfgsuffix(CFG_SUFFIX); @@ -612,6 +617,13 @@ int Engine::run() #endif SysUsage::init(); s_runid = Time::secNow(); + if (s_node.trimBlanks().null()) { + char hostName[HOST_NAME_MAX+1]; + if (::gethostname(hostName,sizeof(hostName))) + hostName[0] = '\0'; + s_node = s_cfg.getValue("general","nodename",hostName); + s_node.trimBlanks(); + } DDebug(DebugAll,"Engine::run()"); install(new EngineStatusHandler); extraPath(clientMode() ? "client" : "server"); @@ -642,7 +654,8 @@ int Engine::run() ::signal(SIGUSR1,sighandler); ::signal(SIGUSR2,sighandler); #endif - Output("Yate%s engine is initialized and starting up",clientMode() ? " client" : ""); + Output("Yate%s engine is initialized and starting up%s%s", + clientMode() ? " client" : "",s_node.null() ? "" : " on " ,s_node.safe()); while (s_haltcode == -1) { if (s_cmds) { Output("Executing initial commands"); @@ -1036,6 +1049,7 @@ static void usage(bool client, FILE* f) " -m pathname Path to modules directory (" MOD_PATH ")\n" " -x relpath Relative path to extra modules directory (can be repeated)\n" " -w directory Change working directory\n" +" -N nodename Set the name of this node in a cluster\n" #ifdef RLIMIT_CORE " -C Enable core dumps if possible\n" #endif @@ -1237,6 +1251,14 @@ int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bo pc = 0; extraPath(argv[++i]); break; + case 'N': + if (i+1 >= argc) { + noarg(client,argv[i]); + return ENOENT; + } + pc = 0; + s_node=argv[++i]; + break; #ifdef RLIMIT_CORE case 'C': s_coredump = true; diff --git a/modules/regexroute.cpp b/modules/regexroute.cpp index 6775e25c..8de9d26b 100644 --- a/modules/regexroute.cpp +++ b/modules/regexroute.cpp @@ -246,6 +246,8 @@ static void evalFunc(String& str) str.clear(); str << Engine::runId(); } + else if (str == "nodename") + str = Engine::nodeName(); else if ((sep >= 0) && (str == "transcode")) { str = par.substr(0,sep); par = par.substr(sep+1).trimBlanks(); diff --git a/modules/server/heartbeat.cpp b/modules/server/heartbeat.cpp index f6112b09..9959cce2 100644 --- a/modules/server/heartbeat.cpp +++ b/modules/server/heartbeat.cpp @@ -149,6 +149,7 @@ void HBeatPlugin::sendHeartbeat(const Time& tStamp, bool goDown) if (m_socket.valid()) { char hex[16]; String buf; + // Linux-HA relies on the fields order so don't change it. Thanks. buf << "t=status\n"; if (goDown) buf << "st=dead\n"; @@ -286,7 +287,7 @@ void HBeatPlugin::initialize() if (!m_socket.valid()) { if (!cfg.getBoolValue("general","enabled",true)) return; - m_node = cfg.getValue("general","node"); + m_node = cfg.getValue("general","node",Engine::nodeName()); if (m_node.null()) return; SocketAddr addr(AF_INET); diff --git a/yatengine.h b/yatengine.h index 5d817716..48d3e7cb 100644 --- a/yatengine.h +++ b/yatengine.h @@ -775,11 +775,18 @@ public: */ static bool Register(const Plugin* plugin, bool reg = true); + /** + * Get the server node name, should be unique in a cluster + * @return Node identifier string, defaults to host name + */ + inline static const String& nodeName() + { return s_node; } + /** * Get the application's shared directory path * @return The base path for shared files and directories */ - inline static String& sharedPath() + inline static const String& sharedPath() { return s_shrpath; } /** @@ -794,20 +801,20 @@ public: * Get the system configuration directory path * @return The directory path for system configuration files */ - inline static String& configPath() + inline static const String& configPath() { return s_cfgpath; } /** * Get the configuration file suffix * @return The suffix for configuration files */ - inline static String& configSuffix() + inline static const String& configSuffix() { return s_cfgsuffix; } /** * The module loading path */ - inline static String& modulePath() + inline static const String& modulePath() { return s_modpath; } /** @@ -821,7 +828,7 @@ public: * Get the module filename suffix * @return The suffix for module files */ - inline static String& moduleSuffix() + inline static const String& moduleSuffix() { return s_modsuffix; } /** @@ -994,6 +1001,7 @@ private: ObjList m_libs; MessageDispatcher m_dispatcher; static Engine* s_self; + static String s_node; static String s_shrpath; static String s_cfgpath; static String s_cfgsuffix;