summaryrefslogtreecommitdiff
path: root/trans/mtab.c
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-01-12 15:05:53 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-01-12 15:59:51 +0100
commit0033d20449b3bb558f2ea470983018db39b572aa (patch)
tree5707a5427fbd97abaa07c0e7eea4641d7d616216 /trans/mtab.c
parent3b016a709dd4be5a978dbc8f04b49289612b5be9 (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.
Diffstat (limited to 'trans/mtab.c')
-rw-r--r--trans/mtab.c40
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)