Make mounts a node with a passive translator record so that the mtab translator is started on access if it is available.
* rootdir.c (MTAB_TRANSLATOR): New macro. (rootdir_mounts_get_translator): New function. (mtab_translator_state): New enum. (rootdir_mounts_exists): New function. (rootdir_translator_make_node): Likewise. (rootdir_entries): Add "mounts" node. --- rootdir.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/rootdir.c b/rootdir.c index 31e2d8c..c8ff01d 100644 --- a/rootdir.c +++ b/rootdir.c @@ -404,6 +404,37 @@ rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len) return 0; } +/* The mtab translator to use by default for the "mounts" node. */ +#define MTAB_TRANSLATOR "/hurd/mtab" + +static error_t +rootdir_mounts_get_translator (void *hook, char **argz, size_t *argz_len) +{ + static char mtab_argz[] = MTAB_TRANSLATOR "\0/"; + + *argz = malloc(sizeof mtab_argz); + if (! *argz) + return ENOMEM; + + memcpy (*argz, mtab_argz, sizeof mtab_argz); + *argz_len = sizeof mtab_argz; + return 0; +} + +enum mtab_translator_state { + MTAB_FALSE = FALSE, + MTAB_TRUE = TRUE, + MTAB_UNINITIALIZED, +}; + +static int +rootdir_mounts_exists () +{ + static enum mtab_translator_state state = MTAB_UNINITIALIZED; + if (state == MTAB_UNINITIALIZED) + state = access(MTAB_TRANSLATOR, F_OK|X_OK) == 0; + return state; +} /* Glue logic and entries table */ @@ -426,6 +457,18 @@ rootdir_symlink_make_node (void *dir_hook, const void *entry_hook) return np; } +static struct node * +rootdir_translator_make_node (void *dir_hook, const void *entry_hook) +{ + struct node *np = procfs_make_node (entry_hook, dir_hook); + if (np) + { + procfs_node_chtype (np, S_IFREG | S_IPTRANS); + procfs_node_chmod (np, 0444); + } + return np; +} + static const struct procfs_dir_entry rootdir_entries[] = { { .name = "self", @@ -487,6 +530,16 @@ static const struct procfs_dir_entry rootdir_entries[] = { .cleanup_contents = procfs_cleanup_contents_with_free, }, }, + { + .name = "mounts", + .hook = & (struct procfs_node_ops) { + .get_translator = rootdir_mounts_get_translator, + }, + .ops = { + .make_node = rootdir_translator_make_node, + .exists = rootdir_mounts_exists, + } + }, #ifdef PROFILE /* In order to get a usable gmon.out file, we must apparently use exit(). */ { -- 1.7.10.4