2
0
Fork 0

fixup update genode

This commit is contained in:
Emery Hemingway 2020-12-19 15:20:35 +01:00
parent 28a4a17769
commit 5036b62eee
2 changed files with 178 additions and 810 deletions

View File

@ -1,7 +1,7 @@
From 017abdc7a59acf7e76109b7fd285f9856b4a9eee Mon Sep 17 00:00:00 2001
From a163f085a918c4af156d84cb40aa1df5afe0bd44 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 6 May 2020 04:38:35 +0530
Subject: [PATCH 1/8] libc: add siginterrupt dummy
Subject: [PATCH 1/7] libc: add siginterrupt dummy
---
repos/libports/src/lib/libc/signal.cc | 3 +++
@ -25,10 +25,10 @@ index a08854a8c0..2d2def34d3 100644
2.29.2
From e73c873a6e329eef4dede312e0bd0e597c93adde Mon Sep 17 00:00:00 2001
From 45bcbeec901f9d5f748d4f1f73c9a70bc449302a Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 6 May 2020 04:59:56 +0530
Subject: [PATCH 2/8] libc: add upstream mbsinit
Subject: [PATCH 2/7] libc: add upstream mbsinit
---
repos/libports/lib/mk/libc-locale.mk | 2 +-
@ -51,10 +51,10 @@ index 8e75e59589..2bb98b1456 100644
2.29.2
From 98d8ef8e3fa37076fab524b6830229f347c89feb Mon Sep 17 00:00:00 2001
From 61b10dc8c6e2dd406667046665c9d31b9505d7ac Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 27 May 2020 16:35:16 +0530
Subject: [PATCH 3/8] libc: add mlock and munlock dummies
Subject: [PATCH 3/7] libc: add mlock and munlock dummies
---
repos/libports/src/lib/libc/dummies.cc | 10 ++++++++++
@ -84,10 +84,10 @@ index b01d95f717..f676b4979c 100644
2.29.2
From a17d8387a9bbc7d340ed42cfcdc0adedce16f4dd Mon Sep 17 00:00:00 2001
From 45c8afc8319fb0eb60914d44712ddcad97509709 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Fri, 29 May 2020 09:26:50 +0530
Subject: [PATCH 4/8] libc: return 0 from getpgrp and getppid dummies
Subject: [PATCH 4/7] libc: return 0 from getpgrp and getppid dummies
---
repos/libports/src/lib/libc/dummies.cc | 4 ++--
@ -112,75 +112,10 @@ index f676b4979c..9c568dcc77 100644
2.29.2
From 9f3375cdca705e3271f209de76beb19354a150e8 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Thu, 26 Nov 2020 12:47:30 +0100
Subject: [PATCH 5/8] libc: always set argv and envp to valid arrays
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The arrays passed to main(…) must always be valid null-terminated arrays.
Fix #3955
---
repos/libports/include/libc/args.h | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/repos/libports/include/libc/args.h b/repos/libports/include/libc/args.h
index 76645d82cb..ca9a8fd38a 100644
--- a/repos/libports/include/libc/args.h
+++ b/repos/libports/include/libc/args.h
@@ -25,6 +25,7 @@ static void populate_args_and_env(Libc::Env &env, int &argc, char **&argv, char
{
using Genode::Xml_node;
using Genode::Xml_attribute;
+ using Genode::max;
env.config([&] (Xml_node const &node) {
@@ -40,12 +41,20 @@ static void populate_args_and_env(Libc::Env &env, int &argc, char **&argv, char
++envc;
});
- if (argc == 0 && envc == 0)
+ if (argc == 0 && envc == 0) {
+ /*
+ * If argc is zero then argv is still a NULL-terminated array.
+ */
+ static char const *args[] = { nullptr, nullptr };
+ argc = 0;
+ argv = (char**)&args;
+ envp = &argv[1];
return; /* from lambda */
+ }
- /* arguments and environment are a contiguous array (but don't count on it) */
- argv = (char**)malloc((argc + envc + 1) * sizeof(char*));
- envp = &argv[argc];
+ /* arguments and environment are arranged System V style (but don't count on it) */
+ argv = (char**)malloc((argc + envc + 2) * sizeof(char*));
+ envp = &argv[argc+1];
/* read the arguments */
int arg_i = 0;
@@ -123,6 +132,8 @@ static void populate_args_and_env(Libc::Env &env, int &argc, char **&argv, char
catch (Xml_node::Nonexistent_attribute) { }
});
+ /* argv and envp are both NULL terminated */
+ argv[arg_i] = NULL;
envp[env_i] = NULL;
});
}
--
2.29.2
From dd89c66247bf751c87b09fffc7af15c04a59fd91 Mon Sep 17 00:00:00 2001
From bc10be54b1057eb5f333cdefb35730371bd22a19 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 2 Dec 2020 16:31:59 +0100
Subject: [PATCH 6/8] libc: implement if_nametoindex
Subject: [PATCH 5/7] libc: implement if_nametoindex
---
.../libports/src/lib/libc/socket_fs_plugin.cc | 50 ++++++++++++++++++-
@ -258,10 +193,10 @@ index d5db46ff83..fabaf68b5c 100644
2.29.2
From 1f249e18ea3972911c1405deb40afd85b8d64dea Mon Sep 17 00:00:00 2001
From 68e56d8e95bbcf8aaa77b2f95d9c76890e1f5489 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Thu, 4 Jun 2020 01:03:37 +0530
Subject: [PATCH 7/8] libc: add readpassphrase
Subject: [PATCH 6/7] libc: add readpassphrase
This symbol is already in the stub library.
---
@ -284,13 +219,13 @@ index ab0ce929aa..1c7f84e800 100644
2.29.2
From 708d1c11c1954636df4eef2efde8f1a5cc4afa7e Mon Sep 17 00:00:00 2001
From f95d3fdeef9186476215e53ead8ed38fd7cd533e Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 2 Dec 2020 22:27:00 +0100
Subject: [PATCH 8/8] libc: replace strange errno values for O_NOFOLLOW
Subject: [PATCH 7/7] libc: do not set different errno values for O_NOFOLLOW
Do not replace ENOENT and EEXIST with ELOOP when open is called with
O_NOFOLLOW.
O_NOFOLLOW. This breaks Tor.
---
repos/libports/src/lib/libc/vfs_plugin.cc | 16 ----------------
1 file changed, 16 deletions(-)

