This is an automated email from the git hooks/post-receive script. sthibault pushed a commit to branch master in repository hurd.
commit df4a2981796bda165d198b1fa6cb3a13d854a19c Author: Samuel Thibault <[email protected]> Date: Sat May 21 22:39:01 2016 +0000 New upstream snapshot --- NEWS | 5 +- configure.ac | 2 +- console-client/Makefile | 5 +- libdiskfs/dir-lookup.c | 154 +++++++++++++------------------ libdiskfs/fsys-getroot.c | 13 ++- libdiskfs/io-restrict-auth.c | 2 - libdiskfs/trans-callback.c | 4 +- libfshelp/fetch-root.c | 40 ++++++++ libfshelp/fshelp.h | 16 ++++ libihash/ihash.c | 18 ++-- libnetfs/dir-lookup.c | 210 +++++++++++++++++++----------------------- libnetfs/fsys-getroot.c | 7 +- libnetfs/io-restrict-auth.c | 3 - libnetfs/trans-callback.c | 4 +- libstore/Makefile | 5 +- libtrivfs/fsys-getroot.c | 6 +- mach-defpager/default_pager.c | 2 +- startup/startup.c | 2 +- utils/settrans.c | 21 ++++- 19 files changed, 281 insertions(+), 238 deletions(-) diff --git a/NEWS b/NEWS index 091840c..e9c4cb5 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Version 0.8 (2016-04-XX) +Version 0.8 (2016-05-18) The netfs library is using the lockless reference-counting primitives for both peropen and node objects now, and the global reference @@ -11,7 +11,8 @@ translator. Several bugs in our native fakeroot tool have been fixed improving stability and correctness of the translation. -The devnode translator and the 'hurd-slab' library have been merged. +The devnode translator and the hurd-slab library have been merged into this +repository. The code has been cleaned up, and we fixed numerous bugs, most notably a crash in pfinet, a locking bug in libdiskfs, and an out-of-bounds diff --git a/configure.ac b/configure.ac index 124eb07..365fc85 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.54) dnl Minimum Autoconf version required. -AC_INIT([GNU Hurd], [0.7], [[email protected]]) +AC_INIT([GNU Hurd], [0.8], [[email protected]]) AC_CONFIG_SRCDIR([hurd/hurd_types.h]) dnl File to look for in srcdir. AC_PREFIX_DEFAULT() dnl Default to empty prefix, not /usr/local. diff --git a/console-client/Makefile b/console-client/Makefile index 1784d7c..024a053 100644 --- a/console-client/Makefile +++ b/console-client/Makefile @@ -1,6 +1,7 @@ # # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, -# 2005, 2008, 2010 Free Software Foundation, Inc. +# 2005, 2008, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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 @@ -91,7 +92,7 @@ $(module-dir)/%: % # You can use this rule to make a dynamically-loadable version of any # of the modules. %.so.$(hurd-version): - $(CC) -shared -Wl,-soname=$@ -o $@ $(rpath) \ + $(CC) -shared -Wl,-soname=$@ -o $@ $(lpath) \ $(CFLAGS) $($*-CFLAGS) $(LDFLAGS) \ '-Wl,-(' $($*-LDLIBS) '-Wl,-)' $^ diff --git a/libdiskfs/dir-lookup.c b/libdiskfs/dir-lookup.c index c50970d..8b43e27 100644 --- a/libdiskfs/dir-lookup.c +++ b/libdiskfs/dir-lookup.c @@ -20,6 +20,7 @@ #include <fcntl.h> #include <string.h> #include <sys/file.h> +#include <hurd/fshelp.h> #include <hurd/fsys.h> #include <hurd/paths.h> @@ -27,19 +28,19 @@ #include "fs_S.h" /* Implement dir_lookup as described in <hurd/fs.defs>. */ -kern_return_t +error_t diskfs_S_dir_lookup (struct protid *dircred, - char *path, + char *filename, int flags, mode_t mode, - enum retry_type *retry, - char *retryname, - file_t *returned_port, - mach_msg_type_name_t *returned_port_poly) + retry_type *do_retry, + char *retry_name, + mach_port_t *retry_port, + mach_msg_type_name_t *retry_port_type) { struct node *dnp; struct node *np; - int nsymlink = 0; + int nsymlinks = 0; char *nextname; char *relpath; int nextnamelen; @@ -66,23 +67,23 @@ diskfs_S_dir_lookup (struct protid *dircred, excl = (flags & O_EXCL); /* Skip leading slashes */ - while (path[0] == '/') - path++; + while (*filename == '/') + filename++; - /* Preserve the path relative to diruser->po->path. */ - relpath = strdup (path); + /* Preserve the path relative to dircred->po->path. */ + relpath = strdup (filename); if (! relpath) return ENOMEM; - /* Keep a pointer to the start of the path for length + /* Keep a pointer to the start of the filename for length calculations. */ - char *path_start = path; + char *filename_start = filename; - *returned_port_poly = MACH_MSG_TYPE_MAKE_SEND; - *retry = FS_RETRY_NORMAL; - retryname[0] = '\0'; + *retry_port_type = MACH_MSG_TYPE_MAKE_SEND; + *do_retry = FS_RETRY_NORMAL; + *retry_name = '\0'; - if (path[0] == '\0') + if (*filename == '\0') { /* Set things up in the state expected by the code from gotit: on. */ dnp = 0; @@ -93,9 +94,7 @@ diskfs_S_dir_lookup (struct protid *dircred, } dnp = dircred->po->np; - pthread_mutex_lock (&dnp->lock); - np = 0; diskfs_nref (dnp); /* acquire a reference for later diskfs_nput */ @@ -104,7 +103,7 @@ diskfs_S_dir_lookup (struct protid *dircred, assert (!lastcomp); /* Find the name of the next pathname component */ - nextname = index (path, '/'); + nextname = index (filename, '/'); if (nextname) { @@ -132,10 +131,10 @@ diskfs_S_dir_lookup (struct protid *dircred, { if (!ds) ds = alloca (diskfs_dirstat_size); - err = diskfs_lookup (dnp, path, CREATE, &np, ds, dircred); + err = diskfs_lookup (dnp, filename, CREATE, &np, ds, dircred); } else - err = diskfs_lookup (dnp, path, LOOKUP, &np, 0, dircred); + err = diskfs_lookup (dnp, filename, LOOKUP, &np, 0, dircred); if (lastcomp && create && excl && (!err || err == EAGAIN)) err = EEXIST; @@ -158,13 +157,13 @@ diskfs_S_dir_lookup (struct protid *dircred, else { /* Punt the client up to the shadow root parent. */ - *retry = FS_RETRY_REAUTH; - *returned_port = dircred->po->shadow_root_parent; - *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; + *do_retry = FS_RETRY_REAUTH; + *retry_port = dircred->po->shadow_root_parent; + *retry_port_type = MACH_MSG_TYPE_COPY_SEND; if (lastcomp && mustbedir) /* Trailing slash. */ - strcpy (retryname, "/"); + strcpy (retry_name, "/"); else if (!lastcomp) - strcpy (retryname, nextname); + strcpy (retry_name, nextname); err = 0; goto out; } @@ -174,13 +173,13 @@ diskfs_S_dir_lookup (struct protid *dircred, shadow root, we can get here if its in a directory that was renamed out from under it... */ { - *retry = FS_RETRY_REAUTH; - *returned_port = dircred->po->root_parent; - *returned_port_poly = MACH_MSG_TYPE_COPY_SEND; + *do_retry = FS_RETRY_REAUTH; + *retry_port = dircred->po->root_parent; + *retry_port_type = MACH_MSG_TYPE_COPY_SEND; if (lastcomp && mustbedir) /* Trailing slash. */ - strcpy (retryname, "/"); + strcpy (retry_name, "/"); else if (!lastcomp) - strcpy (retryname, nextname); + strcpy (retry_name, nextname); err = 0; goto out; } @@ -200,7 +199,7 @@ diskfs_S_dir_lookup (struct protid *dircred, { mode &= ~(S_IFMT | S_ISPARE | S_ISVTX | S_ITRANS); mode |= S_IFREG; - err = diskfs_create_node (dnp, path, mode, &np, dircred, ds); + err = diskfs_create_node (dnp, filename, mode, &np, dircred, ds); if (diskfs_synchronous) { diskfs_file_update (dnp, 1); @@ -227,41 +226,6 @@ diskfs_S_dir_lookup (struct protid *dircred, mach_port_t dirport; struct iouser *user; - /* A callback function for short-circuited translators. - Symlink & ifsock are handled elsewhere. */ - error_t short_circuited_callback1 (void *cookie1, void *cookie2, - uid_t *uid, gid_t *gid, - char **argz, size_t *argz_len) - { - struct node *node = cookie1; - - switch (node->dn_stat.st_mode & S_IFMT) - { - case S_IFCHR: - case S_IFBLK: - asprintf (argz, "%s%c%d%c%d", - (S_ISCHR (node->dn_stat.st_mode) - ? _HURD_CHRDEV : _HURD_BLKDEV), - 0, major (node->dn_stat.st_rdev), - 0, minor (node->dn_stat.st_rdev)); - *argz_len = strlen (*argz) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - break; - case S_IFIFO: - asprintf (argz, "%s", _HURD_FIFO); - *argz_len = strlen (*argz) + 1; - break; - default: - return ENOENT; - } - - *uid = node->dn_stat.st_uid; - *gid = node->dn_stat.st_gid; - - return 0; - } - /* Create an unauthenticated port for DNP, and then unlock it. */ err = iohelp_create_empty_iouser (&user); @@ -292,14 +256,21 @@ diskfs_S_dir_lookup (struct protid *dircred, boolean_t register_translator = np->transbox.active == MACH_PORT_NULL; - err = fshelp_fetch_root (&np->transbox, dircred->po, - dirport, dircred->user, - lastcomp ? flags : 0, - ((np->dn_stat.st_mode & S_IPTRANS) - ? _diskfs_translator_callback1 - : short_circuited_callback1), - _diskfs_translator_callback2, - retry, retryname, returned_port); + struct fshelp_stat_cookie2 cookie = { + .statp = &np->dn_stat, + .modep = &np->dn_stat.st_mode, + .next = dircred->po, + }; + err = fshelp_fetch_root (&np->transbox, + &cookie, + dirport, + dircred->user, + lastcomp ? flags : 0, + ((np->dn_stat.st_mode & S_IPTRANS) + ? _diskfs_translator_callback1 + : fshelp_short_circuited_callback1), + _diskfs_translator_callback2, + do_retry, retry_name, retry_port); /* fetch_root copies DIRPORT for success, so we always should deallocate our send right. */ @@ -307,14 +278,14 @@ diskfs_S_dir_lookup (struct protid *dircred, if (err != ENOENT) { - *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND; + *retry_port_type = MACH_MSG_TYPE_MOVE_SEND; if (!err) { - char *end = strchr (retryname, '\0'); + char *end = strchr (retry_name, '\0'); if (mustbedir) *end++ = '/'; /* Trailing slash. */ else if (!lastcomp) { - if (end != retryname) + if (end != retry_name) *end++ = '/'; strcpy (end, nextname); } @@ -333,7 +304,7 @@ diskfs_S_dir_lookup (struct protid *dircred, char *end = nextname; while (*end != 0) end--; - translator_path[end - path_start] = '\0'; + translator_path[end - filename_start] = '\0'; } if (dircred->po->path == NULL || !strcmp (dircred->po->path,".")) @@ -363,7 +334,7 @@ diskfs_S_dir_lookup (struct protid *dircred, err = 0; if (np != dnp) { - if (!strcmp (path, "..")) + if (!strcmp (filename, "..")) pthread_mutex_lock (&dnp->lock); else { @@ -384,7 +355,7 @@ diskfs_S_dir_lookup (struct protid *dircred, { /* Handle symlink interpretation */ - if (nsymlink++ > diskfs_maxsymlinks) + if (nsymlinks++ > diskfs_maxsymlinks) { err = ELOOP; goto out; @@ -412,7 +383,7 @@ diskfs_S_dir_lookup (struct protid *dircred, goto out; if (np->dn_stat.st_size == 0) /* symlink to "" */ - path = nextname; + filename = nextname; else { if (nextname) @@ -432,13 +403,13 @@ diskfs_S_dir_lookup (struct protid *dircred, if (pathbuf[0] == '/') { /* Punt to the caller. */ - *retry = FS_RETRY_MAGICAL; - *returned_port = MACH_PORT_NULL; - strcpy (retryname, pathbuf); + *do_retry = FS_RETRY_MAGICAL; + *retry_port = MACH_PORT_NULL; + strcpy (retry_name, pathbuf); goto out; } - path = pathbuf; + filename = pathbuf; mustbedir = 0; } @@ -448,7 +419,7 @@ diskfs_S_dir_lookup (struct protid *dircred, diskfs_nput (np); np = 0; - if (path == 0) /* symlink to "" was the last component */ + if (filename == 0) /* symlink to "" was the last component */ { np = dnp; dnp = 0; @@ -458,7 +429,7 @@ diskfs_S_dir_lookup (struct protid *dircred, else { /* Handle normal nodes */ - path = nextname; + filename = nextname; if (np == dnp) diskfs_nrele (dnp); else @@ -471,7 +442,8 @@ diskfs_S_dir_lookup (struct protid *dircred, else dnp = 0; } - } while (path && *path); + } + while (filename && *filename); /* At this point, np is the node to return. If newnode is set, then we just created this node. */ @@ -553,7 +525,7 @@ diskfs_S_dir_lookup (struct protid *dircred, if (! newpi->po->path) err = errno; - *returned_port = ports_get_right (newpi); + *retry_port = ports_get_right (newpi); ports_port_deref (newpi); newpi = 0; } diff --git a/libdiskfs/fsys-getroot.c b/libdiskfs/fsys-getroot.c index 401f103..6f93888 100644 --- a/libdiskfs/fsys-getroot.c +++ b/libdiskfs/fsys-getroot.c @@ -21,6 +21,7 @@ #include "priv.h" #include "fsys_S.h" +#include <hurd/fshelp.h> #include <hurd/fsys.h> #include <fcntl.h> @@ -78,11 +79,15 @@ diskfs_S_fsys_getroot (struct diskfs_control *pt, || fshelp_translated (&diskfs_root_node->transbox)) && !(flags & O_NOTRANS)) { + struct fshelp_stat_cookie2 cookie = { + .next = &peropen_context, + }; + err = fshelp_fetch_root (&diskfs_root_node->transbox, - &peropen_context, dotdot, &user, flags, - _diskfs_translator_callback1, - _diskfs_translator_callback2, - retry, retryname, returned_port); + &cookie, dotdot, &user, flags, + _diskfs_translator_callback1, + _diskfs_translator_callback2, + retry, retryname, returned_port); if (err != ENOENT) { pthread_mutex_unlock (&diskfs_root_node->lock); diff --git a/libdiskfs/io-restrict-auth.c b/libdiskfs/io-restrict-auth.c index 80c0b20..1c2c999 100644 --- a/libdiskfs/io-restrict-auth.c +++ b/libdiskfs/io-restrict-auth.c @@ -40,7 +40,6 @@ diskfs_S_io_restrict_auth (struct protid *cred, if (err) return err; - pthread_mutex_lock (&cred->po->np->lock); refcount_ref (&cred->po->refcnt); err = diskfs_create_protid (cred->po, user, &newpi); if (! err) @@ -51,7 +50,6 @@ diskfs_S_io_restrict_auth (struct protid *cred, } else refcount_deref (&cred->po->refcnt); - pthread_mutex_unlock (&cred->po->np->lock); iohelp_free_iouser (user); return err; diff --git a/libdiskfs/trans-callback.c b/libdiskfs/trans-callback.c index 283b184..15e8f9a 100644 --- a/libdiskfs/trans-callback.c +++ b/libdiskfs/trans-callback.c @@ -20,6 +20,7 @@ #include "priv.h" #include <fcntl.h> +#include <hurd/fshelp.h> /* Callback function needed for calls to fshelp_fetch_root. See <hurd/fshelp.h> for the interface description. */ @@ -56,6 +57,7 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, mach_msg_type_name_t *underlying_type) { struct node *np = cookie1; + struct fshelp_stat_cookie2 *statc = cookie2; struct protid *cred; struct peropen *po; error_t err; @@ -66,7 +68,7 @@ _diskfs_translator_callback2_fn (void *cookie1, void *cookie2, if (err) return err; - err = diskfs_make_peropen (np, flags, cookie2, &po); + err = diskfs_make_peropen (np, flags, statc->next, &po); if (! err) { err = diskfs_create_protid (po, user, &cred); diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c index eb0f315..75aa2d3 100644 --- a/libfshelp/fetch-root.c +++ b/libfshelp/fetch-root.c @@ -20,7 +20,9 @@ #include <assert.h> #include <hurd/fsys.h> +#include <hurd/paths.h> #include <hurd/ports.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -197,3 +199,41 @@ fshelp_fetch_root (struct transbox *box, void *cookie, return err; } + +/* A callback function for short-circuited translators. S_ISLNK and + S_IFSOCK must be handled elsewhere. */ +error_t +fshelp_short_circuited_callback1 (void *cookie1, void *cookie2, + uid_t *uid, gid_t *gid, + char **argz, size_t *argz_len) +{ + struct fshelp_stat_cookie2 *statc = cookie2; + + switch (*statc->modep & S_IFMT) + { + case S_IFCHR: + case S_IFBLK: + if (asprintf (argz, "%s%c%d%c%d", + (S_ISCHR (*statc->modep) + ? _HURD_CHRDEV : _HURD_BLKDEV), + 0, major (statc->statp->st_rdev), + 0, minor (statc->statp->st_rdev)) < 0) + return ENOMEM; + *argz_len = strlen (*argz) + 1; + *argz_len += strlen (*argz + *argz_len) + 1; + *argz_len += strlen (*argz + *argz_len) + 1; + break; + case S_IFIFO: + if (asprintf (argz, "%s", _HURD_FIFO) < 0) + return ENOMEM; + *argz_len = strlen (*argz) + 1; + break; + default: + return ENOENT; + } + + *uid = statc->statp->st_uid; + *gid = statc->statp->st_gid; + + return 0; +} diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h index d04c056..ecd9335 100644 --- a/libfshelp/fshelp.h +++ b/libfshelp/fshelp.h @@ -148,6 +148,22 @@ typedef error_t (*fshelp_fetch_root_callback1_t) (void *cookie1, void *cookie2, uid_t *uid, gid_t *gid, char **argz, size_t *argz_len); +/* A cookie for fshelp_short_circuited_callback1. Such a structure + must be passed to the call to fshelp_fetch_root. */ +struct fshelp_stat_cookie2 +{ + io_statbuf_t *statp; + mode_t *modep; + void *next; +}; + +/* A callback function for short-circuited translators. S_ISLNK and + S_IFSOCK must be handled elsewhere. */ +error_t fshelp_short_circuited_callback1 (void *cookie1, void *cookie2, + uid_t *uid, gid_t *gid, + char **argz, size_t *argz_len); + + /* This routine is called by fshelp_fetch_root to fetch more information. Return an unauthenticated node for the file itself in *UNDERLYING and *UNDERLYING_TYPE (opened with FLAGS). COOKIE1 is the cookie passed in diff --git a/libihash/ihash.c b/libihash/ihash.c index ae1cf12..2fc7093 100644 --- a/libihash/ihash.c +++ b/libihash/ihash.c @@ -287,17 +287,20 @@ hurd_ihash_locp_add (hurd_ihash_t ht, hurd_ihash_locp_t locp, /* In case of complications, fall back to hurd_ihash_add. */ if (ht->size == 0 || item == NULL - || item->value == _HURD_IHASH_DELETED - || ! compare (ht, item->key, key) + || (hurd_ihash_value_valid (item->value) + && ! compare (ht, item->key, key)) || hurd_ihash_get_effective_load (ht) > ht->max_load) return hurd_ihash_add (ht, key, value); - if (item->value == _HURD_IHASH_EMPTY) + if (! hurd_ihash_value_valid (item->value)) { item->key = key; ht->nr_items += 1; - assert (ht->nr_free > 0); - ht->nr_free -= 1; + if (item->value == _HURD_IHASH_EMPTY) + { + assert (ht->nr_free > 0); + ht->nr_free -= 1; + } } else { @@ -418,7 +421,10 @@ hurd_ihash_locp_find (hurd_ihash_t ht, int idx; if (ht->size == 0) - return NULL; + { + *slot = NULL; + return NULL; + } idx = find_index (ht, key); *slot = &ht->items[idx].value; diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c index cbe2941..731e53c 100644 --- a/libnetfs/dir-lookup.c +++ b/libnetfs/dir-lookup.c @@ -30,7 +30,7 @@ #include "misc.h" error_t -netfs_S_dir_lookup (struct protid *diruser, +netfs_S_dir_lookup (struct protid *dircred, char *filename, int flags, mode_t mode, @@ -48,11 +48,11 @@ netfs_S_dir_lookup (struct protid *diruser, struct node *dnp, *np; char *nextname; char *relpath; - error_t error; + error_t err; struct protid *newpi = NULL; struct iouser *user; - if (!diruser) + if (!dircred) return EOPNOTSUPP; create = (flags & O_CREAT); @@ -62,7 +62,7 @@ netfs_S_dir_lookup (struct protid *diruser, while (*filename == '/') filename++; - /* Preserve the path relative to diruser->po->path. */ + /* Preserve the path relative to dircred->po->path. */ relpath = strdup (filename); if (! relpath) return ENOMEM; @@ -79,13 +79,13 @@ netfs_S_dir_lookup (struct protid *diruser, { /* Set things up in the state expected by the code from gotit: on. */ dnp = 0; - np = diruser->po->np; + np = dircred->po->np; pthread_mutex_lock (&np->lock); netfs_nref (np); goto gotit; } - dnp = diruser->po->np; + dnp = dircred->po->np; pthread_mutex_lock (&dnp->lock); netfs_nref (dnp); /* acquire a reference for later netfs_nput */ @@ -120,68 +120,81 @@ netfs_S_dir_lookup (struct protid *diruser, retry_lookup: - if ((dnp == netfs_root_node || dnp == diruser->po->shadow_root) + if ((dnp == netfs_root_node || dnp == dircred->po->shadow_root) && filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') - if (dnp == diruser->po->shadow_root) + if (dnp == dircred->po->shadow_root) /* We're at the root of a shadow tree. */ { - *do_retry = FS_RETRY_REAUTH; - *retry_port = diruser->po->shadow_root_parent; - *retry_port_type = MACH_MSG_TYPE_COPY_SEND; - if (lastcomp && mustbedir) /* Trailing slash. */ - strcpy (retry_name, "/"); - else if (!lastcomp) - strcpy (retry_name, nextname); - error = 0; - pthread_mutex_unlock (&dnp->lock); - goto out; + if (dircred->po->shadow_root_parent == MACH_PORT_NULL) + { + /* This is a shadow root with no parent, meaning + we should treat it as a virtual root disconnected + from its real .. directory. */ + err = 0; + np = dnp; + netfs_nref (np); + } + else + { + /* Punt the client up to the shadow root parent. */ + *do_retry = FS_RETRY_REAUTH; + *retry_port = dircred->po->shadow_root_parent; + *retry_port_type = MACH_MSG_TYPE_COPY_SEND; + if (lastcomp && mustbedir) /* Trailing slash. */ + strcpy (retry_name, "/"); + else if (!lastcomp) + strcpy (retry_name, nextname); + err = 0; + pthread_mutex_unlock (&dnp->lock); + goto out; + } } - else if (diruser->po->root_parent != MACH_PORT_NULL) - /* We're at a real translator root; even if DIRUSER->po has a + else if (dircred->po->root_parent != MACH_PORT_NULL) + /* We're at a real translator root; even if DIRCRED->po has a shadow root, we can get here if its in a directory that was renamed out from under it... */ { *do_retry = FS_RETRY_REAUTH; - *retry_port = diruser->po->root_parent; + *retry_port = dircred->po->root_parent; *retry_port_type = MACH_MSG_TYPE_COPY_SEND; if (lastcomp && mustbedir) /* Trailing slash. */ strcpy (retry_name, "/"); else if (!lastcomp) strcpy (retry_name, nextname); - error = 0; + err = 0; pthread_mutex_unlock (&dnp->lock); goto out; } else /* We are global root */ { - error = 0; + err = 0; np = dnp; netfs_nref (np); } else /* Attempt a lookup on the next pathname component. */ - error = netfs_attempt_lookup (diruser->user, dnp, filename, &np); + err = netfs_attempt_lookup (dircred->user, dnp, filename, &np); /* At this point, DNP is unlocked */ /* Implement O_EXCL flag here */ - if (lastcomp && create && excl && !error) - error = EEXIST; + if (lastcomp && create && excl && !err) + err = EEXIST; /* Create the new node if necessary */ - if (lastcomp && create && error == ENOENT) + if (lastcomp && create && err == ENOENT) { mode &= ~(S_IFMT | S_ISPARE | S_ISVTX); mode |= S_IFREG; pthread_mutex_lock (&dnp->lock); - error = netfs_attempt_create_file (diruser->user, dnp, - filename, mode, &np); + err = netfs_attempt_create_file (dircred->user, dnp, + filename, mode, &np); /* If someone has already created the file (between our lookup and this create) then we just got EEXIST. If we are EXCL, that's fine; otherwise, we have to retry the lookup. */ - if (error == EEXIST && !excl) + if (err == EEXIST && !excl) { pthread_mutex_lock (&dnp->lock); goto retry_lookup; @@ -191,11 +204,11 @@ netfs_S_dir_lookup (struct protid *diruser, } /* All remaining errors get returned to the user */ - if (error) + if (err) goto out; - error = netfs_validate_stat (np, diruser->user); - if (error) + err = netfs_validate_stat (np, dircred->user); + if (err) goto out; if ((((flags & O_NOTRANS) == 0) || !lastcomp || mustbedir) @@ -207,66 +220,30 @@ netfs_S_dir_lookup (struct protid *diruser, { mach_port_t dirport; - /* A callback function for short-circuited translators. - S_ISLNK and S_IFSOCK are handled elsewhere. */ - error_t short_circuited_callback1 (void *cookie1, void *cookie2, - uid_t *uid, gid_t *gid, - char **argz, size_t *argz_len) - { - struct node *np = cookie1; - error_t err; - - err = netfs_validate_stat (np, diruser->user); - if (err) - return err; - - switch (np->nn_translated & S_IFMT) - { - case S_IFCHR: - case S_IFBLK: - if (asprintf (argz, "%s%c%d%c%d", - (S_ISCHR (np->nn_translated) - ? _HURD_CHRDEV : _HURD_BLKDEV), - 0, major (np->nn_stat.st_rdev), - 0, minor (np->nn_stat.st_rdev)) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - *argz_len += strlen (*argz + *argz_len) + 1; - break; - case S_IFIFO: - if (asprintf (argz, "%s", _HURD_FIFO) < 0) - return ENOMEM; - *argz_len = strlen (*argz) + 1; - break; - default: - return ENOENT; - } - - *uid = np->nn_stat.st_uid; - *gid = np->nn_stat.st_gid; - - return 0; - } - /* Create an unauthenticated port for DNP, and then unlock it. */ - error = iohelp_create_empty_iouser (&user); - if (! error) + err = iohelp_create_empty_iouser (&user); + if (! err) { newpi = netfs_make_protid (netfs_make_peropen (dnp, 0, - diruser->po), + dircred->po), user); if (! newpi) { - error = errno; + err = errno; iohelp_free_iouser (user); } } boolean_t register_translator = 0; - if (! error) + if (! err) { + struct fshelp_stat_cookie2 cookie = { + .statp = &np->nn_stat, + .modep = &np->nn_translated, + .next = dircred->po, + }; + dirport = ports_get_send_right (newpi); /* Check if an active translator is currently running. If @@ -275,24 +252,25 @@ netfs_S_dir_lookup (struct protid *diruser, translators. */ register_translator = np->transbox.active == MACH_PORT_NULL; - error = fshelp_fetch_root (&np->transbox, diruser->po, - dirport, - diruser->user, - lastcomp ? flags : 0, - ((np->nn_translated & S_IPTRANS) - ? _netfs_translator_callback1 - : short_circuited_callback1), - _netfs_translator_callback2, - do_retry, retry_name, retry_port); + err = fshelp_fetch_root (&np->transbox, + &cookie, + dirport, + dircred->user, + lastcomp ? flags : 0, + ((np->nn_translated & S_IPTRANS) + ? _netfs_translator_callback1 + : fshelp_short_circuited_callback1), + _netfs_translator_callback2, + do_retry, retry_name, retry_port); /* fetch_root copies DIRPORT for success, so we always should deallocate our send right. */ mach_port_deallocate (mach_task_self (), dirport); } - if (error != ENOENT) + if (err != ENOENT) { *retry_port_type = MACH_MSG_TYPE_MOVE_SEND; - if (!error) + if (!err) { char *end = strchr (retry_name, '\0'); if (mustbedir) @@ -320,18 +298,18 @@ netfs_S_dir_lookup (struct protid *diruser, translator_path[end - filename_start] = '\0'; } - if (diruser->po->path == NULL || !strcmp (diruser->po->path,".")) - /* diruser is the root directory. */ + if (dircred->po->path == NULL || !strcmp (dircred->po->path,".")) + /* dircred is the root directory. */ complete_path = translator_path; else - asprintf (&complete_path, "%s/%s", diruser->po->path, translator_path); + asprintf (&complete_path, "%s/%s", dircred->po->path, translator_path); - error = fshelp_set_active_translator (&newpi->pi, - complete_path, - np->transbox.active); + err = fshelp_set_active_translator (&newpi->pi, + complete_path, + np->transbox.active); if (complete_path != translator_path) free(complete_path); - if (error) + if (err) { ports_port_deref (newpi); goto out; @@ -346,7 +324,7 @@ netfs_S_dir_lookup (struct protid *diruser, /* ENOENT means there was a hiccup, and the translator vanished while NP was unlocked inside fshelp_fetch_root; continue as normal. */ - error = 0; + err = 0; } if (S_ISLNK (np->nn_translated) @@ -360,7 +338,7 @@ netfs_S_dir_lookup (struct protid *diruser, /* Handle symlink interpretation */ if (nsymlinks++ > netfs_maxsymlinks) { - error = ELOOP; + err = ELOOP; goto out; } @@ -370,8 +348,8 @@ netfs_S_dir_lookup (struct protid *diruser, newnamelen = nextnamelen + linklen + 1 + 1; linkbuf = alloca (newnamelen); - error = netfs_attempt_readlink (diruser->user, np, linkbuf); - if (error) + err = netfs_attempt_readlink (dircred->user, np, linkbuf); + if (err) goto out; if (nextname) @@ -433,48 +411,48 @@ netfs_S_dir_lookup (struct protid *diruser, if (mustbedir) { - netfs_validate_stat (np, diruser->user); + netfs_validate_stat (np, dircred->user); if (!S_ISDIR (np->nn_stat.st_mode)) { - error = ENOTDIR; + err = ENOTDIR; goto out; } } - error = netfs_check_open_permissions (diruser->user, np, - flags, newnode); - if (error) + err = netfs_check_open_permissions (dircred->user, np, + flags, newnode); + if (err) goto out; flags &= ~OPENONLY_STATE_MODES; - error = iohelp_dup_iouser (&user, diruser->user); - if (error) + err = iohelp_dup_iouser (&user, dircred->user); + if (err) goto out; - newpi = netfs_make_protid (netfs_make_peropen (np, flags, diruser->po), + newpi = netfs_make_protid (netfs_make_peropen (np, flags, dircred->po), user); if (! newpi) { iohelp_free_iouser (user); - error = errno; + err = errno; goto out; } free (newpi->po->path); - if (diruser->po->path == NULL || !strcmp (diruser->po->path,".")) + if (dircred->po->path == NULL || !strcmp (dircred->po->path,".")) { - /* diruser is the root directory. */ + /* dircred is the root directory. */ newpi->po->path = relpath; relpath = NULL; /* Do not free relpath. */ } else { newpi->po->path = NULL; - asprintf (&newpi->po->path, "%s/%s", diruser->po->path, relpath); + asprintf (&newpi->po->path, "%s/%s", dircred->po->path, relpath); } if (! newpi->po->path) - error = errno; + err = errno; *retry_port = ports_get_right (newpi); ports_port_deref (newpi); @@ -485,5 +463,5 @@ netfs_S_dir_lookup (struct protid *diruser, if (dnp) netfs_nrele (dnp); free (relpath); - return error; + return err; } diff --git a/libnetfs/fsys-getroot.c b/libnetfs/fsys-getroot.c index 2d02120..d919110 100644 --- a/libnetfs/fsys-getroot.c +++ b/libnetfs/fsys-getroot.c @@ -23,6 +23,7 @@ #include "misc.h" #include "callbacks.h" #include <fcntl.h> +#include <hurd/fshelp.h> error_t netfs_S_fsys_getroot (struct netfs_control *pt, @@ -67,8 +68,12 @@ netfs_S_fsys_getroot (struct netfs_control *pt, || fshelp_translated (&netfs_root_node->transbox)) && !(flags & O_NOTRANS)) { + struct fshelp_stat_cookie2 cookie = { + .next = &peropen_context, + }; + err = fshelp_fetch_root (&netfs_root_node->transbox, - &peropen_context, dotdot, cred, flags, + &cookie, dotdot, cred, flags, _netfs_translator_callback1, _netfs_translator_callback2, do_retry, retry_name, retry_port); diff --git a/libnetfs/io-restrict-auth.c b/libnetfs/io-restrict-auth.c index 79b7d09..89df671 100644 --- a/libnetfs/io-restrict-auth.c +++ b/libnetfs/io-restrict-auth.c @@ -42,19 +42,16 @@ netfs_S_io_restrict_auth (struct protid *user, if (err) return err; - pthread_mutex_lock (&user->po->np->lock); refcount_ref (&user->po->refcnt); newpi = netfs_make_protid (user->po, new_user); if (newpi) { *newport = ports_get_right (newpi); - pthread_mutex_unlock (&user->po->np->lock); *newporttype = MACH_MSG_TYPE_MAKE_SEND; } else { refcount_deref (&user->po->refcnt); - pthread_mutex_unlock (&user->po->np->lock); iohelp_free_iouser (new_user); err = ENOMEM; } diff --git a/libnetfs/trans-callback.c b/libnetfs/trans-callback.c index ed21aa2..99f4dc0 100644 --- a/libnetfs/trans-callback.c +++ b/libnetfs/trans-callback.c @@ -20,6 +20,7 @@ #include "priv.h" #include <fcntl.h> +#include <hurd/fshelp.h> /* Callback function needed for calls to fshelp_fetch_root. See <hurd/fshelp.h> for the interface description. */ @@ -57,6 +58,7 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, error_t err; struct protid *cred; struct node *node = cookie1; + struct fshelp_stat_cookie2 *statc = cookie2; struct iouser *user; struct peropen *po; @@ -65,7 +67,7 @@ _netfs_translator_callback2_fn (void *cookie1, void *cookie2, int flags, if (err) return err; - po = netfs_make_peropen (node, flags, cookie2); + po = netfs_make_peropen (node, flags, statc->next); if (! po) { err = errno; diff --git a/libstore/Makefile b/libstore/Makefile index 28f5660..3ba0017 100644 --- a/libstore/Makefile +++ b/libstore/Makefile @@ -1,6 +1,7 @@ # Makefile for libstore # -# Copyright (C) 1995,96,97,2001,02 Free Software Foundation, Inc. +# Copyright (C) 1995, 1996, 1997, 1999, 2001, 2002, 2010, 2012, 2013, 2014, +# 2016 Free Software Foundation, Inc. # Written by Miles Bader <[email protected]> # # This file is part of the GNU Hurd. @@ -73,7 +74,7 @@ libstore_bunzip2.so.$(hurd-version): $(BUNZIP2_OBJS:.o=_pic.o) # just include all the standard store types in libstore.so itself. libstore_%.so.$(hurd-version): %_pic.o libstore.so $(CC) -shared -Wl,-soname=$@ -o $@ \ - $(rpath) $(CFLAGS) $(LDFLAGS) $(libstore_$*.so-LDFLAGS) $^ + $(lpath) $(CFLAGS) $(LDFLAGS) $(libstore_$*.so-LDFLAGS) $^ # Each libstore_TYPE.a is in fact an object file script so that `-lstore_TYPE' # just has the same effect as `-u store_TYPE_class'. diff --git a/libtrivfs/fsys-getroot.c b/libtrivfs/fsys-getroot.c index c44e535..c9b8261 100644 --- a/libtrivfs/fsys-getroot.c +++ b/libtrivfs/fsys-getroot.c @@ -75,11 +75,11 @@ trivfs_S_fsys_getroot (struct trivfs_control *cntl, .alloced = nuids, }; - if (idvec_contains (&idvec, 0)) - /* Root should be given all our rights. */ + if (_is_privileged (&idvec)) + /* Privileged users should be given all our rights. */ err = io_duplicate (cntl->underlying, &new_realnode); else - /* Non-root, restrict rights. */ + /* Non-privileged, restrict rights. */ err = io_restrict_auth (cntl->underlying, &new_realnode, uids, nuids, gids, ngids); diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c index c79a82a..4293e2a 100644 --- a/mach-defpager/default_pager.c +++ b/mach-defpager/default_pager.c @@ -3007,7 +3007,7 @@ default_pager_thread(void *arg) kr = mach_msg_server(default_pager_demux_object, default_pager_msg_size_object, pset); - panic(my_name, kr); + panic("%s%s", my_name, strerror (kr)); } } diff --git a/startup/startup.c b/startup/startup.c index f90b524..3098454 100644 --- a/startup/startup.c +++ b/startup/startup.c @@ -401,7 +401,7 @@ run (const char *server, mach_port_t *ports, task_t *task) } if (verbose) - fprintf (stderr, stderr, "started %s\n", prog); + fprintf (stderr, "started %s\n", prog); /* Dead-name notification on the task port will tell us when it dies, so we can crash if we don't make it to a fully bootstrapped Hurd. */ diff --git a/utils/settrans.c b/utils/settrans.c index e01906b..ee7cba5 100644 --- a/utils/settrans.c +++ b/utils/settrans.c @@ -47,6 +47,7 @@ const char *argp_program_version = STANDARD_HURD_VERSION (settrans); #define STRINGIFY(arg) _STRINGIFY (arg) #define OPT_CHROOT_CHDIR -1 +#define OPT_STACK -2 static struct argp_option options[] = { @@ -66,6 +67,8 @@ static struct argp_option options[] = "(do not ask it to go away)"}, {"underlying", 'U', "NODE", 0, "Open NODE and hand it to the translator " "as the underlying node"}, + {"stack", OPT_STACK, 0, 0, "Replace an existing translator, but keep it " + "running, and put the new one on top"}, {"chroot", 'C', 0, 0, "Instead of setting the node's translator, take following arguments up to" @@ -156,10 +159,12 @@ main(int argc, char *argv[]) int passive = 0, active = 0, keep_active = 0, pause = 0, kill_active = 0, orphan = 0; int start = 0; + int stack = 0; char *pid_file = NULL; int excl = 0; int timeout = DEFAULT_TIMEOUT * 1000; /* ms */ char *underlying_node_name = NULL; + int underlying_lookup_flags; char **chroot_command = 0; char *chroot_chdir = "/"; @@ -193,6 +198,11 @@ main(int argc, char *argv[]) start = 1; active = 1; /* start implies active */ break; + case OPT_STACK: + stack = 1; + active = 1; /* stack implies active */ + orphan = 1; /* stack implies orphan */ + break; case 'p': passive = 1; break; case 'k': keep_active = 1; break; case 'g': kill_active = 1; break; @@ -261,6 +271,14 @@ main(int argc, char *argv[]) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0); + if (stack) + { + underlying_node_name = node_name; + underlying_lookup_flags = lookup_flags && ~O_NOTRANS; + } + else + underlying_lookup_flags = lookup_flags; + if (!active && !passive && !chroot_command) passive = 1; /* By default, set the passive translator. */ @@ -341,7 +359,8 @@ main(int argc, char *argv[]) if (underlying_node_name) { *underlying = file_name_lookup (underlying_node_name, - flags | lookup_flags, 0666); + flags | underlying_lookup_flags, + 0666); if (! MACH_PORT_VALID (*underlying)) { /* For the error message. */ -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hurd/hurd.git
