12 #include "core/os/vdso.h"
13 #include "core/os/process_utilities.h"
14 #include "core/os/thread_local_storage.h"
15 #include "core/os/hangup_signal_handler.h"
16 #include "core/os/virtual_memory.h"
18 #ifdef LLFIX_ENABLE_NUMA // VOLTRON_EXCLUDE
19 #include "core/os/numa_utilities.h"
20 #endif // VOLTRON_EXCLUDE
22 #ifdef LLFIX_ENABLE_TCPDIRECT // VOLTRON_EXCLUDE
23 #include "core/solarflare_tcpdirect/tcpdirect_api.h"
24 #endif // VOLTRON_EXCLUDE
26 #ifdef LLFIX_ENABLE_OPENSSL // VOLTRON_EXCLUDE
27 #include "core/ssl/ssl_api.h"
28 #endif // VOLTRON_EXCLUDE
30 #include "core/os/socket.h"
31 #include "core/utilities/logger.h"
32 #include "core/utilities/version.h"
33 #include "core/utilities/allocator.h"
35 #include "engine_settings.h"
37 #include "management_server/management_server_settings.h"
38 #include "management_server/management_server.h"
62 static void on_start(
const std::string& config_file_path =
"",
const std::string& config_group_name =
"ENGINE")
64 if(m_engine_initialised.load() ==
true)
70 if(ProcessUtilities::has_root_privileges() ==
false)
72 fprintf(stderr,
"llfix engine : Requires root privileges on Linux.\n");
77 m_application_start_timestamp = VDSO::nanoseconds_monotonic();
79 EngineSettings engine_settings;
81 if(config_file_path.length()>0)
83 if(engine_settings.load_from_config_file(config_file_path, config_group_name) ==
false)
85 fprintf(stderr,
"Failed to load %s : %s \n", config_file_path.c_str(), engine_settings.config_load_error.c_str());
90 if(engine_settings.validate() ==
false)
92 fprintf(stderr,
"llfix engine : Failed to verify %s : %s \n", config_file_path.c_str(), engine_settings.validation_error.c_str());
96 HangupSignalHandler::set_ignore(engine_settings.ignore_sighup);
98 if( Logger<>::get_instance().initialise(engine_settings.log_file, Logger<>::convert_string_to_log_level(engine_settings.log_level), engine_settings.logger_async, engine_settings.logger_buffer_capacity) ==
false)
100 fprintf(stderr,
"llfix engine : Logger initialisation failed\n");
104 if(engine_settings.numa_bind_node >= 0)
107 fprintf(stderr,
"WARNING : numa_bind_node is specified however NUMA features supported only on Linux.\n");
109 #ifdef LLFIX_ENABLE_NUMA
110 if(NumaUtilities::get_current_numa_node() == -1)
112 fprintf(stderr,
"WARNING : numa_bind_node is set however there is no NUMA node on the system, therefore it won't take affect\n");
116 if( NumaUtilities::bind_to_numa_node(engine_settings.numa_bind_node) ==
false)
118 fprintf(stderr,
"llfix engine : Failed to bind to NUMA node %d \n", engine_settings.numa_bind_node);
122 LLFIX_LOG_INFO(
"Bound NUMA node : " + std::to_string(NumaUtilities::get_current_numa_node()));
123 Allocator::set_numa_aware(engine_settings.numa_aware_allocations);
126 fprintf(stderr,
"WARNING : numa_bind_node is set however this build not built with LLFIX_ENABLE_NUMA flag, therefore it won't take affect\n");
131 if(engine_settings.lock_pages)
134 auto page_lock_success = VirtualMemory::lock_all_pages();
135 LLFIX_LOG_INFO(
"VM pages locked : " + std::string( (page_lock_success?
"1":
"0") ));
139 if (ThreadLocalStorage::get_instance().create() ==
false)
141 LLFIX_LOG_ERROR(
"Failed to create thread local storage");
145 Socket<>::socket_library_initialise();
147 ManagementServerSettings management_server_settings;
149 if (management_server_settings.specified_by_user(config_file_path, config_group_name))
151 if (management_server_settings.load_from_config_file(config_file_path, config_group_name) ==
true)
153 if (management_server_settings.validate() ==
true)
155 std::filesystem::path cwd = std::filesystem::current_path();
156 std::filesystem::path full_log_path = cwd / engine_settings.log_file;
158 if (m_management_server.create(management_server_settings, m_application_start_timestamp, m_version.to_string(), full_log_path.string()))
160 m_management_server_started =
true;
161 LLFIX_LOG_INFO(
"Started management server , port : " + std::to_string(management_server_settings.management_server_port) +
" nic : " + management_server_settings.management_server_nic_ip);
165 LLFIX_LOG_ERROR(
"Failed to create management server");
170 LLFIX_LOG_ERROR(
"Failed to validate management server settings. Error : " + management_server_settings.validation_error);
175 LLFIX_LOG_INFO(
"LLFIX ENGINE Loaded config =>\n" + engine_settings.to_string());
177 #ifndef LLFIX_BUILD_CONFIG_GENERATED
178 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBRARY TYPE=HEADER-ONLY , version : " + m_version.to_string());
180 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBRARY TYPE=STATIC-LIB , version : " + m_version.to_string());
183 #ifdef LLFIX_ENABLE_TCPDIRECT
184 LLFIX_LOG_INFO(
"LLFIX ENGINE TCPDIRECT=ON , TCPDirect library version : " + std::string(TCPDirectApi::get_version()));
186 LLFIX_LOG_INFO(
"LLFIX ENGINE TCPDIRECT=OFF");
189 #ifdef LLFIX_ENABLE_NUMA
190 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBNUMA=ON");
192 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBNUMA=OFF");
195 #ifdef LLFIX_ENABLE_OPENSSL
196 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=ON , OpenSSL library version : " + std::string(SSLApi::get_version()));
198 if (SSLApi::get_version_major_number() < 3)
200 LLFIX_LOG_ERROR(
"OpenSSL major version >= 3.0.0 required");
204 if ( !(SSLApi::get_version_major_number() == 3 && SSLApi::get_version_minor_number() == 6) )
206 fprintf(stderr,
"WARNING : Supported OpenSSL version is 3.6.\n");
209 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=ON , OpenSSL initialisation : " + std::string(SSLApi::initialise()?
"true":
"false"));
211 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=OFF");
214 #ifdef LLFIX_ENABLE_DICTIONARY
215 LLFIX_LOG_INFO(
"LLFIX ENGINE DICTIONARY=ON");
217 LLFIX_LOG_INFO(
"LLFIX ENGINE DICTIONARY=OFF");
220 #ifdef LLFIX_ENABLE_BINARY_FIELDS
221 LLFIX_LOG_INFO(
"LLFIX BINARY FIELDS SUPPORT=ON");
223 LLFIX_LOG_INFO(
"LLFIX BINARY FIELDS SUPPORT=OFF");
226 LLFIX_LOG_INFO(
"LLFIX ENGINE initialised successfully");
228 m_engine_initialised.store(
true);
240 ThreadLocalStorage::get_instance().destroy();
242 #ifdef LLFIX_ENABLE_OPENSSL
243 SSLApi::uninitialise();
246 #ifdef LLFIX_ENABLE_TCPDIRECT
247 TCPDirectApi::uninitialise();
258 if(m_management_server_stopped ==
false)
260 if (m_management_server_started ==
true)
262 LLFIX_LOG_INFO(
"Stopping management server");
263 m_management_server.stop();
265 m_management_server_stopped =
true;
276 return m_management_server;
279 static bool initialised() {
return m_engine_initialised.load(); }
280 static const Version& get_version() {
return m_version; }
281 static uint64_t get_application_start_timestamp() {
return m_application_start_timestamp; }
283 static inline Version m_version{
"1.0.0"};
284 static inline uint64_t m_application_start_timestamp = 0;
285 static inline std::atomic<bool> m_engine_initialised =
false;
287 static inline ManagementServer m_management_server;
288 static inline bool m_management_server_started =
false;
289 static inline bool m_management_server_stopped =
false;