diff --git a/repos/os/src/server/trace_fs/README b/repos/os/src/server/trace_fs/README
deleted file mode 100644
index f5dcd307af..0000000000
--- a/repos/os/src/server/trace_fs/README
+++ /dev/null
@@ -1,61 +0,0 @@
-The new _trace_fs_ server provides access to a trace session by providing a
-file-system session as front end. Combined with Noux, it allows for the
-interactive exploration and tracing of Genode's process tree using
-traditional Unix tools.
-
-Each trace subject is represented by a directory ('thread_name.subject') that
-contains specific files, which are used to control the tracing process of the
-thread as well as storing the content of its trace buffer:
-
-:'enable': The tracing of a thread is activated if there is a valid policy
- installed and the intend to trace the subject was made clear by writing '1'
- to the 'enable' file. The tracing of a thread may be deactivated by writing a
- '0' to this file.
-
-:'policy': A policy may be changed by overwriting the currently used one in the
- 'policy' file. In this case, the old policy is replaced by the new one and
- automatically used by the framework.
-
-:'buffer_size': Writing a value to the 'buffer_size' file changes the size of
- the trace buffer. This value is evaluated only when reactivating the tracing
- of the thread.
-
-:'events': The trace-buffer contents may be accessed by reading from the
- 'events' file. New trace events are appended to this file.
-
-:'active': Reading the file will return whether the tracing is active (1) or
- not (0).
-
-:'cleanup': Nodes of untraced subjects are kept as long as they do not change
- their tracing state to dead. Dead untraced nodes are automatically removed
- from the file system. Subjects that were traced before and are now untraced
- can be removed by writing '1' to the 'cleanup' file.
-
-To use the trace_fs, a configuration similar to the following may be used:
-
-!
-!
-!
-!
-!
-!
-!
-
-:'interval': sets the period the Trace_session is polled. The
- time is given in milliseconds.
-
-:'subject_limit': specifies how many trace subjects should by acquired at
- max when the Trace_session is polled.
-
-:'trace_quota': is the amount of quota the trace_fs should use for the
- Trace_session connection. The remaining amount of RAM quota will be used
- for the actual nodes of the file system and the 'policy' as well as the
- 'events' files.
-
-In addition, there are 'buffer_size' and 'buffer_size_limit' that define
-the initial and the upper limit of the size of a trace buffer.
-
-A ready-to-use run script can by found in 'ports/run/noux_trace_fs.run'.
diff --git a/repos/os/src/server/trace_fs/buffer.h b/repos/os/src/server/trace_fs/buffer.h
deleted file mode 100644
index 595df39e64..0000000000
--- a/repos/os/src/server/trace_fs/buffer.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * \brief Buffer class
- * \author Josef Soentgen
- * \date 2014-01-15
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _BUFFER_H_
-#define _BUFFER_H_
-
-/* Genode includes */
-#include
-
-namespace Util {
-
- typedef Genode::size_t size_t;
-
-
- /**
- * Buffer merely wrapps a simple char array
- */
- template
- class Buffer
- {
- public:
-
- class Out_of_range { };
-
- private:
-
- char _buf[CAPACITY];
- size_t _length;
-
- public:
-
- static size_t capacity() { return CAPACITY; }
-
- Buffer() : _length(0) { }
-
- Buffer(char const *s)
- :
- _length(Genode::min(Genode::strlen(s) + 1, CAPACITY))
- {
- Genode::strncpy(_buf, s, _length);
- }
-
- char const *data() const { return (_buf[_length -1 ] == '\0') ? _buf : ""; }
-
- char *data() { return _buf; }
-
- size_t length() const { return _length; }
-
- char & operator[](size_t i)
- {
- if (i >= CAPACITY)
- throw Out_of_range();
-
- return _buf[i];
- }
-
- void replace(char p, char c)
- {
- char *s = _buf;
- for (; *s; s++) {
- if (*s == p)
- *s = c;
- }
- }
- };
-
- /**
- * This class walks along a label and returns the next element on request
- */
- class Label_walker
- {
- private:
-
- Buffer<64> _buffer;
- char const *_label;
-
- char const *_next()
- {
- size_t i = 0;
-
- for (; *_label && (i < _buffer.capacity()); _label++, i++) {
- /* check seperator */
- if ((*_label == ' ') &&
- (*(_label + 1) == '-') &&
- (*(_label + 2) == '>') &&
- (*(_label + 3) == ' '))
- break;
- _buffer[i] = *_label;
- }
-
- _buffer[i] = '\0';
-
- /* sanatize the element */
- _buffer.replace('/', '_');
-
- /* omit seperator */
- if (*_label)
- _label += 4;
-
- return _label;
- }
-
-
- public:
-
- Label_walker(char const *label) : _label(label) { }
-
- /**
- * Walk to the next element of the label
- *
- * \return pointer to the remaing part of the label
- */
- char const *next() { return _next(); }
-
- /**
- * Get current element of the label
- *
- * \return pointer to current element
- */
- char const *element() { return _buffer.data(); }
- };
-}
-
-#endif /* _BUFFER_H_ */
diff --git a/repos/os/src/server/trace_fs/chunk.h b/repos/os/src/server/trace_fs/chunk.h
deleted file mode 100644
index 79fcfaa55c..0000000000
--- a/repos/os/src/server/trace_fs/chunk.h
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * \brief Data structure for storing sparse files in RAM
- * \author Norman Feske
- * \date 2012-04-18
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _CHUNK_H_
-#define _CHUNK_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-
-namespace File_system {
-
- using namespace Genode;
-
-
- /**
- * Common base class of both 'Chunk' and 'Chunk_index'
- */
- class Chunk_base : Noncopyable
- {
- public:
-
- class Index_out_of_range { };
-
- protected:
-
- seek_off_t const _base_offset;
- size_t _num_entries; /* corresponds to last used entry */
-
- /**
- * Test if specified range lies within the chunk
- */
- void assert_valid_range(seek_off_t start, size_t len,
- file_size_t chunk_size) const
- {
- if (zero()) return;
-
- if (start < _base_offset)
- throw Index_out_of_range();
-
- if (start + len > _base_offset + chunk_size)
- throw Index_out_of_range();
- }
-
- Chunk_base(seek_off_t base_offset)
- : _base_offset(base_offset), _num_entries(0) { }
-
- /**
- * Construct zero chunk
- *
- * A zero chunk is a chunk that cannot be written to. When reading
- * from it, it returns zeros. Because there is a single zero chunk
- * for each chunk type, the base offset is meaningless. We use a
- * base offset of ~0 as marker to identify zero chunks.
- */
- Chunk_base() : _base_offset(~0L), _num_entries(0) { }
-
- public:
-
- /**
- * Return absolute base offset of chunk in bytes
- */
- seek_off_t base_offset() const { return _base_offset; }
-
- /**
- * Return true if chunk is a read-only zero chunk
- */
- bool zero() const { return _base_offset == (seek_off_t)(~0L); }
-
- /**
- * Return true if chunk has no allocated sub chunks
- */
- bool empty() const { return _num_entries == 0; }
- };
-
-
- /**
- * Chunk of bytes used as leaf in hierarchy of chunk indices
- */
- template
- class Chunk : public Chunk_base
- {
- private:
-
- char _data[CHUNK_SIZE];
-
- public:
-
- enum { SIZE = CHUNK_SIZE };
-
- /**
- * Construct byte chunk
- *
- * \param base_offset absolute offset of chunk in bytes
- *
- * The first argument is unused. Its mere purpose is to make the
- * signature of the constructor compatible to the constructor
- * of 'Chunk_index'.
- */
- Chunk(Allocator &, seek_off_t base_offset)
- :
- Chunk_base(base_offset)
- {
- memset(_data, 0, CHUNK_SIZE);
- }
-
- /**
- * Construct zero chunk
- */
- Chunk() { }
-
- /**
- * Return number of used entries
- *
- * The returned value corresponds to the index of the last used
- * entry + 1. It does not correlate to the number of actually
- * allocated entries (there may be ranges of zero blocks).
- */
- file_size_t used_size() const { return _num_entries; }
-
- void write(char const *src, size_t len, seek_off_t seek_offset)
- {
- assert_valid_range(seek_offset, len, SIZE);
-
- /* offset relative to this chunk */
- seek_off_t const local_offset = seek_offset - base_offset();
-
- memcpy(&_data[local_offset], src, len);
-
- _num_entries = max(_num_entries, local_offset + len);
- }
-
- void read(char *dst, size_t len, seek_off_t seek_offset) const
- {
- assert_valid_range(seek_offset, len, SIZE);
-
- memcpy(dst, &_data[seek_offset - base_offset()], len);
- }
-
- void truncate(file_size_t size)
- {
- assert_valid_range(size, 0, SIZE);
-
- /*
- * Offset of the first free position (relative to the beginning
- * this chunk).
- */
- seek_off_t const local_offset = size - base_offset();
-
- if (local_offset >= _num_entries)
- return;
-
- memset(&_data[local_offset], 0, _num_entries - local_offset);
-
- _num_entries = local_offset;
- }
- };
-
-
- template
- class Chunk_index : public Chunk_base
- {
- public:
-
- typedef ENTRY_TYPE Entry;
-
- enum { ENTRY_SIZE = ENTRY_TYPE::SIZE,
- SIZE = ENTRY_SIZE*NUM_ENTRIES };
-
- private:
-
- Allocator &_alloc;
-
- Entry * _entries[NUM_ENTRIES];
-
- /**
- * Return instance of a zero sub chunk
- */
- static Entry const &_zero_chunk()
- {
- static Entry zero_chunk;
- return zero_chunk;
- }
-
- /**
- * Return sub chunk at given index
- *
- * If there is no sub chunk at the specified index, this function
- * transparently allocates one. Hence, the returned sub chunk
- * is ready to be written to.
- */
- Entry &_entry_for_writing(unsigned index)
- {
- if (index >= NUM_ENTRIES)
- throw Index_out_of_range();
-
- if (_entries[index])
- return *_entries[index];
-
- seek_off_t entry_offset = base_offset() + index*ENTRY_SIZE;
-
- _entries[index] = new (&_alloc) Entry(_alloc, entry_offset);
-
- _num_entries = max(_num_entries, index + 1);
-
- return *_entries[index];
- }
-
- /**
- * Return sub chunk at given index (for reading only)
- *
- * This function transparently provides a zero sub chunk for any
- * index that is not populated by a real chunk.
- */
- Entry const &_entry_for_reading(unsigned index) const
- {
- if (index >= NUM_ENTRIES)
- throw Index_out_of_range();
-
- if (_entries[index])
- return *_entries[index];
-
- return _zero_chunk();
- }
-
- /**
- * Return index of entry located at specified byte offset
- *
- * The caller of this function must make sure that the offset
- * parameter is within the bounds of the chunk.
- */
- unsigned _index_by_offset(seek_off_t offset) const
- {
- return (offset - base_offset()) / ENTRY_SIZE;
- }
-
- /**
- * Apply operation 'func' to a range of entries
- */
- template
- static void _range_op(THIS &obj, DATA *data, size_t len,
- seek_off_t seek_offset, FUNC const &func)
- {
- /*
- * Depending on whether this function is called for reading
- * (const function) or writing (non-const function), the
- * operand type is const or non-const Entry. The correct type
- * is embedded as a trait in the 'FUNC' functor type.
- */
- typedef typename FUNC::Entry Const_qualified_entry;
-
- obj.assert_valid_range(seek_offset, len, SIZE);
-
- while (len > 0) {
-
- unsigned const index = obj._index_by_offset(seek_offset);
-
- Const_qualified_entry &entry = FUNC::lookup(obj, index);
-
- /*
- * Calculate byte offset relative to the chunk
- *
- * We cannot use 'entry.base_offset()' for this calculation
- * because in the const case, the lookup might return a
- * zero chunk, which has no defined base offset. Therefore,
- * we calculate the base offset via index*ENTRY_SIZE.
- */
- seek_off_t const local_seek_offset =
- seek_offset - obj.base_offset() - index*ENTRY_SIZE;
-
- /* available capacity at 'entry' starting at seek offset */
- seek_off_t const capacity = ENTRY_SIZE - local_seek_offset;
- seek_off_t const curr_len = min(len, capacity);
-
- /* apply functor (read or write) to entry */
- func(entry, data, curr_len, seek_offset);
-
- /* advance to next entry */
- len -= curr_len;
- data += curr_len;
- seek_offset += curr_len;
- }
- }
-
- struct Write_func
- {
- typedef ENTRY_TYPE Entry;
-
- static Entry &lookup(Chunk_index &chunk, unsigned i) {
- return chunk._entry_for_writing(i); }
-
- void operator () (Entry &entry, char const *src, size_t len,
- seek_off_t seek_offset) const
- {
- entry.write(src, len, seek_offset);
- }
- };
-
- struct Read_func
- {
- typedef ENTRY_TYPE const Entry;
-
- static Entry &lookup(Chunk_index const &chunk, unsigned i) {
- return chunk._entry_for_reading(i); }
-
- void operator () (Entry &entry, char *dst, size_t len,
- seek_off_t seek_offset) const
- {
- if (entry.zero())
- memset(dst, 0, len);
- else
- entry.read(dst, len, seek_offset);
- }
- };
-
- void _init_entries()
- {
- for (unsigned i = 0; i < NUM_ENTRIES; i++)
- _entries[i] = 0;
- }
-
- void _destroy_entry(unsigned i)
- {
- if (_entries[i] && (i < _num_entries)) {
- destroy(&_alloc, _entries[i]);
- _entries[i] = 0;
- }
- }
-
- public:
-
- /**
- * Constructor
- *
- * \param alloc allocator to use for allocating sub-chunk
- * indices and chunks
- * \param base_offset absolute offset of the chunk in bytes
- */
- Chunk_index(Allocator &alloc, seek_off_t base_offset)
- : Chunk_base(base_offset), _alloc(alloc) { _init_entries(); }
-
- /**
- * Construct zero chunk
- */
- Chunk_index() : _alloc(*(Allocator *)0) { }
-
- /**
- * Destructor
- */
- ~Chunk_index()
- {
- for (unsigned i = 0; i < NUM_ENTRIES; i++)
- _destroy_entry(i);
- }
-
- /**
- * Return size of chunk in bytes
- *
- * The returned value corresponds to the position after the highest
- * offset that was written to.
- */
- file_size_t used_size() const
- {
- if (_num_entries == 0)
- return 0;
-
- /* size of entries that lie completely within the used range */
- file_size_t const size_whole_entries = ENTRY_SIZE*(_num_entries - 1);
-
- Entry *last_entry = _entries[_num_entries - 1];
- if (!last_entry)
- return size_whole_entries;
-
- return size_whole_entries + last_entry->used_size();
- }
-
- /**
- * Write data to chunk
- */
- void write(char const *src, size_t len, seek_off_t seek_offset)
- {
- _range_op(*this, src, len, seek_offset, Write_func());
- }
-
- /**
- * Read data from chunk
- */
- void read(char *dst, size_t len, seek_off_t seek_offset) const
- {
- _range_op(*this, dst, len, seek_offset, Read_func());
- }
-
- /**
- * Truncate chunk to specified size in bytes
- *
- * This function can be used to shrink a chunk only. Specifying a
- * 'size' larger than 'used_size' has no effect. The value returned
- * by 'used_size' refers always to the position of the last byte
- * written to the chunk.
- */
- void truncate(file_size_t size)
- {
- unsigned const trunc_index = _index_by_offset(size);
-
- if (trunc_index >= _num_entries)
- return;
-
- for (unsigned i = trunc_index + 1; i < _num_entries; i++)
- _destroy_entry(i);
-
- /* traverse into sub chunks */
- if (_entries[trunc_index])
- _entries[trunc_index]->truncate(size);
-
- _num_entries = trunc_index + 1;
-
- /*
- * If the truncated at a chunk boundary, we can release the
- * empty trailing chunk at 'trunc_index'.
- */
- if (_entries[trunc_index] && _entries[trunc_index]->empty()) {
- _destroy_entry(trunc_index);
- _num_entries--;
- }
- }
- };
-};
-
-#endif /* _CHUNK_H_ */
diff --git a/repos/os/src/server/trace_fs/directory.h b/repos/os/src/server/trace_fs/directory.h
deleted file mode 100644
index dfcda613a5..0000000000
--- a/repos/os/src/server/trace_fs/directory.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * \brief File-system directory node
- * \author Norman Feske
- * \date 2012-04-11
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _DIRECTORY_H_
-#define _DIRECTORY_H_
-
-/* Genode includes */
-#include
-
-/* local includes */
-#include
-#include
-#include
-
-namespace Trace_fs {
- class Directory;
-}
-
-class Trace_fs::Directory : public Node
-{
- private:
-
- List _entries;
- size_t _num_entries;
-
- public:
-
- Directory(char const *name) : _num_entries(0) { Node::name(name); }
-
-
- /**
- * Check if the directory has the specified subnode
- *
- * \param name name of the searched subnode
- *
- * \return true if the subnode was found, either false
- */
- bool has_sub_node_unsynchronized(char const *name) const
- {
- Node const *sub_node = _entries.first();
- for (; sub_node; sub_node = sub_node->next())
- if (strcmp(sub_node->name(), name) == 0)
- return true;
-
- return false;
- }
-
-
- /**
- * Add node to the list of subnodes
- *
- * \param pointer to node
- */
- void adopt_unsynchronized(Node *node)
- {
- /*
- * XXX inc ref counter
- */
- _entries.insert(node);
- _num_entries++;
-
- mark_as_updated();
- }
-
- /**
- * Remove the node from the list of subnodes
- *
- * \param node pointer to node
- */
- void discard_unsynchronized(Node *node)
- {
- _entries.remove(node);
- _num_entries--;
-
- mark_as_updated();
- }
-
- /**
- * Lookup node which belongs to the specified path
- *
- * \param path path to lookup
- * \param return_parent if true return parent node, otherwise
- * actual path node
- *
- * \return node node founc
- * \throws Lookup_failed
- */
- Node *lookup(char const *path, bool return_parent = false) override
- {
- if (strcmp(path, "") == 0) {
- return this;
- }
-
- if (!path || path[0] == '/')
- throw Lookup_failed();
-
- /* find first path delimiter */
- unsigned i = 0;
- for (; path[i] && path[i] != '/'; i++);
-
- /*
- * If no path delimiter was found, we are the parent of the
- * specified path.
- */
- if (path[i] == 0 && return_parent) {
- return this;
- }
-
- /*
- * The offset 'i' corresponds to the end of the first path
- * element, which can be either the end of the string or the
- * first '/' character.
- */
-
- /* try to find entry that matches the first path element */
- Node *sub_node = _entries.first();
- for (; sub_node; sub_node = sub_node->next())
- if ((strlen(sub_node->name()) == i) &&
- (strcmp(sub_node->name(), path, i) == 0))
- break;
-
- if (!sub_node)
- throw Lookup_failed();
-
- if (!contains_path_delimiter(path)) {
-
- /*
- * Because 'path' is a basename that corresponds to an
- * existing sub_node, we have found what we were looking
- * for.
- */
- return sub_node;
- }
-
- /*
- * As 'path' contains one or more path delimiters, traverse
- * into the sub directory names after the first path element.
- */
-
- /*
- * We cannot traverse into anything other than a directory.
- *
- * XXX we might follow symlinks here
- */
- Directory *sub_dir = dynamic_cast(sub_node);
- if (!sub_dir)
- throw Lookup_failed();
-
- return sub_dir->lookup(path + i + 1, return_parent);
- }
-
- /**
- * Return number of subnodes
- */
- size_t num_entries() const { return _num_entries; }
-
-
- /********************
- ** Node interface **
- ********************/
-
- size_t read(char *dst, size_t len, seek_off_t seek_offset)
- {
- if (len < sizeof(Directory_entry)) {
- Genode::error("read buffer too small for directory entry");
- return 0;
- }
-
- seek_off_t index = seek_offset / sizeof(Directory_entry);
-
- if (seek_offset % sizeof(Directory_entry)) {
- Genode::error("seek offset not alighed to sizeof(Directory_entry)");
- return 0;
- }
-
- /* find list element */
- Node *node = _entries.first();
- for (unsigned i = 0; i < index && node; node = node->next(), i++);
-
- /* index out of range */
- if (!node)
- return 0;
-
- Directory_entry *e = (Directory_entry *)(dst);
-
- if (dynamic_cast(node)) e->type = Directory_entry::TYPE_FILE;
- if (dynamic_cast(node)) e->type = Directory_entry::TYPE_DIRECTORY;
- if (dynamic_cast(node)) e->type = Directory_entry::TYPE_SYMLINK;
-
- strncpy(e->name, node->name(), sizeof(e->name));
-
- return sizeof(Directory_entry);
- }
-
- size_t write(char const *src, size_t len, seek_off_t seek_offset)
- {
- /* writing to directory nodes is not supported */
- return 0;
- }
-
- Status status() const
- {
- Status s;
- s.inode = inode();
- s.size = _num_entries * sizeof (Directory_entry);
- s.mode = File_system::Status::MODE_DIRECTORY;
-
- return s;
- }
-};
-
-#endif /* _DIRECTORY_H_ */
diff --git a/repos/os/src/server/trace_fs/file.h b/repos/os/src/server/trace_fs/file.h
deleted file mode 100644
index 07a3fba215..0000000000
--- a/repos/os/src/server/trace_fs/file.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * \brief File node
- * \author Norman Feske
- * \author Josef Soentgen
- * \date 2012-04-11
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _FILE_H_
-#define _FILE_H_
-
-/* Genode includes */
-#include
-#include
-
-/* local includes */
-#include
-#include
-
-namespace Trace_fs {
- class Changeable_content;
- class File;
- class Buffered_file;
-}
-
-/**
- *
- *
- */
-class Trace_fs::Changeable_content
-{
- protected:
-
- /**
- * This member is used to communicate the state and
- * must be set true by classes using this class in case
- * the content has changed.
- */
- bool _changed;
-
- /**
- * This method is called when the content change is
- * acknowledged. It may be overriden by any class using
- * this particular class.
- */
- virtual void _refresh_content() { }
-
- public:
-
- Changeable_content() : _changed(false) { }
-
- /**
- * Check if the content was changed
- *
- * This evaluation has to be made by classes using this
- * particular class.
- *
- * \return true if changed, otherwise false
- */
- bool changed() const { return _changed; }
-
-
- /**
- * Acknowledge the content has changed
- */
- void acknowledge_change()
- {
- _changed = false;
-
- _refresh_content();
- }
-};
-
-
-/**
- * File interface
- */
-
-class Trace_fs::File : public Node
-{
- public:
-
- File(char const *name)
- {
- Node::name(name);
- }
-
- virtual ~File() { }
-
- /********************
- ** Node interface **
- ********************/
-
- virtual size_t read(char *dst, size_t len, seek_off_t seek_offset) = 0;
-
- virtual size_t write(char const *src, size_t len, seek_off_t seek_offset) = 0;
-
- virtual Status status() const = 0;
-
- /********************
- ** File interface **
- ********************/
-
- virtual file_size_t length() const = 0;
-
- virtual void truncate(file_size_t size) = 0;
-};
-
-/**
- * Memory buffered file
- *
- * This file merely exists in memory and grows automatically.
- */
-
-class Trace_fs::Buffered_file : public File
-{
- private:
-
- typedef Chunk<4096> Chunk_level_3;
- typedef Chunk_index<128, Chunk_level_3> Chunk_level_2;
- typedef Chunk_index<64, Chunk_level_2> Chunk_level_1;
- typedef Chunk_index<64, Chunk_level_1> Chunk_level_0;
-
- Chunk_level_0 _chunk;
-
- file_size_t _length;
-
- public:
-
- Buffered_file(Allocator &alloc, char const *name)
- : File(name), _chunk(alloc, 0), _length(0) { }
-
- virtual size_t read(char *dst, size_t len, seek_off_t seek_offset)
- {
- file_size_t const chunk_used_size = _chunk.used_size();
-
- if (seek_offset >= _length)
- return 0;
-
- /*
- * Constrain read transaction to available chunk data
- *
- * Note that 'chunk_used_size' may be lower than '_length'
- * because 'Chunk' may have truncated tailing zeros.
- */
- if (seek_offset + len >= _length)
- len = _length - seek_offset;
-
- file_size_t read_len = len;
-
- if (seek_offset + read_len > chunk_used_size) {
- if (chunk_used_size >= seek_offset)
- read_len = chunk_used_size - seek_offset;
- else
- read_len = 0;
- }
-
- _chunk.read(dst, read_len, seek_offset);
-
- /* add zero padding if needed */
- if (read_len < len)
- memset(dst + read_len, 0, len - read_len);
-
- return len;
- }
-
- virtual size_t write(char const *src, size_t len, seek_off_t seek_offset)
- {
- if (seek_offset == (seek_off_t)(~0))
- seek_offset = _chunk.used_size();
-
- if (seek_offset + len >= Chunk_level_0::SIZE) {
- len = (Chunk_level_0::SIZE-1) - seek_offset;
- Genode::error(name(), ": size limit ", (long)Chunk_level_0::SIZE, " reached");
- }
-
- _chunk.write(src, len, (size_t)seek_offset);
-
- /*
- * Keep track of file length. We cannot use 'chunk.used_size()'
- * as file length because trailing zeros may by represented
- * by zero chunks, which do not contribute to 'used_size()'.
- */
- _length = max(_length, seek_offset + len);
-
- mark_as_updated();
- return len;
- }
-
- virtual Status status() const
- {
- Status s;
-
- s.inode = inode();
- s.size = _length;
- s.mode = File_system::Status::MODE_FILE;
-
- return s;
- }
-
- virtual file_size_t length() const { return _length; }
-
- void truncate(file_size_t size) override
- {
- if (size < _chunk.used_size())
- _chunk.truncate(size);
-
- _length = size;
-
- mark_as_updated();
- }
-};
-
-#endif /* _FILE_H_ */
diff --git a/repos/os/src/server/trace_fs/followed_subject.h b/repos/os/src/server/trace_fs/followed_subject.h
deleted file mode 100644
index 8a5d0fed94..0000000000
--- a/repos/os/src/server/trace_fs/followed_subject.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * \brief Facility for managing the trace subjects
- * \author Josef Soentgen
- * \date 2014-01-22
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _SUBJECT_REGISTRY_H_
-#define _SUBJECT_REGISTRY_H_
-
-#include
-#include
-#include
-
-#include
-#include
-
-namespace Trace_fs {
- typedef Genode::size_t size_t;
- class Followed_subject;
- class Followed_subject_registry;
-}
-
-class Trace_fs::Followed_subject : public Directory
-{
- public:
-
- /**
- * This class manages the access to the trace subject's trace buffer
- */
- class Trace_buffer_manager
- {
- public:
-
- class Already_managed { };
- class Not_managed { };
-
- struct Process_entry
- {
- virtual size_t operator()(Genode::Trace::Buffer::Entry&) = 0;
- };
-
- private:
-
- Genode::Trace::Buffer *buffer;
- Genode::Trace::Buffer::Entry current_entry;
-
-
- public:
-
- Trace_buffer_manager(Genode::Region_map &rm,
- Genode::Dataspace_capability ds_cap)
- :
- buffer(rm.attach(ds_cap)),
- current_entry(buffer->first())
- { }
-
- size_t dump_entry(Process_entry &process)
- {
- size_t len = process(current_entry);
-
- current_entry = buffer->next(current_entry);
- return len;
- }
-
- bool last_entry() const
- {
- return current_entry.last();
- }
-
- void rewind() { current_entry = buffer->first(); }
- };
-
-
- private:
-
- Genode::Allocator &_md_alloc;
-
- Genode::Region_map &_rm;
-
- int _handle;
-
- Genode::Trace::Subject_id _id;
- Genode::Trace::Policy_id _policy_id;
-
- bool _was_traced;
-
- Trace_buffer_manager *_buffer_manager;
-
- public:
-
- Active_file active_file;
- Buffer_size_file buffer_size_file;
- Cleanup_file cleanup_file;
- Enable_file enable_file;
- Events_file events_file;
- Policy_file policy_file;
-
- Followed_subject(Genode::Allocator &md_alloc, char const *name,
- Genode::Region_map &rm,
- Genode::Trace::Subject_id &id, int handle)
- :
- Directory(name),
- _md_alloc(md_alloc),
- _rm(rm),
- _handle(handle),
- _id(id),
- _was_traced(false),
- _buffer_manager(0),
- active_file(_id),
- buffer_size_file(),
- cleanup_file(_id),
- enable_file(_id),
- events_file(_id, _md_alloc),
- policy_file(_id, _md_alloc)
- {
- adopt_unsynchronized(&active_file);
- adopt_unsynchronized(&cleanup_file);
- adopt_unsynchronized(&enable_file);
- adopt_unsynchronized(&events_file);
- adopt_unsynchronized(&buffer_size_file);
- adopt_unsynchronized(&policy_file);
- }
-
- ~Followed_subject()
- {
- discard_unsynchronized(&active_file);
- discard_unsynchronized(&cleanup_file);
- discard_unsynchronized(&enable_file);
- discard_unsynchronized(&events_file);
- discard_unsynchronized(&buffer_size_file);
- discard_unsynchronized(&policy_file);
- }
-
- bool marked_for_cleanup() const { return cleanup_file.cleanup(); }
- bool was_traced() const { return _was_traced; }
-
- Trace_buffer_manager* trace_buffer_manager() { return _buffer_manager; }
-
- void manage_trace_buffer(Genode::Dataspace_capability ds_cap)
- {
- if (_buffer_manager != 0)
- throw Trace_buffer_manager::Already_managed();
-
- _buffer_manager = new (&_md_alloc) Trace_buffer_manager(_rm, ds_cap);
- }
-
- void unmanage_trace_buffer()
- {
- if (_buffer_manager == 0)
- throw Trace_buffer_manager::Not_managed();
-
- destroy(&_md_alloc, _buffer_manager);
- _buffer_manager = 0;
- }
-
- const Genode::Trace::Subject_id id() const { return _id; }
-
- const Genode::Trace::Policy_id policy_id() const { return _policy_id; }
- void policy_id(Genode::Trace::Policy_id &id) { _policy_id.id = id.id; }
- bool policy_valid() const { return (_policy_id.id != 0); }
- void invalidate_policy() { _policy_id = Genode::Trace::Policy_id(); }
-
- int handle() const { return _handle; }
-};
-
-
-/**
- * This registry contains all current followed trace subjects
- */
-class Trace_fs::Followed_subject_registry
-{
- public:
-
- class Invalid_subject { };
- class Out_of_subject_handles { };
-
- private:
-
- /* XXX abitrary limit - needs to be revisited when highly
- * dynamic scenarios are executed */
- enum { MAX_SUBJECTS = 1024U };
-
- Followed_subject *_subjects[MAX_SUBJECTS];
-
- Genode::Allocator &_md_alloc;
-
- /**
- * Find free subject handle
- *
- * \throw Out_of_subject_handles
- */
- int _find_free_handle()
- {
- for (unsigned i = 0; i < MAX_SUBJECTS; i++)
- if (!_subjects[i]) {
- return i;
- }
-
- throw Out_of_subject_handles();
- }
-
- bool _in_range(int handle) const
- {
- return ((handle >= 0) && (handle < MAX_SUBJECTS));
- }
-
- public:
-
- Followed_subject_registry(Genode::Allocator &md_alloc)
- :
- _md_alloc(md_alloc)
- {
- for (unsigned i = 0; i < MAX_SUBJECTS; i++)
- _subjects[i] = 0;
- }
-
- /**
- * Return maximal number of subject that can be stored in the registry
- *
- * \return maximal number of subjects
- */
- unsigned max_subjects() const { return MAX_SUBJECTS; }
-
- /**
- * Allocate new subject
- *
- * \param name name of subject
- * \param id subject id of tracre subject
- */
- Followed_subject *alloc(char const *name, Genode::Trace::Subject_id &id,
- Genode::Region_map &rm)
- {
- int handle = _find_free_handle();
-
- _subjects[handle] = new (&_md_alloc) Followed_subject(_md_alloc, name, rm, id, handle);
-
- return _subjects[handle];
- }
-
- /**
- * Free subject
- *
- * \param subject pointer to subject
- */
- void free(Followed_subject *subject)
- {
- int handle = subject->handle();
-
- if (!_in_range(handle))
- return;
-
- if(!_subjects[handle])
- return;
-
- _subjects[handle] = 0;
- destroy(&_md_alloc, subject);
- }
-
- /**
- * Lookup subject by using the id
- *
- * \throw Invalid_subject();
- */
- Followed_subject *lookup(Genode::Trace::Subject_id const &sid)
- {
- for (unsigned i = 0; i < MAX_SUBJECTS; i++)
- if (_subjects[i]) {
- if (_subjects[i]->id().id == sid.id)
- return _subjects[i];
- }
-
- throw Invalid_subject();
- }
-};
-
-#endif /* _SUBJECT_REGISTRY_H_ */
diff --git a/repos/os/src/server/trace_fs/main.cc b/repos/os/src/server/trace_fs/main.cc
deleted file mode 100644
index 8205eb3f9c..0000000000
--- a/repos/os/src/server/trace_fs/main.cc
+++ /dev/null
@@ -1,1136 +0,0 @@
-/*
- * \brief Trace file system
- * \author Josef Soentgen
- * \date 2014-01-15
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* local includes */
-#include
-#include
-#include
-#include
-
-
-namespace Trace_fs {
-
- using File_system::Packet_descriptor;
- using File_system::Path;
-
- class Trace_file_system;
- struct Policy;
- struct Main;
- struct Session_component;
- struct Root;
-}
-
-
-/**
- * Session-specific policy defined by the configuation
- */
-struct Trace_fs::Policy
-{
- uint64_t interval; /* in milliseconds */
- unsigned subject_limit;
- Genode::Number_of_bytes trace_quota;
- Genode::Number_of_bytes trace_meta_quota;
- Genode::Number_of_bytes buffer_size;
- Genode::Number_of_bytes buffer_size_max;
- unsigned trace_parent_levels;
-
- static Number_of_bytes _kib(size_t value) { return value * (1 << 10); }
- static Number_of_bytes _mib(size_t value) { return value * (1 << 20); }
-
- static Policy from_xml(Xml_node node)
- {
- return Policy {
- .interval = node.attribute_value("interval", (uint64_t)1000),
- .subject_limit = node.attribute_value("subject_limit", 128U),
- .trace_quota = node.attribute_value("trace_quota", _mib(32)),
- .trace_meta_quota = node.attribute_value("trace_meta_quota", _kib(256)),
- .buffer_size = node.attribute_value("buffer_size", _kib(32)),
- .buffer_size_max = node.attribute_value("buffer_size_max", _mib(1)),
- .trace_parent_levels = node.attribute_value("parent_levels", 0U)
- };
- }
-};
-
-
-/**
- * Return true if 'str' is a valid file name
- */
-static inline bool valid_filename(char const *str)
-{
- if (!str) return false;
-
- /* must have at least one character */
- if (str[0] == 0) return false;
-
- /* must not contain '/' or '\' or ':' */
- if (File_system::string_contains(str, '/') ||
- File_system::string_contains(str, '\\') ||
- File_system::string_contains(str, ':'))
- return false;
-
- return true;
-}
-
-/**
- * This class updates the file system
- *
- * In this context updating means creating the files and directories if
- * needed, refreshing their content or deleting them if they are no
- * longer of any use.
- */
-class Trace_fs::Trace_file_system
-{
- private:
-
- /* local abbreviations */
- typedef Genode::size_t size_t;
-
- typedef Genode::Trace::Subject_id Subject_id;
- typedef Genode::Trace::Subject_info Subject_info;
- typedef Genode::Trace::Connection Trace;
-
- /**
- * Simple node list
- *
- * This list is used to temporarily store pointers to all nodes
- * needed for representing a trace subject in the file system when
- * creating or cleaning up the file system hierachie.
- */
- class Node_list
- {
- private:
-
- /**
- * Node list element class
- *
- * A element only contains a pointer to the actual node.
- */
- struct Node_list_entry : public Genode::List::Element
- {
- Node *node;
-
- Node_list_entry(Node *n) : node(n) { }
- };
-
- Genode::Allocator &_md_alloc;
-
- Genode::List _list;
-
- public:
-
- Node_list(Genode::Allocator &md_alloc) : _md_alloc(md_alloc) { }
-
- /**
- * Free all memory automatically if the object goes out of
- * scope or rather is deleted.
- */
- ~Node_list()
- {
- for (Node_list_entry *e = _list.first(); e; ) {
- Node_list_entry *cur = e;
- e = e->next();
-
- _list.remove(cur);
- destroy(&_md_alloc, cur);
- }
- }
-
- /**
- * Insert a node in the list
- *
- * \param node pointer to node
- */
- void push(Node *node)
- {
- Node_list_entry *e = new (&_md_alloc) Node_list_entry(node);
- _list.insert(e);
- }
-
- /**
- * Remove the first node from the list
- *
- * The first element will be removed from the list and the node
- * is returned.
- *
- * \return pointer to node or 0
- */
- Node *pop()
- {
- Node_list_entry *e = _list.first();
- if (e) {
- Node *node = e->node;
-
- _list.remove(e);
- destroy(&_md_alloc, e);
-
- return node;
- }
-
- return 0;
- }
-
- /**
- * Return the node pointer of the first element in the list
- *
- * This method only returns the pointer but leaves the list
- * element in good order.
- *
- * \return pointer to node of the first element or 0
- */
- Node *first()
- {
- Node_list_entry *e = _list.first();
- return e ? e->node : 0;
- }
- };
-
-
- /**
- * This class implements the Process_entry functor class
- *
- * It is needed by the Trace_buffer_manager to process a entry
- * from the Trace::Buffer.
- */
- template
- class Process_entry : public Followed_subject::Trace_buffer_manager::Process_entry
- {
- private:
-
- char _buf[CAPACITY];
- size_t _length;
-
-
- public:
-
- Process_entry() : _length(0) { _buf[0] = 0; }
-
- /**
- * Return capacity of the internal buffer
- *
- * \return capacity of the buffer in bytes
- */
- size_t capacity() const { return CAPACITY; }
-
- /**
- * Return data of the processed Trace::Buffer::Entry
- *
- * \return pointer to data
- */
- char const *data() const { return _buf; }
-
- /**
- * Functor for processing a Trace:Buffer::Entry
- *
- * \param entry reference of Trace::Buffer::Entry
- *
- * \return length of processed Trace::Buffer::Entry
- */
- Genode::size_t operator()(Genode::Trace::Buffer::Entry &entry)
- {
- Genode::size_t len = Genode::min(entry.length() + 1, CAPACITY);
- Genode::memcpy(_buf, entry.data(), len);
- _buf[len - 1] = '\n';
-
- _length = len;
-
- return len;
- }
- };
-
-
- Genode::Region_map &_rm;
- Genode::Allocator &_alloc;
- Genode::Trace::Connection &_trace;
- Directory &_root_dir;
-
- size_t _buffer_size;
- size_t _buffer_size_max;
-
- Followed_subject_registry _followed_subject_registry;
-
-
- /**
- * Cast Node pointer to Directory pointer
- *
- * \param node pointer to node
- */
- Directory *_node_to_directory(Node *node)
- {
- return dynamic_cast(node);
- }
-
- /**
- * Gather recent trace events
- *
- * \param subject pointer to subject
- */
- void _gather_events(Followed_subject *subject)
- {
- Followed_subject::Trace_buffer_manager *manager = subject->trace_buffer_manager();
- if (!manager)
- return;
-
- Process_entry<512> process_entry;
-
- while (!manager->last_entry()) {
- size_t len = manager->dump_entry(process_entry);
-
- if (len == 0)
- continue;
-
- try { subject->events_file.append(process_entry.data(), len); }
- catch (...) { Genode::error("could not write entry"); }
- }
-
- if (manager->last_entry()) {
- manager->rewind();
- }
- }
-
- /**
- * Disable tracing of a followed subject
- *
- * \param subject pointer to subject
- */
- void _disable_tracing(Followed_subject *subject)
- {
- subject->active_file.set_inactive();
-
- _trace.pause(subject->id());
- _gather_events(subject);
- try { subject->unmanage_trace_buffer(); }
- catch (...) { Genode::error("trace buffer was not managed"); }
- _trace.free(subject->id());
- }
-
- /**
- * Enable tracing of a followed subject
- *
- * \param subject pointer to subject
- */
- void _enable_tracing(Followed_subject *subject)
- {
- try {
- _trace.trace(subject->id().id, subject->policy_id().id,
- subject->buffer_size_file.size());
-
- try { subject->manage_trace_buffer(_trace.buffer(subject->id())); }
- catch (...) { Genode::error("trace buffer is already managed"); }
-
- subject->active_file.set_active();
- }
- catch (...) { Genode::error("could not enable tracing"); }
- }
-
- /**
- * Search recursively the parent node for the corresponding label
- *
- * \param list list of traversed nodes
- * \param walker label walking object
- * \param parent parent node of the current directory
- *
- * \return parent node for the given label
- */
- Directory* _find_parent_node(Node_list &list, Util::Label_walker &walker,
- Directory &parent)
- {
- char const *remainder = walker.next();
-
- Directory *child;
-
- try { child = _node_to_directory(parent.lookup(walker.element())); }
- catch (File_system::Lookup_failed) {
- try {
- child = new (&_alloc) Directory(walker.element());
- parent.adopt_unsynchronized(child);
- }
- catch (...) {
- Genode::error("could not create '", walker.element(), "'");
- return 0;
- }
- }
-
- list.push(child);
-
- if (!*remainder) {
- return child;
- } else {
- return _find_parent_node(list, walker, *child);
- }
- }
-
- /**
- * Remove unsused nodes and free the memory
- *
- * All nodes are removed from the list and discarded from their
- * parent until we hit a node or rather a parent that still has
- * child nodes. In this case we stop. The remaining entries in
- * the node list are freed when the Node_list is deleted.
- *
- * \param list reference to list
- */
- void _remove_nodes(Node_list &list)
- {
- while (Node *child = list.pop()) {
- Node *parent = list.first();
-
- Directory *dir = dynamic_cast(child);
- if (dir->num_entries() == 0) {
-
- if (parent) {
- Directory *dir = dynamic_cast(parent);
- if (!(Genode::strcmp(dir->name(), child->name()) == 0))
- dir->discard_unsynchronized(child);
- }
-
- destroy(&_alloc, dir);
- } else {
- /* do not bother any further, node has other children */
- break;
- }
- }
- }
-
-
- public:
-
- /**
- * Constructor
- */
- Trace_file_system(Genode::Region_map &rm,
- Genode::Allocator &alloc,
- Trace &trace,
- Directory &root_dir,
- size_t buffer_size,
- size_t buffer_size_max)
- :
- _rm(rm), _alloc(alloc), _trace(trace), _root_dir(root_dir),
- _buffer_size(buffer_size), _buffer_size_max(buffer_size_max),
- _followed_subject_registry(_alloc)
- { }
-
- /**
- * Handle the change of the content of a node
- *
- * XXX This method could be made much simpler if a Node would
- * store the subject_id and could be used to make the lookup.
- */
- void handle_changed_node(Node *node)
- {
- Followed_subject *subject = 0;
- bool policy_changed = false;
-
- using namespace File_system;
-
- /**
- * It is enough to invoke acknowledge_change() on the Cleanup_file.
- * Therefore here is nothing to be done.
- */
- Cleanup_file *cleanup_file = dynamic_cast(node);
- if (cleanup_file) {
- return;
- }
-
- Policy_file *policy_file = dynamic_cast(node);
- if (policy_file) {
- try {
- subject = _followed_subject_registry.lookup(policy_file->id());
- size_t policy_length = policy_file->length();
-
- /* policy was changed, unload old one first */
- if (subject->policy_valid()) {
- _trace.unload_policy(subject->policy_id());
-
- subject->invalidate_policy();
- }
-
- /**
- * Copy the new policy only if it may containg something useful.
- * XXX: It might be better to check for a more reaseonable length.
- */
- if (policy_length > 0) {
- try {
- Genode::Trace::Policy_id id = _trace.alloc_policy(policy_length);
-
- Genode::Dataspace_capability ds_cap = _trace.policy(id);
- if (ds_cap.valid()) {
- void *ram = _rm.attach(ds_cap);
- size_t n = policy_file->read((char *)ram, policy_length, 0UL);
-
- if (n != policy_length) {
- Genode::error("error while copying policy content");
- } else { subject->policy_id(id); }
-
- _rm.detach(ram);
- }
- }
- catch (...) { Genode::error("could not allocate policy"); }
- }
-
- policy_changed = true;
- }
- catch (Trace_fs::Followed_subject_registry::Invalid_subject) { }
- }
-
- Enable_file *enable_file = dynamic_cast(node);
- if (enable_file) {
- try { subject = _followed_subject_registry.lookup(enable_file->id()); }
- catch (Trace_fs::Followed_subject_registry::Invalid_subject) { }
- }
-
- /**
- * Perform the action which was originally intended. This is actually
- * safe because at this point we got invoked by either the Enable_file
- * or Policy_file file.
- */
- Subject_info info = _trace.subject_info(subject->id());
- Subject_info::State state = info.state();
-
- /* tracing already enabled but policy has changed */
- if (subject->enable_file.enabled() && policy_changed) {
- /* disable tracing first */
- if (state == Subject_info::State::TRACED)
- _disable_tracing(subject);
-
- /* reenable only if the policy is actually valid */
- if (subject->policy_valid())
- _enable_tracing(subject);
- }
- /* subject is untraced but tracing is now enabled */
- else if (subject->enable_file.enabled() &&
- (state == Subject_info::State::UNTRACED)) {
- if (subject->policy_valid())
- _enable_tracing(subject);
- }
- /* subject is traced but tracing is now disabled */
- else if (!subject->enable_file.enabled() &&
- (state == Subject_info::State::TRACED)) {
- _disable_tracing(subject);
- }
- }
-
- /**
- * Update the trace subjects
- *
- * \param subject_limit limit the number of trace subjects
- */
- void update(int subject_limit)
- {
- Genode::Trace::Subject_id subjects[subject_limit];
-
- size_t num_subjects = _trace.subjects(subjects, subject_limit);
-
- /* traverse current trace subjects */
- for (size_t i = 0; i < num_subjects; i++) {
- Subject_info info = _trace.subject_info(subjects[i]);
- Subject_info::State state = info.state();
-
- /* opt-out early */
- switch (state) {
- case Subject_info::State::INVALID:
- case Subject_info::State::FOREIGN:
- case Subject_info::State::ERROR:
- continue;
- break; /* never reached */
- default:
- break;
- }
-
- Followed_subject *followed_subject;
-
- try {
- /* old subject found */
- followed_subject = _followed_subject_registry.lookup(subjects[i]);
-
- /**
- * Update content of the corresponding events file
- */
- if (state == Subject_info::State::TRACED) {
- _gather_events(followed_subject);
- continue;
- }
-
- /**
- * The subject is either UNTRACED or DEAD in which case we want to remove
- * the nodes if they are marked for deletion.
- */
- if (followed_subject->marked_for_cleanup() ||
- (!followed_subject->was_traced() && state == Subject_info::State::DEAD)) {
- char const *label = info.session_label().string();
-
- Node_list list(_alloc);
- Util::Label_walker walker(label);
-
- Directory *parent = _find_parent_node(list, walker, _root_dir);
- if (!parent) {
- Genode::error("could not find parent node for label:'", label, "'");
- continue;
- }
-
- parent->discard_unsynchronized(followed_subject);
- _remove_nodes(list);
- _followed_subject_registry.free(followed_subject);
- continue;
- }
- } catch (Trace_fs::Followed_subject_registry::Invalid_subject) {
-
- /* ignore unknown but already dead subject */
- if (state == Subject_info::State::DEAD)
- continue;
-
- /* new subject */
- char const *label = info.session_label().string();
- char const *name = info.thread_name().string();
-
- Util::Buffer<64> subject_dir_name;
- Genode::snprintf(subject_dir_name.data(), subject_dir_name.capacity(),
- "%s.%d", name, subjects[i].id);
-
- subject_dir_name.replace('/', '_');
-
- followed_subject = _followed_subject_registry.alloc(subject_dir_name.data(),
- subjects[i], _rm);
-
- /* set trace buffer size */
- followed_subject->buffer_size_file.size_limit(_buffer_size_max);
- followed_subject->buffer_size_file.size(_buffer_size);
-
- Node_list list(_alloc);
- Util::Label_walker walker(label);
- Directory *parent = _find_parent_node(list, walker, _root_dir);
- if (!parent) {
- Genode::error("could not find parent node on creation");
- continue;
- }
-
- parent->adopt_unsynchronized(followed_subject);
- }
- }
- }
-};
-
-
-class Trace_fs::Session_component : public Session_rpc_object
-{
- private:
-
- typedef File_system::Open_node Open_node;
-
- Genode::Entrypoint &_ep;
- Ram_allocator &_ram;
- Allocator &_md_alloc;
- Directory &_root_dir;
- Id_space _open_node_registry;
- bool _writeable;
-
- unsigned _subject_limit;
- uint64_t _poll_interval;
-
- Timer::Connection _fs_update_timer;
-
- Trace::Connection *_trace;
- Trace_file_system *_trace_fs;
-
- Signal_handler _process_packet_handler {
- _ep, *this, &Session_component::_process_packets };
-
- Signal_handler _fs_update_handler {
- _ep, *this, &Session_component::_fs_update };
-
-
- /**************************
- ** File system updating **
- **************************/
-
- /**
- * Update the file system hierarchie and data of active trace subjects
- */
- void _fs_update()
- {
- _trace_fs->update(_subject_limit);
- }
-
- /******************************
- ** Packet-stream processing **
- ******************************/
-
- /**
- * Perform packet operation
- */
- void _process_packet_op(Packet_descriptor &packet, Open_node &open_node)
- {
- void * const content = tx_sink()->packet_content(packet);
- size_t const length = packet.length();
-
- /* resulting length */
- size_t res_length = 0;
- bool succeeded = false;
-
- switch (packet.operation()) {
-
- case Packet_descriptor::READ:
- if (content && (packet.length() <= packet.size())) {
- Locked_ptr node { open_node.node() };
- if (!node.valid())
- break;
- res_length = node->read((char *)content, length, packet.position());
- succeeded = res_length > 0;
- }
- break;
-
- case Packet_descriptor::WRITE:
- if (content && (packet.length() <= packet.size())) {
- Locked_ptr node { open_node.node() };
- if (!node.valid())
- break;
- res_length = node->write((char const *)content, length, packet.position());
-
- /* File system session can't handle partial writes */
- if (res_length != length) {
- Genode::error("partial write detected ",
- res_length, " vs ", length);
- /* don't acknowledge */
- return;
- }
- succeeded = true;
- }
- break;
-
- case Packet_descriptor::CONTENT_CHANGED: {
- open_node.register_notify(*tx_sink());
-
- /* notify_listeners may bounce the packet back*/
- Locked_ptr node { open_node.node() };
- if (!node.valid())
- return;
- node->notify_listeners();
-
- /* otherwise defer acknowledgement of this packet */
- return;
- }
-
- case Packet_descriptor::READ_READY:
- succeeded = true;
- /* not supported */
- break;
-
- case Packet_descriptor::SYNC:
- succeeded = true;
- /* not supported */
- break;
- }
-
- packet.length(res_length);
- packet.succeeded(succeeded);
- tx_sink()->acknowledge_packet(packet);
- }
-
- void _process_packet()
- {
- Packet_descriptor packet = tx_sink()->get_packet();
-
- /* assume failure by default */
- packet.succeeded(false);
-
- auto process_packet_fn = [&] (Open_node &open_node) {
- _process_packet_op(packet, open_node);
- };
-
- try {
- _open_node_registry.apply(packet.handle(), process_packet_fn);
- } catch (Id_space::Unknown_id const &) {
- Genode::error("Invalid_handle");
- }
-
- /*
- * The 'acknowledge_packet' function cannot block because we
- * checked for 'ready_to_ack' in '_process_packets'.
- */
- tx_sink()->acknowledge_packet(packet);
- }
-
- /**
- * Called by signal handler, executed in the context of the main
- * thread (not serialized with the RPC functions)
- */
- void _process_packets()
- {
- while (tx_sink()->packet_avail()) {
-
- /*
- * Make sure that the '_process_packet' function does not
- * block.
- *
- * If the acknowledgement queue is full, we defer packet
- * processing until the client processed pending
- * acknowledgements and thereby emitted a ready-to-ack
- * signal. Otherwise, the call of 'acknowledge_packet()'
- * in '_process_packet' would infinitely block the context
- * of the main thread. The main thread is however needed
- * for receiving any subsequent 'ready-to-ack' signals.
- */
- if (!tx_sink()->ready_to_ack())
- return;
-
- _process_packet();
- }
- }
-
- /**
- * Check if string represents a valid path (must start with '/')
- */
- static void _assert_valid_path(char const *path)
- {
- if (!path || path[0] != '/') {
- Genode::warning("malformed path '", path, "'");
- throw Lookup_failed();
- }
- }
-
-
- public:
-
- /**
- * Constructor
- */
- Session_component(size_t tx_buf_size,
- Genode::Entrypoint &ep,
- Genode::Ram_allocator &ram,
- Genode::Region_map &rm,
- Genode::Env &env,
- Directory &root_dir,
- Allocator &md_alloc,
- Trace_fs::Policy policy)
- :
- Session_rpc_object(ram.alloc(tx_buf_size), rm, ep.rpc_ep()),
- _ep(ep),
- _ram(ram),
- _md_alloc(md_alloc),
- _root_dir(root_dir),
-
- _subject_limit(policy.subject_limit),
- _poll_interval(policy.interval),
- _fs_update_timer(env),
- _trace(new (&_md_alloc)
- Genode::Trace::Connection(env, policy.trace_quota,
- policy.trace_meta_quota,
- policy.trace_parent_levels)),
- _trace_fs(new (&_md_alloc)
- Trace_file_system(rm, _md_alloc, *_trace, _root_dir,
- policy.buffer_size, policy.buffer_size_max))
- {
- _tx.sigh_packet_avail(_process_packet_handler);
- _tx.sigh_ready_to_ack(_process_packet_handler);
-
- /**
- * Register '_fs_update' dispatch function as signal handler
- * for polling the trace session.
- */
- _fs_update_timer.sigh(_fs_update_handler);
-
- /**
- * We need to scale _poll_interval because trigger_periodic()
- * uses usec.
- */
- _fs_update_timer.trigger_periodic(_poll_interval * 1000);
- }
-
- /**
- * Destructor
- */
- ~Session_component()
- {
- destroy(&_md_alloc, _trace_fs);
- destroy(&_md_alloc, _trace);
-
- Dataspace_capability ds = tx_sink()->dataspace();
- _ram.free(static_cap_cast(ds));
- }
-
-
- /***************************
- ** File_system interface **
- ***************************/
-
- File_handle file(Dir_handle dir_handle, Name const &name, Mode mode, bool create)
- {
- if (!valid_filename(name.string()))
- throw Invalid_name();
-
- auto file_fn = [&] (Open_node &open_node) {
-
- Locked_ptr dir { open_node.node() };
-
- if (!dir.valid())
- throw Invalid_handle();
-
- if (create)
- throw Permission_denied();
-
- File *file = dynamic_cast(dir->lookup(name.string()));
- if (!file)
- throw Invalid_name();
-
- Open_node *open_file =
- new (_md_alloc) Open_node(file->weak_ptr(), _open_node_registry);
-
- return open_file->id();
- };
-
- try {
- return File_handle {
- _open_node_registry.apply(dir_handle, file_fn).value
- };
- } catch (Id_space::Unknown_id const &) {
- throw Invalid_handle();
- }
- }
-
- Symlink_handle symlink(Dir_handle dir_handle, Name const &name, bool create)
- {
- Genode::warning("symlinks not supported");
- throw Permission_denied();
- }
-
- Dir_handle dir(Path const &path, bool create)
- {
- char const *path_str = path.string();
-
- _assert_valid_path(path_str);
-
- if (create)
- throw Permission_denied();
-
- if (!path.valid_string())
- throw Name_too_long();
-
- Directory *dir = dynamic_cast(_root_dir.lookup(path_str + 1));
- if (!dir)
- throw Invalid_name();
-
- Open_node *open_dir =
- new (_md_alloc) Open_node(dir->weak_ptr(), _open_node_registry);
-
- return Dir_handle { open_dir->id().value };
- }
-
- Node_handle node(Path const &path)
- {
- char const *path_str = path.string();
-
- _assert_valid_path(path_str);
-
- Node *node = _root_dir.lookup(path_str + 1);
-
- Open_node *open_node =
- new (_md_alloc) Open_node(node->weak_ptr(), _open_node_registry);
-
- return open_node->id();
- }
-
- void close(Node_handle handle)
- {
- auto close_fn = [&] (Open_node &open_node) {
-
- Locked_ptr node { open_node.node() };
-
- if (!node.valid())
- throw Invalid_handle();
-
- /**
- * Acknowledge the change of the content of files which may be
- * modified by the user of the file system.
- */
- Changeable_content *changeable = dynamic_cast(&*node);
- if (changeable) {
- if (changeable->changed()) {
- changeable->acknowledge_change();
-
- /* let the trace fs perform the provoked actions */
- _trace_fs->handle_changed_node(&*node);
- }
- }
-
- /*
- * Notify listeners about the changed file.
- */
- node->notify_listeners();
-
- /*
- * De-allocate handle
- */
- destroy(_md_alloc, &open_node);
- };
-
- try {
- _open_node_registry.apply(handle, close_fn);
- } catch (Id_space::Unknown_id const &) {
- throw Invalid_handle();
- }
- }
-
- Status status(Node_handle node_handle)
- {
- auto status_fn = [&] (Open_node &open_node) {
- Locked_ptr node { open_node.node() };
- if (!node.valid())
- throw Invalid_handle();
- return node->status();
- };
-
- try {
- return _open_node_registry.apply(node_handle, status_fn);
- } catch (Id_space::Unknown_id const &) {
- throw Invalid_handle();
- }
- }
-
- void control(Node_handle, Control) { }
- void unlink(Dir_handle dir_handle, Name const &name) { }
-
- void truncate(File_handle handle, file_size_t size)
- {
- auto truncate_fn = [&] (Open_node &open_node) {
- Locked_ptr node { open_node.node() };
- if (!node.valid())
- throw Invalid_handle();
- node->truncate(size);
- };
-
- try {
- _open_node_registry.apply(handle, truncate_fn);
- } catch (Id_space::Unknown_id const &) {
- throw Invalid_handle();
- }
- }
-
- void move(Dir_handle, Name const &, Dir_handle, Name const &) { }
-};
-
-
-class Trace_fs::Root : public Root_component
-{
- private:
-
- Genode::Entrypoint &_ep;
- Genode::Ram_allocator &_ram;
- Genode::Region_map &_rm;
- Genode::Env &_env;
-
- Directory &_root_dir;
-
- Genode::Attached_rom_dataspace _config { _env, "config" };
-
- protected:
-
- Session_component *_create_session(const char *args)
- {
- /*
- * Determine client-specific policy defined implicitly by
- * the client's label.
- */
- Session_label const label = label_from_args(args);
-
- Session_policy policy(label, _config.xml());
-
- /* make sure that root directory is defined */
- if (!policy.has_attribute("root")) {
- Genode::error("Missing \"root\" attribute in policy definition");
- throw Service_denied();
- }
-
- Trace_fs::Policy const attributes = Trace_fs::Policy::from_xml(policy);
-
- 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);
-
- if (!tx_buf_size) {
- Genode::error(label, " requested a session with a zero length transmission buffer");
- throw Genode::Service_denied();
- }
-
- /*
- * 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) {
- Genode::error("insufficient 'ram_quota', got ", ram_quota, ", "
- "need ", session_size);
- throw Insufficient_ram_quota();
- }
- return new (md_alloc())
- Session_component(tx_buf_size, _ep, _ram, _rm, _env, _root_dir,
- *md_alloc(), attributes);
- }
-
- public:
-
- /**
- * 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(Genode::Entrypoint &ep, Allocator &md_alloc, Ram_allocator &ram,
- Region_map &rm, Env &env, Directory &root_dir)
- :
- Root_component(&ep.rpc_ep(), &md_alloc),
- _ep(ep),
- _ram(ram),
- _rm(rm),
- _env(env),
- _root_dir(root_dir)
- { }
-};
-
-
-struct Trace_fs::Main
-{
- Env &_env;
-
- Directory root_dir = { "/" };
-
- /*
- * Initialize root interface
- */
- Sliced_heap sliced_heap = { _env.ram(), _env.rm() };
-
- Root fs_root = { _env.ep(), sliced_heap, _env.ram(), _env.rm(), _env, root_dir };
-
- Main(Env &env) : _env(env)
- {
- env.parent().announce(env.ep().manage(fs_root));
- }
-};
-
-void Component::construct(Genode::Env &env) { static Trace_fs::Main main(env); }
diff --git a/repos/os/src/server/trace_fs/node.h b/repos/os/src/server/trace_fs/node.h
deleted file mode 100644
index 17785d99d6..0000000000
--- a/repos/os/src/server/trace_fs/node.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * \brief File-system node
- * \author Norman Feske
- * \date 2012-04-11
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _NODE_H_
-#define _NODE_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-
-namespace Trace_fs {
- using namespace File_system;
- using namespace Genode;
- class Node;
-}
-
-class Trace_fs::Node : public Node_base, public Weak_object,
- public List::Element
-{
- public:
-
- typedef char Name[128];
-
- private:
-
- Name _name;
- unsigned long const _inode;
-
- /**
- * Generate unique inode number
- */
- static unsigned long _unique_inode()
- {
- static unsigned long inode_count;
- return ++inode_count;
- }
-
- public:
-
- Node()
- : _inode(_unique_inode())
- { _name[0] = 0; }
-
- virtual ~Node() { lock_for_destruction(); }
-
- unsigned long inode() const { return _inode; }
- char const *name() const { return _name; }
-
- /**
- * Assign name
- */
- void name(char const *name) { strncpy(_name, name, sizeof(_name)); }
-
- virtual Status status() const = 0;
-
- virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
- virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
-
- /*
- * Directory functionality
- */
- virtual Node *lookup(char const *path, bool return_parent = false)
- {
- Genode::error(__PRETTY_FUNCTION__, " called on a non-directory node");
- return nullptr;
- }
-
- /*
- * File functionality
- */
- virtual void truncate(file_size_t size)
- {
- Genode::error(__PRETTY_FUNCTION__, " called on a non-file node");
- }
-};
-
-#endif /* _NODE_H_ */
diff --git a/repos/os/src/server/trace_fs/symlink.h b/repos/os/src/server/trace_fs/symlink.h
deleted file mode 100644
index 84088ac412..0000000000
--- a/repos/os/src/server/trace_fs/symlink.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * \brief Symlink file-system node
- * \author Norman Feske
- * \date 2012-04-11
- */
-
-/*
- * Copyright (C) 2012-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _SYMLINK_H_
-#define _SYMLINK_H_
-
-/* local includes */
-#include
-
-namespace Trace_fs {
- class Symlink;
-}
-
-class Trace_fs::Symlink : public File
-{
- public:
-
- Symlink(char const *name) : File(name) { }
-
- size_t read(char *dst, size_t len, seek_off_t seek_offset) {
- return 0; }
-
- size_t write(char const *src, size_t len, seek_off_t seek_offset) {
- return 0; }
-
- file_size_t length() const { return 0; }
-
- void truncate(file_size_t) { }
-};
-
-#endif /* _SYMLINK_H_ */
diff --git a/repos/os/src/server/trace_fs/target.mk b/repos/os/src/server/trace_fs/target.mk
deleted file mode 100644
index 2ce96cc1bd..0000000000
--- a/repos/os/src/server/trace_fs/target.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-TARGET = trace_fs
-SRC_CC = main.cc
-LIBS = base
-INC_DIR += $(PRG_DIR)
-
-CC_CXX_WARN_STRICT =
diff --git a/repos/os/src/server/trace_fs/trace_files.h b/repos/os/src/server/trace_fs/trace_files.h
deleted file mode 100644
index 43d4b122be..0000000000
--- a/repos/os/src/server/trace_fs/trace_files.h
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * \brief Trace files
- * \author Josef Soentgen
- * \date 2014-01-22
- */
-
-/*
- * Copyright (C) 2014-2017 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TRACE_FILES_H_
-#define _TRACE_FILES_H_
-
-/* Genode includes */
-#include
-
-/* local includes */
-#include
-
-
-namespace Trace_fs {
- class State_file;
- class Active_file;
- class Cleanup_file;
- class Enable_file;
- class Events_file;
- class Buffer_size_file;
- class Policy_file;
-}
-
-/**
- * The State_file is a stateful file that is used to implement
- * files in the file system, which may trigger a action in the
- * file system backend.
- */
-
-class Trace_fs::State_file : public File,
- public Changeable_content
-{
- protected:
-
- bool _state;
-
-
- public:
-
- State_file(char const *name)
- : File(name), _state(false) { }
-
- bool state() const { return _state; }
-
-
- /********************
- ** Node interface **
- ********************/
-
- virtual size_t read(char *dst, size_t len, seek_off_t seek_offset)
- {
- /* limit len */
- if (len > 2)
- len = 2;
-
- switch (len) {
- case 2:
- dst[1] = '\n';
- case 1:
- dst[0] = 0x30 + (char)_state;
- break;
- default:
- /* zero length is useless */
- break;
- }
-
- return len;
- }
-
- virtual size_t write(char const *src, size_t len, seek_off_t seek_offset)
- {
- char buf[32];
- if (len >= sizeof buf)
- return 0;
-
- using namespace Genode;
-
- strncpy(buf, src, min(len + 1, sizeof (buf)));
-
- /**
- * For now, we only check the leading digit and do not care
- * about the rest.
- */
- if (!strcmp(buf, "1", 1)) {
- _state = true;
- }
- else if (!strcmp(buf, "0", 1)) {
- _state = false;
- } else {
- /* silently ignore bogus writes */
- return 0;
- }
-
- Changeable_content::_changed = true;
-
- return len;
- }
-
- Status status() const
- {
- Status s;
-
- s.inode = inode();
- s.size = 2;
- s.mode = File_system::Status::MODE_FILE;
-
- return s;
- }
-
- /********************
- ** File interface **
- ********************/
-
- file_size_t length() const { return 2; }
- void truncate(file_size_t size) { }
-};
-
-
-/**
- * The Active_file node shows the state of the tracing
- */
-
-class Trace_fs::Active_file : public State_file
-{
- private:
-
- Genode::Trace::Subject_id &_id;
- bool _active;
-
-
- public:
-
- Active_file(Genode::Trace::Subject_id &id)
- : State_file("active"), _id(id) { }
-
- Genode::Trace::Subject_id& id() const { return _id; }
-
- bool active() const { return State_file::state(); }
-
- void set_active() { _state = true; }
- void set_inactive() { _state = false; }
-};
-
-
-/**
- * The Cleanup_file is used to trigger the removal of files used by
- * the traced subject and to free utilized memory.
- */
-
-class Trace_fs::Cleanup_file : public State_file
-{
- private:
-
- Genode::Trace::Subject_id &_id;
-
-
- public:
-
- Cleanup_file(Genode::Trace::Subject_id &id)
- : State_file("cleanup"), _id(id) { }
-
- Genode::Trace::Subject_id& id() const { return _id; }
-
- bool cleanup() const { return State_file::state(); }
-};
-
-
-/**
- * The Enable_file is used to initiate the tracing process
- */
-
-class Trace_fs::Enable_file : public State_file
-{
- private:
-
- Genode::Trace::Subject_id &_id;
-
-
- public:
-
- Enable_file(Genode::Trace::Subject_id &id)
- : State_file("enable"), _id(id) { }
-
- Genode::Trace::Subject_id& id() const { return _id; }
-
- bool enabled() const { return State_file::state(); }
-};
-
-
-/**
- * The Events_file encapsulates the trace buffer of traced thread
- */
-
-class Trace_fs::Events_file : public Buffered_file
-{
- private:
-
- Genode::Trace::Subject_id &_id;
-
-
- public:
-
- Events_file(Genode::Trace::Subject_id &id,
- Allocator &md_alloc)
- : Buffered_file(md_alloc, "events"), _id(id) { }
-
- Genode::Trace::Subject_id id() const { return _id; }
-
- size_t append(char const *src, size_t len)
- {
- Buffered_file::write(src, len, length());
-
- return len;
- }
-
- /********************
- ** File interface **
- ********************/
-
- /* override to prevent the user from overriding the file */
- size_t write(char const *src, size_t len, seek_off_t seek_offset) { return 0; }
- void truncate(file_size_t size) { }
-};
-
-
-/**
- * This file contains the size of the trace buffer
- */
-
-class Trace_fs::Buffer_size_file : public File,
- public Changeable_content
-{
- private:
-
- file_size_t _length;
- unsigned long _size_limit;
- unsigned long _size;
-
- char _content[32];
- Genode::size_t _content_filled;
-
- /**
- * Check if new size honors the size limit
- *
- * \param size new size of the buffer
- * \return size limit if new size is greater, otherwise new size
- */
- size_t _check_size_limit(size_t size)
- {
- if (size > _size_limit)
- return _size_limit;
- else
- return size;
- }
-
- /**
- * Evalute the current content of the buffer
- */
- void _refresh_content()
- {
- unsigned long tmp = 0;
-
- _content[_content_filled - 1] = '\0';
- _content_filled = 0;
-
- _length = Genode::strlen(_content);
-
- /* account for \n when reading from the file */
- _length += 1;
-
- ascii_to(_content, tmp);
-
- _size = _check_size_limit(tmp);
- }
-
-
- public:
-
- /**
- * Constructor
- */
- Buffer_size_file() : File("buffer_size"), _size_limit(0), _size(0) { }
-
- /**
- * Return current size of the trace buffer
- */
- unsigned long size() const { return _size; }
-
- /**
- * Set current size of the trace buffer
- */
- void size(unsigned long size)
- {
- _size = _check_size_limit(size);
-
- /* update file content */
- _length = Genode::snprintf(_content, sizeof (_content), "%lu", _size);
-
- /* account for \n when reading from the file */
- _length += 1;
- }
-
- /**
- * Set max size of a trace buffer
- */
- void size_limit(unsigned long limit) { _size_limit = limit; }
-
- /**
- * Return maximal size of the trace buffer
- */
- unsigned long size_limit() const { return _size_limit; }
-
-
- /********************
- ** Node interface **
- ********************/
-
- /**
- * Read current maximal size of the trace buffer
- */
- size_t read(char *dst, size_t len, seek_off_t seek_offset)
- {
- if (len > 32) {
- Genode::error("len:'", len, "' to small");
- return 0;
- }
-
- char buf[32];
- Genode::snprintf(buf, sizeof (buf), "%lu\n", _size);
- memcpy(dst, buf, len);
-
- return len;
- }
-
- /**
- * Write new current maximal size of the trace buffer
- */
- size_t write(char const *src, size_t len, seek_off_t seek_offset)
- {
- if ((_content_filled + len) > sizeof (_content))
- return 0;
-
- Genode::memcpy(_content + _content_filled, src, len);
- _content_filled += len;
-
- Changeable_content::_changed = true;
-
- return len;
- }
-
- Status status() const
- {
- Status s;
-
- s.inode = inode();
- s.size = _length;
- s.mode = File_system::Status::MODE_FILE;
-
- return s;
- }
-
-
- /********************
- ** File interface **
- ********************/
-
- file_size_t length() const { return _length; }
-
- void truncate(file_size_t size) { }
-};
-
-
-/**
- * Policy file
- */
-
-class Trace_fs::Policy_file : public Buffered_file,
- public Changeable_content
-{
- private:
-
- Genode::Trace::Subject_id &_id;
- file_size_t _length;
-
-
- public:
-
- Policy_file(Genode::Trace::Subject_id &id,
- Genode::Allocator &md_alloc)
- : Buffered_file(md_alloc, "policy"), _id(id) { }
-
- Genode::Trace::Subject_id& id() const { return _id; }
-
-
- /********************
- ** Node interface **
- ********************/
-
- size_t read(char *dst, size_t len, seek_off_t seek_offset)
- {
- return Buffered_file::read(dst, len, seek_offset);
- }
-
- size_t write(char const *src, size_t len, seek_off_t seek_offset)
- {
- size_t written = Buffered_file::write(src, len, seek_offset);
-
- if (written > 0)
- _changed = true;
-
- return written;
- }
-
-
- /********************
- ** File interface **
- ********************/
-
- void truncate(file_size_t size)
- {
- Buffered_file::truncate(size);
-
- _changed = true;
- }
-
-};
-
-#endif /* _TRACE_FILES_H_ */
diff --git a/repos/ports/run/noux_trace_fs.run b/repos/ports/run/noux_trace_fs.run
deleted file mode 100644
index 9f21f58038..0000000000
--- a/repos/ports/run/noux_trace_fs.run
+++ /dev/null
@@ -1,160 +0,0 @@
-#
-# The Linux version of Noux lacks the support for the fork system call. Hence,
-# the run script is expected to fail.
-#
-if {[have_spec linux]} {
- puts "Linux is unsupported."
- exit 0
-}
-
-create_boot_directory
-
-import_from_depot [depot_user]/src/[base_src] \
- [depot_user]/pkg/[drivers_interactive_pkg] \
- [depot_user]/pkg/terminal \
- [depot_user]/src/init \
- [depot_user]/src/libc \
- [depot_user]/src/noux \
- [depot_user]/src/posix \
- [depot_user]/src/ncurses \
- [depot_user]/src/vim \
- [depot_user]/src/bash \
- [depot_user]/src/grep \
- [depot_user]/src/coreutils \
- [depot_user]/src/ram_fs
-
-
-# write default vimrc file
-set vimrc_fd [open "bin/vimrc" w]
-puts $vimrc_fd {
-set noloadplugins
-set hls
-set nocompatible
-set laststatus=2
-set noswapfile
-set viminfo=}
-close $vimrc_fd
-
-install_config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-build { server/trace_fs lib/trace/policy/rpc_name }
-
-build_boot_image { vimrc trace_fs rpc_name }
-
-run_genode_until forever
-
-# vi: set ft=tcl :