sculpt: remove part_block upon failure

With this patch, sculpt uses init's heartbeat-monitoring mechanism to
detect the failure of part_block instances during storage disovery.
If part_block gets stuck, the device is released and can thereby
be accessed at the whole-device level.

Issue #3861
This commit is contained in:
Norman Feske 2020-08-21 14:14:18 +02:00
parent 1e7c94759d
commit a68a6665ac
3 changed files with 26 additions and 5 deletions

View File

@ -1478,6 +1478,16 @@ void Sculpt::Main::_handle_runtime_state()
}); /* for each partition */
/* respond to failure of part_block */
if (device.discovery_in_progress()) {
Child_exit_state exit_state(state, device.part_block_start_name());
if (!exit_state.responsive) {
error(device.part_block_start_name(), " got stuck");
device.state = Storage_device::RELEASED;
reconfigure_runtime = true;
}
}
/* respond to completion of GPT relabeling */
if (device.relabel_in_progress()) {
Child_exit_state exit_state(state, device.relabel_start_name());
@ -1607,6 +1617,8 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
xml.attribute("buffer", "1M");
});
xml.node("heartbeat", [&] () { xml.attribute("rate_ms", 1000); });
xml.node("parent-provides", [&] () {
gen_parent_service<Rom_session>(xml);
gen_parent_service<Cpu_session>(xml);

View File

@ -24,9 +24,10 @@ namespace Sculpt { struct Child_exit_state; }
struct Sculpt::Child_exit_state
{
bool exists = false;
bool exited = false;
int code = 0;
bool exists = false;
bool exited = false;
bool responsive = true;
int code = 0;
typedef String<64> Name;
typedef String<16> Version;
@ -39,10 +40,13 @@ struct Sculpt::Child_exit_state
if (child.attribute_value("name", Name()) == name) {
exists = true;
version = child.attribute_value("version", Version());
if (child.has_attribute("exited")) {
exited = true;
code = child.attribute_value("exited", 0L);
}
responsive = (child.attribute_value("skipped_heartbeats", 0U) <= 2);
}
});
}

View File

@ -201,8 +201,11 @@ struct Sculpt::Storage_device
return gpt_expand_in_progress() || fs_resize_in_progress();
}
Start_name relabel_start_name() const { return Start_name(label, ".relabel"); }
Start_name expand_start_name() const { return Start_name(label, ".expand"); }
bool discovery_in_progress() const { return state == UNKNOWN; }
Start_name part_block_start_name() const { return Start_name(label, ".part_block"); }
Start_name relabel_start_name() const { return Start_name(label, ".relabel"); }
Start_name expand_start_name() const { return Start_name(label, ".expand"); }
};
@ -216,6 +219,8 @@ void Sculpt::Storage_device::gen_part_block_start_content(Xml_generator &xml,
gen_named_node(xml, "binary", "part_block");
xml.node("heartbeat", [&] () { });
xml.node("config", [&] () {
xml.node("report", [&] () { xml.attribute("partitions", "yes"); });