Skip to content

Commit 56d8501

Browse files
committed
Using VerifyUpdateScriptPath config param to decide if an update can be marked as good
Signed-off-by: Piet Gömpel <[email protected]>
1 parent f639cfa commit 56d8501

File tree

3 files changed

+54
-25
lines changed

3 files changed

+54
-25
lines changed

lib/everest/system/include/everest/system/rauc-dbus-base.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ struct UpdateTransaction {
6767
std::string primary_slot;
6868
};
6969

70+
enum class HealthCheckStatus {
71+
Success,
72+
ScriptNotSet,
73+
ScriptNotExecutable,
74+
SetupFailed,
75+
ScriptError
76+
};
77+
7078
Operation string_to_operation(const std::string_view& s);
7179
// Stream operators are needed for type conversion in sdbus
7280
sdbus::Message& operator<<(sdbus::Message& msg, const Progress& items);
@@ -84,15 +92,15 @@ class RaucBase {
8492
using slot_info_t = std::map<std::string, std::map<std::string, std::string>>;
8593

8694
struct CurrentState {
87-
int system_health_rc;
95+
rauc_messages::HealthCheckStatus system_health_rc;
8896
std::string boot_slot;
8997
std::string primary_slot;
9098
};
9199

92100
RaucBase();
93101
RaucBase(sdbus::dont_run_event_loop_thread_t);
94102

95-
void configure();
103+
void configure(const std::string& verify_update_script_path = "");
96104
bool check_previous_transaction(const CurrentState& current, const rauc_messages::UpdateTransaction& saved);
97105

98106
// methods
@@ -109,7 +117,7 @@ class RaucBase {
109117
using slots_t = std::vector<sdbus::Struct<std::string, std::map<std::string, sdbus::Variant>>>;
110118
static slot_info_t convert(slots_t& slots);
111119

112-
int check_system_health();
120+
rauc_messages::HealthCheckStatus check_system_health();
113121

114122
// methods
115123
sdbus::PendingAsyncCall get_primary_slot(method_cb handler, uint64_t timeout_us);
@@ -122,6 +130,9 @@ class RaucBase {
122130

123131
virtual bool decide_if_good(const rauc_messages::UpdateTransaction& saved, const CurrentState& current);
124132
virtual void configure_handlers() = 0;
133+
134+
private:
135+
std::string verify_update_script_path;
125136
};
126137

127138
// ----------------------------------------------------------------------------

lib/everest/system/src/rauc-dbus-base.cpp

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ RaucBase::RaucBase(sdbus::dont_run_event_loop_thread_t) {
124124
proxy = dbus::createProxy(defaults::service_domain, defaults::object_path, sdbus::dont_run_event_loop_thread);
125125
}
126126

127-
void RaucBase::configure() {
127+
void RaucBase::configure(const std::string& verify_update_script_path) {
128+
this->verify_update_script_path = verify_update_script_path;
128129
try {
129130
dbus::initialise_handlers(proxy, [this]() { configure_handlers(); });
130131
} catch (const sdbus::Error& e) {
@@ -204,24 +205,36 @@ RaucBase::slot_info_t RaucBase::convert(slots_t& slots) {
204205
return result;
205206
}
206207

207-
int RaucBase::check_system_health() {
208+
rauc_messages::HealthCheckStatus RaucBase::check_system_health() {
208209
// checking the success or failure of an OTA update following reboot
209-
//
210-
// get_primary_slot() may not be helpfull since it is updated as a result
211-
// of rauc status mark-active and isn't a good indicator that we have
212-
// rebooted into the newly updated partition
213-
//
214-
// get_boot_slot() should be more reliable since it indicates the slot
215-
// we booted from. This will change on a successful OTA + reboot
216-
217-
std::string cmd = "/usr/bin/check_system_health.sh";
218-
219-
// TODO(james-ctc): should the failure of this prevent the OTA being marked good?
220-
const auto res = everest::lib::system::safe_system(cmd, {"check_system_health.sh"});
221-
if (res.code != 0) {
222-
EVLOG_error << "Unable to run the system check script:" << cmd.c_str();
210+
using namespace rauc_messages;
211+
if (verify_update_script_path.empty()) {
212+
return HealthCheckStatus::ScriptNotSet;
223213
}
224-
return res.code;
214+
if (access(verify_update_script_path.c_str(), X_OK) != 0) {
215+
EVLOG_error << "Health check script '" << verify_update_script_path << "' not executable";
216+
return HealthCheckStatus::ScriptNotExecutable;
217+
}
218+
const auto res = everest::lib::system::safe_system(verify_update_script_path, {verify_update_script_path});
219+
switch (res.status) {
220+
case everest::lib::system::CMD_SETUP_FAILED:
221+
EVLOG_error << "Health check script '" << verify_update_script_path << "' setup failed, errno: " << res.code;
222+
return HealthCheckStatus::SetupFailed;
223+
case everest::lib::system::CMD_TERMINATED:
224+
EVLOG_error << "Health check script '" << verify_update_script_path << "' terminated by signal: " << res.code;
225+
return HealthCheckStatus::ScriptError;
226+
case everest::lib::system::CMD_SUCCESS:
227+
if (res.code == 0) {
228+
EVLOG_debug << "Health check script '" << verify_update_script_path << "' returned success";
229+
return HealthCheckStatus::Success;
230+
} else {
231+
EVLOG_error << "Health check script '" << verify_update_script_path
232+
<< "' returned error code: " << res.code;
233+
return HealthCheckStatus::ScriptError;
234+
}
235+
}
236+
// Should not reach here
237+
return HealthCheckStatus::ScriptError;
225238
}
226239

227240
sdbus::PendingAsyncCall RaucBase::get_operation(property_cb handler) const {
@@ -245,10 +258,15 @@ sdbus::PendingAsyncCall RaucBase::get_progress(property_cb handler) const {
245258
}
246259

247260
bool RaucBase::decide_if_good(const rauc_messages::UpdateTransaction& saved, const CurrentState& current) {
248-
// by default just check that the boot slot has changed
249-
// The return code from /usr/bin/check_system_health.sh could be used to
250-
// prevent marking as good
251-
return saved.boot_slot != current.boot_slot;
261+
// check that the boot slot has changed and update script ran successfully or was not set
262+
if (saved.boot_slot == current.boot_slot) {
263+
return false;
264+
}
265+
if (current.system_health_rc != rauc_messages::HealthCheckStatus::Success and
266+
current.system_health_rc != rauc_messages::HealthCheckStatus::ScriptNotSet) {
267+
return false;
268+
}
269+
return true;
252270
}
253271

254272
// ----------------------------------------------------------------------------

modules/Misc/Linux_Systemd_Rauc/Linux_Systemd_Rauc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace module {
3030

3131
void Linux_Systemd_Rauc::init() {
3232
invoke_init(*p_main);
33-
rauc.configure();
33+
rauc.configure(this->config.VerifyUpdateScriptPath);
3434

3535
store_path = info.id + "_update_transaction";
3636

0 commit comments

Comments
 (0)