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>
|
</content>
|
||||||
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
||||||
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
||||||
|
<policy label_prefix="test-fs_report -> " root="/test-fs_report" writeable="yes"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
<!--
|
<!--
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
</start>
|
</start>
|
||||||
<start name="test-fs_report">
|
<start name="test-fs_report">
|
||||||
<resource name="RAM" quantum="4M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<config/>
|
<config> <vfs> <fs/> </vfs> </config>
|
||||||
<route>
|
<route>
|
||||||
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
||||||
<service name="ROM" label="focus"> <child name="fs_rom"/> </service>
|
<service name="ROM" label="focus"> <child name="fs_rom"/> </service>
|
||||||
|
|
|
@ -2,3 +2,4 @@ base
|
||||||
os
|
os
|
||||||
report_session
|
report_session
|
||||||
timer_session
|
timer_session
|
||||||
|
vfs
|
||||||
|
|
|
@ -45,6 +45,7 @@ append config {
|
||||||
</content>
|
</content>
|
||||||
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
<policy label_prefix="fs_report -> " root="/" writeable="yes"/>
|
||||||
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
<policy label_prefix="fs_rom -> " root="/test-fs_report"/>
|
||||||
|
<policy label_prefix="test-fs_report -> " root="/test-fs_report" writeable="yes"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
<!--
|
<!--
|
||||||
|
@ -63,7 +64,7 @@ append config {
|
||||||
</start>
|
</start>
|
||||||
<start name="test-fs_report">
|
<start name="test-fs_report">
|
||||||
<resource name="RAM" quantum="4M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<config/>
|
<config> <vfs> <fs/> </vfs> </config>
|
||||||
<route>
|
<route>
|
||||||
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
<service name="ROM" label="devices"> <child name="fs_rom"/> </service>
|
||||||
<service name="ROM" label="focus"> <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; };
|
struct Version { unsigned value; };
|
||||||
Version _curr_version { 0 };
|
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
|
* 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 (Permission_denied) { error(_file_path, ": permission denied"); }
|
||||||
catch (...) { error(_file_path, ": unhandled error"); };
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _notify_client_about_new_version()
|
void _notify_client_about_new_version()
|
||||||
{
|
{
|
||||||
using namespace File_system;
|
if (_sigh.valid() && _curr_version.value != _handed_out_version.value)
|
||||||
|
Signal_transmitter(_sigh).submit();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -364,11 +356,9 @@ class Fs_rom::Rom_session_component : public Rpc_object<Rom_session>
|
||||||
_open_watch_handle();
|
_open_watch_handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_watching_file) {
|
/* notify the client of the change */
|
||||||
/* notify the client of the change */
|
_curr_version = Version { _curr_version.value + 1 };
|
||||||
_curr_version = Version { _curr_version.value + 1 };
|
_notify_client_about_new_version();
|
||||||
_notify_client_about_new_version();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case File_system::Packet_descriptor::READ: {
|
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),
|
Root_component<Rom_session_component>(env.ep(), md_alloc),
|
||||||
_env(env)
|
_env(env)
|
||||||
{
|
{
|
||||||
/* Process CONTENT_CHANGED acknowledgement packets at the entrypoint */
|
|
||||||
_fs.sigh_ack_avail(_packet_handler);
|
_fs.sigh_ack_avail(_packet_handler);
|
||||||
|
|
||||||
env.parent().announce(env.ep().manage(*this));
|
env.parent().announce(env.ep().manage(*this));
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
* under the terms of the GNU Affero General Public License version 3.
|
* 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/log.h>
|
||||||
#include <base/component.h>
|
#include <base/component.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
|
@ -28,8 +30,24 @@ struct Test::Main
|
||||||
{
|
{
|
||||||
Env &_env;
|
Env &_env;
|
||||||
|
|
||||||
|
Genode::Heap _heap { _env.pd(), _env.rm() };
|
||||||
|
|
||||||
Timer::Connection _timer { _env };
|
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> _devices_reporter { };
|
||||||
Constructible<Reporter> _focus_reporter { };
|
Constructible<Reporter> _focus_reporter { };
|
||||||
|
|
||||||
|
@ -50,6 +68,9 @@ struct Test::Main
|
||||||
Signal_handler<Main> _focus_rom_update_handler {
|
Signal_handler<Main> _focus_rom_update_handler {
|
||||||
_env.ep(), *this, &Main::_handle_focus_rom_update };
|
_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 { };
|
Constructible<Timer::One_shot_timeout<Main> > _one_shot_timeout { };
|
||||||
|
|
||||||
void _handle_init()
|
void _handle_init()
|
||||||
|
@ -84,7 +105,7 @@ struct Test::Main
|
||||||
|
|
||||||
_devices_rom->update();
|
_devices_rom->update();
|
||||||
if (_devices_rom->xml().attribute_value("version", Version()) != "version 2") {
|
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();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +132,29 @@ struct Test::Main
|
||||||
_focus_rom->update();
|
_focus_rom->update();
|
||||||
|
|
||||||
if (_focus_rom->xml().attribute_value("version", Version()) != "focus version 1") {
|
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();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
log("(9) received expected focus ROM content");
|
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 */
|
/* test completed successfully */
|
||||||
_env.parent().exit(0);
|
_env.parent().exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
TARGET = test-fs_report
|
TARGET = test-fs_report
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base
|
LIBS = base vfs
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user