diff --git a/repos/os/run/fs_log.run b/repos/os/run/fs_log.run new file mode 100644 index 000000000..1005be537 --- /dev/null +++ b/repos/os/run/fs_log.run @@ -0,0 +1,72 @@ +# +# Test logging to file system +# + +build { + core init drivers/timer + server/vfs server/fs_log + test/bomb +} + +set timeout 240 +set rounds 20 + +set config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +create_boot_directory + +install_config $config + +build_boot_image "core init ld.lib.so bomb timer vfs fs_log" + +append qemu_args " -nographic" + +run_genode_until "Done\. Going to sleep\." $timeout diff --git a/repos/os/src/server/fs_log/README b/repos/os/src/server/fs_log/README index 89aeac642..e6be366be 100644 --- a/repos/os/src/server/fs_log/README +++ b/repos/os/src/server/fs_log/README @@ -15,8 +15,8 @@ trailing "->", the log filename takes the name of the next label element. ! ! ! -! -! +! +! ! ! diff --git a/repos/os/src/server/fs_log/main.cc b/repos/os/src/server/fs_log/main.cc index ff61237f8..46755f043 100644 --- a/repos/os/src/server/fs_log/main.cc +++ b/repos/os/src/server/fs_log/main.cc @@ -12,6 +12,7 @@ */ /* Genode includes */ +#include #include #include #include @@ -37,6 +38,8 @@ namespace Fs_log { TX_BUF_SIZE = BLOCK_SIZE * (QUEUE_SIZE*2 + 1) }; + typedef Genode::Path Path; + } class Fs_log::Root_component : @@ -71,61 +74,38 @@ class Fs_log::Root_component : bool truncate = false; Session_label session_label(args); char const *label_str = session_label.string(); - char const *label_prefix = nullptr; + char const *label_prefix = ""; + + strncpy(dir_path+1, label_str, MAX_PATH_LEN-1); try { Session_policy policy(session_label); - try { - truncate = policy.attribute("truncate").has_value("yes"); - } catch (Xml_node::Nonexistent_attribute) { } + truncate = policy.attribute_value("truncate", truncate); + + if (policy.attribute_value("merge", false) + && policy.has_attribute("label_prefix")) { - bool merge = false; - try { - merge = policy.attribute("merge").has_value("yes"); - } catch (Xml_node::Nonexistent_attribute) { } - if (merge) { - /* - * Use the policy label that was matched rather than - * full session label for the path of the log file. - */ - policy.attribute("label").value(dir_path+1, sizeof(dir_path)-1); if (!dir_path[1]) { PERR("cannot merge an empty policy label"); throw Root::Unavailable(); } /* - * If the policy has a trailing '->', move first element - * from the log prefix to the end of the log path. + * split the label between what will be the log file + * and what will be prepended to messages in the file */ - size_t label_len = strlen(dir_path); - label_prefix = label_str+(label_len-1); + size_t offset = policy.attribute("label_prefix").value_size(); + for (size_t i = offset; i < session_label.length()-4; ++i) { + if (strcmp(label_str+i, " -> ", 4)) + continue; - if ((strcmp((dir_path+label_len)-3, " ->", 4) == 0) || - (strcmp((dir_path+label_len)-4, " -> ", 5) == 0)) { - - for (size_t i = 0;; ++i) { - if (label_prefix[i] == '\0') { - strncpy(dir_path+1, label_str, MAX_PATH_LEN-1); - label_prefix = nullptr; - break; - } - - if (strcmp(label_prefix+i, " -> ", 4)) - continue; - - strncpy(dir_path+label_len, label_prefix, i+1); - label_prefix += i+4; - break; - } + dir_path[i+1] = '\0'; + label_prefix = label_str+i+4; + break; } + } + } catch (Session_policy::No_policy_defined) { } - } else - strncpy(dir_path+1, label_str, MAX_PATH_LEN-1); - - } catch (Session_policy::No_policy_defined) { - strncpy(dir_path+1, label_str, MAX_PATH_LEN-1); - } { /* Parse out a directory and file name. */ @@ -171,6 +151,7 @@ class Fs_log::Root_component : offset = _fs.status(handle).size; } catch (File_system::Lookup_failed) { + PDBG("create"); handle = _fs.file(dir_handle, file_name, File_system::WRITE_ONLY, true); } @@ -181,33 +162,29 @@ class Fs_log::Root_component : _log_files.insert(file); } catch (Permission_denied) { - PERR("%s:%s: permission denied", dir_path, file_name); - - } catch (Name_too_long) { - PERR("%s:%s: name too long", dir_path, file_name); + PERR("%s: permission denied", Path(file_name, dir_path).base()); } catch (No_space) { - PERR("%s:%s: no space", dir_path, file_name); + PERR("file system out of space"); } catch (Out_of_node_handles) { - PERR("%s:%s: out of node handles", dir_path, file_name); + PERR("too many open file handles"); } catch (Invalid_name) { - PERR("%s:%s: invalid_name", dir_path, file_name); + PERR("%s: invalid path", Path(file_name, dir_path).base()); - } catch (Size_limit_reached) { - PERR("%s:%s: size limit reached", dir_path, file_name); + } catch (Name_too_long) { + PERR("%s: name too long", Path(file_name, dir_path).base()); } catch (...) { - PERR("%s:%s: unknown error", dir_path, file_name); + PERR("cannot open log file %s", Path(file_name, dir_path).base()); throw; } - if (!file) { - PERR("file was null"); - throw Root::Unavailable(); - } - if (label_prefix && *label_prefix) + if (!file) + throw Root::Unavailable(); + + if (*label_prefix) return new (md_alloc()) Labeled_session_component(label_prefix, *file); return new (md_alloc()) Unlabeled_session_component(*file); }