1 #include "bootloader.h"
4 #include <sys/reboot.h>
8 #include <boost/filesystem.hpp>
10 #include "storage/invstorage.h"
11 #include "utilities/exceptions.h"
12 #include "utilities/utils.h"
15 reboot_sentinel_ = config_.reboot_sentinel_dir / config_.reboot_sentinel_name;
16 reboot_command_ = config_.reboot_command;
18 if (!Utils::createSecureDirectory(config_.reboot_sentinel_dir)) {
19 LOG_WARNING <<
"Could not create " << config_.reboot_sentinel_dir <<
" securely, reboot detection support disabled";
20 reboot_detect_supported_ =
false;
24 reboot_detect_supported_ =
true;
27 void Bootloader::setBootOK()
const {
29 switch (config_.rollback_mode) {
30 case RollbackMode::kBootloaderNone:
32 case RollbackMode::kUbootGeneric:
33 if (Utils::shell(
"fw_setenv bootcount 0", &sink) != 0) {
34 LOG_WARNING <<
"Failed resetting bootcount";
37 case RollbackMode::kUbootMasked:
38 if (Utils::shell(
"fw_setenv bootcount 0", &sink) != 0) {
39 LOG_WARNING <<
"Failed resetting bootcount";
41 if (Utils::shell(
"fw_setenv upgrade_available 0", &sink) != 0) {
42 LOG_WARNING <<
"Failed resetting upgrade_available for u-boot";
50 void Bootloader::updateNotify()
const {
52 switch (config_.rollback_mode) {
53 case RollbackMode::kBootloaderNone:
55 case RollbackMode::kUbootGeneric:
56 if (Utils::shell(
"fw_setenv bootcount 0", &sink) != 0) {
57 LOG_WARNING <<
"Failed resetting bootcount";
59 if (Utils::shell(
"fw_setenv rollback 0", &sink) != 0) {
60 LOG_WARNING <<
"Failed resetting rollback flag";
63 case RollbackMode::kUbootMasked:
64 if (Utils::shell(
"fw_setenv bootcount 0", &sink) != 0) {
65 LOG_WARNING <<
"Failed resetting bootcount";
67 if (Utils::shell(
"fw_setenv upgrade_available 1", &sink) != 0) {
68 LOG_WARNING <<
"Failed setting upgrade_available for u-boot";
70 if (Utils::shell(
"fw_setenv rollback 0", &sink) != 0) {
71 LOG_WARNING <<
"Failed resetting rollback flag";
79 bool Bootloader::supportRebootDetection()
const {
return reboot_detect_supported_; }
81 bool Bootloader::rebootDetected()
const {
82 if (!reboot_detect_supported_) {
88 bool sentinel_exists = boost::filesystem::exists(reboot_sentinel_);
89 bool need_reboot =
false;
91 storage_.loadNeedReboot(&need_reboot);
93 return need_reboot && !sentinel_exists;
96 void Bootloader::rebootFlagSet() {
97 if (!reboot_detect_supported_) {
103 Utils::writeFile(reboot_sentinel_, std::string(),
false);
104 storage_.storeNeedReboot();
107 void Bootloader::rebootFlagClear() {
108 if (!reboot_detect_supported_) {
114 storage_.clearNeedReboot();
115 boost::filesystem::remove(reboot_sentinel_);
118 void Bootloader::reboot(
bool fake_reboot) {
120 boost::filesystem::remove(reboot_sentinel_);
123 if (setuid(0) != 0) {
124 LOG_ERROR <<
"Failed to set/verify a root user so cannot reboot system programmatically";
128 if (system(reboot_command_.c_str()) != 0) {
129 LOG_ERROR <<
"Failed to execute the reboot command: " << reboot_command_;