mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +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
|
||||
target_diag { target.attribute_value("diag", false) };
|
||||
|
||||
auto no_filter = [] (Service &) -> bool { return false; };
|
||||
|
||||
if (target.has_type("parent")) {
|
||||
|
||||
Parent_service *service = nullptr;
|
||||
|
||||
if ((service = find_service(_parent_services, service_name)))
|
||||
return Route { *service, target_label, target_diag };
|
||||
|
||||
if (service && service->abandoned())
|
||||
throw Service_denied();
|
||||
|
||||
if (!service_wildcard) {
|
||||
warning(name(), ": service lookup for "
|
||||
"\"", service_name, "\" at parent failed");
|
||||
throw Service_denied();
|
||||
}
|
||||
try {
|
||||
return Route { find_service(_parent_services, service_name, no_filter),
|
||||
target_label, target_diag };
|
||||
} catch (Service_denied) { }
|
||||
}
|
||||
|
||||
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());
|
||||
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) {
|
||||
if (s.name() == Service::Name(service_name)
|
||||
&& s.child_name() == server_name)
|
||||
service = &s; });
|
||||
try {
|
||||
return Route { find_service(_child_services, service_name, filter_server_name),
|
||||
target_label, target_diag };
|
||||
|
||||
if (service && service->abandoned())
|
||||
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();
|
||||
}
|
||||
} catch (Service_denied) { }
|
||||
}
|
||||
|
||||
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, "\"");
|
||||
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)))
|
||||
return Route { *service, target_label, target_diag };
|
||||
|
||||
if (!service_wildcard) {
|
||||
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())
|
||||
|
@ -122,15 +122,36 @@ namespace Init {
|
||||
return cnt > 1;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline T *find_service(Registry<T> &services, Service::Name const &name)
|
||||
/**
|
||||
* Find service with certain values in given registry
|
||||
*
|
||||
* \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;
|
||||
services.for_each([&] (T &s) {
|
||||
if (!service && (s.name() == name))
|
||||
service = &s; });
|
||||
return service;
|
||||
|
||||
if (service || s.name() != name || filter_fn(s))
|
||||
return;
|
||||
|
||||
service = &s;
|
||||
});
|
||||
|
||||
if (!service)
|
||||
throw Service_denied();
|
||||
|
||||
if (service->abandoned())
|
||||
throw Service_denied();
|
||||
|
||||
return *service;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user