blob: 996fd30a90a6f4ad0671ac86e92e85793ae751b8 [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 <fuchsia/feedback/cpp/fidl.h>
#include <fuchsia/process/lifecycle/cpp/fidl.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/processargs.h>
#include <cstdlib>
#include <memory>
#include <fbl/unique_fd.h>
#include "src/developer/forensics/crash_reports/default_annotations.h"
#include "src/developer/forensics/feedback/annotations/startup_annotations.h"
#include "src/developer/forensics/feedback/config.h"
#include "src/developer/forensics/feedback/constants.h"
#include "src/developer/forensics/feedback/main_service.h"
#include "src/developer/forensics/feedback/namespace_init.h"
#include "src/developer/forensics/feedback/reboot_log/annotations.h"
#include "src/developer/forensics/feedback/reboot_log/reboot_log.h"
#include "src/developer/forensics/feedback/redactor_factory.h"
#include "src/developer/forensics/utils/cobalt/logger.h"
#include "src/developer/forensics/utils/component/component.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/lib/fxl/strings/split_string.h"
#include "src/lib/uuid/uuid.h"
namespace forensics::feedback {
int main() {
syslog::SetTags({"forensics", "feedback"});
auto crash_reports_config = GetCrashReportsConfig();
if (!crash_reports_config) {
FX_LOGS(FATAL) << "Failed to get config for crash reporting";
return EXIT_FAILURE;
}
auto feedback_data_config = GetFeedbackDataConfig();
if (!feedback_data_config) {
FX_LOGS(FATAL) << "Failed to get config for feedback data";
return EXIT_FAILURE;
}
// TODO(fxbug.dev/100847): stop deleting migration file once all devices are running F8+.
files::DeletePath("/data/migration_log.json", /*recursive=*/false);
forensics::component::Component component;
std::unique_ptr<cobalt::Logger> cobalt = std::make_unique<cobalt::Logger>(
component.Dispatcher(), component.Services(), component.Clock());
if (component.IsFirstInstance()) {
MovePreviousRebootReason();
CreatePreviousLogsFile(cobalt.get());
MoveAndRecordBootId(uuid::Generate());
if (std::string build_version; files::ReadFileToString(kBuildVersionPath, &build_version)) {
MoveAndRecordBuildVersion(build_version);
}
}
auto reboot_log = RebootLog::ParseRebootLog(
"/boot/log/last-panic.txt", kPreviousGracefulRebootReasonFile, TestAndSetNotAFdr());
const bool limit_inspect_data = files::IsFile(kLimitInspectDataPath);
const bool spawn_system_log_recorder = !files::IsFile(kDoNotLaunchSystemLogRecorder);
std::optional<std::string> local_device_id_path = kDeviceIdPath;
if (files::IsFile(kUseRemoteDeviceIdProviderPath)) {
local_device_id_path = std::nullopt;
}
std::optional<zx::duration> delete_previous_boot_logs_time(std::nullopt);
if (files::IsFile(kPreviousLogsFilePath)) {
delete_previous_boot_logs_time = zx::hour(24);
}
const auto startup_annotations = GetStartupAnnotations(reboot_log);
std::unique_ptr<MainService> main_service = std::make_unique<MainService>(
component.Dispatcher(), component.Services(), component.Clock(), component.InspectRoot(),
cobalt.get(), startup_annotations,
MainService::Options{
local_device_id_path,
LastReboot::Options{
.is_first_instance = component.IsFirstInstance(),
.reboot_log = reboot_log,
.graceful_reboot_reason_write_path = kCurrentGracefulRebootReasonFile,
.oom_crash_reporting_delay = kOOMCrashReportingDelay,
},
CrashReports::Options{
.config = *crash_reports_config,
.snapshot_manager_max_annotations_size = kSnapshotAnnotationsMaxSize,
.snapshot_manager_max_archives_size = kSnapshotArchivesMaxSize,
.snapshot_manager_window_duration = kSnapshotSharedRequestWindow,
},
FeedbackData::Options{
.config = *feedback_data_config,
.is_first_instance = component.IsFirstInstance(),
.limit_inspect_data = limit_inspect_data,
.spawn_system_log_recorder = spawn_system_log_recorder,
.delete_previous_boot_logs_time = delete_previous_boot_logs_time,
}});
component.AddPublicService(main_service->GetHandler<fuchsia::feedback::LastRebootInfoProvider>());
component.AddPublicService(main_service->GetHandler<fuchsia::feedback::CrashReporter>());
component.AddPublicService(
main_service->GetHandler<fuchsia::feedback::CrashReportingProductRegister>());
component.AddPublicService(main_service->GetHandler<fuchsia::feedback::ComponentDataRegister>());
component.AddPublicService(main_service->GetHandler<fuchsia::feedback::DataProvider>());
component.AddPublicService(main_service->GetHandler<fuchsia::feedback::DataProviderController>());
zx::channel lifecycle_channel(zx_take_startup_handle(PA_LIFECYCLE));
component.OnStopSignal(::fidl::InterfaceRequest<fuchsia::process::lifecycle::Lifecycle>(
std::move(lifecycle_channel)),
[&](::fit::deferred_callback stop_respond) {
FX_LOGS(INFO)
<< "Received stop signal; stopping upload, but not exiting "
"to continue persisting new reports and logs";
main_service->ShutdownImminent(std::move(stop_respond));
});
component.RunLoop();
return EXIT_SUCCESS;
}
} // namespace forensics::feedback