mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
Fs_rom: send signals on file removal
Clients may wish to act on missing files. In any case the fs_rom needs to reopen a watch handle when a file is deleted, and this sort of change to the internal state machine is propelled by client RPC requests. Fix #2839
This commit is contained in:
parent
87be50c542
commit
1af6bd1454
@ -39,6 +39,7 @@
|
||||
</content>
|
||||
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
||||
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
||||
<policy label_prefix="test-fs_report -> " root="/test-fs_report" writeable="yes"/>
|
||||
</config>
|
||||
</start>
|
||||
<!--
|
||||
@ -57,7 +58,7 @@
|
||||
</start>
|
||||
<start name="test-fs_report">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<config/>
|
||||
<config> <vfs> <fs/> </vfs> </config>
|
||||
<route>
|
||||
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
||||
<service name="ROM" label="focus"> <child name="fs_rom"/> </service>
|
||||
|
@ -2,3 +2,4 @@ base
|
||||
os
|
||||
report_session
|
||||
timer_session
|
||||
vfs
|
||||
|
@ -45,6 +45,7 @@ append config {
|
||||
</content>
|
||||
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
||||
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
||||
<policy label_prefix="test-fs_report -> " root="/test-fs_report" writeable="yes"/>
|
||||
</config>
|
||||
</start>
|
||||
<!--
|
||||
@ -63,7 +64,7 @@ append config {
|
||||
</start>
|
||||
<start name="test-fs_report">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<config/>
|
||||
<config> <vfs> <fs/> </vfs> </config>
|
||||
<route>
|
||||
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
||||
<service name="ROM" label="focus"> <child name="fs_rom"/> </service>
|
||||
|
@ -100,7 +100,7 @@ class Fs_rom::Rom_session_component : public Rpc_object<Rom_session>
|
||||
*/
|
||||
struct Version { unsigned value; };
|
||||
Version _curr_version { 0 };
|
||||
Version _handed_out_version { ~0U };
|
||||
Version _handed_out_version { 0 };
|
||||
|
||||
/**
|
||||
* Track if the session file or a directory is being watched
|
||||
@ -257,26 +257,18 @@ class Fs_rom::Rom_session_component : public Rpc_object<Rom_session>
|
||||
catch (Permission_denied) { error(_file_path, ": permission denied"); }
|
||||
catch (...) { error(_file_path, ": unhandled error"); };
|
||||
|
||||
if (_file_size > 0) {
|
||||
memset(_file_ds.local_addr<char>(), 0x00, min(_file_size, _file_ds.size()));
|
||||
_file_size = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void _notify_client_about_new_version()
|
||||
{
|
||||
using namespace File_system;
|
||||
|
||||
if (_sigh.valid() && _curr_version.value != _handed_out_version.value) {
|
||||
|
||||
/* notify if the file is not empty */
|
||||
try {
|
||||
Node_handle file = _fs.node(_file_path.base());
|
||||
Handle_guard g(_fs, file);
|
||||
_file_size = _fs.status(file).size;
|
||||
}
|
||||
catch (...) { _file_size = 0; }
|
||||
|
||||
if (_file_size > 0)
|
||||
Signal_transmitter(_sigh).submit();
|
||||
}
|
||||
if (_sigh.valid() && _curr_version.value != _handed_out_version.value)
|
||||
Signal_transmitter(_sigh).submit();
|
||||
}
|
||||
|
||||
public:
|
||||
@ -364,11 +356,9 @@ class Fs_rom::Rom_session_component : public Rpc_object<Rom_session>
|
||||
_open_watch_handle();
|
||||
}
|
||||
|
||||
if (_watching_file) {
|
||||
/* notify the client of the change */
|
||||
_curr_version = Version { _curr_version.value + 1 };
|
||||
_notify_client_about_new_version();
|
||||
}
|
||||
/* notify the client of the change */
|
||||
_curr_version = Version { _curr_version.value + 1 };
|
||||
_notify_client_about_new_version();
|
||||
return;
|
||||
|
||||
case File_system::Packet_descriptor::READ: {
|
||||
@ -466,7 +456,6 @@ class Fs_rom::Rom_root : public Root_component<Fs_rom::Rom_session_component>
|
||||
Root_component<Rom_session_component>(env.ep(), md_alloc),
|
||||
_env(env)
|
||||
{
|
||||
/* Process CONTENT_CHANGED acknowledgement packets at the entrypoint */
|
||||
_fs.sigh_ack_avail(_packet_handler);
|
||||
|
||||
env.parent().announce(env.ep().manage(*this));
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <vfs/simple_env.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
@ -28,8 +30,24 @@ struct Test::Main
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Genode::Heap _heap { _env.pd(), _env.rm() };
|
||||
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
Genode::Attached_rom_dataspace _config_rom { _env, "config" };
|
||||
|
||||
Genode::Xml_node vfs_config()
|
||||
{
|
||||
try { return _config_rom.xml().sub_node("vfs"); }
|
||||
catch (...) {
|
||||
Genode::error("VFS not configured");
|
||||
_env.parent().exit(~0);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Vfs::Simple_env _vfs_env { _env, _heap, vfs_config() };
|
||||
|
||||
Constructible<Reporter> _devices_reporter { };
|
||||
Constructible<Reporter> _focus_reporter { };
|
||||
|
||||
@ -50,6 +68,9 @@ struct Test::Main
|
||||
Signal_handler<Main> _focus_rom_update_handler {
|
||||
_env.ep(), *this, &Main::_handle_focus_rom_update };
|
||||
|
||||
Signal_handler<Main> _focus_removal_handler {
|
||||
_env.ep(), *this, &Main::_handle_focus_removal };
|
||||
|
||||
Constructible<Timer::One_shot_timeout<Main> > _one_shot_timeout { };
|
||||
|
||||
void _handle_init()
|
||||
@ -84,7 +105,7 @@ struct Test::Main
|
||||
|
||||
_devices_rom->update();
|
||||
if (_devices_rom->xml().attribute_value("version", Version()) != "version 2") {
|
||||
error("unexpected content of \"devices\" ROM after update");
|
||||
error("(6) unexpected content of \"devices\" ROM after update");
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
@ -111,12 +132,29 @@ struct Test::Main
|
||||
_focus_rom->update();
|
||||
|
||||
if (_focus_rom->xml().attribute_value("version", Version()) != "focus version 1") {
|
||||
error("unexpected content of \"focus\" ROM");
|
||||
error("(9) unexpected content of \"focus\" ROM");
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
log("(9) received expected focus ROM content");
|
||||
|
||||
_focus_rom->sigh(_focus_removal_handler);
|
||||
|
||||
log("(10) remove focus file");
|
||||
_vfs_env.root_dir().unlink("focus");
|
||||
}
|
||||
|
||||
void _handle_focus_removal()
|
||||
{
|
||||
_focus_rom->update();
|
||||
|
||||
if (!_focus_rom->xml().has_type("empty")) {
|
||||
error("(11) unexpected content of \"focus\" ROM");
|
||||
throw Exception();
|
||||
}
|
||||
|
||||
log("(11) received empty focus ROM");
|
||||
|
||||
/* test completed successfully */
|
||||
_env.parent().exit(0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
TARGET = test-fs_report
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base vfs
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user