init: defer forwarded session requests when needed

This patch changes init's service forwarding such that pending requests
are kept unanswered as long as the requested service is not present
(yet). In dynamic-init scenarios, this is needed in situtions where the
dynamic init is known to eventually provide the service but the internal
subsystem is not ready yet. Previously, a client that attempted to
request a session in this early phase would get a 'Service_denied'
exception. By deferring the forwarding in this situation, the behaviour
becomes deterministic.

If a matching '<service>' exists but there is no matching policy sub
node, the request is answered with 'Service_denied' - as expected.
This commit is contained in:
Norman Feske 2017-06-30 15:21:29 +02:00 committed by Christian Helmuth
parent b3e039d0b1
commit 6184a27619
2 changed files with 26 additions and 5 deletions

View File

@ -109,7 +109,7 @@ Init::Server::_resolve_session_request(Service::Name const &service_name,
matching_service = &service; });
if (!matching_service)
throw Service_denied();
throw Service_not_present();
return matching_service->resolve_session_request(label);
}
@ -169,6 +169,16 @@ void Init::Server::session_closed(Session_state &session)
void Init::Server::_handle_create_session_request(Xml_node request,
Parent::Client::Id id)
{
/*
* Ignore requests that are already successfully forwarded (by a prior call
* of '_handle_create_session_request') but still remain present in the
* 'session_requests' ROM because the server child has not responded yet.
*/
try {
_client_id_space.apply<Parent::Client>(id, [&] (Parent::Client const &) { });
return;
} catch (Id_space<Parent::Client>::Unknown_id) { /* normal case */ }
if (!request.has_sub_node("args"))
return;
@ -257,6 +267,7 @@ void Init::Server::_handle_create_session_request(Xml_node request,
catch (Insufficient_cap_quota) {
_env.parent().session_response(Parent::Server::Id { id.value },
Parent::INSUFFICIENT_CAP_QUOTA); }
catch (Service_not_present) { /* keep request pending */ }
}
@ -356,11 +367,15 @@ void Init::Server::apply_config(Xml_node config)
_session_request_handler.construct(_env.ep(), *this,
&Server::_handle_session_requests);
_session_requests->sigh(*_session_request_handler);
if (_session_requests.constructed())
_handle_session_requests();
}
/*
* Try to resolve pending session requests that may become serviceable with
* the new configuration.
*/
if (services_provided && _session_requests.constructed())
_handle_session_requests();
/*
* Re-validate routes of existing sessions, close sessions whose routes
* changed.
@ -375,6 +390,7 @@ void Init::Server::apply_config(Xml_node config)
if (!route_unchanged)
throw Service_denied();
}
catch (Service_denied) { close_session(session); }
catch (Service_denied) { close_session(session); }
catch (Service_not_present) { close_session(session); }
});
}

View File

@ -51,6 +51,11 @@ class Init::Server : Session_state::Ready_callback,
*/
Id_space<Parent::Client> _client_id_space;
/**
* Exception type
*/
class Service_not_present : Exception { };
/**
* Meta data of service provided to our parent
*/