From 632444ae232a6f1b7c814d900e4f9e5e46103f84 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 15 Jun 2016 10:54:21 +0200 Subject: [PATCH] server/rump_fs: transition to the new base API Use new env, component and logging frameworks. Sync file system and block device on component entrypoint. Support for 'root' session argument. Increase Rump open file descriptor limit. Issue #1987 Fixes #2011 --- repos/dde_rump/src/server/rump_fs/directory.h | 7 +- .../src/server/rump_fs/file_system.cc | 57 +---- .../dde_rump/src/server/rump_fs/file_system.h | 5 +- repos/dde_rump/src/server/rump_fs/main.cc | 226 ++++++++++-------- repos/dde_rump/src/server/rump_fs/target.mk | 2 +- 5 files changed, 135 insertions(+), 162 deletions(-) diff --git a/repos/dde_rump/src/server/rump_fs/directory.h b/repos/dde_rump/src/server/rump_fs/directory.h index d689e977c9..3216b5a96b 100644 --- a/repos/dde_rump/src/server/rump_fs/directory.h +++ b/repos/dde_rump/src/server/rump_fs/directory.h @@ -19,6 +19,7 @@ /* Genode include */ #include #include +#include /* local includes */ #include "node.h" @@ -143,12 +144,12 @@ class File_system::Directory : public Node size_t read(char *dst, size_t len, seek_off_t seek_offset) { if (len < sizeof(Directory_entry)) { - PERR("read buffer too small for directory entry"); + Genode::error("read buffer too small for directory entry"); return 0; } if (seek_offset % sizeof(Directory_entry)) { - PERR("seek offset not aligned to sizeof(Directory_entry)"); + Genode::error("seek offset not aligned to sizeof(Directory_entry)"); return 0; } @@ -256,7 +257,7 @@ class File_system::Directory : public Node throw Lookup_failed(); if (ret == -1) - PERR("Error during unlink of %s", node_path.base()); + Genode::error("Error during unlink of ", node_path.base()); } }; diff --git a/repos/dde_rump/src/server/rump_fs/file_system.cc b/repos/dde_rump/src/server/rump_fs/file_system.cc index 2d0606dad4..13afd9517f 100644 --- a/repos/dde_rump/src/server/rump_fs/file_system.cc +++ b/repos/dde_rump/src/server/rump_fs/file_system.cc @@ -13,12 +13,11 @@ #include "file_system.h" -#include #include #include -#include #include #include +#include /** * We define our own fs arg structure to fit all sizes, we assume that 'fspec' @@ -61,9 +60,9 @@ static bool _check_type(char const *type) static void _print_types() { - PERR("fs types:"); - for (int i = 0; fs_types[i]; i++) - PERR("\t%s", fs_types[i]); + Genode::error("fs types:"); + for (int i = 0; fs_types[i]; ++i) + Genode::error("\t", fs_types[i]); } @@ -88,52 +87,14 @@ static bool check_read_only() } -class File_system::Sync : public Genode::Thread_deprecated<1024 * sizeof(Genode::addr_t)> -{ - private: - - Timer::Connection _timer; - Genode::Signal_rpc_member _sync_dispatcher; - - void _process_sync(unsigned) - { - /* sync through front-end */ - rump_sys_sync(); - /* sync Genode back-end */ - rump_io_backend_sync(); - } - - protected: - - void entry() - { - while (1) { - _timer.msleep(1000); - /* send sync request, this goes to server entry point thread */ - Genode::Signal_transmitter(_sync_dispatcher).submit(); - } - } - - public: - - Sync(Server::Entrypoint &ep) - : - Thread_deprecated("rump_fs_sync"), - _sync_dispatcher(ep, *this, &Sync::_process_sync) - { - start(); - } -}; - - -void File_system::init(Server::Entrypoint &ep) +void File_system::init() { if (!_check_type(fs_type().string())) { - PERR("Invalid or no file system given (use \'\"/>)"); + Genode::error("Invalid or no file system given (use \'\"/>)"); _print_types(); throw Genode::Exception(); } - PINF("Using %s as file system", fs_type().string()); + Genode::log("Using ", fs_type().string(), " as file system"); /* start rump kernel */ rump_init(); @@ -147,14 +108,12 @@ void File_system::init(Server::Entrypoint &ep) args.fspec = (char *)GENODE_DEVICE; if (rump_sys_mount(fs_type().string(), "/", opts, &args, sizeof(args)) == -1) { - PERR("Mounting '%s' file system failed (errno %u)", fs_type().string(), errno); + Genode::error("Mounting '", fs_type().string(), "' file system failed (errno ", errno, " )"); throw Genode::Exception(); } /* check support for symlinks */ _supports_symlinks = check_symlinks(); - - new (Genode::env()->heap()) Sync(ep); } diff --git a/repos/dde_rump/src/server/rump_fs/file_system.h b/repos/dde_rump/src/server/rump_fs/file_system.h index 7484baa12c..c4f45cbc35 100644 --- a/repos/dde_rump/src/server/rump_fs/file_system.h +++ b/repos/dde_rump/src/server/rump_fs/file_system.h @@ -25,11 +25,8 @@ extern "C" { #include } -#include -#include - namespace File_system { - void init(Server::Entrypoint &ep); + void init(); bool supports_symlinks(); } diff --git a/repos/dde_rump/src/server/rump_fs/main.cc b/repos/dde_rump/src/server/rump_fs/main.cc index bb21ad3cb5..ecd226960d 100644 --- a/repos/dde_rump/src/server/rump_fs/main.cc +++ b/repos/dde_rump/src/server/rump_fs/main.cc @@ -14,14 +14,16 @@ /* Genode includes */ #include +#include +#include +#include +#include +#include #include "undef.h" -#include -#include -#include -#include -#include +#include +#include #include "file_system.h" #include "directory.h" @@ -40,7 +42,7 @@ class File_system::Session_component : public Session_rpc_object Node_handle_registry _handle_registry; bool _writable; - Signal_rpc_member _process_packet_dispatcher; + Signal_handler _process_packet_handler; /****************************** @@ -93,7 +95,7 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } - catch (Invalid_handle) { PERR("Invalid_handle"); } + catch (Invalid_handle) { Genode::error("Invalid_handle"); } /* * The 'acknowledge_packet' function cannot block because we @@ -106,7 +108,7 @@ class File_system::Session_component : public Session_rpc_object * Called by signal dispatcher, executed in the context of the main * thread (not serialized with the RPC functions) */ - void _process_packets(unsigned) + void _process_packets() { while (tx_sink()->packet_avail()) { @@ -134,10 +136,8 @@ class File_system::Session_component : public Session_rpc_object */ static void _assert_valid_path(char const *path) { - if (!path || path[0] != '/') { - PWRN("malformed path '%s'", path); + if (!path || path[0] != '/') throw Lookup_failed(); - } } public: @@ -145,24 +145,24 @@ class File_system::Session_component : public Session_rpc_object /** * Constructor */ - Session_component(size_t tx_buf_size, - Server::Entrypoint &ep, + Session_component(Genode::Env &env, + size_t tx_buf_size, char const *root_dir, bool writeable, Allocator &md_alloc) : - Session_rpc_object(env()->ram_session()->alloc(tx_buf_size), ep.rpc_ep()), + Session_rpc_object(env.ram().alloc(tx_buf_size), env.ep().rpc_ep()), _md_alloc(md_alloc), _root(*new (&_md_alloc) Directory(_md_alloc, root_dir, false)), _writable(writeable), - _process_packet_dispatcher(ep, *this, &Session_component::_process_packets) + _process_packet_handler(env.ep(), *this, &Session_component::_process_packets) { /* * Register '_process_packets' dispatch function as signal * handler for packet-avail and ready-to-ack signals. */ - _tx.sigh_packet_avail(_process_packet_dispatcher); - _tx.sigh_ready_to_ack(_process_packet_dispatcher); + _tx.sigh_packet_avail(_process_packet_handler); + _tx.sigh_ready_to_ack(_process_packet_handler); } /** @@ -286,10 +286,7 @@ class File_system::Session_component : public Session_rpc_object return Status(); } - void control(Node_handle, Control) - { - PERR("%s not implemented", __func__); - } + void control(Node_handle, Control) override { } void unlink(Dir_handle dir_handle, Name const &name) { @@ -345,11 +342,11 @@ class File_system::Session_component : public Session_rpc_object case ENOENT: throw Lookup_failed(); } - PWRN("renameat produced unhandled error %x %s %s", errno, from_str, to_str); + Genode::warning("renameat produced unhandled error ", errno, ", ", from_str, " -> ", to_str); throw Permission_denied(); } - void sigh(Node_handle node_handle, Signal_context_capability sigh) + void sigh(Node_handle node_handle, Signal_context_capability sigh) override { _handle_registry.sigh(node_handle, sigh); } @@ -361,88 +358,87 @@ class File_system::Root : public Root_component { private: - Server::Entrypoint &_ep; + Genode::Env &_env; protected: Session_component *_create_session(const char *args) { + using namespace Genode; + /* * Determine client-specific policy defined implicitly by * the client's label. */ - char const *root_dir = "."; - bool writeable = false; + Genode::Path session_root; + bool writeable = false; - enum { ROOT_MAX_LEN = 256 }; - char root[ROOT_MAX_LEN]; - root[0] = 0; - - Session_label label(args); - try { - Session_policy policy(label); - - /* - * Determine directory that is used as root directory of - * the session. - */ - try { - policy.attribute("root").value(root, sizeof(root)); - - /* - * Make sure the root path is specified with a - * leading path delimiter. For performing the - * lookup, we skip the first character. - */ - if (root[0] != '/') - throw Lookup_failed(); - - root_dir = root; - } catch (Xml_node::Nonexistent_attribute) { - PERR("Missing \"root\" attribute in policy definition"); - throw Root::Unavailable(); - } catch (Lookup_failed) { - PERR("Session root directory \"%s\" does not exist", root); - throw Root::Unavailable(); - } - - /* - * Determine if write access is permitted for the session. - */ - writeable = policy.attribute_value("writeable", false); - - } catch (Session_policy::No_policy_defined) { - PERR("Invalid session request, no matching policy"); - throw Root::Unavailable(); - } + Session_label const label(args); size_t ram_quota = - Arg_string::find_arg(args, "ram_quota" ).ulong_value(0); + Arg_string::find_arg(args, "ram_quota").aligned_size(); size_t tx_buf_size = - Arg_string::find_arg(args, "tx_buf_size").ulong_value(0); + Arg_string::find_arg(args, "tx_buf_size").aligned_size(); - if (!tx_buf_size) { - PERR("%s requested a session with a zero length transmission buffer", label.string()); + if (!tx_buf_size) throw Root::Invalid_args(); - } /* * Check if donated ram quota suffices for session data, * and communication buffer. */ - size_t session_size = sizeof(Session_component) + tx_buf_size; - if (max((size_t)4096, session_size) > ram_quota) { - PERR("insufficient 'ram_quota', got %zd, need %zd", - ram_quota, session_size); + size_t session_size = + max((size_t)4096, sizeof(Session_component)) + + tx_buf_size; + + if (session_size > ram_quota) { + Genode::error("insufficient 'ram_quota' from ", label.string(), + " got ", ram_quota, "need ", session_size); throw Root::Quota_exceeded(); } + ram_quota -= session_size; + + char tmp[MAX_PATH_LEN]; + try { + Session_policy policy(label); + + /* Determine the session root directory. + * Defaults to '/' if not specified by session + * policy or session arguments. + */ + try { + policy.attribute("root").value(tmp, sizeof(tmp)); + session_root.import(tmp, "/"); + } catch (Xml_node::Nonexistent_attribute) { } + + /* Determine if the session is writeable. + * Policy overrides arguments, both default to false. + */ + if (policy.attribute_value("writeable", false)) + writeable = Arg_string::find_arg(args, "writeable").bool_value(false); + + } catch (...) { } + + /* + * If no policy matches the client gets + * read-only access to the root. + */ + + Arg_string::find_arg(args, "root").string(tmp, sizeof(tmp), "/"); + if (Genode::strcmp("/", tmp, sizeof(tmp))) { + session_root.append("/"); + session_root.append(tmp); + } + session_root.remove_trailing('/'); + + char const *root_dir = session_root.base(); try { return new (md_alloc()) - Session_component(tx_buf_size, _ep, root_dir, writeable, *md_alloc()); + Session_component(_env, tx_buf_size, root_dir, writeable, *md_alloc()); } catch (Lookup_failed) { - PERR("File system root directory \"%s\" does not exist", root_dir); + Genode::error("File system root directory \"", root_dir, "\" does not exist"); throw Root::Unavailable(); } } @@ -451,53 +447,73 @@ class File_system::Root : public Root_component /** * Constructor - * - * \param ep entrypoint - * \param sig_rec signal receiver used for handling the - * data-flow signals of packet streams - * \param md_alloc meta-data allocator */ - Root(Server::Entrypoint &ep, Allocator &md_alloc) + Root(Genode::Env &env, Allocator &md_alloc) : - Root_component(&ep.rpc_ep(), &md_alloc), - _ep(ep) + Root_component(env.ep(), md_alloc), + _env(env) { } }; struct File_system::Main { - Server::Entrypoint &ep; - Server::Signal_rpc_member
resource_dispatcher; + Genode::Env &env; + + Timer::Connection _timer { env }; + + /* return immediately from resource requests */ + void ignore_resource() { } + + Genode::Signal_handler
resource_handler + { env.ep(), *this, &Main::ignore_resource }; + + /* periodic sync */ + void sync() + { + /* sync through front-end */ + rump_sys_sync(); + /* sync Genode back-end */ + rump_io_backend_sync(); + } + + Genode::Signal_handler
sync_handler + { env.ep(), *this, &Main::sync }; /* * Initialize root interface */ - Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() }; + Sliced_heap sliced_heap = { env.ram(), env.rm() }; - Root fs_root = { ep, sliced_heap }; + Root fs_root = { env, sliced_heap }; - - /* return immediately from resource requests */ - void resource_handler(unsigned) { } - - Main(Server::Entrypoint &ep) - : - ep(ep), - resource_dispatcher(ep, *this, &Main::resource_handler) + Main(Genode::Env &env) : env(env) { - File_system::init(ep); - env()->parent()->announce(ep.manage(fs_root)); - env()->parent()->resource_avail_sigh(resource_dispatcher); + File_system::init(); + + /* set all bits but the stickies */ + rump_sys_umask(S_ISUID|S_ISGID|S_ISVTX); + + /* set open file limit to maximum (256) */ + struct rlimit rl { RLIM_INFINITY, RLIM_INFINITY }; + if (rump_sys_setrlimit(RLIMIT_NOFILE, &rl) != 0) + Genode::error("rump_sys_setrlimit(RLIMIT_NOFILE, ...) failed, errno ", errno); + + env.parent().announce(env.ep().manage(fs_root)); + env.parent().resource_avail_sigh(resource_handler); + + _timer.sigh(sync_handler); + _timer.trigger_periodic(10*1000*1000); } }; /********************** - ** Server framework ** + ** Component framework ** **********************/ -char const * Server::name() { return "rump_fs_ep"; } -Genode::size_t Server::stack_size() { return 4 * 1024 * sizeof(long); } -void Server::construct(Server::Entrypoint &ep) { static File_system::Main inst(ep); } +namespace Component { + Genode::size_t stack_size() { return 4 * 1024 * sizeof(long); } + void construct(Genode::Env &env) { static File_system::Main inst(env); } +} diff --git a/repos/dde_rump/src/server/rump_fs/target.mk b/repos/dde_rump/src/server/rump_fs/target.mk index 56fd8f4fda..aea32b44cb 100644 --- a/repos/dde_rump/src/server/rump_fs/target.mk +++ b/repos/dde_rump/src/server/rump_fs/target.mk @@ -1,5 +1,5 @@ TARGET = rump_fs SRC_CC = main.cc file_system.cc random.cc -LIBS = rump rump_fs server startup +LIBS = rump rump_fs startup