mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
@@ -361,9 +361,6 @@ Separate components
|
||||
:_os/src/server/log_terminal/_:
|
||||
Adapter for forwarding terminal output to a LOG session.
|
||||
|
||||
:_os/src/server/fs_log/_:
|
||||
Adapter that writes LOG messages to files on a file system.
|
||||
|
||||
:_demo/src/server/nitlog/_:
|
||||
Provides a LOG session, printing log output on screen via a GUI session.
|
||||
|
||||
@@ -377,9 +374,6 @@ Separate components
|
||||
switching between configuration variants dependent on the state of
|
||||
the system.
|
||||
|
||||
:_os/src/server/log_terminal/_:
|
||||
Forwards terminal output to a LOG session.
|
||||
|
||||
:_gems/src/server/file_terminal/_:
|
||||
Provides terminal sessions that target files on a file system.
|
||||
|
||||
|
||||
@@ -657,7 +657,6 @@ set default_test_pkgs {
|
||||
test-entrypoint
|
||||
test-expat
|
||||
test-fault_detection
|
||||
test-fs_log
|
||||
test-fs_packet
|
||||
test-fs_report
|
||||
test-fs_rom_update
|
||||
|
||||
@@ -3,8 +3,7 @@ of the configured threads on a regular basis for the purpose of statistical
|
||||
profiling.
|
||||
|
||||
The collected samples are written to the LOG session with an individual label
|
||||
for each thread. By using the 'fs_log' component, the sample data can be
|
||||
written into separate files if desired.
|
||||
for each thread.
|
||||
|
||||
Configuration options
|
||||
---------------------
|
||||
@@ -39,10 +38,9 @@ available at
|
||||
! filter_sampled_addresses_from_log <file containing the Genode log output>
|
||||
|
||||
This script extracts the sampled addresses from a file containing the Genode
|
||||
log output and saves them in the file 'sampled_addresses.txt'. It is not
|
||||
needed when the addresses have already been written into a separate file by
|
||||
the 'fs_log' component. The match string (label) in the script might need to
|
||||
be adapted for the specific scenario.
|
||||
log output and saves them in the file 'sampled_addresses.txt'. The match
|
||||
string (label) in the script might need to be adapted for the specific
|
||||
scenario.
|
||||
|
||||
* Filtering the shared library load addresses from the Genode log output
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Test logging to file system
|
||||
@@ -1,4 +0,0 @@
|
||||
_/src/init
|
||||
_/src/fs_log
|
||||
_/src/test-bomb
|
||||
_/src/vfs
|
||||
@@ -1 +0,0 @@
|
||||
2022-01-18 3bc7af292c912a6b4a10a0e79a373e424a4e9a4c
|
||||
@@ -1,63 +0,0 @@
|
||||
<runtime ram="32M" caps="1000" binary="init">
|
||||
|
||||
<requires> <timer/> </requires>
|
||||
|
||||
<events>
|
||||
<timeout meaning="failed" sec="20" />
|
||||
<log meaning="succeeded">[0] Done.</log>
|
||||
</events>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="bomb"/>
|
||||
<rom label="vfs"/>
|
||||
<rom label="fs_log"/>
|
||||
<rom label="vfs.lib.so"/>
|
||||
</content>
|
||||
|
||||
<config prio_levels="2">
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="Timer"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="vfs">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="File_system"/></provides>
|
||||
<config>
|
||||
<vfs>
|
||||
<log name="bomb-master.log"/>
|
||||
<dir name="bomb-master"> <log name="bomb_g5.log"/> </dir>
|
||||
</vfs>
|
||||
<policy label_prefix="fs_log" writeable="yes" root="/"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="fs_log">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="LOG"/></provides>
|
||||
<config>
|
||||
<policy label="bomb-master"/>
|
||||
<policy label_prefix="bomb-master" merge="true"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="bomb-master" priority="-1" caps="500">
|
||||
<binary name="bomb"/>
|
||||
<resource name="CPU" quantum="90"/>
|
||||
<resource name="RAM" quantum="2G"/>
|
||||
<route>
|
||||
<any-service> <any-child/> <parent/> </any-service>
|
||||
</route>
|
||||
<config rounds="1" generations="1" sleep="500"/>
|
||||
</start>
|
||||
</config>
|
||||
</runtime>
|
||||
@@ -1,2 +0,0 @@
|
||||
SRC_DIR = src/server/fs_log
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
||||
@@ -1 +0,0 @@
|
||||
2022-01-18 60ce0bbfa19e8146e8675bf435545dea73682c63
|
||||
@@ -1,5 +0,0 @@
|
||||
base
|
||||
os
|
||||
vfs
|
||||
file_system
|
||||
file_system_session
|
||||
@@ -1,25 +0,0 @@
|
||||
LOG server that writes log messages onto a file system.
|
||||
|
||||
Log files are creating in a directory tree formed from session labels.
|
||||
As an example the session label "init -> nitpicker" would create
|
||||
a log file at "init/nitpicker.log".
|
||||
|
||||
The option to truncate files at the start of each LOG session is available
|
||||
through session policy, as well the option to merge the logs of any
|
||||
session matching a given policy. When a merged policy label contains a
|
||||
trailing "->", the log filename takes the name of the next label element.
|
||||
|
||||
When a default-policy node specifies a merge, all sessions are merged into
|
||||
the file "/log".
|
||||
|
||||
:Example configuration:
|
||||
! <start name="fs_log">
|
||||
! <resource name="RAM" quantum="1M"/>
|
||||
! <provides><service name="LOG"/></provides>
|
||||
! <config>
|
||||
! <policy label_prefix="nic_drv" truncate="no"/>
|
||||
! <policy label_prefix="runtime -> " merge="yes"/>
|
||||
! <default-policy truncate="yes"/>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
/*
|
||||
* \brief Server that writes log messages to a file system.
|
||||
* \author Emery Hemingway
|
||||
* \date 2015-05-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/heap.h>
|
||||
#include <file_system_session/connection.h>
|
||||
#include <file_system/util.h>
|
||||
#include <os/path.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <root/component.h>
|
||||
#include <base/component.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* Local includes */
|
||||
#include "session.h"
|
||||
|
||||
namespace Fs_log {
|
||||
|
||||
using namespace Genode;
|
||||
using namespace File_system;
|
||||
|
||||
class Root_component;
|
||||
|
||||
enum {
|
||||
PACKET_SIZE = Log_session::String::MAX_SIZE,
|
||||
QUEUE_SIZE = File_system::Session::TX_QUEUE_SIZE,
|
||||
TX_BUF_SIZE = PACKET_SIZE * (QUEUE_SIZE+2)
|
||||
};
|
||||
|
||||
typedef Genode::Path<File_system::MAX_PATH_LEN> Path;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Fs_log::Root_component :
|
||||
public Genode::Root_component<Fs_log::Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
|
||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||
Allocator_avl _tx_alloc { &_heap };
|
||||
File_system::Connection _fs
|
||||
{ _env, _tx_alloc, "", "/", true, TX_BUF_SIZE };
|
||||
|
||||
/* enable reception of I/O signals from file-system session */
|
||||
Genode::Io_signal_handler<Root_component> _fs_signal_handler {
|
||||
_env.ep(), *this, &Root_component::_handle_fs_signal };
|
||||
|
||||
void _handle_fs_signal() { };
|
||||
|
||||
void _update_config() { _config_rom.update(); }
|
||||
|
||||
Genode::Signal_handler<Root_component> _config_handler
|
||||
{ _env.ep(), *this, &Root_component::_update_config };
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args) override
|
||||
{
|
||||
using namespace File_system;
|
||||
|
||||
size_t ram_quota =
|
||||
Arg_string::find_arg(args, "ram_quota").aligned_size();
|
||||
if (ram_quota < sizeof(Session_component))
|
||||
throw Insufficient_ram_quota();
|
||||
|
||||
Path dir_path;
|
||||
char file_name[MAX_NAME_LEN];
|
||||
|
||||
Session_label const session_label = label_from_args(args);
|
||||
char const *label_str = session_label.string();
|
||||
char const *label_prefix = "";
|
||||
bool truncate = false;
|
||||
|
||||
try {
|
||||
Session_policy policy(session_label, _config_rom.xml());
|
||||
truncate = policy.attribute_value("truncate", truncate);
|
||||
bool merge = policy.attribute_value("merge", false);
|
||||
|
||||
/* only a match on 'label_prefix' can be merged */
|
||||
if (merge && policy.has_type("policy")
|
||||
&& (!(policy.has_attribute("label")
|
||||
|| policy.has_attribute("label_suffix"))))
|
||||
{
|
||||
/*
|
||||
* split the label between what will be the log file
|
||||
* and what will be prepended to messages in the file
|
||||
*/
|
||||
size_t offset = policy.attribute("label_prefix").value_size();
|
||||
for (size_t i = offset; i < session_label.length()-4; ++i) {
|
||||
if (strcmp(label_str+i, " -> ", 4))
|
||||
continue;
|
||||
|
||||
label_prefix = label_str+i+4;
|
||||
{
|
||||
char tmp[128];
|
||||
copy_cstring(tmp, label_str, min(sizeof(tmp), i+1));
|
||||
dir_path = path_from_label<Path>(tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (dir_path == "/")
|
||||
dir_path = path_from_label<Path>(label_str);
|
||||
|
||||
} else if (!policy.has_type("default-policy")) {
|
||||
dir_path = path_from_label<Path>(label_str);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Session_policy::No_policy_defined) {
|
||||
dir_path = path_from_label<Path>(label_str); }
|
||||
|
||||
if (dir_path == "/") {
|
||||
copy_cstring(file_name, "log", sizeof(file_name));
|
||||
label_prefix = label_str;
|
||||
} else {
|
||||
dir_path.append(".log");
|
||||
copy_cstring(file_name, dir_path.last_element(), sizeof(file_name));
|
||||
dir_path.strip_last_element();
|
||||
dir_path.remove_trailing('/');
|
||||
}
|
||||
|
||||
char const *errstr;
|
||||
try {
|
||||
|
||||
Dir_handle dir_handle = ensure_dir(_fs, dir_path.base());
|
||||
Handle_guard dir_guard(_fs, dir_handle);
|
||||
|
||||
Genode::Constructible<File_handle> handle;
|
||||
try {
|
||||
handle.construct(_fs.file(dir_handle, file_name,
|
||||
File_system::WRITE_ONLY, false));
|
||||
|
||||
/* don't truncate at every new child session */
|
||||
if (truncate && (strcmp(label_prefix, "") == 0))
|
||||
_fs.truncate(*handle, 0);
|
||||
}
|
||||
catch (File_system::Lookup_failed) {
|
||||
handle.construct(_fs.file(dir_handle, file_name,
|
||||
File_system::WRITE_ONLY, true));
|
||||
}
|
||||
|
||||
return new (md_alloc())
|
||||
Session_component(_env.ep(), _fs, *handle, label_prefix);
|
||||
}
|
||||
catch (Permission_denied) {
|
||||
errstr = "permission denied"; }
|
||||
catch (No_space) {
|
||||
errstr = "file system out of space"; }
|
||||
catch (Out_of_ram) {
|
||||
errstr = "file system server out of RAM"; }
|
||||
catch (Out_of_caps) {
|
||||
errstr = "file system server out of caps"; }
|
||||
catch (Invalid_name) {
|
||||
errstr = "invalid path"; }
|
||||
catch (Name_too_long) {
|
||||
errstr = "name too long"; }
|
||||
catch (...) {
|
||||
errstr = "unhandled error"; }
|
||||
|
||||
Genode::error("cannot open log file ",
|
||||
(char const *)dir_path.base(),
|
||||
", ", errstr);
|
||||
throw Service_denied();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Root_component(Genode::Env &env, Genode::Allocator &md_alloc)
|
||||
:
|
||||
Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
|
||||
_env(env)
|
||||
{
|
||||
_fs.sigh(_fs_signal_handler);
|
||||
_config_rom.sigh(_config_handler);
|
||||
|
||||
/* fill the ack queue with packets so sessions never need to alloc */
|
||||
File_system::Session::Tx::Source &source = *_fs.tx();
|
||||
for (int i = 0; i < QUEUE_SIZE-1; ++i)
|
||||
source.submit_packet(source.alloc_packet(PACKET_SIZE));
|
||||
|
||||
env.parent().announce(env.ep().manage(*this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Genode::Sliced_heap sliced_heap { env.ram(), env.rm() };
|
||||
static Fs_log::Root_component root { env, sliced_heap };
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* \brief Log session that writes messages to a file system.
|
||||
* \author Emery Hemingway
|
||||
* \date 2015-05-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-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 _FS_LOG__SESSION_H_
|
||||
#define _FS_LOG__SESSION_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <log_session/log_session.h>
|
||||
#include <file_system_session/file_system_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <base/log.h>
|
||||
|
||||
namespace Fs_log {
|
||||
|
||||
enum { MAX_LABEL_LEN = 128 };
|
||||
|
||||
class Session_component;
|
||||
}
|
||||
|
||||
class Fs_log::Session_component : public Genode::Rpc_object<Genode::Log_session>
|
||||
{
|
||||
private:
|
||||
|
||||
char _label_buf[MAX_LABEL_LEN];
|
||||
Genode::size_t const _label_len;
|
||||
|
||||
Genode::Entrypoint &_ep;
|
||||
File_system::Session &_fs;
|
||||
File_system::File_handle const _handle;
|
||||
|
||||
void _block_for_ack()
|
||||
{
|
||||
while (!_fs.tx()->ack_avail())
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Genode::Entrypoint &ep,
|
||||
File_system::Session &fs,
|
||||
File_system::File_handle handle,
|
||||
char const *label)
|
||||
:
|
||||
_label_len(Genode::strlen(label) ? Genode::strlen(label)+3 : 0),
|
||||
_ep(ep), _fs(fs), _handle(handle)
|
||||
{
|
||||
if (_label_len)
|
||||
Genode::snprintf(_label_buf, MAX_LABEL_LEN, "[%s] ", label);
|
||||
}
|
||||
|
||||
~Session_component()
|
||||
{
|
||||
/* sync */
|
||||
|
||||
File_system::Session::Tx::Source &source = *_fs.tx();
|
||||
|
||||
_block_for_ack();
|
||||
|
||||
File_system::Packet_descriptor packet = source.get_acked_packet();
|
||||
|
||||
if (packet.operation() == File_system::Packet_descriptor::SYNC)
|
||||
_fs.close(packet.handle());
|
||||
|
||||
source.submit_packet(packet);
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Log session **
|
||||
*****************/
|
||||
|
||||
void write(Log_session::String const &msg) override
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (!msg.valid_string()) {
|
||||
Genode::error("received corrupted string");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t msg_len = strlen(msg.string());
|
||||
|
||||
File_system::Session::Tx::Source &source = *_fs.tx();
|
||||
|
||||
_block_for_ack();
|
||||
|
||||
File_system::Packet_descriptor packet = source.get_acked_packet();
|
||||
|
||||
if (packet.operation() == File_system::Packet_descriptor::SYNC)
|
||||
_fs.close(packet.handle());
|
||||
|
||||
packet = File_system::Packet_descriptor(
|
||||
packet, _handle, File_system::Packet_descriptor::WRITE,
|
||||
msg_len, File_system::SEEK_TAIL);
|
||||
|
||||
char *buf = source.packet_content(packet);
|
||||
|
||||
if (_label_len) {
|
||||
memcpy(buf, _label_buf, _label_len);
|
||||
|
||||
if (_label_len+msg_len > Log_session::String::MAX_SIZE) {
|
||||
packet.length(msg_len);
|
||||
source.submit_packet(packet);
|
||||
|
||||
_block_for_ack();
|
||||
|
||||
packet = File_system::Packet_descriptor(
|
||||
source.get_acked_packet(),
|
||||
_handle, File_system::Packet_descriptor::WRITE,
|
||||
msg_len, File_system::SEEK_TAIL);
|
||||
|
||||
buf = source.packet_content(packet);
|
||||
|
||||
} else {
|
||||
buf += _label_len;
|
||||
packet.length(_label_len+msg_len);
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buf, msg.string(), msg_len);
|
||||
|
||||
source.submit_packet(packet);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
TARGET = fs_log
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
Reference in New Issue
Block a user