init: always abandon child on version change

Without this patch, a version change of an already exited child would not
trigger the restart of the child because the version is evaluated as
late as the child configuration, but only if the child has not exited
yet.

This patch evaluates the version at the earlier stage where the identity
of the child (its name) is checked against the new configuration.

Fixes #3226
This commit is contained in:
Norman Feske 2019-03-12 17:55:17 +01:00 committed by Christian Helmuth
parent 8ccfe4361c
commit f3d4ee4d4c
3 changed files with 7 additions and 14 deletions

View File

@ -55,19 +55,10 @@ Init::Child::apply_config(Xml_node start_node)
Config_update config_update = CONFIG_UNCHANGED;
/*
* Import new start node if new version differs
* Import new start node if it differs
*/
if (start_node.differs_from(_start_node->xml())) {
/*
* Check for a change of the version attribute, force restart
* if the version changed.
*/
if (_version != start_node.attribute_value("version", Version())) {
abandon();
return MAY_HAVE_SIDE_EFFECTS;
}
/*
* Start node changed
*

View File

@ -35,6 +35,8 @@ class Init::Child : Child_policy, Routed_service::Wakeup
{
public:
typedef String<80> Version;
/**
* Exception types
*/
@ -87,7 +89,6 @@ class Init::Child : Child_policy, Routed_service::Wakeup
/*
* Version attribute of the start node, used to force child restarts.
*/
typedef String<80> Version;
Version _version { _start_node->xml().attribute_value("version", Version()) };
/*
@ -488,6 +489,8 @@ class Init::Child : Child_policy, Routed_service::Wakeup
*/
bool has_name(Child_policy::Name const &str) const { return str == name(); }
bool has_version(Version const &version) const { return version == _version; }
Ram_quota ram_quota() const { return _resources.assigned_ram_quota; }
Cap_quota cap_quota() const { return _resources.assigned_cap_quota; }

View File

@ -249,11 +249,10 @@ void Init::Main::_abandon_obsolete_children()
{
_children.for_each_child([&] (Child &child) {
Child_policy::Name const name = child.name();
bool obsolete = true;
_config_xml.for_each_sub_node("start", [&] (Xml_node node) {
if (node.attribute_value("name", Child_policy::Name()) == name)
if (child.has_name (node.attribute_value("name", Child_policy::Name()))
&& child.has_version(node.attribute_value("version", Child::Version())))
obsolete = false; });
if (obsolete)