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); /*