From f7b26886114d2c05230c1cccae4ccb25ec2a4b90 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Thu, 3 Dec 2020 12:22:38 +0100 Subject: [PATCH] packages/vfs: patch to fix session directory creation --- packages/genodelabs/depot-targets.nix | 5 +- packages/genodelabs/patches/vfs.patch | 78 +++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 packages/genodelabs/patches/vfs.patch diff --git a/packages/genodelabs/depot-targets.nix b/packages/genodelabs/depot-targets.nix index 6a02bcd..82ffefa 100644 --- a/packages/genodelabs/depot-targets.nix +++ b/packages/genodelabs/depot-targets.nix @@ -280,7 +280,10 @@ in { vbox5-nova = vbox5'; verify = { }; vesa_drv.portInputs = with ports; [ libc x86emu ]; - vfs.outputs = [ "out" "lib" ]; + vfs = { + outputs = [ "out" "lib" ]; + patches = [ ./patches/vfs.patch ]; + }; vfs_audit = { }; vfs_block = { }; vfs_fatfs = { }; diff --git a/packages/genodelabs/patches/vfs.patch b/packages/genodelabs/patches/vfs.patch new file mode 100644 index 0000000..4a161ae --- /dev/null +++ b/packages/genodelabs/patches/vfs.patch @@ -0,0 +1,78 @@ +From a3063497d9aaf6bf06a3797804135105ad5f3bad Mon Sep 17 00:00:00 2001 +From: Emery Hemingway +Date: Thu, 3 Dec 2020 12:19:10 +0100 +Subject: [PATCH] vfs: create missing root directories for writeable sessions + +This is the expected behavior. +--- + repos/os/src/server/vfs/main.cc | 47 ++++++++++++++++++++++++++++++--- + 1 file changed, 43 insertions(+), 4 deletions(-) + +diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc +index b780b1fdd7..358afd28a9 100644 +--- a/repos/os/src/server/vfs/main.cc ++++ b/repos/os/src/server/vfs/main.cc +@@ -841,6 +841,41 @@ class Vfs_server::Root : public Genode::Root_component, + Genode::Signal_transmitter(_reactivate_handler).submit(); + } + ++ /** ++ * Open a directory, ensuring all parent directories exists. ++ */ ++ void _create_session_dir(Path const &path) ++ { ++ using namespace Genode; ++ typedef Vfs::Directory_service::Opendir_result Result; ++ ++ Vfs_handle *handle { nullptr }; ++ Vfs::File_system &vfs = _vfs_env.root_dir(); ++ ++ switch (vfs.opendir(path.string(), true, &handle, _vfs_heap)) { ++ case Result::OPENDIR_OK: ++ handle->close(); ++ return; ++ case Result::OPENDIR_ERR_NODE_ALREADY_EXISTS: ++ if (vfs.directory(path.string())) return; ++ break; ++ case Result::OPENDIR_ERR_LOOKUP_FAILED: { ++ Path parent = path; ++ parent.strip_last_element(); ++ _create_session_dir(parent.string()); ++ auto res = vfs.opendir(path.string(), true, &handle, _vfs_heap); ++ if (res == Result::OPENDIR_OK) { ++ handle->close(); ++ return; ++ } ++ } ++ default: break; ++ } ++ ++ error("cannot create session root at ", path); ++ throw Service_denied(); ++ } ++ + protected: + + Session_component *_create_session(const char *args) override +@@ -916,10 +951,14 @@ class Vfs_server::Root : public Genode::Root_component, + } + + /* check if the session root exists */ +- if (!((session_root == "/") +- || _vfs_env.root_dir().directory(session_root.base()))) { +- error("session root '", session_root, "' not found for '", label, "'"); +- throw Service_denied(); ++ if (session_root != "/") { ++ if (!_vfs_env.root_dir().directory(session_root.base())) { ++ if (writeable) { _create_session_dir(session_root); } ++ else { ++ error("session root '", session_root, "' not found for '", label, "'"); ++ throw Service_denied(); ++ } ++ } + } + + Session_component *session = new (md_alloc()) +-- +2.29.2 +