| // Copyright 2023 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "modemloggerd/modem.h" |
| |
| #include <csignal> |
| |
| #include <base/logging.h> |
| #include <base/strings/stringprintf.h> |
| |
| #include "modemloggerd/dbus-constants.h" |
| #include "modemloggerd/logging_prefs.h" |
| |
| namespace { |
| const char kVarLog[] = "/var/log/modemloggerd"; |
| } |
| |
| namespace modemloggerd { |
| |
| Modem::Modem(dbus::Bus* bus, |
| AdaptorFactoryInterface* adaptor_factory, |
| HelperEntry logging_helper) |
| : output_dir_(kVarLog), |
| dbus_adaptor_(adaptor_factory->CreateModemAdaptor(this, bus)), |
| logging_helper_(logging_helper) { |
| LOG(INFO) << __func__ << ": " << logging_helper_.exe().filename(); |
| if (!LoggingPrefs::Get()->GetAutoStart(logging_helper_.modem_name())) { |
| return; |
| } |
| auto start_result = Start(); |
| if (start_result != nullptr) { |
| LOG(ERROR) << "Failed to auto start logger: " << start_result->GetMessage(); |
| } |
| } |
| |
| brillo::ErrorPtr Modem::SetEnabled(bool enable) { |
| LOG(INFO) << __func__ << ": " << enable; |
| if ((enable && !logging_helper_.has_enable_exe()) || |
| (!enable && !logging_helper_.has_disable_exe())) { |
| return nullptr; |
| } |
| const int exit_code = RunEnableHelper(enable); |
| if (exit_code == 0) { |
| return nullptr; |
| } |
| return brillo::Error::Create( |
| FROM_HERE, brillo::errors::dbus::kDomain, kErrorOperationFailed, |
| base::StringPrintf("Failed to run helper (exit_code=%d)", exit_code)); |
| } |
| |
| brillo::ErrorPtr Modem::SetAutoStart(bool autostart) { |
| LOG(INFO) << __func__ << ": " << autostart; |
| if (!LoggingPrefs::Get()->SetAutoStart(logging_helper_.modem_name(), |
| autostart)) { |
| return brillo::Error::Create(FROM_HERE, brillo::errors::dbus::kDomain, |
| kErrorOperationFailed, |
| "Failed to set auto start"); |
| } |
| return nullptr; |
| } |
| |
| brillo::ErrorPtr Modem::Start() { |
| // TODO(pholla): Sandbox if daemon moves into release images |
| LOG(INFO) << __func__; |
| if (StartLoggingHelper()) { |
| return nullptr; |
| } |
| return brillo::Error::Create(FROM_HERE, brillo::errors::dbus::kDomain, |
| kErrorOperationFailed, "Failed to start logger"); |
| } |
| |
| brillo::ErrorPtr Modem::Stop() { |
| LOG(INFO) << __func__; |
| const int kStopTimeoutSeconds = 2; |
| if (logger_process_.Kill(SIGKILL, kStopTimeoutSeconds)) { |
| return nullptr; |
| } |
| return brillo::Error::Create(FROM_HERE, brillo::errors::dbus::kDomain, |
| kErrorOperationFailed, "Failed to stop logger"); |
| } |
| |
| bool Modem::StartLoggingHelper() { |
| logger_process_.AddArg(logging_helper_.exe().filename()); |
| for (const std::string& extra_argument : |
| logging_helper_.exe().extra_argument()) { |
| logger_process_.AddArg(extra_argument); |
| } |
| if (logging_helper_.exe().has_output_dir_argument()) { |
| logger_process_.AddArg(logging_helper_.exe().output_dir_argument()); |
| logger_process_.AddArg(output_dir_); |
| } |
| logger_process_.RedirectOutput(GetLogPath(logging_helper_.exe().filename())); |
| return logger_process_.Start(); |
| } |
| |
| int Modem::RunEnableHelper(bool enable) { |
| auto exe = |
| enable ? logging_helper_.enable_exe() : logging_helper_.disable_exe(); |
| brillo::ProcessImpl process; |
| process.AddArg(exe.filename()); |
| for (const std::string& extra_argument : exe.extra_argument()) { |
| process.AddArg(extra_argument); |
| } |
| process.RedirectOutput(GetLogPath(exe.filename())); |
| return process.Run(); |
| } |
| |
| std::string Modem::GetLogPath(const std::string& filename) { |
| const std::string log_prefix = |
| base::FilePath(filename).BaseName().MaybeAsASCII(); |
| base::Time::Exploded time; |
| base::Time::Now().LocalExplode(&time); |
| return base::StringPrintf("%s/%s_log.%4u%02u%02u-%02u%02u%02u%03u", |
| output_dir_.c_str(), log_prefix.c_str(), time.year, |
| time.month, time.day_of_month, time.hour, |
| time.minute, time.second, time.millisecond); |
| } |
| |
| dbus::ObjectPath Modem::GetDBusPath() { |
| return dbus_adaptor_->object_path(); |
| } |
| |
| brillo::ErrorPtr Modem::SetOutputDir(const std::string& output_dir) { |
| LOG(INFO) << __func__ << ": " << output_dir; |
| output_dir_ = output_dir; |
| return nullptr; |
| } |
| |
| } // namespace modemloggerd |