| // 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 <memory> |
| #include <string> |
| |
| #include <sysexits.h> |
| |
| #include <base/check.h> |
| #include <base/files/file_path.h> |
| #include <base/logging.h> |
| #include <base/time/time.h> |
| #include <brillo/files/file_util.h> |
| #include "gsclog/gsclog.h" |
| |
| namespace gsclog { |
| namespace { |
| constexpr char kCurrentLogExt[] = "gsc.log"; |
| } // namespace |
| |
| using base::File; |
| |
| GscLog::GscLog(const base::FilePath& log_dir) |
| : log_path_(base::FilePath(log_dir.Append(kCurrentLogExt))), |
| default_trunks_factory_(std::make_unique<trunks::TrunksFactoryImpl>()) {} |
| |
| int GscLog::Fetch() { |
| File log(log_path_, File::Flags::FLAG_OPEN_ALWAYS | File::Flags::FLAG_APPEND); |
| if (!log.IsValid()) { |
| LOG(ERROR) << "Failed to open file: " |
| << File::ErrorToString(log.error_details()); |
| return EX_NOPERM; |
| } |
| if (log.Lock(File::LockMode::kExclusive) != File::Error::FILE_OK) { |
| // If another instance of gsclog was using the file, sleep 1 second and try |
| // again. If that fails, bail. |
| const base::TimeDelta sleep_interval = base::Seconds(1); |
| sleep(sleep_interval.InSeconds()); |
| File::Error error = log.Lock(File::LockMode::kExclusive); |
| if (error != File::Error::FILE_OK) { |
| LOG(ERROR) << "Failed to lock log file: " << File::ErrorToString(error); |
| return EX_UNAVAILABLE; |
| } |
| } |
| |
| if (!default_trunks_factory_->Initialize()) { |
| LOG(ERROR) << "Failed to initialize trunks."; |
| return EX_UNAVAILABLE; |
| } |
| trunks_factory_ = default_trunks_factory_.get(); |
| trunks_utility_ = trunks_factory_->GetTpmUtility(); |
| |
| std::string logs; |
| if (trunks_utility_->GetConsoleLogs(&logs) != trunks::TPM_RC_SUCCESS) { |
| LOG(ERROR) << "Failed to get console logs."; |
| return EX_NOPERM; |
| } |
| |
| if (!log.Write(0, logs.c_str(), logs.length())) { |
| PLOG(ERROR) << "Could not append to log file"; |
| return EX_CANTCREAT; |
| } |
| |
| return EX_OK; |
| } |
| |
| } // namespace gsclog |