mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 23:42:32 +00:00
Infrastructure for posting status reports
This commit introduces the "Report" session interface and a simple service to forward reports to the LOG service. Fixes #1026
This commit is contained in:
parent
f32a97da38
commit
2a576da2b0
94
os/include/os/reporter.h
Normal file
94
os/include/os/reporter.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* \brief Utility for status reporting
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2014-01-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 _INCLUDE__OS__REPORTER_H_
|
||||||
|
#define _INCLUDE__OS__REPORTER_H_
|
||||||
|
|
||||||
|
#include <util/volatile_object.h>
|
||||||
|
#include <os/attached_dataspace.h>
|
||||||
|
#include <report_session/connection.h>
|
||||||
|
#include <util/xml_generator.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Genode { class Reporter; }
|
||||||
|
|
||||||
|
|
||||||
|
class Genode::Reporter : Noncopyable
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
String<100> const _name;
|
||||||
|
|
||||||
|
bool _enabled = false;
|
||||||
|
|
||||||
|
struct Connection
|
||||||
|
{
|
||||||
|
Report::Connection report;
|
||||||
|
Attached_dataspace ds = { report.dataspace() };
|
||||||
|
|
||||||
|
Connection(char const *name) : report(name) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
Lazy_volatile_object<Connection> _conn;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Reporter(char const *report_name) : _name(report_name) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable reporting
|
||||||
|
*/
|
||||||
|
void enabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled == _enabled) return;
|
||||||
|
|
||||||
|
_enabled = enabled;
|
||||||
|
|
||||||
|
if (_enabled)
|
||||||
|
_conn.construct(_name.string());
|
||||||
|
else
|
||||||
|
_conn.destruct();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_enabled() const { return _enabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return size of report buffer
|
||||||
|
*/
|
||||||
|
size_t size() const { return _enabled ? _conn->ds.size() : 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return pointer to report buffer
|
||||||
|
*/
|
||||||
|
char *base() { return _enabled ? _conn->ds.local_addr<char>() : 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML generator targeting a reporter
|
||||||
|
*/
|
||||||
|
struct Xml_generator : public Genode::Xml_generator
|
||||||
|
{
|
||||||
|
template <typename FUNC>
|
||||||
|
Xml_generator(Reporter &reporter, FUNC const &func)
|
||||||
|
:
|
||||||
|
Genode::Xml_generator(reporter.base(),
|
||||||
|
reporter.size(),
|
||||||
|
reporter._name.string(),
|
||||||
|
func)
|
||||||
|
{
|
||||||
|
reporter._conn->report.submit(used());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__OS__REPORTER_H_ */
|
42
os/include/report_session/client.h
Normal file
42
os/include/report_session/client.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* \brief Client-side Report session interface
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2014-01-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 _INCLUDE__REPORT_SESSION__CLIENT_H_
|
||||||
|
#define _INCLUDE__REPORT_SESSION__CLIENT_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/rpc_client.h>
|
||||||
|
#include <report_session/report_session.h>
|
||||||
|
|
||||||
|
namespace Report { struct Session_client; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Report::Session_client : Genode::Rpc_client<Session>
|
||||||
|
{
|
||||||
|
Session_client(Genode::Capability<Session> cap)
|
||||||
|
: Genode::Rpc_client<Session>(cap) { }
|
||||||
|
|
||||||
|
Dataspace_capability dataspace() override {
|
||||||
|
return call<Rpc_dataspace>(); }
|
||||||
|
|
||||||
|
void submit(size_t length) override {
|
||||||
|
call<Rpc_submit>(length); }
|
||||||
|
|
||||||
|
void response_sigh(Signal_context_capability cap) override {
|
||||||
|
call<Rpc_response_sigh>(cap); }
|
||||||
|
|
||||||
|
size_t obtain_response() override {
|
||||||
|
return call<Rpc_obtain_response>(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__REPORT_SESSION__CLIENT_H_ */
|
34
os/include/report_session/connection.h
Normal file
34
os/include/report_session/connection.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* \brief Connection to Report service
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2014-01-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 _INCLUDE__REPORT_SESSION__CONNECTION_H_
|
||||||
|
#define _INCLUDE__REPORT_SESSION__CONNECTION_H_
|
||||||
|
|
||||||
|
#include <report_session/client.h>
|
||||||
|
#include <base/connection.h>
|
||||||
|
|
||||||
|
namespace Report { struct Connection; }
|
||||||
|
|
||||||
|
|
||||||
|
struct Report::Connection : Genode::Connection<Session>, Session_client
|
||||||
|
{
|
||||||
|
Connection(char const *label, size_t buffer_size = 4096)
|
||||||
|
:
|
||||||
|
Genode::Connection<Session>(
|
||||||
|
session("label=\"%s\", ram_quota=%zd, buffer_size=%zd",
|
||||||
|
label, 2*4096 + buffer_size, buffer_size)),
|
||||||
|
Session_client(cap())
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__REPORT_SESSION__CONNECTION_H_ */
|
97
os/include/report_session/report_session.h
Normal file
97
os/include/report_session/report_session.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* \brief Report session interface
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2014-01-10
|
||||||
|
*
|
||||||
|
* A report session allows a client to report status information about itself
|
||||||
|
* to the outer world, in particular to its parent process.
|
||||||
|
*
|
||||||
|
* The communication between client and server is based on the combination
|
||||||
|
* of shared memory with synchronous RPC. A dataspace shared between both
|
||||||
|
* processes is used to carry the data. RPC calls are used to synchronize the
|
||||||
|
* access to the buffer. When the client performs an RPC, it hands over the
|
||||||
|
* responsibility to access the buffer to the server. While an RPC is in
|
||||||
|
* progress and the client blocks for the reply, the server may read and write
|
||||||
|
* the buffer. At all other times, the server is not expected to access the
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* This hand over of the buffer between both parties is a mere convention. It
|
||||||
|
* is not enforced by the system. For this reason, neither of both proceess
|
||||||
|
* must keep its internal state stored in the buffer. Data should always be
|
||||||
|
* copied in/out and never processed directly in the buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 _INCLUDE__REPORT_SESSION__REPORT_SESSION_H_
|
||||||
|
#define _INCLUDE__REPORT_SESSION__REPORT_SESSION_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <session/session.h>
|
||||||
|
#include <base/rpc.h>
|
||||||
|
#include <base/signal.h>
|
||||||
|
#include <dataspace/capability.h>
|
||||||
|
|
||||||
|
namespace Report {
|
||||||
|
|
||||||
|
using Genode::Dataspace_capability;
|
||||||
|
using Genode::Signal_context_capability;
|
||||||
|
using Genode::size_t;
|
||||||
|
|
||||||
|
struct Session;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Report::Session : Genode::Session
|
||||||
|
{
|
||||||
|
static const char *service_name() { return "Report"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the dataspace used to carry reports and responses
|
||||||
|
*/
|
||||||
|
virtual Dataspace_capability dataspace() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit data that is currently contained in the dataspace as report
|
||||||
|
*
|
||||||
|
* \param length length of report in bytes
|
||||||
|
*
|
||||||
|
* While this function is called, the information in the dataspace
|
||||||
|
* must not be modified by the client.
|
||||||
|
*/
|
||||||
|
virtual void submit(size_t length) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install signal handler for response notifications
|
||||||
|
*/
|
||||||
|
virtual void response_sigh(Signal_context_capability) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a response from the recipient of reports
|
||||||
|
*
|
||||||
|
* By calling this function, the client expects that the server will
|
||||||
|
* replace the content of the dataspace with new information.
|
||||||
|
*
|
||||||
|
* \return length of response in bytes
|
||||||
|
*/
|
||||||
|
virtual size_t obtain_response() = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
** RPC interface **
|
||||||
|
*******************/
|
||||||
|
|
||||||
|
GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
|
||||||
|
GENODE_RPC(Rpc_submit, void, submit, size_t);
|
||||||
|
GENODE_RPC(Rpc_response_sigh, void, response_sigh, Signal_context_capability);
|
||||||
|
GENODE_RPC(Rpc_obtain_response, size_t, obtain_response);
|
||||||
|
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_submit, Rpc_response_sigh,
|
||||||
|
Rpc_obtain_response);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _INCLUDE__REPORT_SESSION__REPORT_SESSION_H_ */
|
128
os/src/server/log_report/main.cc
Normal file
128
os/src/server/log_report/main.cc
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* \brief Report server that dumps reports to the LOG
|
||||||
|
* \author Norman Feske
|
||||||
|
* \date 2014-01-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <report_session/report_session.h>
|
||||||
|
#include <util/arg_string.h>
|
||||||
|
#include <base/heap.h>
|
||||||
|
#include <base/env.h>
|
||||||
|
#include <root/component.h>
|
||||||
|
#include <os/server.h>
|
||||||
|
#include <os/attached_ram_dataspace.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Report {
|
||||||
|
using Server::Entrypoint;
|
||||||
|
using Genode::env;
|
||||||
|
|
||||||
|
class Session_component;
|
||||||
|
class Root;
|
||||||
|
struct Main;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Report::Session_component : public Genode::Rpc_object<Session>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Genode::String<200> Label;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Label _label;
|
||||||
|
|
||||||
|
Genode::Attached_ram_dataspace _ds;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Session_component(Label const &label, size_t buffer_size)
|
||||||
|
:
|
||||||
|
_label(label), _ds(env()->ram_session(), buffer_size)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Dataspace_capability dataspace() override { return _ds.cap(); }
|
||||||
|
|
||||||
|
void submit(size_t const length) override
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
printf("\nreport: %s\n", _label.string());
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
for (size_t consumed = 0; consumed < length; consumed += strlen(buf)) {
|
||||||
|
strncpy(buf, _ds.local_addr<char>() + consumed, sizeof(buf));
|
||||||
|
printf("%s", buf);
|
||||||
|
}
|
||||||
|
printf("\nend of report\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void response_sigh(Genode::Signal_context_capability) override { }
|
||||||
|
|
||||||
|
size_t obtain_response() override { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Report::Root : public Genode::Root_component<Session_component>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Session_component *_create_session(const char *args) override
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
/* read label from session arguments */
|
||||||
|
char label[200];
|
||||||
|
Arg_string::find_arg(args, "label").string(label, sizeof(label), "");
|
||||||
|
|
||||||
|
/* read report buffer size from session arguments */
|
||||||
|
size_t const buffer_size =
|
||||||
|
Arg_string::find_arg(args, "buffer_size").long_value(0);
|
||||||
|
|
||||||
|
return new (md_alloc())
|
||||||
|
Session_component(Session_component::Label(label), buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Root(Entrypoint &ep, Genode::Allocator &md_alloc)
|
||||||
|
:
|
||||||
|
Genode::Root_component<Session_component>(&ep.rpc_ep(), &md_alloc)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Report::Main
|
||||||
|
{
|
||||||
|
Entrypoint &ep;
|
||||||
|
|
||||||
|
Genode::Sliced_heap sliced_heap = { env()->ram_session(),
|
||||||
|
env()->rm_session() };
|
||||||
|
Root root = { ep, sliced_heap };
|
||||||
|
|
||||||
|
Main(Entrypoint &ep) : ep(ep)
|
||||||
|
{
|
||||||
|
env()->parent()->announce(ep.manage(root));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Server {
|
||||||
|
|
||||||
|
char const *name() { return "log_report_ep"; }
|
||||||
|
|
||||||
|
size_t stack_size() { return 4*1024*sizeof(long); }
|
||||||
|
|
||||||
|
void construct(Entrypoint &ep)
|
||||||
|
{
|
||||||
|
static Report::Main main(ep);
|
||||||
|
}
|
||||||
|
}
|
3
os/src/server/log_report/target.mk
Normal file
3
os/src/server/log_report/target.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TARGET = log_report
|
||||||
|
SRC_CC = main.cc
|
||||||
|
LIBS = base server
|
Loading…
Reference in New Issue
Block a user