mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 21:57:55 +00:00
init: be aware of abandoned any-child routes
Previously, init did not test if a service is abandoned on a new configuration if the service was routed via an any-child route. Fixes #2483
This commit is contained in:
parent
9476f3f645
commit
96c7f8d53f
@ -463,21 +463,14 @@ Init::Child::Route Init::Child::resolve_session_request(Service::Name const &ser
|
|||||||
Session::Diag const
|
Session::Diag const
|
||||||
target_diag { target.attribute_value("diag", false) };
|
target_diag { target.attribute_value("diag", false) };
|
||||||
|
|
||||||
|
auto no_filter = [] (Service &) -> bool { return false; };
|
||||||
|
|
||||||
if (target.has_type("parent")) {
|
if (target.has_type("parent")) {
|
||||||
|
|
||||||
Parent_service *service = nullptr;
|
try {
|
||||||
|
return Route { find_service(_parent_services, service_name, no_filter),
|
||||||
if ((service = find_service(_parent_services, service_name)))
|
target_label, target_diag };
|
||||||
return Route { *service, target_label, target_diag };
|
} catch (Service_denied) { }
|
||||||
|
|
||||||
if (service && service->abandoned())
|
|
||||||
throw Service_denied();
|
|
||||||
|
|
||||||
if (!service_wildcard) {
|
|
||||||
warning(name(), ": service lookup for "
|
|
||||||
"\"", service_name, "\" at parent failed");
|
|
||||||
throw Service_denied();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.has_type("child")) {
|
if (target.has_type("child")) {
|
||||||
@ -486,24 +479,14 @@ Init::Child::Route Init::Child::resolve_session_request(Service::Name const &ser
|
|||||||
Name server_name = target.attribute_value("name", Name());
|
Name server_name = target.attribute_value("name", Name());
|
||||||
server_name = _name_registry.deref_alias(server_name);
|
server_name = _name_registry.deref_alias(server_name);
|
||||||
|
|
||||||
Routed_service *service = nullptr;
|
auto filter_server_name = [&] (Routed_service &s) -> bool {
|
||||||
|
return s.child_name() != server_name; };
|
||||||
|
|
||||||
_child_services.for_each([&] (Routed_service &s) {
|
try {
|
||||||
if (s.name() == Service::Name(service_name)
|
return Route { find_service(_child_services, service_name, filter_server_name),
|
||||||
&& s.child_name() == server_name)
|
target_label, target_diag };
|
||||||
service = &s; });
|
|
||||||
|
|
||||||
if (service && service->abandoned())
|
} catch (Service_denied) { }
|
||||||
throw Service_denied();
|
|
||||||
|
|
||||||
if (service)
|
|
||||||
return Route { *service, target_label, target_diag };
|
|
||||||
|
|
||||||
if (!service_wildcard) {
|
|
||||||
warning(name(), ": lookup to child "
|
|
||||||
"server \"", server_name, "\" failed");
|
|
||||||
throw Service_denied();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.has_type("any-child")) {
|
if (target.has_type("any-child")) {
|
||||||
@ -513,17 +496,16 @@ Init::Child::Route Init::Child::resolve_session_request(Service::Name const &ser
|
|||||||
"service \"", service_name, "\"");
|
"service \"", service_name, "\"");
|
||||||
throw Service_denied();
|
throw Service_denied();
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
return Route { find_service(_child_services, service_name, no_filter),
|
||||||
|
target_label, target_diag };
|
||||||
|
|
||||||
Routed_service *service = nullptr;
|
} catch (Service_denied) { }
|
||||||
|
}
|
||||||
|
|
||||||
if ((service = find_service(_child_services, service_name)))
|
if (!service_wildcard) {
|
||||||
return Route { *service, target_label, target_diag };
|
warning(name(), ": lookup for service \"", service_name, "\" failed");
|
||||||
|
throw Service_denied();
|
||||||
if (!service_wildcard) {
|
|
||||||
warning(name(), ": lookup for service "
|
|
||||||
"\"", service_name, "\" failed");
|
|
||||||
throw Service_denied();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.last())
|
if (target.last())
|
||||||
|
@ -122,15 +122,36 @@ namespace Init {
|
|||||||
return cnt > 1;
|
return cnt > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
template <typename T>
|
* Find service with certain values in given registry
|
||||||
inline T *find_service(Registry<T> &services, Service::Name const &name)
|
*
|
||||||
|
* \param services service registry
|
||||||
|
* \param name name of wanted service
|
||||||
|
* \param filter_fn function that applies additional filters
|
||||||
|
*
|
||||||
|
* \throw Service_denied
|
||||||
|
*/
|
||||||
|
template <typename T, typename FILTER_FN>
|
||||||
|
inline T &find_service(Registry<T> &services,
|
||||||
|
Service::Name const &name,
|
||||||
|
FILTER_FN const &filter_fn)
|
||||||
{
|
{
|
||||||
T *service = nullptr;
|
T *service = nullptr;
|
||||||
services.for_each([&] (T &s) {
|
services.for_each([&] (T &s) {
|
||||||
if (!service && (s.name() == name))
|
|
||||||
service = &s; });
|
if (service || s.name() != name || filter_fn(s))
|
||||||
return service;
|
return;
|
||||||
|
|
||||||
|
service = &s;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!service)
|
||||||
|
throw Service_denied();
|
||||||
|
|
||||||
|
if (service->abandoned())
|
||||||
|
throw Service_denied();
|
||||||
|
|
||||||
|
return *service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user