| #include <csignal> // NOLINT |
| #include <filesystem> // NOLINT |
| #include <iostream> |
| #include <string> |
| #include <utility> |
| |
| #include "absl/flags/flag.h" |
| #include "absl/flags/parse.h" |
| #include "absl/status/statusor.h" |
| #include "tlbmc/hal/shared_mem/metrics.h" |
| #include "tlbmc/hal/shared_mem/segment_manager.h" |
| #include "tlbmc/hal/shared_mem/server.h" |
| |
| ABSL_FLAG( |
| std::string, command, "", |
| "Command to execute: 'get_metrics', 'check_segment', " |
| "'remove_segment', 'get_metrics_debug', 'get_sensor_value', 'crash_test'"); |
| ABSL_FLAG(bool, unit_test, false, "Use shared memory for unit test."); |
| ABSL_FLAG(std::string, sensor_name, "", "The name of the sensor to read."); |
| |
| int main(int argc, char** argv) { |
| absl::ParseCommandLine(argc, argv); |
| using ::milotic_tlbmc::SharedMemoryServer; |
| using ::milotic_tlbmc::TlbmcMetrics; |
| std::string command = absl::GetFlag(FLAGS_command); |
| |
| bool unit_test = absl::GetFlag(FLAGS_unit_test); |
| |
| if (unit_test) { |
| SharedMemoryServer::SetUpInstanceForUnitTestReadOnly(); |
| } |
| |
| if (command == "get_sensor_value") { |
| std::string sensor_name = absl::GetFlag(FLAGS_sensor_name); |
| if (sensor_name.empty()) { |
| std::cerr << "--sensor_name is required for get_sensor_value\n"; |
| return 1; |
| } |
| absl::StatusOr<std::pair<float, int64_t>> result = |
| SharedMemoryServer::GetInstance().ReadSensorValue(sensor_name); |
| if (!result.ok()) { |
| std::cerr << "Failed to read sensor value for " << sensor_name << ": " |
| << result.status() << "\n"; |
| return 1; |
| } |
| std::cout << "Sensor: " << sensor_name << ", Value: " << result->first |
| << ", Timestamp: " << result->second << "\n"; |
| return 0; |
| } |
| |
| if (command == "crash_test") { |
| boost::interprocess::managed_shared_memory sensors_memory( |
| boost::interprocess::open_only, "TlbmcSharedMemory"); |
| |
| auto crash_fn = [] { |
| std::cerr << "Crashing the process under lock\n"; |
| pid_t current_pid = getpid(); |
| kill(current_pid, SIGKILL); |
| }; |
| sensors_memory.atomic_func(crash_fn); |
| } |
| |
| if (command == "check_segment") { |
| bool file_exists = false; |
| if (!unit_test) { |
| file_exists = std::filesystem::exists( |
| std::string{milotic_tlbmc::kShareMemInitializedFile}); |
| } else { |
| file_exists = std::filesystem::exists("/tmp/tlbmc/tlbmc_shared_memory"); |
| } |
| bool segment_exists = false; |
| try { |
| boost::interprocess::managed_shared_memory sensors_memory( |
| boost::interprocess::open_only, "TlbmcSharedMemory"); |
| segment_exists = true; |
| } catch (const boost::interprocess::interprocess_exception& e) { |
| segment_exists = false; |
| } |
| std::cerr << "file_exists: " << file_exists << '\n'; |
| std::cerr << "segment_exists: " << segment_exists << '\n'; |
| return 0; |
| } |
| |
| if (command == "get_metrics") { |
| const TlbmcMetrics* metrics = |
| SharedMemoryServer::GetInstance().GetMetrics(); |
| std::cerr << "Metrics pointer is " << metrics << '\n'; |
| if (metrics != nullptr) { |
| std::cerr << "Metrics is " << metrics->ToJson().dump(2) << '\n'; |
| } |
| return 0; |
| } |
| |
| if (command == "get_metrics_debug") { |
| const TlbmcMetrics* metrics = |
| SharedMemoryServer::GetInstance().GetMetrics(); |
| std::cerr << "Metrics pointer is " << metrics << '\n'; |
| if (metrics != nullptr) { |
| std::cerr << "Metrics is " << metrics->ToDebugJson().dump(2) << '\n'; |
| } |
| return 0; |
| } |
| |
| if (command == "remove_segment") { |
| boost::interprocess::shared_memory_object::remove("TlbmcSharedMemory"); |
| std::filesystem::remove( |
| std::string{milotic_tlbmc::kShareMemInitializedFile}); |
| return 0; |
| } |
| |
| return 0; |
| } |