summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
Diffstat (limited to 'debian')
-rw-r--r--debian/patches/translatorslist-detect-passive-translators.patch481
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.