diff --git a/repos/gems/sculpt/default-linux.sculpt b/repos/gems/sculpt/default-linux.sculpt
index 277fe8e23d..65264839ac 100644
--- a/repos/gems/sculpt/default-linux.sculpt
+++ b/repos/gems/sculpt/default-linux.sculpt
@@ -2,6 +2,7 @@
drivers: linux
deploy: example
ram_fs: depot
+manager: use_ram_fs
# selection of launcher-menu entries
launcher: sticks_blue_backdrop nano3d system_shell
diff --git a/repos/gems/sculpt/manager/use_ram_fs b/repos/gems/sculpt/manager/use_ram_fs
new file mode 100644
index 0000000000..b89d7ddde6
--- /dev/null
+++ b/repos/gems/sculpt/manager/use_ram_fs
@@ -0,0 +1,3 @@
+
+
+
diff --git a/repos/gems/src/app/phone_manager/main.cc b/repos/gems/src/app/phone_manager/main.cc
index edad695579..29f3434164 100644
--- a/repos/gems/src/app/phone_manager/main.cc
+++ b/repos/gems/src/app/phone_manager/main.cc
@@ -255,6 +255,8 @@ struct Sculpt::Main : Input_event_handler,
void _handle_config(Xml_node const &config)
{
+ _handle_storage_devices();
+
_verbose_modem = config.attribute_value("verbose_modem", false);
}
@@ -303,20 +305,22 @@ struct Sculpt::Main : Input_event_handler,
void _handle_storage_devices()
{
- Storage_target const orig_sculpt_partition = _storage._sculpt_partition;
+ Storage_target const orig_target = _storage._selected_target;
bool total_progress = false;
for (bool progress = true; progress; total_progress |= progress) {
progress = false;
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
- progress = _storage.update(devices.usb, devices.ahci,
- devices.nvme, devices.mmc).progress; });
+ _config.with_xml([&] (Xml_node const &config) {
+ progress = _storage.update(config,
+ devices.usb, devices.ahci,
+ devices.nvme, devices.mmc).progress; }); });
/* update USB policies for storage devices */
_drivers.update_usb();
}
- if (orig_sculpt_partition != _storage._sculpt_partition)
+ if (orig_target != _storage._selected_target)
_restart_from_storage_target();
if (total_progress) {
@@ -410,7 +414,7 @@ struct Sculpt::Main : Input_event_handler,
*/
bool _update_running() const
{
- return _storage._sculpt_partition.valid()
+ return _storage._selected_target.valid()
&& !_prepare_in_progress()
&& _network.ready()
&& _deploy.update_needed();
@@ -750,7 +754,7 @@ struct Sculpt::Main : Input_event_handler,
Conditional_widget _storage_widget {
Conditional_widget::Attr { .centered = true },
- Id { "storage dialog" }, _storage._storage_devices, _storage._sculpt_partition };
+ Id { "storage dialog" }, _storage._storage_devices, _storage._selected_target };
/*
* Network section
@@ -797,7 +801,7 @@ struct Sculpt::Main : Input_event_handler,
Conditional_widget
_graph { Id { "graph" },
_runtime_state, _cached_runtime_config, _storage._storage_devices,
- _storage._sculpt_partition, _storage._ram_fs_state,
+ _storage._selected_target, _storage._ram_fs_state,
_popup.state, _deploy._children };
Conditional_widget
@@ -897,28 +901,28 @@ struct Sculpt::Main : Input_event_handler,
_software_title_bar.view_status(s, _software_status_message()); });
s.widget(_software_tabs_widget, _software_title_bar.selected(),
- _storage._sculpt_partition, _presets, _software_status_available());
+ _storage._selected_target, _presets, _software_status_available());
s.widget(_graph, _software_title_bar.selected()
&& _software_tabs_widget.hosted.runtime_selected());
s.widget(_software_presets_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.presets_selected()
- && _storage._sculpt_partition.valid(),
+ && _storage._selected_target.valid(),
_presets);
s.widget(_software_options_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.options_selected()
- && _storage._sculpt_partition.valid());
+ && _storage._selected_target.valid());
s.widget(_software_add_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.add_selected()
- && _storage._sculpt_partition.valid());
+ && _storage._selected_target.valid());
_image_index_rom.with_xml([&] (Xml_node const &image_index) {
s.widget(_software_update_widget, _software_title_bar.selected()
&& _software_tabs_widget.hosted.update_selected()
- && _storage._sculpt_partition.valid(),
+ && _storage._selected_target.valid(),
image_index);
});
@@ -966,7 +970,7 @@ struct Sculpt::Main : Input_event_handler,
void _handle_runtime_state(Xml_node const &);
- Runtime_state _runtime_state { _heap, _storage._sculpt_partition };
+ Runtime_state _runtime_state { _heap, _storage._selected_target };
Managed_config _runtime_config {
_env, "config", "runtime", *this, &Main::_handle_runtime };
@@ -1314,9 +1318,15 @@ struct Sculpt::Main : Input_event_handler,
void use(Storage_target const &target) override
{
- _storage._sculpt_partition = target;
+ Storage_target const orig_target = _storage._selected_target;
+
+ _storage._selected_target = target;
_software_update_widget.hosted.reset();
_download_queue.reset();
+
+ if (orig_target != _storage._selected_target)
+ _restart_from_storage_target();
+
generate_runtime_config();
}
@@ -2382,7 +2392,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
/*
* Load configuration and update depot config on the sculpt partition
*/
- if (_storage._sculpt_partition.valid() && _prepare_in_progress())
+ if (_storage._selected_target.valid() && _prepare_in_progress())
xml.node("start", [&] {
gen_prepare_start_content(xml, _prepare_version); });
@@ -2390,7 +2400,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
* Spawn chroot instances for accessing '/depot' and '/public'. The
* chroot instances implicitly refer to the 'default_fs_rw'.
*/
- if (_storage._sculpt_partition.valid()) {
+ if (_storage._selected_target.valid()) {
auto chroot = [&] (Start_name const &name, Path const &path, Writeable w) {
xml.node("start", [&] {
@@ -2405,7 +2415,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
}
/* execute file operations */
- if (_storage._sculpt_partition.valid())
+ if (_storage._selected_target.valid())
if (_file_operation_queue.any_operation_in_progress())
xml.node("start", [&] {
gen_fs_tool_start_content(xml, _fs_tool_version,
@@ -2417,7 +2427,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
xml.node("start", [&] {
gen_update_start_content(xml); });
- if (_storage._sculpt_partition.valid() && !_prepare_in_progress()) {
+ if (_storage._selected_target.valid() && !_prepare_in_progress()) {
xml.node("start", [&] {
gen_launcher_query_start_content(xml); });
diff --git a/repos/gems/src/app/sculpt_manager/graph.cc b/repos/gems/src/app/sculpt_manager/graph.cc
index 706b142f6d..825c0d2d1d 100644
--- a/repos/gems/src/app/sculpt_manager/graph.cc
+++ b/repos/gems/src/app/sculpt_manager/graph.cc
@@ -98,7 +98,7 @@ void Graph::_view_selected_node_content(Scope &s,
}
if (name == "ram_fs")
- s.widget(_ram_fs_widget, _sculpt_partition, _ram_fs_state);
+ s.widget(_ram_fs_widget, _selected_target, _ram_fs_state);
String<100> const
ram (Capacity{info.assigned_ram - info.avail_ram}, " / ",
@@ -130,7 +130,7 @@ void Graph::_view_selected_node_content(Scope &s,
void Graph::view(Scope &s) const
{
- if (Feature::PRESENT_PLUS_MENU && _sculpt_partition.valid())
+ if (Feature::PRESENT_PLUS_MENU && _selected_target.valid())
s.widget(_plus, _popup_state == Popup::VISIBLE);
/* parent roles */
@@ -185,7 +185,7 @@ void Graph::view(Scope &s) const
Dialog::Id primary_dep = Id { component.primary_dependency };
if (primary_dep.value == "default_fs_rw")
- primary_dep = Dialog::Id { _sculpt_partition.fs() };
+ primary_dep = Dialog::Id { _selected_target.fs() };
/* primary dependency is another component */
_runtime_config.with_graph_id(primary_dep,
@@ -222,7 +222,7 @@ void Graph::view(Scope &s) const
return;
if (dep_name == "default_fs_rw")
- dep_name = _sculpt_partition.fs();
+ dep_name = _selected_target.fs();
Dialog::Id dep_id { dep_name };
@@ -264,7 +264,7 @@ void Graph::click(Clicked_at const &at, Action &action)
action.open_popup_dialog(popup_anchor(at._location));
});
- _ram_fs_widget .propagate(at, _sculpt_partition, action);
+ _ram_fs_widget .propagate(at, _selected_target, action);
_ahci_devices_widget.propagate(at, action);
_nvme_devices_widget.propagate(at, action);
_mmc_devices_widget .propagate(at, action);
diff --git a/repos/gems/src/app/sculpt_manager/graph.h b/repos/gems/src/app/sculpt_manager/graph.h
index ea953a3df4..d9a850e84a 100644
--- a/repos/gems/src/app/sculpt_manager/graph.h
+++ b/repos/gems/src/app/sculpt_manager/graph.h
@@ -40,7 +40,7 @@ struct Sculpt::Graph : Widget
Runtime_state &_runtime_state;
Runtime_config const &_runtime_config;
Storage_devices const &_storage_devices;
- Storage_target const &_sculpt_partition;
+ Storage_target const &_selected_target;
Ram_fs_state const &_ram_fs_state;
Popup::State const &_popup_state;
Depot_deploy::Children const &_deploy_children;
@@ -56,19 +56,19 @@ struct Sculpt::Graph : Widget
Hosted
_ahci_devices_widget { Id { "ahci_devices" },
- _storage_devices, _sculpt_partition };
+ _storage_devices, _selected_target };
Hosted
_nvme_devices_widget { Id { "nvme_devices" },
- _storage_devices, _sculpt_partition };
+ _storage_devices, _selected_target };
Hosted
_mmc_devices_widget { Id { "mmc_devices" },
- _storage_devices, _sculpt_partition };
+ _storage_devices, _selected_target };
Hosted
_usb_devices_widget { Id { "usb_devices" },
- _storage_devices, _sculpt_partition };
+ _storage_devices, _selected_target };
bool _storage_selected = false;
@@ -79,13 +79,13 @@ struct Sculpt::Graph : Widget
Graph(Runtime_state &runtime_state,
Runtime_config const &runtime_config,
Storage_devices const &storage_devices,
- Storage_target const &sculpt_partition,
+ Storage_target const &selected_target,
Ram_fs_state const &ram_fs_state,
Popup::State const &popup_state,
Depot_deploy::Children const &deploy_children)
:
_runtime_state(runtime_state), _runtime_config(runtime_config),
- _storage_devices(storage_devices), _sculpt_partition(sculpt_partition),
+ _storage_devices(storage_devices), _selected_target(selected_target),
_ram_fs_state(ram_fs_state), _popup_state(popup_state),
_deploy_children(deploy_children)
{ }
diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc
index 3a9008c01d..b19e6f59d8 100644
--- a/repos/gems/src/app/sculpt_manager/main.cc
+++ b/repos/gems/src/app/sculpt_manager/main.cc
@@ -119,6 +119,13 @@ struct Sculpt::Main : Input_event_handler,
void _handle_gui_mode();
+ Rom_handler _config { _env, "config", *this, &Main::_handle_config };
+
+ void _handle_config(Xml_node const &)
+ {
+ _handle_storage_devices();
+ }
+
Screensaver _screensaver { _env, *this };
/**
@@ -249,20 +256,22 @@ struct Sculpt::Main : Input_event_handler,
void _handle_storage_devices()
{
- Storage_target const orig_sculpt_partition = _storage._sculpt_partition;
+ Storage_target const orig_target = _storage._selected_target;
bool total_progress = false;
for (bool progress = true; progress; total_progress |= progress) {
progress = false;
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
- progress = _storage.update(devices.usb, devices.ahci,
- devices.nvme, devices.mmc).progress; });
+ _config.with_xml([&] (Xml_node const &config) {
+ progress = _storage.update(config,
+ devices.usb, devices.ahci,
+ devices.nvme, devices.mmc).progress; }); });
/* update USB policies for storage devices */
_drivers.update_usb();
}
- if (orig_sculpt_partition != _storage._sculpt_partition)
+ if (orig_target != _storage._selected_target)
_restart_from_storage_target();
if (total_progress) {
@@ -381,7 +390,7 @@ struct Sculpt::Main : Input_event_handler,
*/
bool _update_running() const
{
- return _storage._sculpt_partition.valid()
+ return _storage._selected_target.valid()
&& !_prepare_in_progress()
&& _network.ready()
&& _deploy.update_needed();
@@ -603,7 +612,7 @@ struct Sculpt::Main : Input_event_handler,
bool system_available() const override
{
- return _storage._sculpt_partition.valid() && !_prepare_in_progress();
+ return _storage._selected_target.valid() && !_prepare_in_progress();
}
struct Diag_dialog : Top_level_dialog
@@ -669,7 +678,7 @@ struct Sculpt::Main : Input_event_handler,
void _handle_runtime_state(Xml_node const &);
- Runtime_state _runtime_state { _heap, _storage._sculpt_partition };
+ Runtime_state _runtime_state { _heap, _storage._selected_target };
Managed_config _runtime_config {
_env, "config", "runtime", *this, &Main::_handle_runtime };
@@ -801,10 +810,15 @@ struct Sculpt::Main : Input_event_handler,
void use(Storage_target const &target) override
{
- _storage._sculpt_partition = target;
+ Storage_target const orig_target = _storage._selected_target;
+
+ _storage._selected_target = target;
_system_dialog.reset_update_widget();
_download_queue.reset();
+ if (orig_target != _storage._selected_target)
+ _restart_from_storage_target();
+
/* hide system panel button and system dialog when "un-using" */
_panel_dialog.refresh();
_system_dialog.refresh();
@@ -1394,7 +1408,7 @@ struct Sculpt::Main : Input_event_handler,
Popup _popup { };
Graph _graph { _runtime_state, _cached_runtime_config, _storage._storage_devices,
- _storage._sculpt_partition, _storage._ram_fs_state,
+ _storage._selected_target, _storage._ram_fs_state,
_popup.state, _deploy._children };
struct Graph_dialog : Dialog::Top_level_dialog
@@ -2049,7 +2063,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
/*
* Load configuration and update depot config on the sculpt partition
*/
- if (_storage._sculpt_partition.valid() && _prepare_in_progress())
+ if (_storage._selected_target.valid() && _prepare_in_progress())
xml.node("start", [&] {
gen_prepare_start_content(xml, _prepare_version); });
@@ -2061,7 +2075,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
* Spawn chroot instances for accessing '/depot' and '/public'. The
* chroot instances implicitly refer to the 'default_fs_rw'.
*/
- if (_storage._sculpt_partition.valid()) {
+ if (_storage._selected_target.valid()) {
auto chroot = [&] (Start_name const &name, Path const &path, Writeable w) {
xml.node("start", [&] {
@@ -2076,7 +2090,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
}
/* execute file operations */
- if (_storage._sculpt_partition.valid())
+ if (_storage._selected_target.valid())
if (_file_operation_queue.any_operation_in_progress())
xml.node("start", [&] {
gen_fs_tool_start_content(xml, _fs_tool_version,
@@ -2088,7 +2102,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
xml.node("start", [&] {
gen_update_start_content(xml); });
- if (_storage._sculpt_partition.valid() && !_prepare_in_progress()) {
+ if (_storage._selected_target.valid() && !_prepare_in_progress()) {
xml.node("start", [&] {
gen_launcher_query_start_content(xml); });
diff --git a/repos/gems/src/app/sculpt_manager/model/storage_target.h b/repos/gems/src/app/sculpt_manager/model/storage_target.h
index 10e7eb842d..166878af70 100644
--- a/repos/gems/src/app/sculpt_manager/model/storage_target.h
+++ b/repos/gems/src/app/sculpt_manager/model/storage_target.h
@@ -28,6 +28,15 @@ struct Sculpt::Storage_target
Storage_device::Port port;
Partition::Number partition;
+ static Storage_target from_xml(Xml_node const &target)
+ {
+ return {
+ .driver = target.attribute_value("driver", Storage_device::Driver()),
+ .port = target.attribute_value("port", Storage_device::Port()),
+ .partition = target.attribute_value("partition", Partition::Number())
+ };
+ }
+
bool operator == (Storage_target const &other) const
{
return (driver == other.driver)
diff --git a/repos/gems/src/app/sculpt_manager/storage.cc b/repos/gems/src/app/sculpt_manager/storage.cc
index f6dc03473d..b943aa7adb 100644
--- a/repos/gems/src/app/sculpt_manager/storage.cc
+++ b/repos/gems/src/app/sculpt_manager/storage.cc
@@ -17,7 +17,8 @@
using namespace Sculpt;
-Progress Storage::update(Xml_node const &usb, Xml_node const &ahci,
+Progress Storage::update(Xml_node const &config,
+ Xml_node const &usb, Xml_node const &ahci,
Xml_node const &nvme, Xml_node const &mmc)
{
bool progress = false;
@@ -36,49 +37,67 @@ Progress Storage::update(Xml_node const &usb, Xml_node const &ahci,
_storage_devices.usb_storage_devices.for_each([&] (Usb_storage_device &dev) {
dev.process_report(); });
- if (!_sculpt_partition.valid()) {
+ Storage_target const orig_selected_target = _selected_target;
+ Storage_target const orig_configured_target = _configured_target;
+
+ config.with_sub_node("target",
+ [&] (Xml_node const &target) {
+ Storage_target const configured_target = Storage_target::from_xml(target);
+ if (configured_target != _configured_target) {
+ _configured_target = configured_target;
+ _malconfiguration = false; } },
+
+ [&] { _configured_target = { }; });
+
+ if (orig_configured_target != _configured_target)
+ _selected_target = { };
+
+ if (!_selected_target.valid()) {
bool const all_devices_enumerated = !usb .has_type("empty")
&& !ahci.has_type("empty")
&& !nvme.has_type("empty")
&& !mmc .has_type("empty");
if (all_devices_enumerated) {
-
- Storage_target const default_target =
- _discovery_state.detect_default_target(_storage_devices);
-
- if (default_target.valid()) {
- _sculpt_partition = default_target;
- progress |= true;
- }
+ if (_configured_target.valid())
+ _selected_target = _malconfiguration ? Storage_target { } : _configured_target;
+ else
+ _selected_target = _discovery_state.detect_default_target(_storage_devices);
}
}
/*
* Detect the removal of a USB stick that is currently in "use". Reset
- * the '_sculpt_partition' to enable the selection of another storage
+ * the '_selected_target' to enable the selection of another storage
* target to use.
*/
- else if (_sculpt_partition.valid()) {
+ else if (_selected_target.valid()) {
- bool sculpt_partition_exists = false;
+ bool selected_target_exists = false;
- if (_sculpt_partition.ram_fs())
- sculpt_partition_exists = true;
+ if (_selected_target.ram_fs())
+ selected_target_exists = true;
_storage_devices.for_each([&] (Storage_device const &device) {
device.for_each_partition([&] (Partition const &partition) {
- if (device.driver == _sculpt_partition.driver
- && partition.number == _sculpt_partition.partition)
- sculpt_partition_exists = true; }); });
+ if (device.driver == _selected_target.driver
+ && partition.number == _selected_target.partition)
+ selected_target_exists = true; }); });
- if (!sculpt_partition_exists) {
- warning("sculpt partition unexpectedly vanished");
- _sculpt_partition = Storage_target { };
- progress |= true;
+ if (!selected_target_exists) {
+ if (_configured_target.valid()) {
+ warning("configured storage target does not exist");
+ _malconfiguration = true;
+ } else {
+ warning("selected storage target unexpectedly vanished");
+ }
+
+ _selected_target = { };
}
}
+ progress |= (orig_selected_target != _selected_target);
+
return { progress };
}
@@ -90,11 +109,11 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
auto contains_used_fs = [&] (Storage_device const &device)
{
- if (!_sculpt_partition.valid())
+ if (!_selected_target.valid())
return false;
- return (device.port == _sculpt_partition.port)
- && (device.driver == _sculpt_partition.driver);
+ return (device.port == _selected_target.port)
+ && (device.driver == _selected_target.driver);
};
_storage_devices.usb_storage_devices.for_each([&] (Usb_storage_device const &device) {
@@ -135,7 +154,7 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
gen_resize2fs_start_content(xml, target); }); }
if (partition.file_system.type != File_system::UNKNOWN) {
- if (partition.file_system.inspected || target == _sculpt_partition)
+ if (partition.file_system.inspected || target == _selected_target)
xml.node("start", [&] {
gen_fs_start_content(xml, target, partition.file_system.type); });
@@ -144,7 +163,7 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
* to as "default_fs_rw" without the need to know the name of the
* underlying storage target.
*/
- if (target == _sculpt_partition)
+ if (target == _selected_target)
gen_named_node(xml, "alias", "default_fs_rw", [&] {
xml.attribute("child", target.fs()); });
}
@@ -163,7 +182,7 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
}); /* for each device */
- if (_sculpt_partition.ram_fs())
+ if (_selected_target.ram_fs())
gen_named_node(xml, "alias", "default_fs_rw", [&] {
xml.attribute("child", "ram_fs"); });
}
diff --git a/repos/gems/src/app/sculpt_manager/storage.h b/repos/gems/src/app/sculpt_manager/storage.h
index 01eef4d17d..f520f9b166 100644
--- a/repos/gems/src/app/sculpt_manager/storage.h
+++ b/repos/gems/src/app/sculpt_manager/storage.h
@@ -31,13 +31,17 @@ struct Sculpt::Storage : Noncopyable
Ram_fs_state _ram_fs_state;
- Storage_target _sculpt_partition { };
+ Storage_target _configured_target { },
+ _selected_target { };
+
+ bool _malconfiguration = false;
Discovery_state _discovery_state { };
Inspect_view_version _inspect_view_version { 0 };
- Progress update(Xml_node const &usb_devices, Xml_node const &ahci_ports,
+ Progress update(Xml_node const &config,
+ Xml_node const &usb_devices, Xml_node const &ahci_ports,
Xml_node const &nvme_namespaces, Xml_node const &mmc_devices);
/*