noux: Decouple Dir_file_system from file systems

By introducing the new 'File_system_registry', we can remove the
knowledge about the actual file-system implementations from the
'Dir_file_system'. Thereby the code becomes more generic, which is
a precondition for using it as the basis for Genode's VFS library.

Issue #999
This commit is contained in:
Norman Feske 2014-04-07 12:34:41 +02:00
parent 28a5404281
commit 3bb7d4e67b
13 changed files with 124 additions and 90 deletions

View File

@ -271,7 +271,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "block"; }
static char const *name() { return "block"; }
/********************************

View File

@ -16,6 +16,7 @@
/* Genode includes */
#include <base/rpc_server.h>
#include <dataspace/client.h>
namespace Noux {

View File

@ -20,14 +20,8 @@
/* Noux includes */
#include <noux_session/sysio.h>
#include <tar_file_system.h>
#include <fs_file_system.h>
#include <terminal_file_system.h>
#include <null_file_system.h>
#include <zero_file_system.h>
#include <stdio_file_system.h>
#include <random_file_system.h>
#include <block_file_system.h>
#include <file_system_registry.h>
#include <vfs_handle.h>
namespace Noux {
@ -69,7 +63,9 @@ namespace Noux {
public:
Dir_file_system(Xml_node node) : _first_file_system(0)
Dir_file_system(Xml_node node, File_system_registry &fs_registry)
:
_first_file_system(0)
{
/* remember directory name */
if (node.has_type("fstab"))
@ -81,59 +77,22 @@ namespace Noux {
Xml_node sub_node = node.sub_node(i);
if (sub_node.has_type("tar")) {
_append_file_system(new Tar_file_system(sub_node));
continue;
}
if (sub_node.has_type("fs")) {
_append_file_system(new Fs_file_system(sub_node));
continue;
}
/* traverse into <dir> nodes */
if (sub_node.has_type("dir")) {
_append_file_system(new Dir_file_system(sub_node));
_append_file_system(new Dir_file_system(sub_node,
fs_registry));
continue;
}
if (sub_node.has_type("terminal")) {
_append_file_system(new Terminal_file_system(sub_node));
File_system_registry::Entry *fs = fs_registry.lookup(sub_node);
if (fs) {
_append_file_system(fs->create(sub_node));
continue;
}
if (sub_node.has_type("null")) {
_append_file_system(new Null_file_system());
continue;
}
if (sub_node.has_type("zero")) {
_append_file_system(new Zero_file_system());
continue;
}
if (sub_node.has_type("stdio")) {
_append_file_system(new Stdio_file_system(sub_node));
continue;
}
if (sub_node.has_type("random")) {
_append_file_system(new Random_file_system(0, 0));
continue;
}
if (sub_node.has_type("block")) {
_append_file_system(new Block_file_system(sub_node));
continue;
}
{
char type_name[64];
sub_node.type_name(type_name, sizeof(type_name));
PWRN("unknown fstab node type <%s>", type_name);
}
char type_name[64];
sub_node.type_name(type_name, sizeof(type_name));
PWRN("unknown fstab node type <%s>", type_name);
}
}
@ -660,26 +619,11 @@ namespace Noux {
/**
* Synchronize all file systems
*
* Only file system using the File_system_session interface are
* synchronized.
*/
void sync()
{
for (File_system *fs = _first_file_system; fs; fs = fs->next) {
Fs_file_system *fs_fs = dynamic_cast<Fs_file_system *>(fs);
if (fs_fs) {
fs_fs->sync();
continue;
}
/* the directory might contain Fs_file_systems */
Dir_file_system *dir_fs = dynamic_cast<Dir_file_system *>(fs);
if (dir_fs) {
dir_fs->sync();
continue;
}
}
for (File_system *fs = _first_file_system; fs; fs = fs->next)
fs->sync();
}

View File

@ -36,13 +36,6 @@ namespace Noux {
File_system() : next(0) { }
/**
* Return name of file system
*
* This function is used for debugging only.
*/
virtual char const *name() const = 0;
/**
* Synchronize file system
*

View File

@ -0,0 +1,55 @@
/*
* \brief Registry of file systems
* \author Norman Feske
* \date 2014-04-07
*/
/*
* Copyright (C) 2014 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.
*/
#ifndef _NOUX__FILE_SYSTEM_REGISTRY_H_
#define _NOUX__FILE_SYSTEM_REGISTRY_H_
/* Noux includes */
#include <file_system.h>
namespace Noux {
class File_system_registry
{
public:
struct Entry : List<Entry>::Element
{
virtual File_system *create(Xml_node node) = 0;
virtual bool matches(Xml_node node) = 0;
};
private:
List<Entry> _list;
public:
void insert(Entry &entry)
{
_list.insert(&entry);
}
Entry *lookup(Xml_node node)
{
for (Entry *e = _list.first(); e; e = e->next())
if (e->matches(node))
return e;
return 0;
}
};
}
#endif /* _NOUX__FILE_SYSTEM_REGISTRY_H_ */

View File

@ -574,7 +574,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "fs"; }
static char const *name() { return "fs"; }
void sync()
{

View File

@ -30,6 +30,17 @@
#include <io_receptor_registry.h>
#include <destruct_queue.h>
#include <kill_broadcaster.h>
#include <file_system_registry.h>
/* supported file systems */
#include <tar_file_system.h>
#include <fs_file_system.h>
#include <terminal_file_system.h>
#include <null_file_system.h>
#include <zero_file_system.h>
#include <stdio_file_system.h>
#include <random_file_system.h>
#include <block_file_system.h>
static const bool verbose_quota = false;
@ -993,6 +1004,23 @@ void *operator new (Genode::size_t size) {
return Genode::env()->heap()->alloc(size); }
template <typename FILE_SYSTEM>
struct File_system_factory : Noux::File_system_registry::Entry
{
Noux::File_system *create(Genode::Xml_node node) override
{
return new FILE_SYSTEM(node);
}
bool matches(Genode::Xml_node node) override
{
char buf[100];
node.type_name(buf, sizeof(buf));
return node.has_type(FILE_SYSTEM::name());
}
};
int main(int argc, char **argv)
{
using namespace Noux;
@ -1017,9 +1045,20 @@ int main(int argc, char **argv)
verbose = config()->xml_node().attribute("verbose").has_value("yes");
} catch (Xml_node::Nonexistent_attribute) { }
/* register file systems */
static File_system_registry fs_registry;
fs_registry.insert(*new File_system_factory<Tar_file_system>());
fs_registry.insert(*new File_system_factory<Fs_file_system>());
fs_registry.insert(*new File_system_factory<Terminal_file_system>());
fs_registry.insert(*new File_system_factory<Null_file_system>());
fs_registry.insert(*new File_system_factory<Zero_file_system>());
fs_registry.insert(*new File_system_factory<Stdio_file_system>());
fs_registry.insert(*new File_system_factory<Random_file_system>());
fs_registry.insert(*new File_system_factory<Block_file_system>());
/* initialize virtual file system */
static Dir_file_system
root_dir(config()->xml_node().sub_node("fstab"));
root_dir(config()->xml_node().sub_node("fstab"), fs_registry);
/* set user information */
try {

View File

@ -44,7 +44,7 @@ namespace Noux {
public:
Null_file_system() { }
Null_file_system(Xml_node) { }
/*********************************
@ -162,7 +162,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "null"; }
static char const *name() { return "null"; }
/********************************

View File

@ -250,8 +250,10 @@ namespace Noux {
public:
Random_file_system(void *bytes, size_t nbytes)
Random_file_system(Xml_node node)
{
void *bytes = 0;
size_t nbytes = 0;
_arc4random = new (env()->heap()) Arc4random(bytes, nbytes);
}
@ -376,7 +378,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "random"; }
static char const *name() { return "random"; }
/********************************

View File

@ -179,7 +179,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "stdio"; }
static char const *name() { return "stdio"; }
/********************************

View File

@ -606,7 +606,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "tar"; }
static char const *name() { return "tar"; }
/********************************

View File

@ -190,7 +190,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "terminal"; }
static char const *name() { return "terminal"; }
/********************************

View File

@ -44,7 +44,7 @@ namespace Noux {
public:
Zero_file_system() { }
Zero_file_system(Xml_node) { }
/*********************************
@ -162,7 +162,7 @@ namespace Noux {
** File_system interface **
***************************/
char const *name() const { return "zero"; }
static char const *name() { return "zero"; }
/********************************