blob: 7884151f8b74e2a9abbef6ff6c4d6a78b97e23e1 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/forensics/feedback/namespace_init.h"
#include <lib/syslog/cpp/macros.h>
#include "src/developer/forensics/feedback_data/system_log_recorder/encoding/production_encoding.h"
#include "src/developer/forensics/feedback_data/system_log_recorder/encoding/version.h"
#include "src/developer/forensics/feedback_data/system_log_recorder/reader.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace forensics::feedback {
namespace {
void MoveFile(const std::string& from, const std::string& to) {
// Bail if the file doesn't exist.
if (!files::IsFile(from)) {
return;
}
// Bail if the file can't be read.
std::string content;
if (!files::ReadFileToString(from, &content)) {
FX_LOGS(ERROR) << "Failed to read file " << from;
return;
}
// Copy the file content – we cannot move as the two files are under different namespaces.
if (!files::WriteFile(to, content)) {
FX_LOGS(ERROR) << "Failed to write file " << to;
return;
}
// Delete the original file.
if (!files::DeletePath(from, /*recursive=*/true)) {
FX_LOGS(ERROR) << "Failed to delete " << from;
}
}
} // namespace
bool TestAndSetNotAFdr(const std::string& not_a_fdr_file) {
if (files::IsFile(not_a_fdr_file)) {
return true;
}
if (!files::WriteFile(not_a_fdr_file, "", 0u)) {
FX_LOGS(ERROR) << "Failed to create " << not_a_fdr_file;
}
return false;
}
void MovePreviousRebootReason(const std::string& from, const std::string& legacy_from,
const std::string& to) {
if (files::IsFile(from)) {
MoveFile(from, to);
} else {
MoveFile(legacy_from, to);
}
}
void CreatePreviousLogsFile(cobalt::Logger* cobalt, const std::string& dir,
const std::string& write_path) {
// We read the set of /cache files into a single /tmp file.
feedback_data::system_log_recorder::ProductionDecoder decoder;
float compression_ratio;
if (!feedback_data::system_log_recorder::Concatenate(dir, &decoder, write_path,
&compression_ratio)) {
return;
}
FX_LOGS(INFO) << fxl::StringPrintf(
"Found logs from previous boot cycle (compression ratio %.2f), available at %s\n",
compression_ratio, write_path.c_str());
cobalt->LogCount(feedback_data::system_log_recorder::ToCobalt(decoder.GetEncodingVersion()),
(uint64_t)(compression_ratio * 100));
// Clean up the /cache files now that they have been concatenated into a single /tmp file.
files::DeletePath(dir, /*recursive=*/true);
}
void MoveAndRecordBootId(const std::string& new_boot_id, const std::string& previous_boot_id_path,
const std::string& current_boot_id_path) {
MoveFile(/*from=*/current_boot_id_path, /*to=*/previous_boot_id_path);
files::WriteFile(current_boot_id_path, new_boot_id);
}
void MoveAndRecordBuildVersion(const std::string& current_build_version,
const std::string& previous_build_version_path,
const std::string& current_build_version_path) {
MoveFile(/*from=*/current_build_version_path, /*to=*/previous_build_version_path);
files::WriteFile(current_build_version_path, current_build_version);
}
} // namespace forensics::feedback