Omit child-name prefix in <if-args> check

When matching the 'label' session argument using '<if-args>' in a
routing table, we can omit the child name prefix because it is always
the same for all sessions originating from the child anyway. Therefore,
this patch adds a special case for matching session labels. It makes the
expression of label-specific routing more intuitive.
This commit is contained in:
Norman Feske 2013-01-10 14:43:15 +01:00
parent 507d467e37
commit 277af91376
3 changed files with 59 additions and 6 deletions

View File

@ -96,11 +96,47 @@ namespace Init {
} }
/**
* Return sub string of label with the leading child name stripped out
*
*/
inline char const *skip_label_prefix(char const *child_name, char const *label)
{
Genode::size_t const child_name_len = Genode::strlen(child_name);
/*
* If the function was called with a valid "label" string, the
* following condition should be always satisfied. See the
* comment in 'service_node_args_condition_satisfied'.
*/
if (Genode::strcmp(child_name, label, child_name_len) == 0)
label += child_name_len;
/*
* If the original label was empty, the 'Child_policy_enforce_labeling'
* does not append a label separator after the child-name prefix. In
* this case, we resulting label is empty.
*/
if (*label == 0)
return label;
/*
* Skip label separator. This condition should be always satisfied.
*/
if (Genode::strcmp(" -> ", label, 4) == 0)
return label + 4;
PWRN("cannot skip label prefix while processing <if-arg>");
return label;
}
/** /**
* Check if arguments satisfy the condition specified for the route * Check if arguments satisfy the condition specified for the route
*/ */
inline bool service_node_args_condition_satisfied(Genode::Xml_node service_node, inline bool service_node_args_condition_satisfied(Genode::Xml_node service_node,
const char *args) const char *args,
char const *child_name)
{ {
try { try {
Genode::Xml_node if_arg = service_node.sub_node("if-arg"); Genode::Xml_node if_arg = service_node.sub_node("if-arg");
@ -112,6 +148,23 @@ namespace Init {
char arg_value[VALUE_MAX_LEN]; char arg_value[VALUE_MAX_LEN];
Genode::Arg_string::find_arg(args, key).string(arg_value, sizeof(arg_value), ""); Genode::Arg_string::find_arg(args, key).string(arg_value, sizeof(arg_value), "");
PDBG("key='%s' value='%s' arg_value='%s'", key, value, arg_value);
/*
* Skip child-name prefix if the key is the process "label".
*
* Because 'filter_session_args' is called prior the call of
* 'resolve_session_request' from the 'Child::session' function,
* 'args' contains the filtered arguments, in particular the label
* prefixed with the child's name. For the 'if-args' declaration,
* however, we want to omit specifying this prefix because the
* session route is specific to the named start node anyway. So
* the prefix information is redundant.
*/
if (Genode::strcmp("label", key) == 0)
return Genode::strcmp(value, skip_label_prefix(child_name, arg_value)) == 0;
return Genode::strcmp(value, arg_value) == 0; return Genode::strcmp(value, arg_value) == 0;
} catch (...) { } } catch (...) { }
@ -492,7 +545,7 @@ namespace Init {
if (!service_node_matches(service_node, service_name)) if (!service_node_matches(service_node, service_name))
continue; continue;
if (!service_node_args_condition_satisfied(service_node, args)) if (!service_node_args_condition_satisfied(service_node, args, name()))
continue; continue;
Genode::Xml_node target = service_node.sub_node(); Genode::Xml_node target = service_node.sub_node();

View File

@ -195,10 +195,10 @@ append config {
<resource name="RAM" quantum="1G"/> <resource name="RAM" quantum="1G"/>
<route> <route>
<service name="Terminal"> <service name="Terminal">
<if-arg key="label" value="noux"/><child name="terminal_noux"/> <if-arg key="label" value=""/><child name="terminal_noux"/>
</service> </service>
<service name="Terminal"> <service name="Terminal">
<if-arg key="label" value="noux -> noux(terminal_fs)"/><child name="terminal_gdb"/> <if-arg key="label" value="noux(terminal_fs)"/><child name="terminal_gdb"/>
</service> </service>
<any-service><parent/><any-child/></any-service> <any-service><parent/><any-child/></any-service>
</route> </route>

View File

@ -163,10 +163,10 @@ append config {
<resource name="RAM" quantum="1G" /> <resource name="RAM" quantum="1G" />
<route> <route>
<service name="Terminal"> <service name="Terminal">
<if-arg key="label" value="noux"/><child name="terminal_noux"/> <if-arg key="label" value=""/><child name="terminal_noux"/>
</service> </service>
<service name="Terminal"> <service name="Terminal">
<if-arg key="label" value="noux -> noux(terminal_fs)"/><child name="terminal_test"/> <if-arg key="label" value="noux(terminal_fs)"/><child name="terminal_test"/>
</service> </service>
<any-service><parent/><any-child/></any-service> <any-service><parent/><any-child/></any-service>
</route> </route>