View File

@ -1,754 +1,187 @@
From 735e7af9458005092451f448ddf3dfc1cad4acbd Mon Sep 17 00:00:00 2001
From 5570eb3814bad4ef6ce33ddc42b74f9b9d22bdbc Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 25 Apr 2020 17:10:03 +0530
Subject: [PATCH 1/4] init/sandbox: <routes> support
Apply routing rules to a child from a <routes> node at the top-level of
a sandbox config, unless the corresponding start node has as <route>
node. If neither are present routes are taken from <default-route> as a
fallback.
Unlike the <route> and <default-route> the <routes> rules are checked by
labels prefixed by child name, so <routes> may contain child-specific
rules.
---
repos/os/src/lib/sandbox/child.cc | 12 +++++++++++-
repos/os/src/lib/sandbox/child.h | 10 ++++++++++
repos/os/src/lib/sandbox/library.cc | 14 +++++++++++++-
repos/os/src/lib/sandbox/utils.h | 8 +++++---
4 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
index e321df61fd..d25e3d9683 100644
--- a/repos/os/src/lib/sandbox/child.cc
+++ b/repos/os/src/lib/sandbox/child.cc
@@ -487,17 +487,25 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
Session::Label(), Session::Diag{false} };
try {
+ /* Lookup route in <default-route>… */
Xml_node route_node = _default_route_accessor.default_route();
+ /* …unless <routes> is present… */
+ route_node = _routes_accessor.routes(route_node);
try {
+ /* …otherwise use <child><route>. */
route_node = _start_node->xml().sub_node("route"); }
catch (...) { }
+
Xml_node service_node = route_node.sub_node();
+ /* <routes> is processed with the "«child» -> " prefix */
+ bool skip_prefix = route_node.type() != "routes";
+
for (; ; service_node = service_node.next()) {
bool service_wildcard = service_node.has_type("any-service");
- if (!service_node_matches(service_node, label, name(), service_name))
+ if (!service_node_matches(service_node, label, name(), service_name, skip_prefix))
continue;
Xml_node target = service_node.sub_node();
@@ -705,6 +713,7 @@ Sandbox::Child::Child(Env &env,
Report_update_trigger &report_update_trigger,
Xml_node start_node,
Default_route_accessor &default_route_accessor,
+ Routes_accessor &routes_accessor,
Default_caps_accessor &default_caps_accessor,
Name_registry &name_registry,
Ram_quota ram_limit,
@@ -722,6 +731,7 @@ Sandbox::Child::Child(Env &env,
_list_element(this),
_start_node(_alloc, start_node),
_default_route_accessor(default_route_accessor),
+ _routes_accessor(routes_accessor),
_default_caps_accessor(default_caps_accessor),
_ram_limit_accessor(ram_limit_accessor),
_cap_limit_accessor(cap_limit_accessor),
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
index 2c213e662c..81836a2045 100644
--- a/repos/os/src/lib/sandbox/child.h
+++ b/repos/os/src/lib/sandbox/child.h
@@ -52,6 +52,14 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
struct Default_route_accessor : Interface { virtual Xml_node default_route() = 0; };
struct Default_caps_accessor : Interface { virtual Cap_quota default_caps() = 0; };
+ struct Routes_accessor : Interface
+ {
+ virtual Xml_node routes(Xml_node _default)
+ {
+ return _default;
+ }
+ };
+
template <typename QUOTA>
struct Resource_limit_accessor : Interface
{
@@ -98,6 +106,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
bool const _use_ld = _start_node->xml().attribute_value("ld", true);
Default_route_accessor &_default_route_accessor;
+ Routes_accessor &_routes_accessor;
Default_caps_accessor &_default_caps_accessor;
Ram_limit_accessor &_ram_limit_accessor;
Cap_limit_accessor &_cap_limit_accessor;
@@ -473,6 +482,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Report_update_trigger &report_update_trigger,
Xml_node start_node,
Default_route_accessor &default_route_accessor,
+ Routes_accessor &route_accessor,
Default_caps_accessor &default_caps_accessor,
Name_registry &name_registry,
Ram_quota ram_limit,
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
index 28b60c491f..30d0f2dfc1 100644
--- a/repos/os/src/lib/sandbox/library.cc
+++ b/repos/os/src/lib/sandbox/library.cc
@@ -23,6 +23,7 @@
struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
::Sandbox::Child::Default_route_accessor,
+ ::Sandbox::Child::Routes_accessor,
::Sandbox::Child::Default_caps_accessor,
::Sandbox::Child::Ram_limit_accessor,
::Sandbox::Child::Cap_limit_accessor
@@ -52,6 +53,8 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
Constructible<Buffered_xml> _default_route { };
+ Constructible<Buffered_xml> _routes { };
+
Cap_quota _default_caps { 0 };
unsigned _child_cnt = 0;
@@ -140,6 +143,12 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
: Xml_node("<empty/>");
}
+ /**
+ * Routes_accessor interface
+ */
+ Xml_node routes(Xml_node _default) override {
+ return _routes.constructed() ? _routes->xml() : _default; }
+
/**
* Default_caps_accessor interface
*/
@@ -314,6 +323,9 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
_default_route.construct(_heap, config.sub_node("default-route")); }
catch (...) { }
+ try { _routes.construct(_heap, config.sub_node("routes")); }
+ catch (...) { }
+
_default_caps = Cap_quota { 0 };
try {
_default_caps = Cap_quota { config.sub_node("default")
@@ -404,7 +416,7 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
Child &child = *new (_heap)
Child(_env, _heap, *_verbose,
Child::Id { ++_child_cnt }, _state_reporter,
- start_node, *this, *this, _children,
+ start_node, *this, *this, *this, _children,
Ram_quota { avail_ram.value - used_ram.value },
Cap_quota { avail_caps.value - used_caps.value },
*this, *this, prio_levels, affinity_space,
diff --git a/repos/os/src/lib/sandbox/utils.h b/repos/os/src/lib/sandbox/utils.h
index 7afcaebf00..36aab737f2 100644
--- a/repos/os/src/lib/sandbox/utils.h
+++ b/repos/os/src/lib/sandbox/utils.h
@@ -59,7 +59,8 @@ namespace Sandbox {
inline bool service_node_matches(Xml_node const service_node,
Session_label const &label,
Child_policy::Name const &child_name,
- Service::Name const &service_name)
+ Service::Name const &service_name,
+ bool skip_child_prefix = true)
{
bool const service_matches =
service_node.has_type("any-service") ||
@@ -98,8 +99,9 @@ namespace Sandbox {
if (!route_depends_on_child_provided_label)
return true;
- char const * const scoped_label = skip_label_prefix(
- child_name.string(), label.string());
+ char const * const scoped_label = skip_child_prefix
+ ? skip_label_prefix(child_name.string(), label.string())
+ : label.string();
if (!scoped_label)
return false;
--
2.29.2
From 0b65d7660784dbff4ef4fe392af686103c60a32d Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 4 Nov 2020 11:03:49 +0100
Subject: [PATCH 2/4] init/sandbox: do not parse <parent-provides> if <routes>
is present
Date: Sat, 19 Dec 2020 12:18:16 +0100
Subject: [PATCH 1/2] usb_block_drv: do not enable report by default,
diagnostics
---
repos/os/src/lib/sandbox/library.cc | 124 +++++++++++++++++++---------
1 file changed, 85 insertions(+), 39 deletions(-)
repos/os/src/drivers/usb_block/main.cc | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
index 30d0f2dfc1..caa9840ea6 100644
--- a/repos/os/src/lib/sandbox/library.cc
+++ b/repos/os/src/lib/sandbox/library.cc
@@ -184,47 +184,93 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
diff --git a/repos/os/src/drivers/usb_block/main.cc b/repos/os/src/drivers/usb_block/main.cc
index 578a5015e5..a244ddf0f5 100644
--- a/repos/os/src/drivers/usb_block/main.cc
+++ b/repos/os/src/drivers/usb_block/main.cc
@@ -110,12 +110,14 @@ struct Usb::Block_driver : Usb::Completion
log("Device plugged");
void Genode::Sandbox::Library::_update_parent_services_from_config(Xml_node const &config)
{
- Xml_node const node = config.has_sub_node("parent-provides")
- ? config.sub_node("parent-provides")
- : Xml_node("<empty/>");
-
- /* remove services that are no longer present in config */
- _parent_services.for_each([&] (Parent_service &service) {
-
- Service::Name const name = service.name();
-
- bool obsolete = true;
+ if (config.has_sub_node("routes")) {
+ if (config.has_sub_node("parent-provides"))
+ warning("ignoring <parent-provides> and parsing <routes> instead");
+
+ Xml_node const node = config.sub_node("routes");
+
+ /* remove services that are no longer present in config */
+ _parent_services.for_each([&] (Parent_service &service) {
+
+ Service::Name const name = service.name();
+
+ bool obsolete = true;
+ node.for_each_sub_node("service", [&] (Xml_node service) {
+ if (obsolete && name == service.attribute_value("name", Service::Name())) {
+ obsolete = !service.has_sub_node("parent"); }});
+
+ if (obsolete)
+ service.abandon();
+ });
+
+ /* used to prepend the list of new parent services with title */
+ bool first_log = true;
+
+ /* register new services */
node.for_each_sub_node("service", [&] (Xml_node service) {
- if (name == service.attribute_value("name", Service::Name())) {
- obsolete = false; }});
-
- if (obsolete)
- service.abandon();
- });
-
- /* used to prepend the list of new parent services with title */
- bool first_log = true;
-
- /* register new services */
- node.for_each_sub_node("service", [&] (Xml_node service) {
-
- Service::Name const name = service.attribute_value("name", Service::Name());
-
- bool registered = false;
- _parent_services.for_each([&] (Parent_service const &service) {
- if (service.name() == name)
- registered = true; });
-
- if (!registered) {
- new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
- if (_verbose->enabled()) {
- if (first_log)
- log("parent provides");
- log(" service \"", name, "\"");
- first_log = false;
+ if (service.has_sub_node("child")) return;
+
+ Service::Name const name = service.attribute_value("name", Service::Name());
+
+ bool registered = false;
+ _parent_services.for_each([&] (Parent_service const &service) {
+ if (service.name() == name)
+ registered = true; });
+
+ if (!registered) {
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
+ if (_verbose->enabled()) {
+ if (first_log)
+ log("parent provides");
+ log(" service \"", name, "\"");
+ first_log = false;
+ }
}
- }
- });
+ });
+ } else {
+ Xml_node const node = config.has_sub_node("parent-provides")
+ ? config.sub_node("parent-provides")
+ : Xml_node("<empty/>");
+
+ /* remove services that are no longer present in config */
+ _parent_services.for_each([&] (Parent_service &service) {
+
+ Service::Name const name = service.name();
+
+ bool obsolete = true;
+ node.for_each_sub_node("service", [&] (Xml_node service) {
+ if (name == service.attribute_value("name", Service::Name())) {
+ obsolete = false; }});
+
+ if (obsolete)
+ service.abandon();
+ });
+
+ /* used to prepend the list of new parent services with title */
+ bool first_log = true;
+
+ /* register new services */
+ node.for_each_sub_node("service", [&] (Xml_node service) {
+
+ Service::Name const name = service.attribute_value("name", Service::Name());
+
+ bool registered = false;
+ _parent_services.for_each([&] (Parent_service const &service) {
+ if (service.name() == name)
+ registered = true; });
+
+ if (!registered) {
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
+ if (_verbose->enabled()) {
+ if (first_log)
+ log("parent provides");
+ log(" service \"", name, "\"");
+ first_log = false;
+ }
+ }
+ });
+ }
}
--
2.29.2
From 67d834c4556969e37bc050e151baeedddfb05ac9 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Wed, 4 Nov 2020 20:02:03 +0100
Subject: [PATCH 3/4] init/sandbox: simplify routing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Remove <default-route>, <any-service>, and <any-child> configuration
options.
Allow label rewriting with <parent prefix="…" suffix="…">
and <child name="…" prefix="…" suffix="…">.
Routes are now selected by longest match rather than first match.
---
repos/os/src/lib/sandbox/child.cc | 131 ++++++++++------------------
repos/os/src/lib/sandbox/child.h | 3 -
repos/os/src/lib/sandbox/library.cc | 12 +--
repos/os/src/lib/sandbox/utils.h | 57 ++++++------
4 files changed, 76 insertions(+), 127 deletions(-)
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
index d25e3d9683..46aa22411c 100644
--- a/repos/os/src/lib/sandbox/child.cc
+++ b/repos/os/src/lib/sandbox/child.cc
@@ -11,6 +11,7 @@
* under the terms of the GNU Affero General Public License version 3.
*/
+#include <os/session_policy.h>
#include <vm_session/vm_session.h>
/* local includes */
@@ -486,105 +487,65 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
return Route { _session_requester.service(),
Session::Label(), Session::Diag{false} };
- try {
- /* Lookup route in <default-route>… */
- Xml_node route_node = _default_route_accessor.default_route();
- /* …unless <routes> is present… */
- route_node = _routes_accessor.routes(route_node);
- try {
- /* …otherwise use <child><route>. */
- route_node = _start_node->xml().sub_node("route"); }
- catch (...) { }
-
- Xml_node service_node = route_node.sub_node();
-
- /* <routes> is processed with the "«child» -> " prefix */
- bool skip_prefix = route_node.type() != "routes";
-
- for (; ; service_node = service_node.next()) {
-
- bool service_wildcard = service_node.has_type("any-service");
-
- if (!service_node_matches(service_node, label, name(), service_name, skip_prefix))
- continue;
-
- Xml_node target = service_node.sub_node();
- for (; ; target = target.next()) {
-
- /*
- * Determine session label to be provided to the server
- *
- * By default, the client's identity (accompanied with the a
- * client-provided label) is presented as session label to the
- * server. However, the target node can explicitly override the
- * client's identity by a custom label via the 'label'
- * attribute.
- */
- typedef String<Session_label::capacity()> Label;
- Label const target_label =
- target.attribute_value("label", Label(label.string()));
-
- Session::Diag const
- target_diag { target.attribute_value("diag", false) };
-
- auto no_filter = [] (Service &) -> bool { return false; };
-
- if (target.has_type("parent")) {
-
- try {
- return Route { find_service(_parent_services, service_name, no_filter),
- target_label, target_diag };
- } catch (Service_denied) { }
+ {
+ Xml_node service_node("<deny/>");
+ Xml_node routes_node = _routes_accessor.routes(service_node);
+ Xml_node_label_score best_score;
+
+ routes_node.for_each_sub_node([&] (Xml_node const &node) {
+ if (service_node_matches(node, label, service_name)) {
+ Xml_node_label_score score(node, label);
+ if (score.stronger(best_score)
+ || service_node.has_type("deny")) {
+ best_score = score;
+ service_node = node;
}
+ }
+ });
- if (target.has_type("local")) {
+ if (service_node.has_type("deny")) {
+ warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
+ throw Service_denied();
+ }
- try {
- return Route { find_service(_local_services, service_name, no_filter),
- target_label, target_diag };
- } catch (Service_denied) { }
- }
+ for (Xml_node target_node = service_node.sub_node(); ;
+ target_node = target_node.next()) {
- if (target.has_type("child")) {
+ Session_label the_label_part_of_label(skip_label_prefix(name().string(), label.string()));
+ if (the_label_part_of_label == "") the_label_part_of_label = label;
- typedef Name_registry::Name Name;
- Name server_name = target.attribute_value("name", Name());
- server_name = _name_registry.deref_alias(server_name);
+ auto target_label = Sandbox::target_label(
+ target_node, name(), the_label_part_of_label);
- auto filter_server_name = [&] (Routed_service &s) -> bool {
- return s.child_name() != server_name; };
+ Session::Diag const
+ target_diag { target_node.attribute_value("diag", false) };
- try {
- return Route { find_service(_child_services, service_name, filter_server_name),
- target_label, target_diag };
+ auto no_filter = [] (Service &) -> bool { return false; };
- } catch (Service_denied) { }
- }
+ if (target_node.has_type("parent"))
+ return Route { find_service(_parent_services, service_name, no_filter),
+ target_label, target_diag };
- if (target.has_type("any-child")) {
+ if (target_node.has_type("local"))
+ return Route { find_service(_local_services, service_name, no_filter),
+ target_label, target_diag };
- if (is_ambiguous(_child_services, service_name)) {
- error(name(), ": ambiguous routes to "
- "service \"", service_name, "\"");
- throw Service_denied();
- }
- try {
- return Route { find_service(_child_services, service_name, no_filter),
- target_label, target_diag };
+ if (target_node.has_type("child")) {
- } catch (Service_denied) { }
- }
+ typedef Name_registry::Name Name;
+ Name server_name = target_node.attribute_value("name", Name());
+ server_name = _name_registry.deref_alias(server_name);
- if (!service_wildcard) {
- warning(name(), ": lookup for service \"", service_name, "\" failed");
- throw Service_denied();
- }
+ auto filter_server_name = [&] (Routed_service &s) -> bool {
+ return s.child_name() != server_name; };
- if (target.last())
- break;
+ return Route { find_service(_child_services, service_name, filter_server_name),
+ target_label, target_diag };
}
+
+ if (target_node.last()) break;
if (!initialize()) {
+ error("Initialization failed");
env.parent().exit(-1);
sleep_forever();
return;
}
- } catch (Xml_node::Nonexistent_sub_node) { }
+ }
warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
throw Service_denied();
@@ -712,7 +673,6 @@ Sandbox::Child::Child(Env &env,
Id id,
Report_update_trigger &report_update_trigger,
Xml_node start_node,
- Default_route_accessor &default_route_accessor,
Routes_accessor &routes_accessor,
Default_caps_accessor &default_caps_accessor,
Name_registry &name_registry,
@@ -730,7 +690,6 @@ Sandbox::Child::Child(Env &env,
_report_update_trigger(report_update_trigger),
_list_element(this),
_start_node(_alloc, start_node),
- _default_route_accessor(default_route_accessor),
_routes_accessor(routes_accessor),
_default_caps_accessor(default_caps_accessor),
_ram_limit_accessor(ram_limit_accessor),
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
index 81836a2045..f9d04cfdaf 100644
--- a/repos/os/src/lib/sandbox/child.h
+++ b/repos/os/src/lib/sandbox/child.h
@@ -49,7 +49,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
*/
struct Id { unsigned value; };
- struct Default_route_accessor : Interface { virtual Xml_node default_route() = 0; };
struct Default_caps_accessor : Interface { virtual Cap_quota default_caps() = 0; };
struct Routes_accessor : Interface
@@ -105,7 +104,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
*/
bool const _use_ld = _start_node->xml().attribute_value("ld", true);
- Default_route_accessor &_default_route_accessor;
Routes_accessor &_routes_accessor;
Default_caps_accessor &_default_caps_accessor;
Ram_limit_accessor &_ram_limit_accessor;
@@ -481,7 +479,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Id id,
Report_update_trigger &report_update_trigger,
Xml_node start_node,
- Default_route_accessor &default_route_accessor,
Routes_accessor &route_accessor,
Default_caps_accessor &default_caps_accessor,
Name_registry &name_registry,
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
index caa9840ea6..7b4e72c60e 100644
--- a/repos/os/src/lib/sandbox/library.cc
+++ b/repos/os/src/lib/sandbox/library.cc
@@ -22,7 +22,6 @@
#include <heartbeat.h>
struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
- ::Sandbox::Child::Default_route_accessor,
::Sandbox::Child::Routes_accessor,
::Sandbox::Child::Default_caps_accessor,
::Sandbox::Child::Ram_limit_accessor,
@@ -134,15 +133,6 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
_children.report_state(xml, detail);
/* all is well, announce the device */
+ log("Announce device");
Signal_transmitter(announce_sigh).submit();
}
- /**
- * Default_route_accessor interface
- */
- Xml_node default_route() override
- {
- return _default_route.constructed() ? _default_route->xml()
- : Xml_node("<empty/>");
- }
-
/**
* Routes_accessor interface
*/
@@ -462,7 +452,7 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
Child &child = *new (_heap)
Child(_env, _heap, *_verbose,
Child::Id { ++_child_cnt }, _state_reporter,
- start_node, *this, *this, *this, _children,
+ start_node, *this, *this, _children,
Ram_quota { avail_ram.value - used_ram.value },
Cap_quota { avail_caps.value - used_caps.value },
*this, *this, prio_levels, affinity_space,
diff --git a/repos/os/src/lib/sandbox/utils.h b/repos/os/src/lib/sandbox/utils.h
index 36aab737f2..639a4be4dd 100644
--- a/repos/os/src/lib/sandbox/utils.h
+++ b/repos/os/src/lib/sandbox/utils.h
@@ -58,12 +58,9 @@ namespace Sandbox {
*/
inline bool service_node_matches(Xml_node const service_node,
Session_label const &label,
- Child_policy::Name const &child_name,
- Service::Name const &service_name,
- bool skip_child_prefix = true)
+ Service::Name const &service_name)
@@ -795,9 +797,10 @@ struct Usb::Block_driver : Usb::Completion
device(&alloc, usb, ep), wake_up_handler(wake_up_handler)
{
bool const service_matches =
- service_node.has_type("any-service") ||
(service_node.has_type("service") &&
service_node.attribute_value("name", Service::Name()) == service_name);
parse_config(config.xml());
- reporter.enabled(true);
+ reporter.enabled(_report_device);
@@ -72,7 +69,6 @@ namespace Sandbox {
typedef String<Session_label::capacity()> Label;
- char const *unscoped_attr = "unscoped_label";
char const *label_last_attr = "label_last";
bool const route_depends_on_child_provided_label =
@@ -81,34 +77,13 @@ namespace Sandbox {
service_node.has_attribute("label_suffix") ||
service_node.has_attribute(label_last_attr);
- if (service_node.has_attribute(unscoped_attr)) {
-
- /*
- * If an 'unscoped_label' attribute is provided, don't consider any
- * scoped label attribute.
- */
- if (route_depends_on_child_provided_label)
- warning("service node contains both scoped and unscoped label attributes");
-
- return label == service_node.attribute_value(unscoped_attr, Label());
- }
-
if (service_node.has_attribute(label_last_attr))
return service_node.attribute_value(label_last_attr, Label()) == label.last_element();
if (!route_depends_on_child_provided_label)
return true;
- char const * const scoped_label = skip_child_prefix
- ? skip_label_prefix(child_name.string(), label.string())
- : label.string();
-
- if (!scoped_label)
- return false;
-
- Session_label const session_label(scoped_label);
-
- return !Xml_node_label_score(service_node, session_label).conflict();
+ return !Xml_node_label_score(service_node, label).conflict();
/* USB device gets initialized by handle_state_change() */
+ log("waiting for device to initialize…");
}
@@ -131,6 +106,34 @@ namespace Sandbox {
return cnt > 1;
~Block_driver()
--
2.29.2
From cc7b477c808cdb8876a2f8713693dc6f0a4ef60f Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 19 Dec 2020 12:20:53 +0100
Subject: [PATCH 2/2] usb_drv: select raw session device by class
Select devices for raw Usb sessions by device class. This is for
simple scenarios where the number of attached USB devices is known
but not vendor and product identifiers or bus topology.
---
repos/dde_linux/src/drivers/usb/raw/raw.cc | 57 +++++++++++++++++++---
1 file changed, 49 insertions(+), 8 deletions(-)
diff --git a/repos/dde_linux/src/drivers/usb/raw/raw.cc b/repos/dde_linux/src/drivers/usb/raw/raw.cc
index efa86bf29b..1a94a72cfe 100644
--- a/repos/dde_linux/src/drivers/usb/raw/raw.cc
+++ b/repos/dde_linux/src/drivers/usb/raw/raw.cc
@@ -55,6 +55,20 @@ struct Device : List<Device>::Element
return &_l;
}
+
+ /*
+ * Determine session label to be provided to the server
+ *
+ * By default, the client's identity (accompanied with the a
+ * client-provided label) is presented as session label to the
+ * server. However, the target node can explicitly override the
+ * client's identity by a custom label via the 'label' attribute or
+ * by specifying a 'prefix' and 'suffix attributes.
+ */
+ typedef String<Session_label::capacity()> Label;
+ inline Label target_label(Xml_node const node,
+ Child_policy::Name const &child_name,
+ Session_label const &label)
+ static Device * device_class(uint8_t class_)
+ {
+ if (node.has_attribute("label"))
+ return Session_label(node.attribute_value("label", Label()).string());
+ for (Device *d = list()->first(); d; d = d->next()) {
+ usb_interface *iface = d->interface(0);
+ if (!iface || !iface->cur_altsetting || !d->udev || !d->udev->bus)
+ continue;
+
+ Label head = node.attribute_value("prefix", Label(child_name.string()));
+ Label tail = node.attribute_value("suffix", Label(child_name == label ? "" : label));
+ if (iface->cur_altsetting->desc.bInterfaceClass == class_)
+ return d;
+ }
+
+ if (head == "") return tail;
+ if (tail == "") return head;
+
+ return Label(prefixed_label(head, tail).string());
+ return nullptr;
+ }
+
static Device * device_product(uint16_t vendor, uint16_t product)
{
for (Device *d = list()->first(); d; d = d->next()) {
@@ -670,10 +684,6 @@ class Usb::Session_component : public Session_rpc_object,
private:
Genode::Entrypoint &_ep;
- unsigned long _vendor;
- unsigned long _product;
- long _bus = 0;
- long _dev = 0;
Device *_device = nullptr;
Signal_context_capability _sigh_state_change;
Io_signal_handler<Session_component> _packet_avail;
@@ -697,6 +707,11 @@ class Usb::Session_component : public Session_rpc_object,
public:
+ unsigned long _vendor;
+ unsigned long _product;
+ long _bus;
+ long _dev;
+
/**
* Find service with certain values in given registry
*
--
2.29.2
From 92c1f192d432f177c681e3ab001214e66e96e0f0 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 28 Nov 2020 14:00:49 +0100
Subject: [PATCH 4/4] Do not default Child::binary_name() to Child::name()
---
repos/base/include/base/child.h | 2 +-
repos/base/src/core/main.cc | 2 ++
repos/os/src/lib/sandbox/child.h | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h
index 8c7b33a9d9..bca0d566f2 100644
--- a/repos/base/include/base/child.h
+++ b/repos/base/include/base/child.h
@@ -58,7 +58,7 @@ struct Genode::Child_policy
/**
* ROM module name of the binary to start
*/
- virtual Binary_name binary_name() const { return name(); }
+ virtual Binary_name binary_name() const = 0;
/**
* ROM module name of the dynamic linker
diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc
index d480585221..7acacf0ffd 100644
--- a/repos/base/src/core/main.cc
+++ b/repos/base/src/core/main.cc
@@ -145,6 +145,8 @@ class Core_child : public Child_policy
Name name() const override { return "init"; }
+ Binary_name binary_name() const override { return "init"; }
+
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
{
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
index f9d04cfdaf..a1e45dab0d 100644
--- a/repos/os/src/lib/sandbox/child.h
+++ b/repos/os/src/lib/sandbox/child.h
@@ -595,6 +595,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
****************************/
Child_policy::Name name() const override { return _unique_name; }
+ Child_policy::Binary_name binary_name() const override { return _binary_name; }
Pd_session &ref_pd() override { return _env.pd(); }
Pd_session_capability ref_pd_cap() const override { return _env.pd_session_cap(); }
enum State {
DEVICE_ADD,
DEVICE_REMOVE,
@@ -705,8 +720,10 @@ class Usb::Session_component : public Session_rpc_object,
Session_component(Genode::Ram_dataspace_capability tx_ds,
Genode::Entrypoint &ep,
Genode::Region_map &rm,
+ unsigned long class_,
unsigned long vendor, unsigned long product,
- long bus, long dev, Usb::Cleaner &cleaner)
+ long bus, long dev,
+ Usb::Cleaner &cleaner)
: Session_rpc_object(tx_ds, ep.rpc_ep(), rm),
_ep(ep), _vendor(vendor), _product(product), _bus(bus), _dev(dev),
_packet_avail(ep, *this, &Session_component::_receive),
@@ -716,11 +733,20 @@ class Usb::Session_component : public Session_rpc_object,
Device *device;
if (bus && dev)
device = Device::device_bus(bus, dev);
- else
+ else if (_vendor || _product)
device = Device::device_product(_vendor, _product);
+ else if (class_) {
+ device = Device::device_class(class_);
+ else
+ throw Service_denied();
if (device) {
state_change(DEVICE_ADD, device);
- }
+
+ _vendor = device->udev->descriptor.idVendor;
+ _product = device->udev->descriptor.idProduct;
+ _bus = device->udev->bus->busnum;
+ _dev = device->udev->devnum == dev;
+ } // else do nothing!?
/* register signal handlers */
_tx.sigh_packet_avail(_packet_avail);
@@ -973,6 +999,11 @@ class Usb::Root : public Genode::Root_component<Session_component>
using namespace Genode;
using Genode::size_t;
+ bool diag = Arg_string::find_arg(args, "diag").bool_value(false);
+
+ if (diag)
+ log("request for ", args);
+
Session_label const label = label_from_args(args);
try {
Xml_node config_node = Lx_kit::env().config_rom().xml();
@@ -982,11 +1013,18 @@ class Usb::Root : public Genode::Root_component<Session_component>
size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
+ unsigned long class_ = policy.attribute_value<unsigned long>("class", 0);
unsigned long vendor = policy.attribute_value<unsigned long>("vendor_id", 0);
unsigned long product = policy.attribute_value<unsigned long>("product_id", 0);
unsigned long bus = policy.attribute_value<unsigned long>("bus", 0);
unsigned long dev = policy.attribute_value<unsigned long>("dev", 0);
+ if (!(class_ || (vendor && product) || (bus && dev))) {
+ error("policy lacks class, vendor/product, or bus/dev attributes");
+ error(policy);
+ throw Genode::Service_denied();
+ }
+
/* check session quota */
size_t session_size = max<size_t>(4096, sizeof(Session_component));
if (ram_quota < session_size)
@@ -1000,8 +1038,11 @@ class Usb::Root : public Genode::Root_component<Session_component>
Ram_dataspace_capability tx_ds = _env.ram().alloc(tx_buf_size);
Session_component *session = new (md_alloc())
- Session_component(tx_ds, _env.ep(), _env.rm(), vendor, product, bus, dev, _cleaner);
+ Session_component(
+ tx_ds, _env.ep(), _env.rm(), class_, vendor, product, bus, dev, _cleaner);
::Session::list()->insert(session);
+ if (diag)
+ log("serve device ", Hex(session->_vendor), ":", Hex(session->_product), " at ", Hex(session->_bus), ":", Hex(session->_dev), " to \"", label, "\"");
return session;
}
catch (Genode::Session_policy::No_policy_defined) {
--
2.29.2