mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-05 17:01:47 +00:00
sculpt: make storage target configurable
This patch lays the selection of the used storage target into the hands of the config/manager file. By default, Sculpt selects the target by its built-in heuristics, probing for a Sculpt partition. However, by specifying a <target> node, one can explicitly select a storage target. E.g., for using the 2nd partition of the SATA disk connected to port 1 of the AHCI controller, one can now specify: <target driver="ahci" port="1" partition="2"/> For selecting the ram_fs as target: <target driver="ram_fs"/> The latter case is particularly useful for custom Sculpt scenarios deployed entirely from RAM. For such scenarios, add two lines to your .sculpt file: ram_fs: depot manager: use_ram_fs The first line configures the ram_fs such that the depot is mounted as a tar archive. The second line configures the sculpt manager to select the ram_fs as storage target. You can find this feature exemplified in default-linux.sculpt scenario. build/x86_64$ make run/sculpt_test KERNEL=linux BOARD=linux It is worth noting that the configuration can be changed at runtime. This allows for switching between different storage targets on the fly. Issue #5166
This commit is contained in:
parent
508e0bdfbf
commit
4a1a29b3d0
@ -2,6 +2,7 @@
|
|||||||
drivers: linux
|
drivers: linux
|
||||||
deploy: example
|
deploy: example
|
||||||
ram_fs: depot
|
ram_fs: depot
|
||||||
|
manager: use_ram_fs
|
||||||
|
|
||||||
# selection of launcher-menu entries
|
# selection of launcher-menu entries
|
||||||
launcher: sticks_blue_backdrop nano3d system_shell
|
launcher: sticks_blue_backdrop nano3d system_shell
|
||||||
|
3
repos/gems/sculpt/manager/use_ram_fs
Normal file
3
repos/gems/sculpt/manager/use_ram_fs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<config>
|
||||||
|
<target driver="ram_fs"/>
|
||||||
|
</config>
|
@ -255,6 +255,8 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_config(Xml_node const &config)
|
void _handle_config(Xml_node const &config)
|
||||||
{
|
{
|
||||||
|
_handle_storage_devices();
|
||||||
|
|
||||||
_verbose_modem = config.attribute_value("verbose_modem", false);
|
_verbose_modem = config.attribute_value("verbose_modem", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,20 +305,22 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_storage_devices()
|
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;
|
bool total_progress = false;
|
||||||
for (bool progress = true; progress; total_progress |= progress) {
|
for (bool progress = true; progress; total_progress |= progress) {
|
||||||
progress = false;
|
progress = false;
|
||||||
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
|
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
|
||||||
progress = _storage.update(devices.usb, devices.ahci,
|
_config.with_xml([&] (Xml_node const &config) {
|
||||||
devices.nvme, devices.mmc).progress; });
|
progress = _storage.update(config,
|
||||||
|
devices.usb, devices.ahci,
|
||||||
|
devices.nvme, devices.mmc).progress; }); });
|
||||||
|
|
||||||
/* update USB policies for storage devices */
|
/* update USB policies for storage devices */
|
||||||
_drivers.update_usb();
|
_drivers.update_usb();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orig_sculpt_partition != _storage._sculpt_partition)
|
if (orig_target != _storage._selected_target)
|
||||||
_restart_from_storage_target();
|
_restart_from_storage_target();
|
||||||
|
|
||||||
if (total_progress) {
|
if (total_progress) {
|
||||||
@ -410,7 +414,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
*/
|
*/
|
||||||
bool _update_running() const
|
bool _update_running() const
|
||||||
{
|
{
|
||||||
return _storage._sculpt_partition.valid()
|
return _storage._selected_target.valid()
|
||||||
&& !_prepare_in_progress()
|
&& !_prepare_in_progress()
|
||||||
&& _network.ready()
|
&& _network.ready()
|
||||||
&& _deploy.update_needed();
|
&& _deploy.update_needed();
|
||||||
@ -750,7 +754,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
Conditional_widget<Storage_widget> _storage_widget {
|
Conditional_widget<Storage_widget> _storage_widget {
|
||||||
Conditional_widget<Storage_widget>::Attr { .centered = true },
|
Conditional_widget<Storage_widget>::Attr { .centered = true },
|
||||||
Id { "storage dialog" }, _storage._storage_devices, _storage._sculpt_partition };
|
Id { "storage dialog" }, _storage._storage_devices, _storage._selected_target };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Network section
|
* Network section
|
||||||
@ -797,7 +801,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
Conditional_widget<Graph>
|
Conditional_widget<Graph>
|
||||||
_graph { Id { "graph" },
|
_graph { Id { "graph" },
|
||||||
_runtime_state, _cached_runtime_config, _storage._storage_devices,
|
_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 };
|
_popup.state, _deploy._children };
|
||||||
|
|
||||||
Conditional_widget<Network_widget>
|
Conditional_widget<Network_widget>
|
||||||
@ -897,28 +901,28 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
_software_title_bar.view_status(s, _software_status_message()); });
|
_software_title_bar.view_status(s, _software_status_message()); });
|
||||||
|
|
||||||
s.widget(_software_tabs_widget, _software_title_bar.selected(),
|
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()
|
s.widget(_graph, _software_title_bar.selected()
|
||||||
&& _software_tabs_widget.hosted.runtime_selected());
|
&& _software_tabs_widget.hosted.runtime_selected());
|
||||||
|
|
||||||
s.widget(_software_presets_widget, _software_title_bar.selected()
|
s.widget(_software_presets_widget, _software_title_bar.selected()
|
||||||
&& _software_tabs_widget.hosted.presets_selected()
|
&& _software_tabs_widget.hosted.presets_selected()
|
||||||
&& _storage._sculpt_partition.valid(),
|
&& _storage._selected_target.valid(),
|
||||||
_presets);
|
_presets);
|
||||||
|
|
||||||
s.widget(_software_options_widget, _software_title_bar.selected()
|
s.widget(_software_options_widget, _software_title_bar.selected()
|
||||||
&& _software_tabs_widget.hosted.options_selected()
|
&& _software_tabs_widget.hosted.options_selected()
|
||||||
&& _storage._sculpt_partition.valid());
|
&& _storage._selected_target.valid());
|
||||||
|
|
||||||
s.widget(_software_add_widget, _software_title_bar.selected()
|
s.widget(_software_add_widget, _software_title_bar.selected()
|
||||||
&& _software_tabs_widget.hosted.add_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) {
|
_image_index_rom.with_xml([&] (Xml_node const &image_index) {
|
||||||
s.widget(_software_update_widget, _software_title_bar.selected()
|
s.widget(_software_update_widget, _software_title_bar.selected()
|
||||||
&& _software_tabs_widget.hosted.update_selected()
|
&& _software_tabs_widget.hosted.update_selected()
|
||||||
&& _storage._sculpt_partition.valid(),
|
&& _storage._selected_target.valid(),
|
||||||
image_index);
|
image_index);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -966,7 +970,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_runtime_state(Xml_node const &);
|
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<Main> _runtime_config {
|
Managed_config<Main> _runtime_config {
|
||||||
_env, "config", "runtime", *this, &Main::_handle_runtime };
|
_env, "config", "runtime", *this, &Main::_handle_runtime };
|
||||||
@ -1314,9 +1318,15 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void use(Storage_target const &target) override
|
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();
|
_software_update_widget.hosted.reset();
|
||||||
_download_queue.reset();
|
_download_queue.reset();
|
||||||
|
|
||||||
|
if (orig_target != _storage._selected_target)
|
||||||
|
_restart_from_storage_target();
|
||||||
|
|
||||||
generate_runtime_config();
|
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
|
* 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", [&] {
|
xml.node("start", [&] {
|
||||||
gen_prepare_start_content(xml, _prepare_version); });
|
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
|
* Spawn chroot instances for accessing '/depot' and '/public'. The
|
||||||
* chroot instances implicitly refer to the 'default_fs_rw'.
|
* 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) {
|
auto chroot = [&] (Start_name const &name, Path const &path, Writeable w) {
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
@ -2405,7 +2415,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* execute file operations */
|
/* execute file operations */
|
||||||
if (_storage._sculpt_partition.valid())
|
if (_storage._selected_target.valid())
|
||||||
if (_file_operation_queue.any_operation_in_progress())
|
if (_file_operation_queue.any_operation_in_progress())
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
gen_fs_tool_start_content(xml, _fs_tool_version,
|
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", [&] {
|
xml.node("start", [&] {
|
||||||
gen_update_start_content(xml); });
|
gen_update_start_content(xml); });
|
||||||
|
|
||||||
if (_storage._sculpt_partition.valid() && !_prepare_in_progress()) {
|
if (_storage._selected_target.valid() && !_prepare_in_progress()) {
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
gen_launcher_query_start_content(xml); });
|
gen_launcher_query_start_content(xml); });
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void Graph::_view_selected_node_content(Scope<Depgraph, Frame, Vbox> &s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name == "ram_fs")
|
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
|
String<100> const
|
||||||
ram (Capacity{info.assigned_ram - info.avail_ram}, " / ",
|
ram (Capacity{info.assigned_ram - info.avail_ram}, " / ",
|
||||||
@ -130,7 +130,7 @@ void Graph::_view_selected_node_content(Scope<Depgraph, Frame, Vbox> &s,
|
|||||||
|
|
||||||
void Graph::view(Scope<Depgraph> &s) const
|
void Graph::view(Scope<Depgraph> &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);
|
s.widget(_plus, _popup_state == Popup::VISIBLE);
|
||||||
|
|
||||||
/* parent roles */
|
/* parent roles */
|
||||||
@ -185,7 +185,7 @@ void Graph::view(Scope<Depgraph> &s) const
|
|||||||
Dialog::Id primary_dep = Id { component.primary_dependency };
|
Dialog::Id primary_dep = Id { component.primary_dependency };
|
||||||
|
|
||||||
if (primary_dep.value == "default_fs_rw")
|
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 */
|
/* primary dependency is another component */
|
||||||
_runtime_config.with_graph_id(primary_dep,
|
_runtime_config.with_graph_id(primary_dep,
|
||||||
@ -222,7 +222,7 @@ void Graph::view(Scope<Depgraph> &s) const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (dep_name == "default_fs_rw")
|
if (dep_name == "default_fs_rw")
|
||||||
dep_name = _sculpt_partition.fs();
|
dep_name = _selected_target.fs();
|
||||||
|
|
||||||
Dialog::Id dep_id { dep_name };
|
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));
|
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);
|
_ahci_devices_widget.propagate(at, action);
|
||||||
_nvme_devices_widget.propagate(at, action);
|
_nvme_devices_widget.propagate(at, action);
|
||||||
_mmc_devices_widget .propagate(at, action);
|
_mmc_devices_widget .propagate(at, action);
|
||||||
|
@ -40,7 +40,7 @@ struct Sculpt::Graph : Widget<Depgraph>
|
|||||||
Runtime_state &_runtime_state;
|
Runtime_state &_runtime_state;
|
||||||
Runtime_config const &_runtime_config;
|
Runtime_config const &_runtime_config;
|
||||||
Storage_devices const &_storage_devices;
|
Storage_devices const &_storage_devices;
|
||||||
Storage_target const &_sculpt_partition;
|
Storage_target const &_selected_target;
|
||||||
Ram_fs_state const &_ram_fs_state;
|
Ram_fs_state const &_ram_fs_state;
|
||||||
Popup::State const &_popup_state;
|
Popup::State const &_popup_state;
|
||||||
Depot_deploy::Children const &_deploy_children;
|
Depot_deploy::Children const &_deploy_children;
|
||||||
@ -56,19 +56,19 @@ struct Sculpt::Graph : Widget<Depgraph>
|
|||||||
|
|
||||||
Hosted<Depgraph, Frame, Vbox, Frame, Ahci_devices_widget>
|
Hosted<Depgraph, Frame, Vbox, Frame, Ahci_devices_widget>
|
||||||
_ahci_devices_widget { Id { "ahci_devices" },
|
_ahci_devices_widget { Id { "ahci_devices" },
|
||||||
_storage_devices, _sculpt_partition };
|
_storage_devices, _selected_target };
|
||||||
|
|
||||||
Hosted<Depgraph, Frame, Vbox, Frame, Nvme_devices_widget>
|
Hosted<Depgraph, Frame, Vbox, Frame, Nvme_devices_widget>
|
||||||
_nvme_devices_widget { Id { "nvme_devices" },
|
_nvme_devices_widget { Id { "nvme_devices" },
|
||||||
_storage_devices, _sculpt_partition };
|
_storage_devices, _selected_target };
|
||||||
|
|
||||||
Hosted<Depgraph, Frame, Vbox, Frame, Mmc_devices_widget>
|
Hosted<Depgraph, Frame, Vbox, Frame, Mmc_devices_widget>
|
||||||
_mmc_devices_widget { Id { "mmc_devices" },
|
_mmc_devices_widget { Id { "mmc_devices" },
|
||||||
_storage_devices, _sculpt_partition };
|
_storage_devices, _selected_target };
|
||||||
|
|
||||||
Hosted<Depgraph, Frame, Vbox, Frame, Usb_devices_widget>
|
Hosted<Depgraph, Frame, Vbox, Frame, Usb_devices_widget>
|
||||||
_usb_devices_widget { Id { "usb_devices" },
|
_usb_devices_widget { Id { "usb_devices" },
|
||||||
_storage_devices, _sculpt_partition };
|
_storage_devices, _selected_target };
|
||||||
|
|
||||||
bool _storage_selected = false;
|
bool _storage_selected = false;
|
||||||
|
|
||||||
@ -79,13 +79,13 @@ struct Sculpt::Graph : Widget<Depgraph>
|
|||||||
Graph(Runtime_state &runtime_state,
|
Graph(Runtime_state &runtime_state,
|
||||||
Runtime_config const &runtime_config,
|
Runtime_config const &runtime_config,
|
||||||
Storage_devices const &storage_devices,
|
Storage_devices const &storage_devices,
|
||||||
Storage_target const &sculpt_partition,
|
Storage_target const &selected_target,
|
||||||
Ram_fs_state const &ram_fs_state,
|
Ram_fs_state const &ram_fs_state,
|
||||||
Popup::State const &popup_state,
|
Popup::State const &popup_state,
|
||||||
Depot_deploy::Children const &deploy_children)
|
Depot_deploy::Children const &deploy_children)
|
||||||
:
|
:
|
||||||
_runtime_state(runtime_state), _runtime_config(runtime_config),
|
_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),
|
_ram_fs_state(ram_fs_state), _popup_state(popup_state),
|
||||||
_deploy_children(deploy_children)
|
_deploy_children(deploy_children)
|
||||||
{ }
|
{ }
|
||||||
|
@ -119,6 +119,13 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_gui_mode();
|
void _handle_gui_mode();
|
||||||
|
|
||||||
|
Rom_handler<Main> _config { _env, "config", *this, &Main::_handle_config };
|
||||||
|
|
||||||
|
void _handle_config(Xml_node const &)
|
||||||
|
{
|
||||||
|
_handle_storage_devices();
|
||||||
|
}
|
||||||
|
|
||||||
Screensaver _screensaver { _env, *this };
|
Screensaver _screensaver { _env, *this };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -249,20 +256,22 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_storage_devices()
|
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;
|
bool total_progress = false;
|
||||||
for (bool progress = true; progress; total_progress |= progress) {
|
for (bool progress = true; progress; total_progress |= progress) {
|
||||||
progress = false;
|
progress = false;
|
||||||
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
|
_drivers.with_storage_devices([&] (Drivers::Storage_devices const &devices) {
|
||||||
progress = _storage.update(devices.usb, devices.ahci,
|
_config.with_xml([&] (Xml_node const &config) {
|
||||||
devices.nvme, devices.mmc).progress; });
|
progress = _storage.update(config,
|
||||||
|
devices.usb, devices.ahci,
|
||||||
|
devices.nvme, devices.mmc).progress; }); });
|
||||||
|
|
||||||
/* update USB policies for storage devices */
|
/* update USB policies for storage devices */
|
||||||
_drivers.update_usb();
|
_drivers.update_usb();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orig_sculpt_partition != _storage._sculpt_partition)
|
if (orig_target != _storage._selected_target)
|
||||||
_restart_from_storage_target();
|
_restart_from_storage_target();
|
||||||
|
|
||||||
if (total_progress) {
|
if (total_progress) {
|
||||||
@ -381,7 +390,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
*/
|
*/
|
||||||
bool _update_running() const
|
bool _update_running() const
|
||||||
{
|
{
|
||||||
return _storage._sculpt_partition.valid()
|
return _storage._selected_target.valid()
|
||||||
&& !_prepare_in_progress()
|
&& !_prepare_in_progress()
|
||||||
&& _network.ready()
|
&& _network.ready()
|
||||||
&& _deploy.update_needed();
|
&& _deploy.update_needed();
|
||||||
@ -603,7 +612,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
bool system_available() const override
|
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
|
struct Diag_dialog : Top_level_dialog
|
||||||
@ -669,7 +678,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void _handle_runtime_state(Xml_node const &);
|
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<Main> _runtime_config {
|
Managed_config<Main> _runtime_config {
|
||||||
_env, "config", "runtime", *this, &Main::_handle_runtime };
|
_env, "config", "runtime", *this, &Main::_handle_runtime };
|
||||||
@ -801,10 +810,15 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
|
|
||||||
void use(Storage_target const &target) override
|
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();
|
_system_dialog.reset_update_widget();
|
||||||
_download_queue.reset();
|
_download_queue.reset();
|
||||||
|
|
||||||
|
if (orig_target != _storage._selected_target)
|
||||||
|
_restart_from_storage_target();
|
||||||
|
|
||||||
/* hide system panel button and system dialog when "un-using" */
|
/* hide system panel button and system dialog when "un-using" */
|
||||||
_panel_dialog.refresh();
|
_panel_dialog.refresh();
|
||||||
_system_dialog.refresh();
|
_system_dialog.refresh();
|
||||||
@ -1394,7 +1408,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
Popup _popup { };
|
Popup _popup { };
|
||||||
|
|
||||||
Graph _graph { _runtime_state, _cached_runtime_config, _storage._storage_devices,
|
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 };
|
_popup.state, _deploy._children };
|
||||||
|
|
||||||
struct Graph_dialog : Dialog::Top_level_dialog
|
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
|
* 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", [&] {
|
xml.node("start", [&] {
|
||||||
gen_prepare_start_content(xml, _prepare_version); });
|
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
|
* Spawn chroot instances for accessing '/depot' and '/public'. The
|
||||||
* chroot instances implicitly refer to the 'default_fs_rw'.
|
* 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) {
|
auto chroot = [&] (Start_name const &name, Path const &path, Writeable w) {
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
@ -2076,7 +2090,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* execute file operations */
|
/* execute file operations */
|
||||||
if (_storage._sculpt_partition.valid())
|
if (_storage._selected_target.valid())
|
||||||
if (_file_operation_queue.any_operation_in_progress())
|
if (_file_operation_queue.any_operation_in_progress())
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
gen_fs_tool_start_content(xml, _fs_tool_version,
|
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", [&] {
|
xml.node("start", [&] {
|
||||||
gen_update_start_content(xml); });
|
gen_update_start_content(xml); });
|
||||||
|
|
||||||
if (_storage._sculpt_partition.valid() && !_prepare_in_progress()) {
|
if (_storage._selected_target.valid() && !_prepare_in_progress()) {
|
||||||
xml.node("start", [&] {
|
xml.node("start", [&] {
|
||||||
gen_launcher_query_start_content(xml); });
|
gen_launcher_query_start_content(xml); });
|
||||||
|
|
||||||
|
@ -28,6 +28,15 @@ struct Sculpt::Storage_target
|
|||||||
Storage_device::Port port;
|
Storage_device::Port port;
|
||||||
Partition::Number partition;
|
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
|
bool operator == (Storage_target const &other) const
|
||||||
{
|
{
|
||||||
return (driver == other.driver)
|
return (driver == other.driver)
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
using namespace Sculpt;
|
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)
|
Xml_node const &nvme, Xml_node const &mmc)
|
||||||
{
|
{
|
||||||
bool progress = false;
|
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) {
|
_storage_devices.usb_storage_devices.for_each([&] (Usb_storage_device &dev) {
|
||||||
dev.process_report(); });
|
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")
|
bool const all_devices_enumerated = !usb .has_type("empty")
|
||||||
&& !ahci.has_type("empty")
|
&& !ahci.has_type("empty")
|
||||||
&& !nvme.has_type("empty")
|
&& !nvme.has_type("empty")
|
||||||
&& !mmc .has_type("empty");
|
&& !mmc .has_type("empty");
|
||||||
if (all_devices_enumerated) {
|
if (all_devices_enumerated) {
|
||||||
|
if (_configured_target.valid())
|
||||||
Storage_target const default_target =
|
_selected_target = _malconfiguration ? Storage_target { } : _configured_target;
|
||||||
_discovery_state.detect_default_target(_storage_devices);
|
else
|
||||||
|
_selected_target = _discovery_state.detect_default_target(_storage_devices);
|
||||||
if (default_target.valid()) {
|
|
||||||
_sculpt_partition = default_target;
|
|
||||||
progress |= true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detect the removal of a USB stick that is currently in "use". Reset
|
* 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.
|
* 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())
|
if (_selected_target.ram_fs())
|
||||||
sculpt_partition_exists = true;
|
selected_target_exists = true;
|
||||||
|
|
||||||
_storage_devices.for_each([&] (Storage_device const &device) {
|
_storage_devices.for_each([&] (Storage_device const &device) {
|
||||||
device.for_each_partition([&] (Partition const &partition) {
|
device.for_each_partition([&] (Partition const &partition) {
|
||||||
if (device.driver == _sculpt_partition.driver
|
if (device.driver == _selected_target.driver
|
||||||
&& partition.number == _sculpt_partition.partition)
|
&& partition.number == _selected_target.partition)
|
||||||
sculpt_partition_exists = true; }); });
|
selected_target_exists = true; }); });
|
||||||
|
|
||||||
if (!sculpt_partition_exists) {
|
if (!selected_target_exists) {
|
||||||
warning("sculpt partition unexpectedly vanished");
|
if (_configured_target.valid()) {
|
||||||
_sculpt_partition = Storage_target { };
|
warning("configured storage target does not exist");
|
||||||
progress |= true;
|
_malconfiguration = true;
|
||||||
|
} else {
|
||||||
|
warning("selected storage target unexpectedly vanished");
|
||||||
|
}
|
||||||
|
|
||||||
|
_selected_target = { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress |= (orig_selected_target != _selected_target);
|
||||||
|
|
||||||
return { progress };
|
return { progress };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,11 +109,11 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
|
|||||||
|
|
||||||
auto contains_used_fs = [&] (Storage_device const &device)
|
auto contains_used_fs = [&] (Storage_device const &device)
|
||||||
{
|
{
|
||||||
if (!_sculpt_partition.valid())
|
if (!_selected_target.valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (device.port == _sculpt_partition.port)
|
return (device.port == _selected_target.port)
|
||||||
&& (device.driver == _sculpt_partition.driver);
|
&& (device.driver == _selected_target.driver);
|
||||||
};
|
};
|
||||||
|
|
||||||
_storage_devices.usb_storage_devices.for_each([&] (Usb_storage_device const &device) {
|
_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); }); }
|
gen_resize2fs_start_content(xml, target); }); }
|
||||||
|
|
||||||
if (partition.file_system.type != File_system::UNKNOWN) {
|
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", [&] {
|
xml.node("start", [&] {
|
||||||
gen_fs_start_content(xml, target, partition.file_system.type); });
|
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
|
* to as "default_fs_rw" without the need to know the name of the
|
||||||
* underlying storage target.
|
* underlying storage target.
|
||||||
*/
|
*/
|
||||||
if (target == _sculpt_partition)
|
if (target == _selected_target)
|
||||||
gen_named_node(xml, "alias", "default_fs_rw", [&] {
|
gen_named_node(xml, "alias", "default_fs_rw", [&] {
|
||||||
xml.attribute("child", target.fs()); });
|
xml.attribute("child", target.fs()); });
|
||||||
}
|
}
|
||||||
@ -163,7 +182,7 @@ void Storage::gen_runtime_start_nodes(Xml_generator &xml) const
|
|||||||
|
|
||||||
}); /* for each device */
|
}); /* for each device */
|
||||||
|
|
||||||
if (_sculpt_partition.ram_fs())
|
if (_selected_target.ram_fs())
|
||||||
gen_named_node(xml, "alias", "default_fs_rw", [&] {
|
gen_named_node(xml, "alias", "default_fs_rw", [&] {
|
||||||
xml.attribute("child", "ram_fs"); });
|
xml.attribute("child", "ram_fs"); });
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,17 @@ struct Sculpt::Storage : Noncopyable
|
|||||||
|
|
||||||
Ram_fs_state _ram_fs_state;
|
Ram_fs_state _ram_fs_state;
|
||||||
|
|
||||||
Storage_target _sculpt_partition { };
|
Storage_target _configured_target { },
|
||||||
|
_selected_target { };
|
||||||
|
|
||||||
|
bool _malconfiguration = false;
|
||||||
|
|
||||||
Discovery_state _discovery_state { };
|
Discovery_state _discovery_state { };
|
||||||
|
|
||||||
Inspect_view_version _inspect_view_version { 0 };
|
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);
|
Xml_node const &nvme_namespaces, Xml_node const &mmc_devices);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user