This is an automated email from the git hooks/post-receive script. sthibault pushed a commit to branch master in repository hurd.
commit 5ef6e237a460754e5d1fab7d9f6df5d19543b26d Author: Samuel Thibault <[email protected]> Date: Sun Feb 14 21:24:57 2016 +0000 New upstream snapshot --- boot/boot.c | 8 +- devnode/devnode.c | 21 +++- exec/Makefile | 3 +- exec/main.c | 5 - ftpfs/dir.c | 146 +++++++---------------- ftpfs/ftpfs.h | 17 +-- libfshelp/fetch-root.c | 11 +- libfshelp/lock-acquire.c | 5 +- libfshelp/lock-init.c | 4 +- libfshelp/locks.h | 28 ----- libfshelp/trans.h | 32 ----- libnetfs/io-duplicate.c | 1 + libnetfs/io-reauthenticate.c | 2 + libnetfs/io-restrict-auth.c | 2 + libnetfs/make-peropen.c | 2 +- libnetfs/make-protid.c | 1 - libnetfs/netfs.h | 2 +- libnetfs/release-peropen.c | 38 +++--- libnetfs/trans-callback.c | 16 ++- mach-defpager/Makefile | 1 - proc/mgt.c | 16 +-- procfs/main.c | 11 +- trans/fakeroot.c | 2 +- utils/Makefile | 2 +- utils/fakeauth.c | 6 +- utils/fakeroot.sh | 15 +-- utils/remap.sh | 14 +-- utils/settrans.c | 32 ++++- utils/vmallocate.c | 272 +++++++++++++++++++++++++++++++++++++++++++ 29 files changed, 456 insertions(+), 259 deletions(-) diff --git a/boot/boot.c b/boot/boot.c index 4dda26b..462243c 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -1601,13 +1601,17 @@ S_io_reauthenticate (mach_port_t object, MACH_MSG_TYPE_MAKE_SEND); assert_perror (err); - if (! auth_server_authenticate (authserver, + do + err = auth_server_authenticate (authserver, rend, MACH_MSG_TYPE_COPY_SEND, object, MACH_MSG_TYPE_COPY_SEND, &gu, &gulen, &au, &aulen, &gg, &gglen, - &ag, &aglen)) + &ag, &aglen); + while (err == EINTR); + + if (!err) { mig_deallocate ((vm_address_t) gu, gulen * sizeof *gu); mig_deallocate ((vm_address_t) au, aulen * sizeof *gu); diff --git a/devnode/devnode.c b/devnode/devnode.c index 2802471..a5120d7 100644 --- a/devnode/devnode.c +++ b/devnode/devnode.c @@ -153,12 +153,20 @@ ds_device_open (mach_port_t master_port, mach_port_t reply_port, if (master_file != NULL) { - if (master_device != MACH_PORT_NULL) + mach_port_t md; + if (MACH_PORT_VALID (master_device)) mach_port_deallocate (mach_task_self (), master_device); - - master_device = file_name_lookup (master_file, 0, 0); - if (master_device == MACH_PORT_NULL) - error (1, errno, "file_name_lookup"); + md = file_name_lookup (master_file, 0, 0); + if (MACH_PORT_VALID (md)) + master_device = md; + else + { + error (0, 0, "%s: %s.\nFalling back to kernel driver.", + master_file, strerror (errno)); + err = get_privileged_ports (0, &master_device); + if (err) + return err; + } } err = device_open (master_device, mode, device_name, device); @@ -298,7 +306,8 @@ parse_opt (int opt, char *arg, struct argp_state *state) master_file = arg; master_device = file_name_lookup (arg, 0, 0); if (master_device == MACH_PORT_NULL) - error (1, errno, "file_name_lookup"); + error (0, 0, "%s: %s.\nFalling back to kernel driver.", + arg, strerror (errno)); break; case 'n': user_device_name = arg; diff --git a/exec/Makefile b/exec/Makefile index 2406203..17d03e3 100644 --- a/exec/Makefile +++ b/exec/Makefile @@ -24,8 +24,7 @@ SRCS = exec.c main.c hashexec.c hostarch.c OBJS = main.o hostarch.o exec.o hashexec.o \ execServer.o exec_startupServer.o -target = exec -#targets = exec exec.static +target = exec exec.static HURDLIBS = trivfs fshelp iohelp ports ihash shouldbeinlibc LDLIBS = -lpthread diff --git a/exec/main.c b/exec/main.c index 1ed7763..2658df5 100644 --- a/exec/main.c +++ b/exec/main.c @@ -230,11 +230,6 @@ main (int argc, char **argv) /* Reply to our parent. */ err = trivfs_startup (bootstrap, 0, - trivfs_control_class, port_bucket, - trivfs_protid_class, port_bucket, &fsys); - - /* Reply to our parent. */ - err = trivfs_startup (bootstrap, 0, trivfs_control_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); diff --git a/ftpfs/dir.c b/ftpfs/dir.c index be20b3d..733a2dc 100644 --- a/ftpfs/dir.c +++ b/ftpfs/dir.c @@ -30,72 +30,31 @@ void free_entry (struct ftpfs_dir_entry *e) { - assert (! e->self_p); /* We should only free deleted nodes. */ + assert (e->deleted); free (e->name); if (e->symlink_target) free (e->symlink_target); free (e); } -/* Put the directory entry E into the hash table HTABLE, of length HTABLE_LEN. */ -static void -insert (struct ftpfs_dir_entry *e, - struct ftpfs_dir_entry **htable, size_t htable_len) +/* Calculate NAME_PTR's hash value. */ +static hurd_ihash_key_t +ihash_hash (const void *name_ptr) { - struct ftpfs_dir_entry **t = &htable[e->hv % htable_len]; - if (*t) - (*t)->self_p = &e->next; - e->next = *t; - e->self_p = t; - *t = e; + const char *name = (const char *) name_ptr; + return (hurd_ihash_key_t) hurd_ihash_hash32 (name, strlen (name), 0); } - -/* Replace DIR's hashtable with a new one of length NEW_LEN, retaining all - existing entries. */ -static error_t -rehash (struct ftpfs_dir *dir, size_t new_len) + +/* Compare two names which are used as keys. */ +static int +ihash_compare (const void *key1, const void *key2) { - int i; - size_t old_len = dir->htable_len; - struct ftpfs_dir_entry **old_htable = dir->htable; - struct ftpfs_dir_entry **new_htable = - malloc (new_len * sizeof (struct ftpfs_dir_entry *)); - - if (! new_htable) - return ENOMEM; - - memset (new_htable, 0, new_len * sizeof(struct ftpfs_dir_entry *)); - - for (i = 0; i < old_len; i++) - while (old_htable[i]) - { - struct ftpfs_dir_entry *e = old_htable[i]; + const char *name1 = (const char *) key1; + const char *name2 = (const char *) key2; - /* Remove E from the old table (don't bother to fixup - e->next->self_p). */ - old_htable[i] = e->next; - - insert (e, new_htable, new_len); - } - - free (old_htable); - - dir->htable = new_htable; - dir->htable_len = new_len; - - return 0; + return strcmp (name1, name2) == 0; } -/* Calculate NAME's hash value. */ -static size_t -hash (const char *name) -{ - size_t hv = 0; - while (*name) - hv = ((hv << 5) + *name++) & 0xFFFFFF; - return hv; -} - /* Lookup NAME in DIR and return its entry. If there is no such entry, and ADD is true, then a new entry is allocated and returned, otherwise 0 is returned (if ADD is true then 0 can be returned if a memory allocation @@ -103,23 +62,14 @@ hash (const char *name) struct ftpfs_dir_entry * lookup (struct ftpfs_dir *dir, const char *name, int add) { - size_t hv = hash (name); - struct ftpfs_dir_entry *h = dir->htable[hv % dir->htable_len], *e = h; - - while (e && strcmp (name, e->name) != 0) - e = e->next; + struct ftpfs_dir_entry *e = + hurd_ihash_find (&dir->htable, (hurd_ihash_key_t) name); if (!e && add) { - if (dir->num_entries > dir->htable_len) - /* Grow the hash table. */ - if (rehash (dir, (dir->htable_len + 1) * 2 - 1) != 0) - return 0; - e = malloc (sizeof *e); if (e) { - e->hv = hv; e->name = strdup (name); e->node = 0; e->dir = dir; @@ -128,13 +78,11 @@ lookup (struct ftpfs_dir *dir, const char *name, int add) e->symlink_target = 0; e->noent = 0; e->valid = 0; + e->deleted = 0; e->name_timestamp = e->stat_timestamp = 0; e->ordered_next = 0; e->ordered_self_p = 0; - e->next = 0; - e->self_p = 0; - insert (e, dir->htable, dir->htable_len); - dir->num_entries++; + hurd_ihash_add (&dir->htable, (hurd_ihash_key_t) e->name, e); } } @@ -148,28 +96,21 @@ ordered_unlink (struct ftpfs_dir_entry *e) if (e->ordered_self_p) *e->ordered_self_p = e->ordered_next; if (e->ordered_next) - e->ordered_next->self_p = e->ordered_self_p; + e->ordered_next->ordered_self_p = e->ordered_self_p; } - + /* Delete E from its directory, freeing any resources it holds. */ static void delete (struct ftpfs_dir_entry *e, struct ftpfs_dir *dir) { - dir->num_entries--; - - /* Take out of the hash chain. */ - if (e->self_p) - *e->self_p = e->next; - if (e->next) - e->next->self_p = e->self_p; - /* This indicates a deleted entry. */ - e->self_p = 0; - e->next = 0; + e->deleted = 1; /* Take out of the directory ordered list. */ ordered_unlink (e); + hurd_ihash_locp_remove (&dir->htable, e->dir_locp); + /* If there's a node attached, we'll delete the entry whenever it goes away, otherwise, just delete it now. */ if (! e->node) @@ -180,25 +121,23 @@ delete (struct ftpfs_dir_entry *e, struct ftpfs_dir *dir) static void mark (struct ftpfs_dir *dir) { - size_t len = dir->htable_len, i; - struct ftpfs_dir_entry **htable = dir->htable, *e; - - for (i = 0; i < len; i++) - for (e = htable[i]; e; e = e->next) + HURD_IHASH_ITERATE (&dir->htable, value) + { + struct ftpfs_dir_entry *e = (struct ftpfs_dir_entry *) value; e->valid = 0; + } } - + /* Delete any entries in DIR which don't have their valid bit set. */ static void sweep (struct ftpfs_dir *dir) { - size_t len = dir->htable_len, i; - struct ftpfs_dir_entry **htable = dir->htable, *e; - - for (i = 0; i < len; i++) - for (e = htable[i]; e; e = e->next) + HURD_IHASH_ITERATE (&dir->htable, value) + { + struct ftpfs_dir_entry *e = (struct ftpfs_dir_entry *) value; if (!e->valid && !e->noent) - delete (e, dir); + delete (e, dir); + } } /* Update the directory entry for NAME to reflect ST and SYMLINK_TARGET. @@ -466,7 +405,7 @@ ftpfs_refresh_node (struct node *node) pthread_mutex_lock (&dir->node->lock); - if (! entry->self_p) + if (entry->deleted) /* This is a deleted entry, just awaiting disposal; do so. */ { nn->dir_entry = 0; @@ -572,7 +511,7 @@ ftpfs_detach_node (struct node *node) pthread_mutex_lock (&dir->node->lock); - if (entry->self_p) + if (! entry->deleted) /* Just detach NODE from the still active entry. */ entry->node = 0; else @@ -837,15 +776,10 @@ ftpfs_dir_create (struct ftpfs *fs, struct node *node, const char *rmt_path, struct ftpfs_dir **dir) { struct ftpfs_dir *new = malloc (sizeof (struct ftpfs_dir)); - struct ftpfs_dir_entry **htable - = calloc (INIT_HTABLE_LEN, sizeof (struct ftpfs_dir_entry *)); - if (!new || !htable) + if (! new) { - if (new) - free (new); - if (htable) - free (htable); + free (new); return ENOMEM; } @@ -854,10 +788,9 @@ ftpfs_dir_create (struct ftpfs *fs, struct node *node, const char *rmt_path, node->references++; pthread_spin_unlock (&netfs_node_refcnt_lock); - new->num_entries = 0; + hurd_ihash_init (&new->htable, offsetof (struct ftpfs_dir_entry, dir_locp)); + hurd_ihash_set_gki (&new->htable, ihash_hash, ihash_compare); new->num_live_entries = 0; - new->htable_len = INIT_HTABLE_LEN; - new->htable = htable; new->ordered = 0; new->rmt_path = rmt_path; new->fs = fs; @@ -880,8 +813,7 @@ ftpfs_dir_free (struct ftpfs_dir *dir) mark (dir); sweep (dir); - if (dir->htable) - free (dir->htable); + hurd_ihash_destroy (&dir->htable); netfs_nrele (dir->node); diff --git a/ftpfs/ftpfs.h b/ftpfs/ftpfs.h index 206726f..a067bfe 100644 --- a/ftpfs/ftpfs.h +++ b/ftpfs/ftpfs.h @@ -35,7 +35,6 @@ struct ftpfs_conn; struct ftpfs_dir_entry { char *name; /* Name of this entry */ - size_t hv; /* Hash value of NAME (before mod'ing) */ /* The active node referred to by this name (may be 0). NETFS_NODE_REFCNT_LOCK should be held while frobbing this. */ @@ -48,11 +47,6 @@ struct ftpfs_dir_entry /* The directory to which this entry belongs. */ struct ftpfs_dir *dir; - /* Link to next entry in hash bucket, and address of previous entry's (or - hash table's) pointer to this entry. If the SELF_P field is 0, then - this is a deleted entry, awaiting final disposal. */ - struct ftpfs_dir_entry *next, **self_p; - /* Next entry in `directory order', or 0 if none known. */ struct ftpfs_dir_entry *ordered_next, **ordered_self_p; @@ -61,24 +55,23 @@ struct ftpfs_dir_entry hurd_ihash_locp_t inode_locp; /* Used for removing this entry */ + hurd_ihash_locp_t dir_locp; /* Position in the directory table. */ + int noent : 1; /* A negative lookup result. */ int valid : 1; /* Marker for GC'ing. */ + int deleted : 1; /* Indicates a deleted entry. */ }; /* A directory. */ struct ftpfs_dir { - /* Number of entries in HTABLE. */ - size_t num_entries; + /* Hash table mapping names to children nodes. */ + struct hurd_ihash htable; /* The number of entries that have nodes attached. We keep an additional reference to our node if there are any, to prevent it from going away. */ size_t num_live_entries; - /* Hash table of entries. */ - struct ftpfs_dir_entry **htable; - size_t htable_len; /* # of elements in HTABLE (not bytes). */ - /* List of dir entries in `directory order', in a linked list using the ORDERED_NEXT and ORDERED_SELF_P fields in each entry. Not all entries in HTABLE need be in this list. */ diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index 712c11f..d7761e5 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -18,11 +18,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "trans.h" -#include <unistd.h> #include <assert.h> -#include <string.h> #include <hurd/fsys.h> +#include <hurd/ports.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "fshelp.h" error_t fshelp_fetch_root (struct transbox *box, void *cookie, @@ -72,10 +75,10 @@ fshelp_fetch_root (struct transbox *box, void *cookie, /* MAKE_SEND is safe here because we destroy REND ourselves. */ err = io_reauthenticate (port, rend, MACH_MSG_TYPE_MAKE_SEND); - mach_port_deallocate (mach_task_self (), port); if (! err) err = auth_user_authenticate (newauth, rend, MACH_MSG_TYPE_MAKE_SEND, &ret); + mach_port_deallocate (mach_task_self (), port); if (err) ret = MACH_PORT_NULL; diff --git a/libfshelp/lock-acquire.c b/libfshelp/lock-acquire.c index f68c30a..07df428 100644 --- a/libfshelp/lock-acquire.c +++ b/libfshelp/lock-acquire.c @@ -19,7 +19,10 @@ /* Written by Michael I. Bushnell. */ -#include "locks.h" +#include <assert.h> +#include <sys/file.h> + +#include "fshelp.h" #define EWOULDBLOCK EAGAIN /* XXX */ diff --git a/libfshelp/lock-init.c b/libfshelp/lock-init.c index 21fb0d7..bb1f1f8 100644 --- a/libfshelp/lock-init.c +++ b/libfshelp/lock-init.c @@ -19,7 +19,9 @@ /* Written by Michael I. Bushnell. */ -#include "locks.h" +#include <sys/file.h> + +#include "fshelp.h" /* Initialize a lock box. */ void diff --git a/libfshelp/locks.h b/libfshelp/locks.h deleted file mode 100644 index a950f61..0000000 --- a/libfshelp/locks.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (C) 1994 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Written by Michael I. Bushnell. */ - -#include <mach.h> -#include <hurd.h> -#include <pthread.h> -#include <hurd/ports.h> -#include "fshelp.h" -#include <sys/file.h> -#include <assert.h> diff --git a/libfshelp/trans.h b/libfshelp/trans.h deleted file mode 100644 index a9ea648..0000000 --- a/libfshelp/trans.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 1994 Free Software Foundation - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <mach.h> -#include <hurd.h> -#include <pthread.h> -#include <hurd/ports.h> -#include "fshelp.h" - -struct transboot -{ - struct port_info pi; - file_t node; - struct trans_link *link; -}; - -pthread_spinlock_t _fshelp_translistlock; -struct trans_link *_fshelp_translist; diff --git a/libnetfs/io-duplicate.c b/libnetfs/io-duplicate.c index b2c3a3a..263f9e8 100644 --- a/libnetfs/io-duplicate.c +++ b/libnetfs/io-duplicate.c @@ -34,6 +34,7 @@ netfs_S_io_duplicate (struct protid *user, if (err) return err; + refcount_ref (&user->po->refcnt); pthread_mutex_lock (&user->po->np->lock); newpi = netfs_make_protid (user->po, clone); *newport = ports_get_right (newpi); diff --git a/libnetfs/io-reauthenticate.c b/libnetfs/io-reauthenticate.c index 8ff4182..b2d4a44 100644 --- a/libnetfs/io-reauthenticate.c +++ b/libnetfs/io-reauthenticate.c @@ -34,12 +34,14 @@ netfs_S_io_reauthenticate (struct protid *user, mach_port_t rend_port) /* This routine must carefully ignore EINTR because we are a simpleroutine, so callers won't know to restart. */ + refcount_ref (&user->po->refcnt); pthread_mutex_lock (&user->po->np->lock); do newpi = netfs_make_protid (user->po, 0); while (! newpi && errno == EINTR); if (! newpi) { + refcount_deref (&user->po->refcnt); pthread_mutex_unlock (&user->po->np->lock); return errno; } diff --git a/libnetfs/io-restrict-auth.c b/libnetfs/io-restrict-auth.c index 0c3403d..79b7d09 100644 --- a/libnetfs/io-restrict-auth.c +++ b/libnetfs/io-restrict-auth.c @@ -43,6 +43,7 @@ netfs_S_io_restrict_auth (struct protid *user, return err; pthread_mutex_lock (&user->po->np->lock); + refcount_ref (&user->po->refcnt); newpi = netfs_make_protid (user->po, new_user); if (newpi) { @@ -52,6 +53,7 @@ netfs_S_io_restrict_auth (struct protid *user, } else { + refcount_deref (&user->po->refcnt); pthread_mutex_unlock (&user->po->np->lock); iohelp_free_iouser (new_user); err = ENOMEM; diff --git a/libnetfs/make-peropen.c b/libnetfs/make-peropen.c index f7be58b..413e914 100644 --- a/libnetfs/make-peropen.c +++ b/libnetfs/make-peropen.c @@ -31,7 +31,7 @@ netfs_make_peropen (struct node *np, int flags, struct peropen *context) po->filepointer = 0; po->lock_status = LOCK_UN; - po->refcnt = 0; + refcount_init (&po->refcnt, 1); po->openstat = flags; po->np = np; po->path = NULL; diff --git a/libnetfs/make-protid.c b/libnetfs/make-protid.c index bf18283..995ac1e 100644 --- a/libnetfs/make-protid.c +++ b/libnetfs/make-protid.c @@ -36,7 +36,6 @@ netfs_make_protid (struct peropen *po, struct iouser *cred) if (errno) return 0; - po->refcnt++; pi->po = po; pi->user = cred; pi->shared_object = MACH_PORT_NULL; diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h index fbe2c60..3f94ccd 100644 --- a/libnetfs/netfs.h +++ b/libnetfs/netfs.h @@ -51,7 +51,7 @@ struct peropen { loff_t filepointer; int lock_status; - int refcnt; + refcount_t refcnt; int openstat; struct node *np; diff --git a/libnetfs/release-peropen.c b/libnetfs/release-peropen.c index c206b43..01af97d 100644 --- a/libnetfs/release-peropen.c +++ b/libnetfs/release-peropen.c @@ -24,29 +24,27 @@ void netfs_release_peropen (struct peropen *po) { + if (refcount_deref (&po->refcnt) > 0) + return; + pthread_mutex_lock (&po->np->lock); - if (--po->refcnt) - pthread_mutex_unlock (&po->np->lock); - else - { - if (po->root_parent) - mach_port_deallocate (mach_task_self (), po->root_parent); + if (po->root_parent) + mach_port_deallocate (mach_task_self (), po->root_parent); - if (po->shadow_root && po->shadow_root != po->np) - { - pthread_mutex_lock (&po->shadow_root->lock); - netfs_nput (po->shadow_root); - } - if (po->shadow_root_parent) - mach_port_deallocate (mach_task_self (), po->shadow_root_parent); + if (po->shadow_root && po->shadow_root != po->np) + { + pthread_mutex_lock (&po->shadow_root->lock); + netfs_nput (po->shadow_root); + } + if (po->shadow_root_parent) + mach_port_deallocate (mach_task_self (), po->shadow_root_parent); - if (po->lock_status != LOCK_UN) - fshelp_acquire_lock (&po->np->userlock, &po->lock_status, - &po->np->lock, LOCK_UN); + if (po->lock_status != LOCK_UN) + fshelp_acquire_lock (&po->np->userlock, &po->lock_status, + &po->np->lock, LOCK_UN); - netfs_nput (po->np); + netfs_nput (po->np); - free (po->path); - free (po); - } + free (po->path); + free (po); } diff --git a/libnetfs/trans-callback.c b/libnetfs/trans-callback.c index f4f0c62..ed21aa2 100644 --- a/libnetfs/trans-callback.c +++ b/libnetfs/trans-callback.c @@ -58,14 +58,22 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, struct protid *cred; struct node *node = cookie1; struct iouser *user; + struct peropen *po; err = iohelp_create_simple_iouser (&user, node->nn_stat.st_uid, node->nn_stat.st_gid); if (err) return err; - cred = netfs_make_protid (netfs_make_peropen (node, flags, cookie2), - user); + po = netfs_make_peropen (node, flags, cookie2); + if (! po) + { + err = errno; + iohelp_free_iouser (user); + return err; + } + + cred = netfs_make_protid (po, user); if (cred) { *underlying = ports_get_right (cred); @@ -75,8 +83,10 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, } else { + err = errno; + netfs_release_peropen (po); iohelp_free_iouser (user); - return errno; + return err; } } diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile index 036a49a..3b8ce58 100644 --- a/mach-defpager/Makefile +++ b/mach-defpager/Makefile @@ -30,7 +30,6 @@ OBJS := $(SRCS:.c=.o) \ default_pager_replyUser.o HURDLIBS:= ihash -LDFLAGS += -static -z muldefs LDLIBS:= -lpthread include ../Makeconf diff --git a/proc/mgt.c b/proc/mgt.c index dacce46..128a1c8 100644 --- a/proc/mgt.c +++ b/proc/mgt.c @@ -110,13 +110,15 @@ S_proc_reauthenticate (struct proc *p, mach_port_t rendport) /* Release the global lock while blocking on the auth server and client. */ pthread_mutex_unlock (&global_lock); - err = auth_server_authenticate (authserver, - rendport, MACH_MSG_TYPE_COPY_SEND, - MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, - &gen_uids, &ngen_uids, - &aux_uids, &naux_uids, - &gen_gids, &ngen_gids, - &aux_gids, &naux_gids); + do + err = auth_server_authenticate (authserver, + rendport, MACH_MSG_TYPE_COPY_SEND, + MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, + &gen_uids, &ngen_uids, + &aux_uids, &naux_uids, + &gen_gids, &ngen_gids, + &aux_gids, &naux_gids); + while (err == EINTR); pthread_mutex_lock (&global_lock); if (err) diff --git a/procfs/main.c b/procfs/main.c index 509f488..857eac4 100644 --- a/procfs/main.c +++ b/procfs/main.c @@ -50,6 +50,13 @@ uid_t opt_anon_owner; #define NOEXEC_KEY -2 /* Likewise. */ #define NOSUID_KEY -3 /* Likewise. */ +static void set_compatibility_options (void) +{ + opt_clk_tck = 100; + opt_stat_mode = 0444; + opt_fake_self = 1; +} + static error_t argp_parser (int key, char *arg, struct argp_state *state) { @@ -97,9 +104,7 @@ argp_parser (int key, char *arg, struct argp_state *state) break; case 'c': - opt_clk_tck = 100; - opt_stat_mode = 0444; - opt_fake_self = 1; + set_compatibility_options(); break; case 'a': diff --git a/trans/fakeroot.c b/trans/fakeroot.c index 84b4efc..64f3208 100644 --- a/trans/fakeroot.c +++ b/trans/fakeroot.c @@ -308,10 +308,10 @@ netfs_S_dir_lookup (struct protid *diruser, err = io_reauthenticate (file, ref, MACH_MSG_TYPE_MAKE_SEND); if (! err) { - mach_port_deallocate (mach_task_self (), file); err = auth_user_authenticate (fakeroot_auth_port, ref, MACH_MSG_TYPE_MAKE_SEND, &dir); + mach_port_deallocate (mach_task_self (), file); } mach_port_destroy (mach_task_self (), ref); if (err) diff --git a/utils/Makefile b/utils/Makefile index 603b722..d2ef9e8 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -22,7 +22,7 @@ targets = shd ps settrans showtrans syncfs fsysopts \ storeinfo login w uptime ids loginpr sush vmstat portinfo \ devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \ storeread msgport rpctrace mount gcore fakeauth fakeroot remap \ - umount nullauth rpcscan + umount nullauth rpcscan vmallocate special-targets = loginpr sush uptime fakeroot remap SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ diff --git a/utils/fakeauth.c b/utils/fakeauth.c index ba6a3ee..004cc46 100644 --- a/utils/fakeauth.c +++ b/utils/fakeauth.c @@ -402,9 +402,13 @@ believe it has restricted them to different identities or no identity at all.\ { task_t newtask; process_t proc; - file_t execfile = file_name_lookup (argv[argi], O_EXEC, 0); + char *prefixed_name; + file_t execfile = file_name_path_lookup (argv[argi], getenv ("PATH"), + O_EXEC, 0, &prefixed_name); if (execfile == MACH_PORT_NULL) error (3, errno, "%s", argv[argi]); + if (prefixed_name) + argv[0] = prefixed_name; err = task_create (mach_task_self (), #ifdef KERN_INVALID_LEDGER diff --git a/utils/fakeroot.sh b/utils/fakeroot.sh index 6993365..7bc5dc7 100644 --- a/utils/fakeroot.sh +++ b/utils/fakeroot.sh @@ -54,12 +54,9 @@ if [ $# -eq 0 ]; then set -- ${SHELL:-/bin/sh} fi -# We exec settrans, which execs the "fakeauth" command in the chroot context. -# The `pwd` is evaluated here and now, and that result interpreted inside -# the shell running under fakeauth to chdir there inside the chroot world. -# That shell then execs our arguments as a command line. -exec /bin/settrans --chroot \ - /bin/fakeauth \ - /bin/sh -c 'cd "$1" || exit ; shift ; exec "$@"' \ - "$1" "$PWD" "$@" \ - -- / /hurd/fakeroot +# We exec settrans, which execs the "fakeauth" command in the chroot +# context provided by /hurd/fakeroot. +exec /bin/settrans \ + --chroot-chdir "$PWD" \ + --chroot /bin/fakeauth "$@" -- \ + / /hurd/fakeroot diff --git a/utils/remap.sh b/utils/remap.sh index f24ed0e..40c2d76 100644 --- a/utils/remap.sh +++ b/utils/remap.sh @@ -57,11 +57,9 @@ if [ $# -eq 0 ]; then set -- ${SHELL:-/bin/sh} fi -# We exec settrans, which execs the "fakeauth" command in the chroot context. -# The `pwd` is evaluated here and now, and that result interpreted inside -# the shell running under fakeauth to chdir there inside the chroot world. -# That shell then execs our arguments as a command line. -exec /bin/settrans --chroot \ - /bin/sh -c 'cd "$1" || exit ; shift ; exec "$@"' \ - "$1" "$PWD" "$@" \ - -- / /hurd/remap $MAPPED +# We exec settrans, which execs the target command in the chroot +# context provided by /hurd/remap. +exec /bin/settrans \ + --chroot-chdir "$PWD" \ + --chroot "$@" -- \ + / /hurd/remap $MAPPED diff --git a/utils/settrans.c b/utils/settrans.c index cd40c56..00cc358 100644 --- a/utils/settrans.c +++ b/utils/settrans.c @@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <assert.h> #include <hurd.h> #include <stdio.h> #include <stdlib.h> @@ -45,6 +46,8 @@ const char *argp_program_version = STANDARD_HURD_VERSION (settrans); #define _STRINGIFY(arg) #arg #define STRINGIFY(arg) _STRINGIFY (arg) +#define OPT_CHROOT_CHDIR -1 + static struct argp_option options[] = { {"active", 'a', 0, 0, "Start TRANSLATOR and set it as NODE's active translator" }, @@ -65,6 +68,9 @@ static struct argp_option options[] = {"chroot", 'C', 0, 0, "Instead of setting the node's translator, take following arguments up to" " `--' and run that command chroot'd to the translated node."}, + {"chroot-chdir", OPT_CHROOT_CHDIR, "DIR", 0, + "Change to DIR before running the chrooted command. " + "DIR must be an absolute path."}, {0,0,0,0, "When setting the passive translator, if there's an active translator:"}, {"goaway", 'g', 0, 0, "Ask the active translator to go away"}, @@ -114,6 +120,7 @@ main(int argc, char *argv[]) int excl = 0; int timeout = DEFAULT_TIMEOUT * 1000; /* ms */ char **chroot_command = 0; + char *chroot_chdir = "/"; /* Parse our options... */ error_t parse_opt (int key, char *arg, struct argp_state *state) @@ -183,6 +190,12 @@ main(int argc, char *argv[]) argp_error (state, "--chroot command must be terminated with `--'"); return EINVAL; + case OPT_CHROOT_CHDIR: + if (arg[0] != '/') + argp_error (state, "--chroot-chdir must be absolute"); + chroot_chdir = arg; + break; + case 'c': lookup_flags |= O_CREAT; break; case 'L': lookup_flags &= ~O_NOTRANS; break; @@ -325,6 +338,8 @@ main(int argc, char *argv[]) char retry_name[1024]; /* XXX */ retry_type do_retry; mach_port_t root; + file_t executable; + char *prefixed_name; err = fsys_getroot (active_control, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, NULL, 0, NULL, 0, 0, @@ -341,8 +356,21 @@ main(int argc, char *argv[]) if (setcrdir (root)) error (7, errno, "cannot install root port"); mach_port_deallocate (mach_task_self (), root); - if (chdir ("/")) - error (8, errno, "cannot chdir to new root"); + if (chdir (chroot_chdir)) + error (8, errno, "%s", chroot_chdir); + + /* Lookup executable in PATH. */ + executable = file_name_path_lookup (chroot_command[0], + getenv ("PATH"), + O_EXEC, 0, + &prefixed_name); + if (MACH_PORT_VALID (executable)) + { + err = mach_port_deallocate (mach_task_self (), executable); + assert_perror (err); + if (prefixed_name) + chroot_command[0] = prefixed_name; + } execvp (chroot_command[0], chroot_command); error (8, errno, "cannot execute %s", chroot_command[0]); diff --git a/utils/vmallocate.c b/utils/vmallocate.c new file mode 100644 index 0000000..628cfd1 --- /dev/null +++ b/utils/vmallocate.c @@ -0,0 +1,272 @@ +/* vmallocate -- a utility to allocate memory. + + Copyright (C) 2015,2016 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ + +#include <argp.h> +#include <assert.h> +#include <error.h> +#include <hurd.h> +#include <inttypes.h> +#include <mach.h> +#include <mach/vm_param.h> +#include <unistd.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <version.h> + + + +const char *argp_program_version = STANDARD_HURD_VERSION (vmallocate); + +int verbose; +int do_pause; +int do_read; +int do_write; + +uint64_t size; +uint64_t chunk_size = 1U << 30; /* 1 gigabyte */ +uint64_t allocated; + +static const struct argp_option options[] = +{ + {NULL, 0, NULL, OPTION_DOC, "Mapping options", 1}, + {"read", 'r', NULL, 0, "read from mapping", 1}, + {"write", 'w', NULL, 0, "write to mapping", 1}, + + {NULL, 0, NULL, OPTION_DOC, "Options", 2}, + {"verbose", 'v', NULL, 0, "be more verbose", 2}, + {"pause", 'p', NULL, 0, "read newline from stdin before exiting", 2}, + {0} +}; + +#define UNITS "gGmMkKpP" +static const char args_doc[] = "SIZE["UNITS"]"; +static const char doc[] = "Allocates memory.\v" + "This is a stress-test for the vm system."; + +/* Parse our options... */ +error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + char *end; + switch (key) + { + case 'r': + do_read = 1; + break; + + case 'w': + do_write = 1; + break; + + case 'v': + verbose += 1; + break; + + case 'p': + do_pause = 1; + break; + + case ARGP_KEY_ARG: + if (size > 0) + argp_error (state, "Extra argument after size: %s", arg); + + size = strtoull (arg, &end, 10); + if (arg == end || (end[0] != 0 && end[1] != 0)) + argp_error (state, "Could not parse size `%s'.", arg); + + switch (end[0]) { + case 0: + break; + + case 'g': + case 'G': + size <<= 30; + break; + + case 'm': + case 'M': + size <<= 20; + break; + + case 'k': + case 'K': + size <<= 10; + break; + + case 'p': + case 'P': + size <<= PAGE_SHIFT; + break; + + default: + argp_error (state, + "Unknown unit `%c', expected one of "UNITS".", + end[0]); + } + break; + + case ARGP_KEY_NO_ARGS: + argp_usage (state); + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +const struct argp argp = + { + options: options, + parser: parse_opt, + args_doc: args_doc, + doc: doc, + }; + + + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +struct child +{ + task_t task; + struct child *next; +}; + +int +main (int argc, char **argv) +{ + error_t err; + int nchildren = 0; + struct child *c, *children = NULL; + process_t proc = getproc (); + + /* We must make sure that chunk_size fits into vm_size_t. */ + assert (chunk_size <= 1U << (sizeof (vm_size_t) * 8 - 1)); + + /* Parse our arguments. */ + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (verbose) + fprintf (stderr, "About to allocate %"PRIu64" bytes in chunks of " + "%"PRIu64" bytes.\n", size, chunk_size); + + while (allocated < size) + { + task_t task; + uint64_t s = min (chunk_size, size - allocated); + vm_address_t address = 0; + volatile char *p; + char **argv = NULL; + + err = vm_allocate (mach_task_self (), &address, (vm_size_t) s, + 1 /* anywhere */); + if (err) + error (1, err, "vm_allocate"); + + /* Write an argument and environment vector. */ + if (s > 128) + { + int written; + char *arg0; + + arg0 = (char *) address; + written = sprintf (arg0, "[vmallocate %d]", nchildren); + + argv = (char **) (address + (unsigned) written + 1); + argv[0] = arg0; + argv[1] = NULL; + } + + for (p = (char *) address + PAGE_SIZE; + p < (char *) (address + (size_t) s); + p += PAGE_SIZE) + { + if (do_read) + (void) *p; + if (do_write) + *p = 1; + + if (verbose > 1 + && ((unsigned int) (p - address) & ((1U<<20) - 1)) == 0) + fprintf (stderr, "\r%"PRIu64, + allocated + + ((uint64_t) (uintptr_t) p - (uint64_t) address)); + } + + err = vm_inherit (mach_task_self (), address, (vm_size_t) s, + VM_INHERIT_COPY); + if (err) + error (1, err, "vm_inherit"); + + err = task_create (mach_task_self (), 1, &task); + if (err) + error (1, err, "task_create"); + + err = proc_child (proc, task); + if (err) + error (1, err, "proc_child"); + + if (argv != NULL) + { + process_t childp; + + err = proc_task2proc (proc, task, &childp); + if (err) + error (1, err, "proc_task2proc"); + + err = proc_set_arg_locations (childp, + (vm_offset_t) &argv[0], + (vm_offset_t) &argv[1]); + if (err) + error (1, err, "proc_set_arg_locations"); + } + + c = malloc (sizeof *c); + if (c == NULL) + error (1, errno, "malloc"); + c->task = task; + c->next = children; + children = c; + + err = vm_deallocate (mach_task_self (), address, (vm_size_t) s); + if (err) + error (1, err, "vm_deallocate"); + + allocated += s; + nchildren += 1; + + if (verbose) + fprintf (stderr, "\rAllocated %"PRIu64" bytes.\n", allocated); + } + + if (do_pause) + { + fprintf (stderr, "Press enter to exit and release the memory."); + getchar (); + } + + for (c = children; c; c = c->next) + task_terminate (c->task); + + return EXIT_SUCCESS; +} -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hurd/hurd.git
