blob: 85205092bf2712e7ba1c9a7759efe3ef9b003866 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fcntl.h>
#include <unistd.h>
#include <absl/cleanup/cleanup.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/values.h>
#include <brillo/key_value_store.h>
#include <brillo/process/process.h>
#include <brillo/syslog_logging.h>
#include <libcrossystem/crossystem.h>
#include <libhwsec-foundation/tlcl_wrapper/tlcl_wrapper_impl.h>
#include <libstorage/platform/platform.h>
#include <vpd/vpd.h>
#include "init/metrics/metrics.h"
#include "init/startup/chromeos_startup.h"
#include "init/startup/flags.h"
#include "init/startup/mount_helper.h"
#include "init/startup/mount_helper_factory.h"
#include "init/startup/startup_dep_impl.h"
namespace {
// Given that we want to be able to log even if the stateful_partition fails to
// mount we write the logs to /dev/kmsg so they are included in the kernel
// console output. This is especially useful for troubleshooting boot loops.
constexpr char kLogFile[] = "/dev/kmsg";
constexpr char kLsbRelease[] = "/etc/lsb-release";
constexpr char kPrintkDevkmsg[] = "/proc/sys/kernel/printk_devkmsg";
constexpr char kStatefulPartition[] = "/mnt/stateful_partition";
constexpr char kChromeosStartupMetricsPath[] =
"/run/chromeos_startup/metrics.chromeos_startup";
} // namespace
int main(int argc, char* argv[]) {
// Set up logging to a file to record any unexpected but non-fatal
// behavior.
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_FILE;
settings.log_file_path = kLogFile;
settings.lock_log = logging::DONT_LOCK_LOG_FILE;
settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE;
logging::InitLogging(settings);
std::unique_ptr<libstorage::Platform> platform =
std::make_unique<libstorage::Platform>();
// dmesg already handles the timestamp.
logging::SetLogItems(false, false, false, false);
std::string printk_devkmsg_value("ratelimit\n");
// Temporarily disable printk ratelimiting until this exits.
if (!platform->ReadFileToString(base::FilePath(kPrintkDevkmsg),
&printk_devkmsg_value)) {
PLOG(ERROR) << "Failed to read " << kPrintkDevkmsg;
}
absl::Cleanup restore_rate_limit = [&]() {
if (!platform->WriteStringToFile(base::FilePath(kPrintkDevkmsg),
printk_devkmsg_value)) {
PLOG(ERROR) << "Failed to restore " << kPrintkDevkmsg;
}
};
if (!platform->WriteStringToFile(base::FilePath(kPrintkDevkmsg), "on\n")) {
PLOG(ERROR) << "Failed to write " << kPrintkDevkmsg;
}
startup::Flags flags;
startup::ChromeosStartup::ParseFlags(&flags, argc, argv);
// A decreasing number is more verbose and numbers below zero are OK.
logging::SetMinLogLevel(logging::LOGGING_WARNING - flags.verbosity);
// Create metric object to store UMA stats.
init_metrics::ScopedInitMetricsSingleton scoped_metrics(
kChromeosStartupMetricsPath);
std::unique_ptr<libstorage::StorageContainerFactory>
storage_container_factory =
std::make_unique<libstorage::StorageContainerFactory>(
platform.get(), init_metrics::InitMetrics::GetInternal());
std::unique_ptr<startup::StartupDep> startup_dep =
std::make_unique<startup::StartupDep>(platform.get());
startup::MountHelperFactory mount_helper_factory(
platform.get(), startup_dep.get(), flags, base::FilePath("/"),
base::FilePath(kStatefulPartition), base::FilePath(kLsbRelease));
std::unique_ptr<startup::MountHelper> mount_helper =
mount_helper_factory.Generate(std::move(storage_container_factory));
std::unique_ptr<hwsec_foundation::TlclWrapper> tlcl =
std::make_unique<hwsec_foundation::TlclWrapperImpl>();
std::unique_ptr<startup::ChromeosStartup> startup =
std::make_unique<startup::ChromeosStartup>(
std::make_unique<vpd::Vpd>(), flags, base::FilePath("/"),
base::FilePath(kStatefulPartition), base::FilePath(kLsbRelease),
platform.get(), startup_dep.get(), std::move(mount_helper),
std::move(tlcl), init_metrics::InitMetrics::Get());
return startup->Run();
}