From 3bbeacad20169437dc40ee18d97f93d22ab84ba4 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 21 Jun 2018 11:46:44 +0200 Subject: [PATCH] init: preserve final state of exited children This is a follow-up patch of "init: avoid too eager child restart". On each config update of init, init re-applies child-specific configuration changes. In the case of an already exited child, this re-evaluation wrongly marked such a child as abandoned because the child's environment sessions do no longer exist. Abandoning the child, in turn, triggers the destruction and subseqent restart (because the node of the configuration still exists). The latter is bad for two reasons. First, the exit state of the original instance becomes lost. Second, the restart may have unexpected side effects due to sessions created by the new instance. I.e., when resizing a partition in sculpt, init would wrongly restart the gpt-write tool after the tool successfully exited. This collides with a newly started instance of part_blk/resize2fs, which now competes with the second gpt-write instance for the exclusive access of the targeted block device. The patch prevents init from re-applying configurations to exited children. The accompanied test case covers the corner case. --- repos/os/run/init.run | 88 ++++++++++++++++++++++++++++++---- repos/os/src/app/dummy/main.cc | 6 +++ repos/os/src/init/child.cc | 2 +- 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/repos/os/run/init.run b/repos/os/run/init.run index 87cc1fd6a4..bd43a9fb64 100644 --- a/repos/os/run/init.run +++ b/repos/os/run/init.run @@ -91,6 +91,78 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1336,11 +1408,11 @@ append config { - + - + @@ -1371,7 +1443,7 @@ append config { - + @@ -1478,5 +1550,5 @@ build_boot_image $boot_modules append qemu_args " -nographic " -run_genode_until {.*child "test-init" exited with exit value 0.*} 200 +run_genode_until {.*child "test-init" exited with exit value 0.*} 300 diff --git a/repos/os/src/app/dummy/main.cc b/repos/os/src/app/dummy/main.cc index 9df645753e..a1d88fd318 100644 --- a/repos/os/src/app/dummy/main.cc +++ b/repos/os/src/app/dummy/main.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -333,6 +334,11 @@ struct Dummy::Main if (node.type() == "log") log(node.attribute_value("string", String<50>())); + + if (node.type() == "exit") { + _env.parent().exit(0); + sleep_forever(); + } }); } diff --git a/repos/os/src/init/child.cc b/repos/os/src/init/child.cc index 68417becbb..67b386a7ab 100644 --- a/repos/os/src/init/child.cc +++ b/repos/os/src/init/child.cc @@ -26,7 +26,7 @@ void Init::Child::destroy_services() Init::Child::Apply_config_result Init::Child::apply_config(Xml_node start_node) { - if (_state == STATE_ABANDONED) + if (_state == STATE_ABANDONED || _exited) return NO_SIDE_EFFECTS; /*