From e410be69a725c9f4aaa6a9dfc3dcba3cc3f2aa97 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 13 Jul 2016 18:49:07 +0200 Subject: [PATCH] server/fs_rom: adjust to component API - Use component API. - Use signal handlers. - Log ROM file path at error. - Add Output printing support to os/path.h utility. Fixes #2042 --- repos/os/include/os/path.h | 6 ++ repos/os/src/server/fs_rom/main.cc | 158 ++++++++++++----------------- 2 files changed, 70 insertions(+), 94 deletions(-) diff --git a/repos/os/include/os/path.h b/repos/os/include/os/path.h index b9e553a777..62f7cccb4e 100644 --- a/repos/os/include/os/path.h +++ b/repos/os/include/os/path.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include namespace Genode { @@ -326,6 +327,11 @@ class Genode::Path_base { return strcmp(_path, other) != 0; } + + /** + * Print path to output stream + */ + void print(Genode::Output &output) const { output.out_string(base()); } }; diff --git a/repos/os/src/server/fs_rom/main.cc b/repos/os/src/server/fs_rom/main.cc index b03b9254dd..f0882b8810 100755 --- a/repos/os/src/server/fs_rom/main.cc +++ b/repos/os/src/server/fs_rom/main.cc @@ -13,15 +13,13 @@ /* Genode includes */ #include -#include -#include #include #include -#include -#include -#include #include +#include +#include #include +#include #include @@ -38,6 +36,8 @@ class Rom_session_component : public Genode::Rpc_object { private: + Genode::Env &_env; + File_system::Session &_fs; enum { PATH_MAX_LEN = 512 }; @@ -72,13 +72,23 @@ class Rom_session_component : public Genode::Rpc_object Genode::Ram_dataspace_capability _file_ds; /** - * Handler for ROM file changes + * Signal destination for ROM file changes */ - Genode::Lock _sigh_lock; Genode::Signal_context_capability _sigh; /** - * Dispatcher that is called each time when the requested file is not + * Signal-handling function called by the main thread the compound + * directory changed. + */ + void _dir_changed() + { + Genode::log("detected directory change"); + if (_sigh.valid()) + Genode::Signal_transmitter(_sigh).submit(); + } + + /** + * Handler that is called each time when the requested file is not * yet available and the compound directory changes * * The change of the compound directory bears the chance that the @@ -86,24 +96,8 @@ class Rom_session_component : public Genode::Rpc_object * module change and thereby give it a chance to call 'dataspace()' in * response. */ - Genode::Signal_dispatcher _dir_change_dispatcher; - - /** - * Signal-handling function called by the main thread the compound - * directory changed. - * - * Note that this function is not executed in the context of the RPC - * entrypoint. Therefore, the access to '_sigh' is synchronized with - * the 'sigh()' function using '_sigh_lock'. - */ - void _dir_changed(unsigned) - { - Genode::Lock::Guard guard(_sigh_lock); - - Genode::log("detected directory change"); - if (_sigh.valid()) - Genode::Signal_transmitter(_sigh).submit(); - } + Genode::Signal_handler _dir_change_handler + { _env.ep(), *this, &Rom_session_component::_dir_changed }; /** * Open compound directory of specified file @@ -113,9 +107,9 @@ class Rom_session_component : public Genode::Rpc_object * existing directory on the way. If set to false, the * function returns the immediate compound directory. */ - static File_system::Dir_handle _open_compound_dir(File_system::Session &fs, - Path const &path, - bool walk_up) + File_system::Dir_handle _open_compound_dir(File_system::Session &fs, + Path const &path, + bool walk_up) { using namespace File_system; @@ -127,12 +121,12 @@ class Rom_session_component : public Genode::Rpc_object try { return fs.dir(dir_path.base(), false); } - catch (Invalid_handle) { PERR("Invalid_handle"); } - catch (Invalid_name) { PERR("Invalid_name"); } - catch (Lookup_failed) { PERR("Lookup_failed"); } - catch (Permission_denied) { PERR("Permission_denied"); } - catch (Name_too_long) { PERR("Name_too_long"); } - catch (No_space) { PERR("No_space"); } + catch (Invalid_handle) { Genode::error(_file_path, ": invalid_handle"); } + catch (Invalid_name) { Genode::error(_file_path, ": invalid_name"); } + catch (Lookup_failed) { Genode::error(_file_path, ": lookup_failed"); } + catch (Permission_denied) { Genode::error(_file_path, ": permission_denied"); } + catch (Name_too_long) { Genode::error(_file_path, ": name_too_long"); } + catch (No_space) { Genode::error(_file_path, ": no_space"); } /* * If the directory could not be opened, walk up the hierarchy @@ -146,8 +140,8 @@ class Rom_session_component : public Genode::Rpc_object /** * Open file with specified name at the file system */ - static File_system::File_handle _open_file(File_system::Session &fs, - Path const &path) + File_system::File_handle _open_file(File_system::Session &fs, + Path const &path) { using namespace File_system; @@ -164,9 +158,9 @@ class Rom_session_component : public Genode::Rpc_object file_handle = fs.file(dir, file_name.base() + 1, File_system::READ_ONLY, false); } - catch (Invalid_handle) { PERR("Invalid_handle"); } - catch (Invalid_name) { PERR("Invalid_name"); } - catch (Lookup_failed) { PERR("Lookup_failed"); } + catch (Invalid_handle) { Genode::error(_file_path, ": Invalid_handle"); } + catch (Invalid_name) { Genode::error(_file_path, ": invalid_name"); } + catch (Lookup_failed) { Genode::error(_file_path, ": lookup_failed"); } return file_handle; } @@ -181,7 +175,7 @@ class Rom_session_component : public Genode::Rpc_object /* register for changes in compound directory */ if (_compound_dir_handle.valid()) - _fs.sigh(_compound_dir_handle, _dir_change_dispatcher); + _fs.sigh(_compound_dir_handle, _dir_change_handler); else Genode::warning("could not track compound dir, giving up"); } @@ -206,7 +200,7 @@ class Rom_session_component : public Genode::Rpc_object _fs.status(file_handle).size; if (_file_ds.valid() && (new_file_size > _file_size)) { - env()->ram_session()->free(_file_ds); + _env.ram().free(_file_ds); /* mark as invalid */ _file_ds = Ram_dataspace_capability(); @@ -240,7 +234,7 @@ class Rom_session_component : public Genode::Rpc_object if (file_size > 0) { try { if (!_file_ds.valid()) { - _file_ds = env()->ram_session()->alloc(file_size); + _file_ds = _env.ram().alloc(file_size); _file_size = file_size; } } catch (...) { @@ -256,13 +250,13 @@ class Rom_session_component : public Genode::Rpc_object } /* map dataspace locally */ - void * const dst_addr = env()->rm_session()->attach(_file_ds); + void * const dst_addr = _env.rm().attach(_file_ds); /* read content from file */ read(_fs, _file_handle, dst_addr, file_size); /* unmap dataspace */ - env()->rm_session()->detach(dst_addr); + _env.rm().detach(dst_addr); } public: @@ -277,11 +271,11 @@ class Rom_session_component : public Genode::Rpc_object * the requested file could not be found at session- * creation time) */ - Rom_session_component(File_system::Session &fs, const char *file_path, - Genode::Signal_receiver &sig_reg) + Rom_session_component(Genode::Env &env, + File_system::Session &fs, const char *file_path) : - _fs(fs), _file_path(file_path), _file_handle(_open_file(_fs, _file_path)), - _dir_change_dispatcher(sig_reg, *this, &Rom_session_component::_dir_changed) + _env(env), _fs(fs), _file_path(file_path), + _file_handle(_open_file(_fs, _file_path)) { if (!_file_handle.valid()) _register_for_compound_dir_changes(); @@ -300,7 +294,7 @@ class Rom_session_component : public Genode::Rpc_object _fs.close(_compound_dir_handle); /* close file */ - Genode::env()->ram_session()->free(_file_ds); + _env.ram().free(_file_ds); } /** @@ -315,7 +309,6 @@ class Rom_session_component : public Genode::Rpc_object void sigh(Genode::Signal_context_capability sigh) { - Genode::Lock::Guard guard(_sigh_lock); _sigh = sigh; if (_file_handle.valid()) _fs.sigh(_file_handle, _sigh); @@ -327,19 +320,23 @@ class Rom_root : public Genode::Root_component { private: - File_system::Session &_fs; - Genode::Signal_receiver &_sig_rec; + Genode::Env &_env; + Genode::Heap _heap { _env.ram(), _env.rm() }; + Genode::Allocator_avl _fs_tx_block_alloc { &_heap }; + + /* open file-system session */ + File_system::Connection _fs { _env, _fs_tx_block_alloc }; Rom_session_component *_create_session(const char *args) { Genode::Session_label const label = label_from_args(args); Genode::Session_label const module_name = label.last_element(); - Genode::log(label.string(), " requests '", module_name.string(), "'"); + Genode::log("request for ", label); /* create new session for the requested file */ return new (md_alloc()) - Rom_session_component(_fs, module_name.string(), _sig_rec); + Rom_session_component(_env, _fs, module_name.string()); } public: @@ -347,50 +344,23 @@ class Rom_root : public Genode::Root_component /** * Constructor * - * \param entrypoint entrypoint to be used for ROM sessions + * \param env Component environment * \param md_alloc meta-data allocator used for ROM sessions - * \param fs file-system session */ - Rom_root(Genode::Rpc_entrypoint &entrypoint, - Genode::Allocator &md_alloc, - File_system::Session &fs, - Genode::Signal_receiver &sig_rec) + Rom_root(Genode::Env &env, + Genode::Allocator &md_alloc) : - Genode::Root_component(&entrypoint, &md_alloc), - _fs(fs), _sig_rec(sig_rec) - { } + Genode::Root_component(env.ep(), md_alloc), + _env(env) + { + env.parent().announce(env.ep().manage(*this)); + } }; +Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); } -int main(void) +void Component::construct(Genode::Env &env) { - using namespace Genode; - - /* open file-system session */ - static Genode::Allocator_avl fs_tx_block_alloc(env()->heap()); - static File_system::Connection fs(fs_tx_block_alloc); - - /* connection to capability service needed to create capabilities */ - static Cap_connection cap; - - /* creation of the entrypoint and the root interface */ - static Sliced_heap sliced_heap(env()->ram_session(), - env()->rm_session()); - - /* receiver of directory-change signals */ - static Signal_receiver sig_rec; - - enum { STACK_SIZE = 2*1024*sizeof(long) }; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "fs_rom_ep"); - static Rom_root rom_root(ep, sliced_heap, fs, sig_rec); - - /* announce server*/ - env()->parent()->announce(ep.manage(&rom_root)); - - /* process incoming signals */ - for (;;) { - Signal s = sig_rec.wait_for_signal(); - static_cast(s.context())->dispatch(s.num()); - } - return 0; + static Sliced_heap sliced_heap(env.ram(), env.rm()); + static Rom_root inst(env, sliced_heap); }