diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 19:22:02 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 19:22:02 +0100 |
commit | 5d31113644fda962319716a01165d10f9ad919b8 (patch) | |
tree | cb50c721ece96fa3d953dff332a0897360509fc9 /debian/patches/translatorslist-detect-passive-translators.patch | |
parent | 059523dc25ecf68e5b220d5b14504fa491cd005a (diff) |
update translatorslist-detect-passive-translators.patch, add the mtab fixes
Diffstat (limited to 'debian/patches/translatorslist-detect-passive-translators.patch')
-rw-r--r-- | debian/patches/translatorslist-detect-passive-translators.patch | 481 |
1 files changed, 458 insertions, 23 deletions
diff --git a/debian/patches/translatorslist-detect-passive-translators.patch b/debian/patches/translatorslist-detect-passive-translators.patch index 59aa0691..25823bc7 100644 --- a/debian/patches/translatorslist-detect-passive-translators.patch +++ b/debian/patches/translatorslist-detect-passive-translators.patch @@ -1,8 +1,27 @@ diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c -index 86116e3..57610a5 100644 +index 86116e3..3950bf9 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c -@@ -274,11 +274,16 @@ diskfs_S_dir_lookup (struct protid *dircred, +@@ -1,6 +1,6 @@ + /* libdiskfs implementation of fs.defs:dir_lookup + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +- 2002, 2008, 2013 Free Software Foundation, Inc. ++ 2002, 2008, 2013, 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as +@@ -74,6 +74,10 @@ diskfs_S_dir_lookup (struct protid *dircred, + if (! relpath) + return ENOMEM; + ++ /* Keep a pointer to the start of the path for length ++ calculations. */ ++ char *path_start = path; ++ + *returned_port_poly = MACH_MSG_TYPE_MAKE_SEND; + *retry = FS_RETRY_NORMAL; + retryname[0] = '\0'; +@@ -274,11 +278,16 @@ diskfs_S_dir_lookup (struct protid *dircred, goto out; dirport = ports_get_send_right (newpi); @@ -21,21 +40,28 @@ index 86116e3..57610a5 100644 error = fshelp_fetch_root (&np->transbox, dircred->po, dirport, dircred->user, lastcomp ? flags : 0, -@@ -301,9 +306,28 @@ diskfs_S_dir_lookup (struct protid *dircred, +@@ -301,9 +310,35 @@ diskfs_S_dir_lookup (struct protid *dircred, *end++ = '/'; strcpy (end, nextname); } + + if (register_translator) + { -+ char *stripped_relpath = strdupa (relpath); -+ char *end = strchr (stripped_relpath, '\0'); -+ end -= 1; -+ if (*end == '/') -+ *end = '\0'; ++ char *translator_path = strdupa (relpath); ++ if (nextname != NULL) ++ { ++ /* This was not the last path component. ++ NEXTNAME points to the next component, locate ++ the end of the current component and use it ++ to trim TRANSLATOR_PATH. */ ++ char *end = nextname; ++ while (*end != 0) ++ end--; ++ translator_path[end - path_start] = '\0'; ++ } + + error = fshelp_set_active_translator (&newpi->pi, -+ stripped_relpath, ++ translator_path, + np->transbox.active); + if (error) + goto out; @@ -51,9 +77,16 @@ index 86116e3..57610a5 100644 vanished while NP was unlocked inside fshelp_fetch_root. Reacquire the locks, and continue as normal. */ diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c -index 8de2e64..8752900 100644 +index 8de2e64..58f6255 100644 --- a/libdiskfs/file-set-trans.c +++ b/libdiskfs/file-set-trans.c +@@ -1,5 +1,5 @@ + /* libdiskfs implementation of fs.defs: file_set_translator +- Copyright (C) 1992,93,94,95,96,99,2001,02,13 ++ Copyright (C) 1992,93,94,95,96,99,2001,02,13,14 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or @@ -208,20 +208,8 @@ diskfs_S_file_set_translator (struct protid *cred, pthread_mutex_unlock (&np->lock); @@ -78,9 +111,16 @@ index 8de2e64..8752900 100644 return error; } diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h -index a7702ca..cd86e6f 100644 +index a7702ca..5d3a0ce 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h +@@ -1,5 +1,5 @@ + /* FS helper library definitions +- Copyright (C) 1994,95,96,97,98,99,2000,01,02,13 ++ Copyright (C) 1994,95,96,97,98,99,2000,01,02,13,14 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or @@ -34,14 +34,20 @@ @@ -108,9 +148,17 @@ index a7702ca..cd86e6f 100644 /* Remove the active translator specified by its control port ACTIVE. If there is no active translator with the given control port, this diff --git a/libfshelp/translator-list.c b/libfshelp/translator-list.c -index 87dcb21..b8bbd95 100644 +index 87dcb21..3ece711 100644 --- a/libfshelp/translator-list.c +++ b/libfshelp/translator-list.c +@@ -1,6 +1,6 @@ + /* A list of active translators. + +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013,14 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + @@ -22,6 +22,7 @@ #include <argz.h> #include <hurd/fsys.h> @@ -195,10 +243,28 @@ index 87dcb21..b8bbd95 100644 hurd_ihash_remove (&translator_ihash, (hurd_ihash_key_t) t); diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c -index 74351fa..9668a61 100644 +index 74351fa..99a8746 100644 --- a/libnetfs/dir-lookup.c +++ b/libnetfs/dir-lookup.c -@@ -256,10 +256,16 @@ netfs_S_dir_lookup (struct protid *diruser, +@@ -1,5 +1,5 @@ + /* +- Copyright (C) 1995,96,97,98,99,2000,01,02,13 ++ Copyright (C) 1995,96,97,98,99,2000,01,02,13,14 + Free Software Foundation, Inc. + Written by Michael I. Bushnell, p/BSG. + +@@ -67,6 +67,10 @@ netfs_S_dir_lookup (struct protid *diruser, + if (! relpath) + return ENOMEM; + ++ /* Keep a pointer to the start of the filename for length ++ calculations. */ ++ char *filename_start = filename; ++ + *retry_port_type = MACH_MSG_TYPE_MAKE_SEND; + *do_retry = FS_RETRY_NORMAL; + *retry_name = '\0'; +@@ -256,10 +260,16 @@ netfs_S_dir_lookup (struct protid *diruser, } } @@ -216,21 +282,28 @@ index 74351fa..9668a61 100644 error = fshelp_fetch_root (&np->transbox, diruser->po, dirport, -@@ -283,9 +289,31 @@ netfs_S_dir_lookup (struct protid *diruser, +@@ -283,9 +293,38 @@ netfs_S_dir_lookup (struct protid *diruser, strcat (retry_name, "/"); strcat (retry_name, nextname); } + + if (register_translator) + { -+ char *stripped_relpath = strdupa (relpath); -+ char *end = strchr (stripped_relpath, '\0'); -+ end -= 1; -+ if (*end == '/') -+ *end = '\0'; ++ char *translator_path = strdupa (relpath); ++ if (nextname != NULL) ++ { ++ /* This was not the last path component. ++ NEXTNAME points to the next component, locate ++ the end of the current component and use it ++ to trim TRANSLATOR_PATH. */ ++ char *end = nextname; ++ while (*end != 0) ++ end--; ++ translator_path[end - filename_start] = '\0'; ++ } + + error = fshelp_set_active_translator (&newpi->pi, -+ stripped_relpath, ++ translator_path, + np->transbox.active); + if (error) + { @@ -249,10 +322,18 @@ index 74351fa..9668a61 100644 while NP was unlocked inside fshelp_fetch_root; continue as normal. */ error = 0; diff --git a/libnetfs/file-set-translator.c b/libnetfs/file-set-translator.c -index a9883a3..8b9a65f 100644 +index a9883a3..b46eb02 100644 --- a/libnetfs/file-set-translator.c +++ b/libnetfs/file-set-translator.c -@@ -175,20 +175,8 @@ netfs_S_file_set_translator (struct protid *user, +@@ -1,5 +1,6 @@ + /* +- Copyright (C) 1996, 1997, 1999, 2001, 2013 Free Software Foundation, Inc. ++ Copyright (C) 1996, 1997, 1999, 2001, 2013, 2014 ++ Free Software Foundation, Inc. + Written by Michael I. Bushnell, p/BSG. + + This file is part of the GNU Hurd. +@@ -175,20 +176,8 @@ netfs_S_file_set_translator (struct protid *user, } } @@ -275,3 +356,357 @@ index a9883a3..8b9a65f 100644 out: pthread_mutex_unlock (&np->lock); +diff --git a/trans/mtab.c b/trans/mtab.c +index 250de7d..75ef1d3 100644 +--- a/trans/mtab.c ++++ b/trans/mtab.c +@@ -1,6 +1,6 @@ + /* This is an mtab translator. + +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013,14 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + +@@ -27,6 +27,7 @@ + #include <hurd/trivfs.h> + #include <inttypes.h> + #include <mntent.h> ++#include <pthread.h> + #include <stdlib.h> + #include <stdio.h> + #include <string.h> +@@ -39,6 +40,7 @@ + + static char *target_path = NULL; + static int insecure = 0; ++static int all_translators = 0; + + /* Our control port. */ + struct trivfs_control *control; +@@ -47,6 +49,7 @@ struct trivfs_control *control; + They keep track of the content and file position of the client. */ + struct mtab + { ++ pthread_mutex_t lock; + char *contents; + size_t contents_len; + off_t offs; +@@ -58,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"}, + {} + }; + +@@ -70,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) +@@ -233,9 +243,13 @@ main (int argc, char *argv[]) + error (4, err, "trivfs_startup"); + + /* Launch. */ +- ports_manage_port_operations_one_thread (control->pi.bucket, +- trivfs_demuxer, +- 0); ++ ports_manage_port_operations_multithread (control->pi.bucket, ++ trivfs_demuxer, ++ /* idle thread timeout */ ++ 30 * 1000, ++ /* idle server timeout */ ++ 0, ++ NULL); + } + else + { +@@ -271,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. */ +@@ -282,7 +322,6 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) + + /* These resources are freed in the epilogue. */ + file_t node = MACH_PORT_NULL; +- fsys_t fsys = MACH_PORT_NULL; + char *argz = NULL; + size_t argz_len = 0; + char **argv = NULL; +@@ -295,16 +334,16 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) + char *children = NULL; + size_t children_len = 0; + +- /* Get the underlying node. */ +- node = file_name_lookup (path, O_NOTRANS, 0666); +- if (node == MACH_PORT_NULL) +- { +- err = errno; +- goto errout; +- } +- + if (! insecure) + { ++ /* Get the underlying node. */ ++ node = file_name_lookup (path, O_NOTRANS, 0666); ++ if (node == MACH_PORT_NULL) ++ { ++ err = errno; ++ goto errout; ++ } ++ + /* Check who owns the node the translator is bound to. */ + io_statbuf_t st; + err = io_stat (node, &st); +@@ -316,28 +355,11 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) + err = EPERM; + goto errout; + } +- } +- +- err = file_get_translator_cntl (node, &fsys); +- if (err == EPERM) +- /* If we do not have permission to do that, it cannot be a node +- bound to our control port, so ignore this error. */ +- err = 0; +- +- if (err == ENXIO && strcmp (path, "/") == 0) +- /* The root translator fails differently, but this can't be bound +- to our control port either, so ignore this error. */ +- err = 0; + +- if (err) +- return err; +- +- if (control && control->pi.port_right == fsys) +- /* This node is bound to our control port, ignore it. */ +- goto errout; ++ mach_port_deallocate (mach_task_self (), node); ++ } + +- /* Re-do the lookup without O_NOTRANS to get the root node. */ +- mach_port_deallocate (mach_task_self (), node); ++ /* (Re-)do the lookup without O_NOTRANS to get the root node. */ + node = file_name_lookup (path, 0, 0666); + if (node == MACH_PORT_NULL) + { +@@ -345,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) +@@ -461,9 +489,6 @@ mtab_populate (struct mtab *mtab, const char *path, int insecure) + if (node != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), node); + +- if (fsys != MACH_PORT_NULL) +- mach_port_deallocate (mach_task_self (), fsys); +- + if (argz) + vm_deallocate (mach_task_self (), (vm_address_t) argz, argz_len); + +@@ -590,18 +615,44 @@ open_hook (struct trivfs_peropen *peropen) + peropen->hook = mtab; + + /* Initialize the fields. */ ++ pthread_mutex_init (&mtab->lock, NULL); + mtab->offs = 0; + mtab->contents = NULL; + mtab->contents_len = 0; + +- return mtab_populate (mtab, target_path, insecure); ++ /* The mtab object is initialized, but not yet populated. We delay ++ that until that data is really needed. This avoids the following ++ problems: ++ ++ Suppose you have ++ ++ settrans -ac /foo /hurd/mtab / ++ ++ If you now access /foo, the mtab translator will walk the tree of ++ all active translators starting from /. If it visits /foo, it ++ will talk to itself. Previously the translator migitated this by ++ comparing the control port of the translator with its own. This ++ does not work if you got two mtab translators like this: ++ ++ settrans -ac /foo /hurd/mtab / ++ settrans -ac /bar /hurd/mtab / ++ ++ With a single-threaded mtab server this results in a dead-lock, ++ with a multi-threaded server this will create more and more ++ threads. ++ ++ Delaying the data generation until it is really needed cleanly ++ avoids these kind of problems. */ ++ return 0; + } + + static void + close_hook (struct trivfs_peropen *peropen) + { +- free (((struct mtab *) peropen->hook)->contents); +- free (peropen->hook); ++ struct mtab *op = peropen->hook; ++ pthread_mutex_destroy (&op->lock); ++ free (op->contents); ++ free (op); + } + + /* Read data from an IO object. If offset is -1, read from the object +@@ -613,6 +664,7 @@ trivfs_S_io_read (struct trivfs_protid *cred, + char **data, mach_msg_type_number_t *data_len, + loff_t offs, mach_msg_type_number_t amount) + { ++ error_t err = 0; + struct mtab *op; + + /* Deny access if they have bad credentials. */ +@@ -624,6 +676,15 @@ trivfs_S_io_read (struct trivfs_protid *cred, + + /* Get the offset. */ + op = cred->po->hook; ++ pthread_mutex_lock (&op->lock); ++ ++ if (op->contents == NULL) ++ { ++ err = mtab_populate (op, target_path, insecure); ++ if (err) ++ goto out; ++ } ++ + if (offs == -1) + offs = op->offs; + +@@ -640,7 +701,10 @@ trivfs_S_io_read (struct trivfs_protid *cred, + { + *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + if (*data == MAP_FAILED) +- return ENOMEM; ++ { ++ err = ENOMEM; ++ goto out; ++ } + } + + /* Copy the constant data into the buffer. */ +@@ -651,7 +715,9 @@ trivfs_S_io_read (struct trivfs_protid *cred, + } + + *data_len = amount; +- return 0; ++ out: ++ pthread_mutex_unlock (&op->lock); ++ return err; + } + + +@@ -661,10 +727,19 @@ trivfs_S_io_seek (struct trivfs_protid *cred, + mach_port_t reply, mach_msg_type_name_t reply_type, + off_t offs, int whence, off_t *new_offs) + { ++ error_t err = 0; + if (! cred) + return EOPNOTSUPP; + + struct mtab *op = cred->po->hook; ++ pthread_mutex_lock (&op->lock); ++ ++ if (op->contents == NULL) ++ { ++ err = mtab_populate (op, target_path, insecure); ++ if (err) ++ goto out; ++ } + + switch (whence) + { +@@ -681,10 +756,12 @@ trivfs_S_io_seek (struct trivfs_protid *cred, + break; + } + default: +- return EINVAL; ++ err = EINVAL; + } + +- return 0; ++ out: ++ pthread_mutex_unlock (&op->lock); ++ return err; + } + + /* If this variable is set, it is called every time a new peropen +@@ -703,6 +780,7 @@ trivfs_S_io_readable (struct trivfs_protid *cred, + mach_port_t reply, mach_msg_type_name_t replytype, + mach_msg_type_number_t *amount) + { ++ error_t err = 0; + if (!cred) + return EOPNOTSUPP; + +@@ -710,9 +788,19 @@ trivfs_S_io_readable (struct trivfs_protid *cred, + return EINVAL; + + struct mtab *op = cred->po->hook; ++ pthread_mutex_lock (&op->lock); ++ ++ if (op->contents == NULL) ++ { ++ error_t err = mtab_populate (op, target_path, insecure); ++ if (err) ++ goto out; ++ } + + *amount = op->contents_len - op->offs; +- return 0; ++ out: ++ pthread_mutex_unlock (&op->lock); ++ return err; + } + + /* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG. |