34 #include "core/os/vdso.h"
35 #include "core/os/process_utilities.h"
36 #include "core/os/thread_local_storage.h"
37 #include "core/os/hangup_signal_handler.h"
38 #include "core/os/virtual_memory.h"
40 #ifdef LLFIX_ENABLE_NUMA // VOLTRON_EXCLUDE
41 #include "core/os/numa_utilities.h"
42 #endif // VOLTRON_EXCLUDE
44 #ifdef LLFIX_ENABLE_TCPDIRECT // VOLTRON_EXCLUDE
45 #include "core/solarflare_tcpdirect/tcpdirect_api.h"
46 #endif // VOLTRON_EXCLUDE
48 #ifdef LLFIX_ENABLE_OPENSSL // VOLTRON_EXCLUDE
49 #include "core/ssl/ssl_api.h"
50 #endif // VOLTRON_EXCLUDE
52 #include "core/os/socket.h"
53 #include "core/utilities/logger.h"
54 #include "core/utilities/version.h"
55 #include "core/utilities/allocator.h"
57 #include "engine_settings.h"
59 #include "management_server/management_server_settings.h"
60 #include "management_server/management_server.h"
84 static void on_start(
const std::string& config_file_path =
"",
const std::string& config_group_name =
"ENGINE")
86 if(m_engine_initialised.load() ==
true)
92 if(ProcessUtilities::has_root_privileges() ==
false)
94 fprintf(stderr,
"llfix engine : Requires root privileges on Linux.\n");
99 m_application_start_timestamp = VDSO::nanoseconds_monotonic();
101 EngineSettings engine_settings;
103 if(config_file_path.length()>0)
105 if(engine_settings.load_from_config_file(config_file_path, config_group_name) ==
false)
107 fprintf(stderr,
"Failed to load %s : %s \n", config_file_path.c_str(), engine_settings.config_load_error.c_str());
112 if(engine_settings.validate() ==
false)
114 fprintf(stderr,
"llfix engine : Failed to verify %s : %s \n", config_file_path.c_str(), engine_settings.validation_error.c_str());
118 HangupSignalHandler::set_ignore(engine_settings.ignore_sighup);
120 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)
122 fprintf(stderr,
"llfix engine : Logger initialisation failed\n");
126 if(engine_settings.numa_bind_node >= 0)
129 fprintf(stderr,
"WARNING : numa_bind_node is specified however NUMA features supported only on Linux.\n");
131 #ifdef LLFIX_ENABLE_NUMA
132 if(NumaUtilities::get_current_numa_node() == -1)
134 fprintf(stderr,
"WARNING : numa_bind_node is set however there is no NUMA node on the system, therefore it won't take affect\n");
138 if( NumaUtilities::bind_to_numa_node(engine_settings.numa_bind_node) ==
false)
140 fprintf(stderr,
"llfix engine : Failed to bind to NUMA node %d \n", engine_settings.numa_bind_node);
144 LLFIX_LOG_INFO(
"Bound NUMA node : " + std::to_string(NumaUtilities::get_current_numa_node()));
145 Allocator::set_numa_aware(engine_settings.numa_aware_allocations);
148 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");
153 if(engine_settings.lock_pages)
156 auto page_lock_success = VirtualMemory::lock_all_pages();
157 LLFIX_LOG_INFO(
"VM pages locked : " + std::string( (page_lock_success?
"1":
"0") ));
161 if (ThreadLocalStorage::get_instance().create() ==
false)
163 LLFIX_LOG_ERROR(
"Failed to create thread local storage");
167 Socket<>::socket_library_initialise();
169 ManagementServerSettings management_server_settings;
171 if (management_server_settings.specified_by_user(config_file_path, config_group_name))
173 if (management_server_settings.load_from_config_file(config_file_path, config_group_name) ==
true)
175 if (management_server_settings.validate() ==
true)
177 std::filesystem::path cwd = std::filesystem::current_path();
178 std::filesystem::path full_log_path = cwd / engine_settings.log_file;
180 if (m_management_server.create(management_server_settings, m_application_start_timestamp, m_version.to_string(), full_log_path.string()))
182 m_management_server_started =
true;
183 LLFIX_LOG_INFO(
"Started management server , port : " + std::to_string(management_server_settings.management_server_port) +
" nic : " + management_server_settings.management_server_nic_ip);
187 LLFIX_LOG_ERROR(
"Failed to create management server");
192 LLFIX_LOG_ERROR(
"Failed to validate management server settings. Error : " + management_server_settings.validation_error);
197 LLFIX_LOG_INFO(
"LLFIX ENGINE Loaded config =>\n" + engine_settings.to_string());
199 #ifndef LLFIX_BUILD_CONFIG_GENERATED
200 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBRARY TYPE=HEADER-ONLY , version : " + m_version.to_string());
202 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBRARY TYPE=STATIC-LIB , version : " + m_version.to_string());
205 #ifdef LLFIX_ENABLE_TCPDIRECT
206 LLFIX_LOG_INFO(
"LLFIX ENGINE TCPDIRECT=ON , TCPDirect library version : " + std::string(TCPDirectApi::get_version()));
208 LLFIX_LOG_INFO(
"LLFIX ENGINE TCPDIRECT=OFF");
211 #ifdef LLFIX_ENABLE_NUMA
212 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBNUMA=ON");
214 LLFIX_LOG_INFO(
"LLFIX ENGINE LIBNUMA=OFF");
217 #ifdef LLFIX_ENABLE_OPENSSL
218 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=ON , OpenSSL library version : " + std::string(SSLApi::get_version()));
220 if (SSLApi::get_version_major_number() < 3)
222 LLFIX_LOG_ERROR(
"OpenSSL major version >= 3.0.0 required");
226 if ( !(SSLApi::get_version_major_number() == 3 && SSLApi::get_version_minor_number() == 6) )
228 fprintf(stderr,
"WARNING : Supported OpenSSL version is 3.6.\n");
231 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=ON , OpenSSL initialisation : " + std::string(SSLApi::initialise()?
"true":
"false"));
233 LLFIX_LOG_INFO(
"LLFIX ENGINE OPENSSL=OFF");
236 #ifdef LLFIX_ENABLE_DICTIONARY
237 LLFIX_LOG_INFO(
"LLFIX ENGINE DICTIONARY=ON");
239 LLFIX_LOG_INFO(
"LLFIX ENGINE DICTIONARY=OFF");
242 #ifdef LLFIX_ENABLE_BINARY_FIELDS
243 LLFIX_LOG_INFO(
"LLFIX BINARY FIELDS SUPPORT=ON");
245 LLFIX_LOG_INFO(
"LLFIX BINARY FIELDS SUPPORT=OFF");
248 LLFIX_LOG_INFO(
"LLFIX ENGINE initialised successfully");
250 m_engine_initialised.store(
true);
262 ThreadLocalStorage::get_instance().destroy();
264 #ifdef LLFIX_ENABLE_OPENSSL
265 SSLApi::uninitialise();
268 #ifdef LLFIX_ENABLE_TCPDIRECT
269 TCPDirectApi::uninitialise();
280 if(m_management_server_stopped ==
false)
282 if (m_management_server_started ==
true)
284 LLFIX_LOG_INFO(
"Stopping management server");
285 m_management_server.stop();
287 m_management_server_stopped =
true;
298 return m_management_server;
301 static bool initialised() {
return m_engine_initialised.load(); }
302 static const Version& get_version() {
return m_version; }
303 static uint64_t get_application_start_timestamp() {
return m_application_start_timestamp; }
305 static inline Version m_version{
"1.0.1"};
306 static inline uint64_t m_application_start_timestamp = 0;
307 static inline std::atomic<bool> m_engine_initialised =
false;
309 static inline ManagementServer m_management_server;
310 static inline bool m_management_server_started =
false;
311 static inline bool m_management_server_stopped =
false;