diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 15:05:53 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 15:59:51 +0100 |
commit | 0033d20449b3bb558f2ea470983018db39b572aa (patch) | |
tree | 5707a5427fbd97abaa07c0e7eea4641d7d616216 | |
parent | 3b016a709dd4be5a978dbc8f04b49289612b5be9 (diff) |
trans/mtab: do not include non-filesystem translators by default
Traditionally, /proc/mounts includes only filesystem mount points.
Previously though, the mtab translator included any kind of
translator, like all /hurd/storeio translators. This causes problems
with umount --all as this would remove the passive translator records
from nodes in /dev.
Fix this by only listing filesystem-like translators by default.
Filesystem-like translators are identified by their response to
dir_readdir messages sent to their root node.
* trans/mtab.c (all_translators): New variable.
(options): Add flag to preserve the old behavior.
(parse_opt): Handle the new flag.
(is_filesystem_translator): New function.
(mtab_populate): Skip non-filesystem translators by default.
-rw-r--r-- | trans/mtab.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/trans/mtab.c b/trans/mtab.c index adfb3458..75ef1d3a 100644 --- a/trans/mtab.c +++ b/trans/mtab.c @@ -40,6 +40,7 @@ static char *target_path = NULL; static int insecure = 0; +static int all_translators = 0; /* Our control port. */ struct trivfs_control *control; @@ -60,6 +61,9 @@ static const struct argp_option options[] = { {"insecure", 'I', 0, 0, "Follow translators not bound to nodes owned by you or root"}, + {"all-translators", 'A', 0, 0, + "List all translators, even those that are probably not " + "filesystem translators"}, {} }; @@ -72,6 +76,10 @@ error_t parse_opt (int key, char *arg, struct argp_state *state) insecure = 1; break; + case 'A': + all_translators = 1; + break; + case ARGP_KEY_ARG: target_path = realpath (arg, NULL); if (! target_path) @@ -277,6 +285,32 @@ mtab_add_entry (struct mtab *mtab, const char *entry, size_t length) return 0; } +/* Check whether the given NODE is a directory on a filesystem + translator. */ +static boolean_t +is_filesystem_translator (file_t node) +{ + error_t err; + char *data = NULL; + size_t datacnt = 0; + int amount; + err = dir_readdir (node, &data, &datacnt, 0, 1, 0, &amount); + if (data != NULL && datacnt > 0) + vm_deallocate (mach_task_self (), (vm_address_t) data, datacnt); + + /* Filesystem translators return either no error, or, if NODE has + not been looked up with O_READ, EBADF to dir_readdir + requests. */ + switch (err) + { + case 0: + case EBADF: + return TRUE; + default: + return FALSE; + } +} + /* Populates the given MTAB object with the information for PATH. If INSECURE is given, also follow translators bound to nodes not owned by root or the current user. */ @@ -333,6 +367,12 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) goto errout; } + if (! (all_translators || is_filesystem_translator (node))) + { + err = 0; + goto errout; + } + /* Query its options. */ err = file_get_fs_options (node, &argz, &argz_len); if (err) |