diff --git a/repos/libports/src/lib/libc/task.cc b/repos/libports/src/lib/libc/task.cc
index 7fefd8a659..5065f05f6f 100644
--- a/repos/libports/src/lib/libc/task.cc
+++ b/repos/libports/src/lib/libc/task.cc
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -75,7 +76,8 @@ class Libc::Env_implementation : public Libc::Env
return Genode::Xml_node("");
}
- Vfs::Dir_file_system _vfs;
+ Vfs::Global_file_system_factory _file_system_factory;
+ Vfs::Dir_file_system _vfs;
Genode::Xml_node _config_xml() const override {
return _config.xml(); };
@@ -85,9 +87,9 @@ class Libc::Env_implementation : public Libc::Env
Env_implementation(Genode::Env &env, Genode::Allocator &alloc,
Vfs::Io_response_handler &io_response_handler)
:
- _env(env),
+ _env(env), _file_system_factory(alloc),
_vfs(_env, alloc, _vfs_config(), io_response_handler,
- Vfs::global_file_system_factory())
+ _file_system_factory)
{ }
diff --git a/repos/os/include/vfs/file_system_factory.h b/repos/os/include/vfs/file_system_factory.h
index c8f5b28f2f..e801ddde70 100644
--- a/repos/os/include/vfs/file_system_factory.h
+++ b/repos/os/include/vfs/file_system_factory.h
@@ -20,11 +20,6 @@ namespace Vfs {
struct File_system_factory;
struct Global_file_system_factory;
-
- /**
- * Return singleton instance of a file-system factory
- */
- Global_file_system_factory &global_file_system_factory();
}
@@ -36,6 +31,7 @@ struct Vfs::File_system_factory
* \param env Env for service connections
* \param alloc internal file-system allocator
* \param config file-system configuration
+ * \param io_handler callback handler
*/
virtual File_system *create(Genode::Env &env,
Genode::Allocator &alloc,
@@ -44,16 +40,97 @@ struct Vfs::File_system_factory
};
-struct Vfs::Global_file_system_factory : File_system_factory
+class Vfs::Global_file_system_factory : public Vfs::File_system_factory
{
- /**
- * Register an additional factory for new file-system type
- *
- * \name name of file-system type
- * \factory factory to create instances of this file-system type
- */
- virtual void extend(char const *name, File_system_factory &factory) = 0;
+ private:
+
+ Genode::Allocator &_md_alloc;
+
+ public:
+
+ typedef Genode::String<128> Fs_type_name;
+ typedef Genode::String<128> Node_name;
+ typedef Genode::String<128> Library_name;
+
+ struct Entry_base;
+
+ private:
+
+ Genode::List _list;
+
+ /**
+ * Add builtin File_system type
+ */
+ template
+ void _add_builtin_fs();
+
+ Vfs::File_system *_try_create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Io_response_handler &io_handler);
+
+ /**
+ * Return name of factory provided by the shared library
+ */
+ static char const *_factory_symbol()
+ {
+ return "vfs_file_system_factory";
+ }
+
+ /**
+ * Return name of VFS node
+ */
+ Node_name _node_name(Genode::Xml_node node);
+
+ /**
+ * Return matching library name for a given vfs node name
+ */
+ Library_name _library_name(Node_name const &node_name);
+
+ class Factory_not_available { };
+
+ /**
+ * \throw Factory_not_available
+ */
+ Vfs::File_system_factory &_load_factory(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Library_name const &lib_name);
+
+ /**
+ * Try to load external File_system_factory provider
+ */
+ bool _probe_external_factory(Genode::Env &env, Genode::Allocator &alloc,
+ Genode::Xml_node node);
+
+ public:
+
+ /**
+ * Constructor
+ *
+ * \param alloc internal factory allocator
+ */
+ Global_file_system_factory(Genode::Allocator &md_alloc);
+
+ /**
+ * Create and return a new file-system
+ *
+ * \param env Env for service connections
+ * \param alloc internal file-system allocator
+ * \param config file-system configuration
+ * \param io_handler callback handler
+ */
+ Vfs::File_system *create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Io_response_handler &io_handler) override;
+
+ /**
+ * Register an additional factory for new file-system type
+ *
+ * \name name of file-system type
+ * \factory factory to create instances of this file-system type
+ */
+ void extend(char const *name, File_system_factory &factory);
};
-
#endif /* _INCLUDE__VFS__FILE_SYSTEM_FACTORY_H_ */
diff --git a/repos/os/lib/mk/vfs.mk b/repos/os/lib/mk/vfs.mk
index 75702f9201..435e11ca5e 100644
--- a/repos/os/lib/mk/vfs.mk
+++ b/repos/os/lib/mk/vfs.mk
@@ -1,4 +1,5 @@
-SRC_CC += file_system_factory.cc
+SRC_CC += file_system_factory.cc
+INC_DIR += $(REP_DIR)/src/lib/vfs
LIBS = ld
diff --git a/repos/os/src/app/cli_monitor/main.cc b/repos/os/src/app/cli_monitor/main.cc
index 6bd2375f80..60d208a913 100644
--- a/repos/os/src/app/cli_monitor/main.cc
+++ b/repos/os/src/app/cli_monitor/main.cc
@@ -154,9 +154,11 @@ struct Cli_monitor::Main
void handle_io_response(Vfs::Vfs_handle::Context *) override { }
} io_response_handler;
+ Vfs::Global_file_system_factory _global_file_system_factory { _heap };
+
/* initialize virtual file system */
Vfs::Dir_file_system _root_dir { _env, _heap, _vfs_config(), io_response_handler,
- Vfs::global_file_system_factory() };
+ _global_file_system_factory };
Subsystem_config_registry _subsystem_config_registry { _root_dir, _heap };
diff --git a/repos/os/src/lib/vfs/file_system_factory.cc b/repos/os/src/lib/vfs/file_system_factory.cc
index 58a1f5712a..ce1369207e 100644
--- a/repos/os/src/lib/vfs/file_system_factory.cc
+++ b/repos/os/src/lib/vfs/file_system_factory.cc
@@ -11,234 +11,246 @@
* under the terms of the GNU General Public License version 2.
*/
+
/* Genode includes */
#include
#include
/* supported builtin file systems */
-#include "block_file_system.h"
-#include "fs_file_system.h"
-#include "inline_file_system.h"
-#include "log_file_system.h"
-#include "null_file_system.h"
-#include "ram_file_system.h"
-#include "rom_file_system.h"
-#include "rtc_file_system.h"
-#include "symlink_file_system.h"
-#include "tar_file_system.h"
-#include "terminal_file_system.h"
-#include "zero_file_system.h"
-
-
-using Vfs::Io_response_handler;
-
-
-class Default_file_system_factory : public Vfs::Global_file_system_factory
-{
- private:
-
- typedef Genode::String<128> Fs_type_name;
- typedef Genode::String<128> Node_name;
- typedef Genode::String<128> Library_name;
-
- struct Entry_base : Vfs::File_system_factory,
- Genode::List::Element
- {
- Fs_type_name name;
-
- Entry_base(Fs_type_name const &name) : name(name) { }
-
- bool matches(Genode::Xml_node node) const {
- return node.has_type(name.string()); }
- };
-
-
- template
- struct Builtin_entry : Entry_base
- {
- Builtin_entry() : Entry_base(FILE_SYSTEM::name()) { }
-
- Vfs::File_system *create(Genode::Env &env,
- Genode::Allocator &alloc,
- Genode::Xml_node node,
- Io_response_handler &io_handler) override
- {
- return new (alloc) FILE_SYSTEM(env, alloc, node, io_handler);
- }
- };
-
- struct External_entry : Entry_base
- {
- File_system_factory &_fs_factory;
-
- External_entry(Fs_type_name const &name,
- Vfs::File_system_factory &fs_factory)
- :
- Entry_base(name), _fs_factory(fs_factory) { }
-
- Vfs::File_system *create(Genode::Env &env,
- Genode::Allocator &alloc,
- Genode::Xml_node node,
- Io_response_handler &io_handler) override {
- return _fs_factory.create(env, alloc, node, io_handler); }
- };
-
- Genode::List _list;
-
- template
- void _add_builtin_fs()
- {
- _list.insert(new (Genode::env()->heap()) Builtin_entry());
- }
-
- Vfs::File_system *_try_create(Genode::Env &env,
- Genode::Allocator &alloc,
- Genode::Xml_node node,
- Io_response_handler &io_handler)
- {
- for (Entry_base *e = _list.first(); e; e = e->next())
- if (e->matches(node))
- return e->create(env, alloc, node, io_handler);
-
- return 0;
- }
-
- /**
- * Return name of factory provided by the shared library
- */
- static char const *_factory_symbol()
- {
- return "vfs_file_system_factory";
- }
-
- /**
- * Return name of VFS node
- */
- Node_name _node_name(Genode::Xml_node node)
- {
- char node_name [Node_name::capacity()];
- node.type_name(node_name, sizeof(node_name));
- return Node_name(node_name);
- }
-
- /**
- * Return matching library name for a given vfs node name
- */
- Library_name _library_name(Node_name const &node_name)
- {
- char lib_name [Library_name::capacity()];
- Genode::snprintf(lib_name, sizeof(lib_name), "vfs_%s.lib.so",
- node_name.string());
-
- return Library_name(lib_name);
- }
-
- class Factory_not_available { };
-
- /**
- * \throw Factory_not_available
- */
- Vfs::File_system_factory &_load_factory(Genode::Env &env,
- Genode::Allocator &alloc,
- Library_name const &lib_name)
- {
- Genode::Shared_object *shared_object = nullptr;
-
- try {
- shared_object = new (alloc)
- Genode::Shared_object(env, alloc, lib_name.string(),
- Genode::Shared_object::BIND_LAZY,
- Genode::Shared_object::DONT_KEEP);
-
- typedef Vfs::File_system_factory *(*Query_fn)();
-
- Query_fn query_fn = shared_object->lookup(_factory_symbol());
-
- return *query_fn();
-
- } catch (Genode::Shared_object::Invalid_rom_module) {
- Genode::warning("could not open '", lib_name, "'");
- throw Factory_not_available();
-
- } catch (Genode::Shared_object::Invalid_symbol) {
- Genode::warning("could not find symbol '",
- Genode::Cstring(_factory_symbol()),
- "' in '", lib_name, "'");
-
- Genode::destroy(alloc, shared_object);
- throw Factory_not_available();
- }
- }
-
- bool _probe_external_factory(Genode::Env &env, Genode::Allocator &alloc,
- Genode::Xml_node node)
- {
- Library_name const lib_name = _library_name(_node_name(node));
-
- try {
- _list.insert(new (alloc)
- External_entry(_node_name(node).string(),
- _load_factory(env, alloc, lib_name)));
- return true;
-
- } catch (Factory_not_available) { return false; }
- }
-
- public:
-
- Vfs::File_system *create(Genode::Env &env,
- Genode::Allocator &alloc,
- Genode::Xml_node node,
- Io_response_handler &io_handler) override
- {
- try {
- /* try if type is handled by the currently registered fs types */
- if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
- return fs;
- /* if the builtin fails, do not try loading an external */
- } catch (...) { return 0; }
-
- try {
- /* probe for file system implementation available as shared lib */
- if (_probe_external_factory(env, alloc, node)) {
- /* try again with the new file system type loaded */
- if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
- return fs;
- }
- } catch (...) { }
-
- return 0;
- }
-
- void extend(char const *name, File_system_factory &factory) override
- {
- _list.insert(new (Genode::env()->heap())
- External_entry(name, factory));
- }
-
- Default_file_system_factory()
- {
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- _add_builtin_fs();
- }
-};
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
namespace Vfs {
- Global_file_system_factory &global_file_system_factory()
+ using Vfs::Io_response_handler;
+
+ template struct Builtin_entry;
+ struct External_entry;
+}
+
+
+using Fs_type_name = Vfs::Global_file_system_factory::Fs_type_name;
+using Node_name = Vfs::Global_file_system_factory::Node_name;
+using Library_name = Vfs::Global_file_system_factory::Library_name;
+
+
+struct Vfs::Global_file_system_factory::Entry_base : Vfs::File_system_factory,
+ Genode::List::Element
+{
+ Fs_type_name name;
+
+ Entry_base(Fs_type_name const &name) : name(name) { }
+
+ bool matches(Genode::Xml_node node) const {
+ return node.has_type(name.string()); }
+};
+
+
+template
+struct Vfs::Builtin_entry : Vfs::Global_file_system_factory::Entry_base
+{
+ Builtin_entry() : Entry_base(FILE_SYSTEM::name()) { }
+
+ Vfs::File_system *create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Vfs::Io_response_handler &io_handler) override
{
- static Default_file_system_factory inst;
- return inst;
+ return new (alloc) FILE_SYSTEM(env, alloc, node, io_handler);
+ }
+};
+
+
+struct Vfs::External_entry : Vfs::Global_file_system_factory::Entry_base
+{
+ File_system_factory &_fs_factory;
+
+ External_entry(Fs_type_name const &name,
+ Vfs::File_system_factory &fs_factory)
+ :
+ Entry_base(name), _fs_factory(fs_factory) { }
+
+ Vfs::File_system *create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Vfs::Io_response_handler &io_handler) override {
+ return _fs_factory.create(env, alloc, node, io_handler); }
+};
+
+
+/**
+ * Add builtin File_system type
+ */
+template
+void Vfs::Global_file_system_factory::_add_builtin_fs()
+{
+ _list.insert(new (&_md_alloc) Builtin_entry());
+}
+
+
+/**
+ * Lookup and create File_system instance
+ */
+Vfs::File_system *Vfs::Global_file_system_factory::_try_create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Io_response_handler &io_handler)
+{
+ for (Entry_base *e = _list.first(); e; e = e->next()) {
+ if (e->matches(node)) {
+ return e->create(env, alloc, node, io_handler);
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * Return name of VFS node
+ */
+Node_name Vfs::Global_file_system_factory::_node_name(Genode::Xml_node node)
+{
+ char node_name [Node_name::capacity()];
+ node.type_name(node_name, sizeof(node_name));
+ return Node_name(node_name);
+}
+
+
+/**
+ * Return matching library name for a given vfs node name
+ */
+Library_name Vfs::Global_file_system_factory::_library_name(Node_name const &node_name)
+{
+ char lib_name [Library_name::capacity()];
+ Genode::snprintf(lib_name, sizeof(lib_name), "vfs_%s.lib.so",
+ node_name.string());
+
+ return Library_name(lib_name);
+}
+
+
+/**
+ * \throw Factory_not_available
+ */
+Vfs::File_system_factory &Vfs::Global_file_system_factory::_load_factory(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Library_name const &lib_name)
+{
+ Genode::Shared_object *shared_object = nullptr;
+
+ try {
+ shared_object = new (alloc)
+ Genode::Shared_object(env, alloc, lib_name.string(),
+ Genode::Shared_object::BIND_LAZY,
+ Genode::Shared_object::DONT_KEEP);
+
+ typedef Vfs::File_system_factory *(*Query_fn)();
+
+ Query_fn query_fn = shared_object->lookup(_factory_symbol());
+
+ return *query_fn();
+
+ } catch (Genode::Shared_object::Invalid_rom_module) {
+ Genode::warning("could not open '", lib_name, "'");
+ throw Factory_not_available();
+
+ } catch (Genode::Shared_object::Invalid_symbol) {
+ Genode::warning("could not find symbol '",
+ Genode::Cstring(_factory_symbol()),
+ "' in '", lib_name, "'");
+
+ Genode::destroy(alloc, shared_object);
+ throw Factory_not_available();
}
}
+
+
+/**
+ * Try to load external File_system_factory provider
+ */
+bool Vfs::Global_file_system_factory::_probe_external_factory(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node)
+{
+ Library_name const lib_name = _library_name(_node_name(node));
+
+ try {
+ _list.insert(new (alloc)
+ External_entry(_node_name(node).string(),
+ _load_factory(env, alloc, lib_name)));
+ return true;
+
+ } catch (Factory_not_available) { return false; }
+}
+
+
+/**
+ * Create and return a new file-system
+ */
+Vfs::File_system *Vfs::Global_file_system_factory::create(Genode::Env &env,
+ Genode::Allocator &alloc,
+ Genode::Xml_node node,
+ Io_response_handler &io_handler)
+{
+ try {
+ /* try if type is handled by the currently registered fs types */
+ if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
+ return fs;
+ /* if the builtin fails, do not try loading an external */
+ } catch (...) { return 0; }
+
+ try {
+ /* probe for file system implementation available as shared lib */
+ if (_probe_external_factory(env, alloc, node)) {
+ /* try again with the new file system type loaded */
+ if (Vfs::File_system *fs = _try_create(env, alloc, node, io_handler))
+ return fs;
+ }
+ } catch (...) { }
+
+ return 0;
+}
+
+
+/**
+ * Register an additional factory for new file-system type
+ */
+void Vfs::Global_file_system_factory::extend(char const *name, File_system_factory &factory)
+{
+ _list.insert(new (&_md_alloc)
+ External_entry(name, factory));
+}
+
+
+/**
+ * Constructor
+ */
+Vfs::Global_file_system_factory::Global_file_system_factory(Genode::Allocator &alloc)
+:
+ _md_alloc(alloc)
+{
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+ _add_builtin_fs();
+}
diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc
index b5a1413749..eb38941525 100644
--- a/repos/os/src/server/vfs/main.cc
+++ b/repos/os/src/server/vfs/main.cc
@@ -625,9 +625,11 @@ class Vfs_server::Root :
Io_response_handler _io_response_handler { _session_registry };
+ Vfs::Global_file_system_factory _global_file_system_factory { _heap };
+
Vfs::Dir_file_system _vfs {
_env, _heap, vfs_config(), _io_response_handler,
- Vfs::global_file_system_factory() };
+ _global_file_system_factory };
Genode::Signal_handler _config_dispatcher {
_env.ep(), *this, &Root::_config_update };
diff --git a/repos/os/src/test/vfs_stress/main.cc b/repos/os/src/test/vfs_stress/main.cc
index adc5e821ca..1b2ad4933c 100644
--- a/repos/os/src/test/vfs_stress/main.cc
+++ b/repos/os/src/test/vfs_stress/main.cc
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2015 Genode Labs GmbH
+ * Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@@ -480,9 +480,11 @@ void Component::construct(Genode::Env &env)
}
} io_response_handler;
+ Vfs::Global_file_system_factory global_file_system_factory(heap);
+
Vfs::Dir_file_system vfs_root(env, heap, config_xml.sub_node("vfs"),
io_response_handler,
- Vfs::global_file_system_factory());
+ global_file_system_factory);
char path[Vfs::MAX_PATH_LEN];
MAX_DEPTH = config_xml.attribute_value("depth", 16U);
diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc
index 1aa6f317ac..1f8fe49938 100644
--- a/repos/ports/src/noux/main.cc
+++ b/repos/ports/src/noux/main.cc
@@ -210,7 +210,7 @@ struct Noux::Main
}
/* initialize virtual file system */
- Vfs::Global_file_system_factory &_fs_factory = Vfs::global_file_system_factory();
+ Vfs::Global_file_system_factory _global_file_system_factory { _heap };
struct Io_response_handler : Vfs::Io_response_handler
{
@@ -219,7 +219,7 @@ struct Noux::Main
Vfs::Dir_file_system _root_dir { _env, _heap, _config.xml().sub_node("fstab"),
_io_response_handler,
- _fs_factory };
+ _global_file_system_factory };
Pid_allocator _pid_allocator;