genode/repos/os/include/report_rom/report_service.h
Norman Feske 4d442bca30 Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.

Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.

This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-31 13:16:07 +02:00

155 lines
3.7 KiB
C++

/*
* \brief Server that aggregates reports and exposes them as ROM modules
* \author Norman Feske
* \date 2014-01-11
*/
/*
* 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 _INCLUDE__REPORT_ROM__REPORT_SERVICE_H_
#define _INCLUDE__REPORT_ROM__REPORT_SERVICE_H_
/* Genode includes */
#include <util/arg_string.h>
#include <report_session/report_session.h>
#include <root/component.h>
#include <util/print_lines.h>
#include <report_rom/rom_registry.h>
#include <base/log.h>
namespace Report {
struct Session_component;
struct Root;
}
struct Report::Session_component : Genode::Rpc_object<Session>, Rom::Writer
{
private:
Rom::Registry_for_writer &_registry;
Genode::Session_label const _label;
Genode::Attached_ram_dataspace _ds;
Rom::Module &_module;
bool &_verbose;
Rom::Module &_create_module(Rom::Module::Name const &name)
{
try { return _registry.lookup(*this, name); }
catch (...) { throw Genode::Service_denied(); }
}
static void _log_lines(char const *string, size_t len)
{
Genode::print_lines<200>(string, len,
[&] (char const *line)
{ Genode::log(" ", line); });
}
public:
Session_component(Genode::Env &env,
Genode::Session_label const &label, size_t buffer_size,
Rom::Registry_for_writer &registry, bool &verbose)
:
_registry(registry), _label(label),
_ds(env.ram(), env.rm(), buffer_size),
_module(_create_module(label.string())),
_verbose(verbose)
{ }
~Session_component()
{
_registry.release(*this, _module);
}
/**
* Rom::Writer interface
*/
Genode::Session_label label() const override { return _label; }
Dataspace_capability dataspace() override { return _ds.cap(); }
void submit(size_t length) override
{
length = Genode::min(length, _ds.size());
if (_verbose) {
Genode::log("report '", _module.name(), "'");
_log_lines(_ds.local_addr<char>(), length);
}
_module.write_content(*this, _ds.local_addr<char>(), length);
}
void response_sigh(Genode::Signal_context_capability) override { }
size_t obtain_response() override { return 0; }
};
struct Report::Root : Genode::Root_component<Session_component>
{
private:
Genode::Env &_env;
Rom::Registry_for_writer &_rom_registry;
bool &_verbose;
protected:
Session_component *_create_session(const char *args) override
{
using namespace Genode;
Session_label const label = label_from_args(args);
size_t const ram_quota =
Arg_string::find_arg(args, "ram_quota").aligned_size();
/* read report buffer size from session arguments */
size_t const buffer_size =
Arg_string::find_arg(args, "buffer_size").aligned_size();
size_t const session_size =
max(sizeof(Session_component), 4096U) + buffer_size;
if (ram_quota < session_size) {
Genode::error("insufficient ram donation from ", label.string());
throw Insufficient_ram_quota();
}
if (buffer_size == 0) {
Genode::error("zero-length report requested by ", label.string());
throw Service_denied();
}
return new (md_alloc())
Session_component(_env, label, buffer_size,
_rom_registry, _verbose);
}
public:
Root(Genode::Env &env,
Genode::Allocator &md_alloc,
Rom::Registry_for_writer &rom_registry,
bool &verbose)
:
Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
_env(env), _rom_registry(rom_registry), _verbose(verbose)
{ }
};
#endif /* _INCLUDE__REPORT_ROM__REPORT_SERVICE_H_ */