[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 01/03: New upstream snapshot
From: |
Samuel Thibault |
Subject: |
[hurd] 01/03: New upstream snapshot |
Date: |
Wed, 10 Aug 2016 00:05:48 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch master
in repository hurd.
commit fb0d04483082a25ad722fcab5b2136903ddc9498
Author: Samuel Thibault <address@hidden>
Date: Tue Aug 9 21:42:03 2016 +0000
New upstream snapshot
---
console-client/kbd-repeat.c | 5 +-
console-client/pc-mouse.c | 5 +-
console/pager.c | 22 +--
doc/hurd.texi | 5 +
exec/elfcore.c | 4 +-
ext2fs/pager.c | 56 ++++---
fatfs/pager.c | 21 +--
hurd/crash.defs | 6 +-
include/sys/procfs.h | 3 +-
isofs/pager.c | 18 +-
.../contrib/include/linux/compiler-gcc6.h | 25 +++
libdiskfs/dir-rmdir.c | 2 +-
libpager/pager-create.c | 50 +++++-
libpager/pager.h | 8 +
libpipe/pipe.c | 5 +-
mach-defpager/kalloc.c | 47 +++++-
nfs/cache.c | 3 -
pfinet/socket-ops.c | 6 +-
pflocal/socket.c | 14 +-
proc/main.c | 5 +-
proc/mgt.c | 6 +-
proc/msg.c | 10 +-
proc/proc.h | 2 +-
startup/startup.c | 10 +-
sutils/Makefile | 2 +-
sutils/bless.c | 96 +++++++++++
trans/crash.c | 183 ++++++++++++++++++++-
trans/fifo.c | 2 -
trans/mtab.c | 4 -
trans/new-fifo.c | 2 -
trans/null.c | 6 +-
trans/streamio.c | 12 +-
32 files changed, 511 insertions(+), 134 deletions(-)
diff --git a/console-client/kbd-repeat.c b/console-client/kbd-repeat.c
index d3a39d0..8d8c9ee 100644
--- a/console-client/kbd-repeat.c
+++ b/console-client/kbd-repeat.c
@@ -94,8 +94,11 @@ repeater_select (struct protid *cred, mach_port_t reply,
if (!cred)
return EOPNOTSUPP;
+ *type &= ~SELECT_URG;
+
if (*type & ~SELECT_READ)
- return EINVAL;
+ /* Error immediately available... */
+ return 0;
if (*type == 0)
return 0;
diff --git a/console-client/pc-mouse.c b/console-client/pc-mouse.c
index abdb602..40a569d 100644
--- a/console-client/pc-mouse.c
+++ b/console-client/pc-mouse.c
@@ -118,8 +118,11 @@ repeater_select (struct protid *cred, mach_port_t reply,
if (!cred)
return EOPNOTSUPP;
+ *type &= ~SELECT_URG;
+
if (*type & ~SELECT_READ)
- return EINVAL;
+ /* Error immediately available... */
+ return 0;
if (*type == 0)
return 0;
diff --git a/console/pager.c b/console/pager.c
index 05074a7..d60935a 100644
--- a/console/pager.c
+++ b/console/pager.c
@@ -49,12 +49,11 @@ static struct pager_requests *pager_requests;
void
pager_clear_user_data (struct user_pager_info *upi)
{
- int idx;
+ size_t idx;
for (idx = 0; idx < upi->memobj_npages; idx++)
if (upi->memobj_pages[idx])
vm_deallocate (mach_task_self (), upi->memobj_pages[idx], vm_page_size);
- free (upi);
}
@@ -148,21 +147,17 @@ user_pager_create (struct user_pager *user_pager,
unsigned int npages,
error_t err;
struct user_pager_info *upi;
- upi = calloc (1, sizeof (struct user_pager_info)
- + sizeof (vm_address_t) * npages);
- if (!upi)
+ /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
+ user_pager->pager = \
+ pager_create_alloc (sizeof *upi + sizeof (vm_address_t) * npages,
+ pager_bucket, 1, MEMORY_OBJECT_COPY_DELAY, 0);
+ if (!user_pager->pager)
return errno;
+ upi = pager_get_upi (user_pager->pager);
upi->memobj_npages = npages;
+ memset (upi->memobj_pages, 0, sizeof (vm_address_t) * npages);
- /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
- user_pager->pager = pager_create (upi, pager_bucket,
- 1, MEMORY_OBJECT_COPY_DELAY, 0);
- if (!user_pager->pager)
- {
- free (upi);
- return errno;
- }
user_pager->memobj = pager_get_port (user_pager->pager);
ports_port_deref (user_pager->pager);
@@ -182,7 +177,6 @@ user_pager_create (struct user_pager *user_pager, unsigned
int npages,
VM_INHERIT_NONE);
if (err)
{
- /* UPI will be cleaned up by libpager. */
mach_port_deallocate (mach_task_self (), user_pager->memobj);
return err;
}
diff --git a/doc/hurd.texi b/doc/hurd.texi
index 2bcf561..8428a77 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -1410,6 +1410,11 @@ create references to pagers by use of the relevant ports
library
functions. On errors, return null and set @code{errno}.
@end deftypefun
address@hidden {struct pager *} pager_create_alloc (@w{size_t
@var{u_pager_size}}, @w{struct port_bucket address@hidden, @w{boolean_t
@var{may_cache}}, @w{memory_object_copy_strategy_t @var{copy_strategy}})
+Likewise, but allocate space for the user hook adjacent to the pager
+data.
address@hidden deftypefun
+
Once you are ready to turn over control to the pager library, you should
call @code{ports_manage_port_operations_multithread} on the
@var{bucket}, using @code{pager_demuxer} as the ports @var{demuxer}.
diff --git a/exec/elfcore.c b/exec/elfcore.c
index 4840217..3e4551e 100644
--- a/exec/elfcore.c
+++ b/exec/elfcore.c
@@ -408,8 +408,8 @@ dump_core (task_t task, file_t file, off_t corelimit,
if (err == 0)
{
err = proc_get_arg_locations (proc,
- (vm_address_t *) &psinfo.data.pr_argv,
- (vm_address_t *)
&psinfo.data.pr_envp);
+ &psinfo.data.pr_argv,
+ &psinfo.data.pr_envp);
mach_port_deallocate (mach_task_self (), proc);
}
{
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 7d3a8f3..456b582 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -817,22 +817,32 @@ pager_clear_user_data (struct user_pager_info *upi)
pthread_spin_lock (&node_to_page_lock);
pager = diskfs_node_disknode (upi->node)->pager;
- if (pager && pager_get_upi (pager) == upi)
- diskfs_node_disknode (upi->node)->pager = 0;
+ assert (!pager || pager_get_upi (pager) != upi);
pthread_spin_unlock (&node_to_page_lock);
diskfs_nrele_light (upi->node);
}
-
- free (upi);
}
/* This will be called when the ports library wants to drop weak references.
The pager library creates no weak references itself. If the user doesn't
either, then it's OK for this function to do nothing. */
void
-pager_dropweak (struct user_pager_info *p __attribute__ ((unused)))
+pager_dropweak (struct user_pager_info *upi)
{
+ if (upi->type == FILE_DATA)
+ {
+ struct pager *pager;
+
+ pthread_spin_lock (&node_to_page_lock);
+ pager = diskfs_node_disknode (upi->node)->pager;
+ if (pager && pager_get_upi (pager) == upi)
+ {
+ diskfs_node_disknode (upi->node)->pager = NULL;
+ ports_port_deref_weak (pager);
+ }
+ pthread_spin_unlock (&node_to_page_lock);
+ }
}
/* Cached blocks from disk. */
@@ -1298,35 +1308,31 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
struct pager *pager = diskfs_node_disknode (node)->pager;
if (pager)
{
- /* Because PAGER is not a real reference,
- this might be nearly deallocated. If that's so, then
- the port right will be null. In that case, clear here
- and loop. The deallocation will complete separately. */
right = pager_get_port (pager);
- if (right == MACH_PORT_NULL)
- diskfs_node_disknode (node)->pager = 0;
- else
- pager_get_upi (pager)->max_prot |= prot;
+ assert (MACH_PORT_VALID (right));
+ pager_get_upi (pager)->max_prot |= prot;
}
else
{
- struct user_pager_info *upi =
- malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->node = node;
- upi->max_prot = prot;
- diskfs_nref_light (node);
- diskfs_node_disknode (node)->pager =
- pager_create (upi, file_pager_bucket, MAY_CACHE,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (diskfs_node_disknode (node)->pager == 0)
+ struct user_pager_info *upi;
+ pager = pager_create_alloc (sizeof *upi, file_pager_bucket,
+ MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0);
+ if (pager == NULL)
{
- diskfs_nrele_light (node);
- free (upi);
pthread_spin_unlock (&node_to_page_lock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (pager);
+ upi->type = FILE_DATA;
+ upi->node = node;
+ upi->max_prot = prot;
+ diskfs_nref_light (node);
+ diskfs_node_disknode (node)->pager = pager;
+
+ /* A weak reference for being part of the node. */
+ ports_port_ref_weak (diskfs_node_disknode (node)->pager);
+
right = pager_get_port (diskfs_node_disknode (node)->pager);
ports_port_deref (diskfs_node_disknode (node)->pager);
}
diff --git a/fatfs/pager.c b/fatfs/pager.c
index 84376bd..bef8dbe 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -747,8 +747,6 @@ pager_clear_user_data (struct user_pager_info *upi)
diskfs_nrele_light (upi->node);
}
-
- free (upi);
}
/* This will be called when the ports library wants to drop weak
@@ -839,22 +837,21 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
}
else
{
- struct user_pager_info *upi =
- malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->node = node;
- upi->max_prot = prot;
- diskfs_nref_light (node);
+ struct user_pager_info *upi;
node->dn->pager =
- pager_create (upi, file_pager_bucket, MAY_CACHE,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (node->dn->pager == 0)
+ pager_create_alloc (sizeof *upi, file_pager_bucket, MAY_CACHE,
+ MEMORY_OBJECT_COPY_DELAY, 0);
+ if (node->dn->pager == NULL)
{
diskfs_nrele_light (node);
- free (upi);
pthread_spin_unlock (&node_to_page_lock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (node->dn->pager);
+ upi->type = FILE_DATA;
+ upi->node = node;
+ upi->max_prot = prot;
+ diskfs_nref_light (node);
right = pager_get_port (node->dn->pager);
ports_port_deref (node->dn->pager);
diff --git a/hurd/crash.defs b/hurd/crash.defs
index 442957d..4295861 100644
--- a/hurd/crash.defs
+++ b/hurd/crash.defs
@@ -25,8 +25,10 @@ subsystem crash 32000;
/* Handle a crashing task, whose task control port is TASK.
- FILE is a file port open for writing. The caller will link it to "core"
- (or whatever name) if the RPC returns success.
+ FILE is a file port open for writing. The caller will link it to
+ "core" (or whatever name) if the RPC returns success. If EEXIST is
+ returned, the core file has been written to a different file,
+ therefore FILE can be discarded.
SIGNO, SIGCODE, and SIGERROR indicate the signal that killed the
process. EXC is zero for a software signal; otherwise EXC, CODE, and
diff --git a/include/sys/procfs.h b/include/sys/procfs.h
index 09d2030..4acc346 100644
--- a/include/sys/procfs.h
+++ b/include/sys/procfs.h
@@ -1,5 +1,5 @@
/* <sys/procfs.h> -- data structures describing ELF core file formats
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2015, 2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
#include <features.h>
#include <inttypes.h>
+#include <mach/std_types.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ucontext.h>
diff --git a/isofs/pager.c b/isofs/pager.c
index b4be4e2..42cad8d 100644
--- a/isofs/pager.c
+++ b/isofs/pager.c
@@ -128,7 +128,6 @@ pager_clear_user_data (struct user_pager_info *upi)
pthread_spin_unlock (&node2pagelock);
diskfs_nrele_light (upi->np);
}
- free (upi);
}
void
@@ -176,19 +175,20 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
do
if (!np->dn->fileinfo)
{
- upi = malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->np = np;
- diskfs_nref_light (np);
- upi->p = pager_create (upi, pager_bucket, 1,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (upi->p == 0)
+ struct pager *p;
+ p = pager_create_alloc (sizeof *upi, pager_bucket, 1,
+ MEMORY_OBJECT_COPY_DELAY, 0);
+ if (p == NULL)
{
diskfs_nrele_light (np);
- free (upi);
pthread_spin_unlock (&node2pagelock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (p);
+ upi->type = FILE_DATA;
+ upi->np = np;
+ diskfs_nref_light (np);
+ upi->p = p;
np->dn->fileinfo = upi;
right = pager_get_port (np->dn->fileinfo->p);
ports_port_deref (np->dn->fileinfo->p);
diff --git a/libdde-linux26/contrib/include/linux/compiler-gcc6.h
b/libdde-linux26/contrib/include/linux/compiler-gcc6.h
new file mode 100644
index 0000000..e1d96fc
--- /dev/null
+++ b/libdde-linux26/contrib/include/linux/compiler-gcc6.h
@@ -0,0 +1,25 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc6.h> directly, include
<linux/compiler.h> instead."
+#endif
+
+#define __used __attribute__((__used__))
+#define __must_check __attribute__((warn_unused_result))
+#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
+#define __always_inline inline __attribute__((always_inline))
+
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
+
+/* Mark functions as cold. gcc will assume any path leading to a call
+ to them will be unlikely. This means a lot of manual unlikely()s
+ are unnecessary now for any paths leading to the usual suspects
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
+ older compilers]
+
+ gcc also has a __attribute__((__hot__)) to move hot functions into
+ a special section, but I don't see any sense in this right now in
+ the kernel context */
+#define __cold __attribute__((__cold__))
diff --git a/libdiskfs/dir-rmdir.c b/libdiskfs/dir-rmdir.c
index 83ec37b..8a29979 100644
--- a/libdiskfs/dir-rmdir.c
+++ b/libdiskfs/dir-rmdir.c
@@ -25,7 +25,7 @@ diskfs_S_dir_rmdir (struct protid *dircred,
char *name)
{
struct node *dnp;
- struct node *np;
+ struct node *np = NULL;
struct dirstat *ds = alloca (diskfs_dirstat_size);
error_t error;
diff --git a/libpager/pager-create.c b/libpager/pager-create.c
index b583f02..b3b7c8f 100644
--- a/libpager/pager-create.c
+++ b/libpager/pager-create.c
@@ -17,21 +17,19 @@
#include "priv.h"
-/* Create and return a new pager with user info UPI. */
-struct pager *
-pager_create (struct user_pager_info *upi,
- struct port_bucket *bucket,
- boolean_t may_cache,
- memory_object_copy_strategy_t copy_strategy,
- boolean_t notify_on_evict)
+static struct pager *
+_pager_create (size_t size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
{
struct pager *p;
- errno = ports_create_port (_pager_class, bucket, sizeof (struct pager), &p);
+ errno = ports_create_port (_pager_class, bucket, sizeof *p + size, &p);
if (errno)
return 0;
- p->upi = upi;
p->pager_state = NOTINIT;
pthread_mutex_init (&p->interlock, NULL);
pthread_cond_init (&p->wakeup, NULL);
@@ -50,6 +48,40 @@ pager_create (struct user_pager_info *upi,
return p;
}
+/* Create and return a new pager with user info UPI. */
+struct pager *
+pager_create (struct user_pager_info *upi,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
+{
+ struct pager *p;
+
+ p = _pager_create (0, bucket, may_cache, copy_strategy, notify_on_evict);
+ if (p)
+ p->upi = upi;
+
+ return p;
+}
+
+struct pager *
+pager_create_alloc (size_t u_pager_size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
+{
+ struct pager *p;
+
+ p = _pager_create (u_pager_size, bucket, may_cache, copy_strategy,
+ notify_on_evict);
+ if (p)
+ p->upi = (struct user_pager_info *) ((char *) p + sizeof *p);
+
+ return p;
+}
+
/* This causes the function to be run at startup by compiler magic. */
static void create_class (void) __attribute__ ((constructor));
diff --git a/libpager/pager.h b/libpager/pager.h
index df4db68..d2a8d39 100644
--- a/libpager/pager.h
+++ b/libpager/pager.h
@@ -69,6 +69,14 @@ pager_create (struct user_pager_info *u_pager,
memory_object_copy_strategy_t copy_strategy,
boolean_t notify_on_evict);
+/* Likewise, but also allocate space for the user hook. */
+struct pager *
+pager_create_alloc (size_t u_pager_size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict);
+
/* Return the user_pager_info struct associated with a pager. */
struct user_pager_info *
pager_get_upi (struct pager *p);
diff --git a/libpipe/pipe.c b/libpipe/pipe.c
index c3d2a28..0b53921 100644
--- a/libpipe/pipe.c
+++ b/libpipe/pipe.c
@@ -319,7 +319,10 @@ pipe_send (struct pipe *pipe, int noblock, void *source,
/* Nothing to do. */
if (data_len == 0 && control_len == 0 && num_ports == 0)
- return 0;
+ {
+ *amount = 0;
+ return 0;
+ }
err = pipe_wait_writable (pipe, noblock);
if (err)
diff --git a/mach-defpager/kalloc.c b/mach-defpager/kalloc.c
index 35ddf9a..e4ed12f 100644
--- a/mach-defpager/kalloc.c
+++ b/mach-defpager/kalloc.c
@@ -34,9 +34,25 @@
#include <mach.h>
#include <pthread.h> /* for spin locks */
+#include <malloc.h> /* for malloc_hook/free_hook */
#include "wiring.h"
+static void init_hook (void);
+static void *malloc_hook (size_t size, const void *caller);
+static void *realloc_hook (void *ptr, size_t size, const void *caller);
+static void *memalign_hook (size_t alignment, size_t size, const void *caller);
+static void free_hook (void *ptr, const void *caller);
+
+/* GNU libc 2.14 defines this macro to declare hook variables as volatile.
+ Define it as empty for older libc versions. */
+#ifndef __MALLOC_HOOK_VOLATILE
+# define __MALLOC_HOOK_VOLATILE
+#endif
+
+void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = init_hook;
+
+
/* #define DEBUG */
/*
@@ -250,14 +266,37 @@ kfree( void *data,
}
}
-void *
-malloc (size_t size)
+static void
+init_hook (void)
+{
+ __malloc_hook = malloc_hook;
+ __realloc_hook = realloc_hook;
+ __memalign_hook = memalign_hook;
+ __free_hook = free_hook;
+}
+
+static void *
+malloc_hook (size_t size, const void *caller)
{
return (void *) kalloc ((vm_size_t) size);
}
-void
-free (void *ptr)
+static void *
+realloc_hook (void *ptr, size_t size, const void *caller)
+{
+ panic("realloc_hook not implemented");
+}
+
+static void *
+memalign_hook (size_t alignment, size_t size, const void *caller)
+{
+ if (alignment > vm_page_size)
+ panic("memalign_hook not implemented");
+ return malloc_hook(size, caller);
+}
+
+static void
+free_hook (void *ptr, const void *caller)
{
/* Just ignore harmless attempts at cleanliness. */
/* panic("free not implemented"); */
diff --git a/nfs/cache.c b/nfs/cache.c
index 2015603..ecf3b11 100644
--- a/nfs/cache.c
+++ b/nfs/cache.c
@@ -129,13 +129,10 @@ netfs_node_norefs (struct node *np)
args = malloc (sizeof (struct fnd));
assert (args);
- netfs_nref (np);
-
args->dir = np->nn->dead_dir;
args->name = np->nn->dead_name;
np->nn->dead_dir = 0;
np->nn->dead_name = 0;
- netfs_nput (np);
/* Do this in a separate thread so that we don't wait for it; it
acquires a lock on the dir, which we are not allowed to
diff --git a/pfinet/socket-ops.c b/pfinet/socket-ops.c
index 14b3120..c768602 100644
--- a/pfinet/socket-ops.c
+++ b/pfinet/socket-ops.c
@@ -521,7 +521,11 @@ S_socket_recv (struct sock_user *user,
pthread_mutex_unlock (&global_lock);
if (err < 0)
- err = -err;
+ {
+ err = -err;
+ if (alloced)
+ munmap (*data, amount);
+ }
else
{
*datalen = err;
diff --git a/pflocal/socket.c b/pflocal/socket.c
index f2b75a7..0fcf484 100644
--- a/pflocal/socket.c
+++ b/pflocal/socket.c
@@ -282,6 +282,7 @@ S_socket_send (struct sock_user *user, struct addr
*dest_addr, int flags,
size_t *amount)
{
error_t err = 0;
+ int noblock;
struct pipe *pipe;
struct sock *sock, *dest_sock;
struct addr *source_addr;
@@ -333,8 +334,9 @@ S_socket_send (struct sock_user *user, struct addr
*dest_addr, int flags,
if (!err)
{
- err = pipe_send (pipe, sock->flags & PFLOCAL_SOCK_NONBLOCK,
- source_addr, data, data_len,
+ noblock = (user->sock->flags & PFLOCAL_SOCK_NONBLOCK)
+ || (flags & MSG_DONTWAIT);
+ err = pipe_send (pipe, noblock, source_addr, data, data_len,
control, control_len, ports, num_ports,
amount);
if (dest_sock)
@@ -373,6 +375,7 @@ S_socket_recv (struct sock_user *user,
{
error_t err;
unsigned flags;
+ int noblock;
struct pipe *pipe;
void *source_addr = NULL;
@@ -398,10 +401,11 @@ S_socket_recv (struct sock_user *user,
}
else if (!err)
{
+ noblock = (user->sock->flags & PFLOCAL_SOCK_NONBLOCK)
+ || (in_flags & MSG_DONTWAIT);
err =
- pipe_recv (pipe, user->sock->flags & PFLOCAL_SOCK_NONBLOCK, &flags,
- &source_addr, data, data_len, amount,
- control, control_len, ports, num_ports);
+ pipe_recv (pipe, noblock, &flags, &source_addr, data, data_len,
+ amount, control, control_len, ports, num_ports);
pipe_release_reader (pipe);
}
diff --git a/proc/main.c b/proc/main.c
index f78b2af..c4936f6 100644
--- a/proc/main.c
+++ b/proc/main.c
@@ -111,7 +111,7 @@ main (int argc, char **argv, char **envp)
err = task_get_bootstrap_port (mach_task_self (), &boot);
assert_perror (err);
if (boot == MACH_PORT_NULL)
- error (2, 0, "proc server can only be run by init during boot");
+ error (2, 0, "proc server can only be run by startup during boot");
proc_bucket = ports_create_bucket ();
proc_class = ports_create_class (0, 0);
@@ -124,7 +124,7 @@ main (int argc, char **argv, char **envp)
/* Create the initial proc object for init (PID 1). */
init_proc = create_init_proc ();
- /* Create the startup proc object for /hurd/init (PID 2). */
+ /* Create the startup proc object for /hurd/startup (PID 2). */
startup_proc = allocate_proc (MACH_PORT_NULL);
startup_proc->p_deadmsg = 1;
complete_proc (startup_proc, HURD_PID_STARTUP);
@@ -168,7 +168,6 @@ main (int argc, char **argv, char **envp)
/* Get our stderr set up to print on the console, in case we have
to panic or something. */
mach_port_t cons;
- error_t err;
err = device_open (_hurd_device_master, D_READ|D_WRITE, "console", &cons);
assert_perror (err);
stdin = mach_open_devstream (cons, "r");
diff --git a/proc/mgt.c b/proc/mgt.c
index 128a1c8..cb442b0 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -994,9 +994,9 @@ S_proc_mark_important (struct proc *p)
exempt from this restriction, as startup_proc calls this on their
behalf. The kernel process is a notable example of an process
that needs this exemption. That is not an problem however, since
- all children of /hurd/init are important and we mark them as such
- anyway. */
- if (! check_uid (p, 0) && ! check_owner (startup_proc, p))
+ all children of /hurd/startup are important and we mark them as
+ such anyway. */
+ if (! check_uid (p, 0) && p->p_parent != startup_proc)
return EPERM;
p->p_important = 1;
diff --git a/proc/msg.c b/proc/msg.c
index c7bab99..1f132cd 100644
--- a/proc/msg.c
+++ b/proc/msg.c
@@ -35,11 +35,11 @@ check_message_return (struct proc *p, void *availpaddr)
}
}
-/* Register ourselves with init. */
+/* Register ourselves with statup. */
static void *
-tickle_init (void *initport)
+tickle_statup (void *statupport)
{
- startup_essential_task ((mach_port_t) initport, mach_task_self (),
+ startup_essential_task ((mach_port_t) statupport, mach_task_self (),
MACH_PORT_NULL, "proc", _hurd_host_priv);
return NULL;
}
@@ -65,11 +65,11 @@ S_proc_setmsgport (struct proc *p,
if (p == startup_proc && startup_fallback)
{
- /* Init is single threaded, so we can't delay our reply for
+ /* Statup is single threaded, so we can't delay our reply for
the essential task RPC; spawn a thread to do it. */
pthread_t thread;
error_t err;
- err = pthread_create (&thread, NULL, tickle_init,
+ err = pthread_create (&thread, NULL, tickle_statup,
(void*) (uintptr_t) msgport);
if (!err)
pthread_detach (thread);
diff --git a/proc/proc.h b/proc/proc.h
index 4be1de4..2c08fd1 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -140,7 +140,7 @@ struct exc
mach_port_t authserver;
struct proc *self_proc; /* process HURD_PID_PROC (us) */
struct proc *init_proc; /* process 1 (sysvinit) */
-struct proc *startup_proc; /* process 2 (hurd/init) */
+struct proc *startup_proc; /* process 2 (hurd/startup) */
struct port_bucket *proc_bucket;
struct port_class *proc_class;
diff --git a/startup/startup.c b/startup/startup.c
index 3098454..49ba9ce 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -900,6 +900,12 @@ frob_kernel_process (void)
error (0, err, "cannot get kernel task port");
return;
}
+
+ /* Make the kernel our child. */
+ err = proc_child (procserver, task);
+ if (err)
+ error (0, err, "cannot make the kernel our child");
+
err = proc_task2proc (procserver, task, &proc);
if (err)
{
@@ -910,7 +916,9 @@ frob_kernel_process (void)
/* Mark the kernel task as an essential task so that we or the proc server
never want to task_terminate it. */
- proc_mark_important (proc);
+ err = proc_mark_important (proc);
+ if (err)
+ error (0, err, "cannot mark the kernel as important");
err = record_essential_task ("kernel", task);
assert_perror (err);
diff --git a/sutils/Makefile b/sutils/Makefile
index b74a506..85343f4 100644
--- a/sutils/Makefile
+++ b/sutils/Makefile
@@ -20,7 +20,7 @@
dir := sutils
makemode := utilities
-progs = reboot halt fsck swapon swapoff
+progs = reboot halt fsck swapon swapoff bless
scripts = e2os MAKEDEV losetup
targets = $(special-targets) $(progs)
special-targets = $(scripts)
diff --git a/sutils/bless.c b/sutils/bless.c
new file mode 100644
index 0000000..039320a
--- /dev/null
+++ b/sutils/bless.c
@@ -0,0 +1,96 @@
+/* Bless processes.
+
+ Copyright (C) 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 <mach.h>
+#include <version.h>
+
+const char *argp_program_version = STANDARD_HURD_VERSION (bless);
+
+pid_t pid;
+
+static const struct argp_option options[] =
+{
+ {0}
+};
+
+static const char args_doc[] = "PID";
+static const char doc[] = "Bless the given process. Such a process is "
+ "considered an essential part of the operating system and is not "
+ "terminated when switching runlevels.";
+
+/* Parse our options... */
+error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ char *end;
+
+ switch (key)
+ {
+ case ARGP_KEY_ARG:
+ if (state->arg_num > 0)
+ argp_error (state, "Too many non option arguments");
+
+ pid = strtol (arg, &end, 10);
+ if (arg == end || *end != '\0')
+ argp_error (state, "Malformed pid '%s'", arg);
+ break;
+
+ case ARGP_KEY_NO_ARGS:
+ argp_usage (state);
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+const struct argp argp =
+ {
+ options: options,
+ parser: parse_opt,
+ args_doc: args_doc,
+ doc: doc,
+ };
+
+int
+main (int argc, char **argv)
+{
+ error_t err;
+ process_t proc;
+
+ /* Parse our arguments. */
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+
+ err = proc_pid2proc (getproc (), pid, &proc);
+ if (err)
+ error (1, err, "Could not get process for pid %d", pid);
+
+ err = proc_mark_important (proc);
+ if (err)
+ error (1, err, "Could not mark process as important");
+
+ err = mach_port_deallocate (mach_task_self (), proc);
+ assert_perror (err);
+
+ return EXIT_SUCCESS;
+}
diff --git a/trans/crash.c b/trans/crash.c
index 5db9974..14783cf 100644
--- a/trans/crash.c
+++ b/trans/crash.c
@@ -70,7 +70,105 @@ enum crash_action
#define CRASH_ORPHANS_DEFAULT crash_corefile
static enum crash_action crash_how, crash_orphans_how;
+static char *corefile_template;
+
+
+/* Template parsing. */
+static int
+template_valid (const char *template, const char **errp)
+{
+ int valid = 0;
+ const char *t;
+ int specifier = 0;
+
+ for (t = template; *t; t++)
+ {
+ if (specifier)
+ switch (*t)
+ {
+ case '%':
+ case 'p':
+ case 's':
+ case 't':
+ specifier = 0;
+ break;
+ default:
+ goto out;
+ }
+ else if (*t == '%')
+ specifier = 1;
+ }
+
+ out:
+ valid = ! specifier;
+ *errp = valid? NULL: t;
+ return valid;
+}
+
+static char *
+template_make_file_name (const char *template,
+ task_t task,
+ int signo)
+{
+ const char *t;
+ char *file_name = NULL;
+ size_t file_name_len = 0;
+ FILE *stream;
+ int specifier = 0;
+
+ if (! template_valid (template, &t))
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ stream = open_memstream (&file_name, &file_name_len);
+ if (stream == NULL)
+ return NULL;
+
+ for (t = template; *t; t++)
+ {
+ if (specifier)
+ {
+ switch (*t)
+ {
+ case '%':
+ fprintf (stream, "%%");
+ break;
+
+ case 'p':
+ fprintf (stream, "%d", task2pid (task));
+ break;
+
+ case 's':
+ fprintf (stream, "%d", signo);
+ break;
+
+ case 't':
+ fprintf (stream, "%d", time (NULL));
+ break;
+
+ default:
+ assert (!"reached!");
+ }
+ specifier = 0;
+ }
+ else if (*t == '%')
+ specifier = 1;
+ else
+ fprintf (stream, "%c", *t);
+ }
+
+ assert (! specifier);
+
+ fprintf (stream, "%c", 0);
+ fclose (stream);
+
+ return file_name;
+}
+
+
/* This is defined in ../exec/elfcore.c, or we could have
different implementations for other formats. */
@@ -217,7 +315,9 @@ S_crash_dump_task (mach_port_t port,
proc_mark_stop (user_proc, signo, sigcode);
c->task = task;
+ task = MACH_PORT_NULL;
c->core_file = core_file;
+ core_file = MACH_PORT_NULL;
c->core_limit = (off_t) -1; /* XXX should core limit in RPC */
c->signo = signo;
c->sigcode = sigcode;
@@ -235,10 +335,42 @@ S_crash_dump_task (mach_port_t port,
err = task_suspend (task);
if (!err)
{
- err = dump_core (task, core_file,
+ file_t sink = core_file;
+ if (corefile_template)
+ {
+ char *file_name;
+
+ file_name = template_make_file_name (corefile_template,
+ task, signo);
+ if (file_name == NULL)
+ error (0, errno, "template_make_file_name");
+ else
+ {
+ sink = file_name_lookup (file_name, O_WRONLY|O_CREAT,
+ S_IRUSR);
+ if (! MACH_PORT_VALID (sink))
+ {
+ error (0, errno, "%s", file_name);
+ sink = core_file;
+ }
+ free (file_name);
+ }
+ }
+
+ err = dump_core (task, sink,
(off_t) -1, /* XXX should get core limit in RPC */
signo, sigcode, sigerror);
task_resume (task);
+
+ if (sink != core_file)
+ {
+ mach_port_deallocate (mach_task_self (), sink);
+
+ /* We return an error so that the libc discards
+ CORE_FILE. */
+ if (! err)
+ err = EEXIST;
+ }
}
break;
@@ -251,17 +383,20 @@ S_crash_dump_task (mach_port_t port,
if (!err)
err = proc_mark_exit (user_proc, W_EXITCODE (0, signo), sigcode);
err = task_terminate (task);
- if (!err)
- {
- mach_port_deallocate (mach_task_self (), task);
- mach_port_deallocate (mach_task_self (), core_file);
- mach_port_deallocate (mach_task_self (), ctty_id);
- }
}
}
if (user_proc != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), user_proc);
+ if (err == 0 || err == MIG_NO_REPLY)
+ {
+ if (MACH_PORT_VALID (task))
+ mach_port_deallocate (mach_task_self (), task);
+ if (MACH_PORT_VALID (core_file))
+ mach_port_deallocate (mach_task_self (), core_file);
+ if (MACH_PORT_VALID (ctty_id))
+ mach_port_deallocate (mach_task_self (), ctty_id);
+ }
ports_port_deref (cred);
return err;
@@ -445,13 +580,25 @@ static const struct argp_option options[] =
{"kill", 'k', 0, 0, "Kill the process", 2},
{"core-file", 'c', 0, 0, "Dump a core file", 2},
{"dump-core", 0, 0, OPTION_ALIAS },
+ {"core-file-name", 'C', "TEMPLATE", 0,
+ "Specify core file name (see below)", 2},
{0}
};
static const char doc[] =
"Server to handle crashing tasks and dump core files or equivalent.\v"
"The ACTION values can be `suspend', `kill', or `core-file'.\n\n"
"If `--orphan-action' is not specified, the `--action' value is used for "
-"orphans. The default is `--action=suspend --orphan-action=core-file'.";
+"orphans. The default is `--action=suspend --orphan-action=core-file'.\n"
+"\n"
+"The core file is either written to the file provided by the "
+"crashing process, or if a TEMPLATE value is given, to the file "
+"with the name constructed by expanding TEMPLATE value. "
+"TEMPLATE may contain % specifiers:\n"
+"\n"
+"\t%% just %\n"
+"\t%p the process' PID\n"
+"\t%s the signal number that caused the dump\n"
+"\t%t time of crash in seconds since the EPOCH\n";
static error_t
parse_opt (int opt, char *arg, struct argp_state *state)
@@ -489,6 +636,14 @@ parse_opt (int opt, char *arg, struct argp_state *state)
case 's': crash_how = crash_suspend; break;
case 'k': crash_how = crash_kill; break;
case 'c': crash_how = crash_corefile; break;
+ case 'C':
+ {
+ char *errp;
+ if (! template_valid (arg, &errp))
+ error (1, 0, "Invalid template: ...'%s'", errp);
+ }
+ corefile_template = arg;
+ break;
case ARGP_KEY_SUCCESS:
if (crash_orphans_how == crash_unspecified)
@@ -531,6 +686,18 @@ trivfs_append_args (struct trivfs_control *fsys,
err = argz_add (argz, argz_len, opt);
}
+ if (!err && corefile_template)
+ {
+ char *template;
+ if (asprintf (&template, "--core-file-name=%s", corefile_template) < 0)
+ err = errno;
+ else
+ {
+ err = argz_add (argz, argz_len, template);
+ free (template);
+ }
+ }
+
return err;
}
diff --git a/trans/fifo.c b/trans/fifo.c
index f52baba..ac31f49 100644
--- a/trans/fifo.c
+++ b/trans/fifo.c
@@ -436,7 +436,6 @@ io_select_common (struct trivfs_protid *cred,
}
else
{
- err = EBADF;
ready |= SELECT_READ; /* Error immediately available... */
}
if (err)
@@ -458,7 +457,6 @@ io_select_common (struct trivfs_protid *cred,
}
else
{
- err = EBADF;
ready |= SELECT_WRITE; /* Error immediately available... */
}
}
diff --git a/trans/mtab.c b/trans/mtab.c
index e0fcb46..c03749c 100644
--- a/trans/mtab.c
+++ b/trans/mtab.c
@@ -843,10 +843,6 @@ trivfs_S_io_select (struct trivfs_protid *cred,
if (!cred)
return EOPNOTSUPP;
- if (((*type & SELECT_READ) && !(cred->po->openmodes & O_READ))
- || ((*type & SELECT_WRITE) && !(cred->po->openmodes & O_WRITE)))
- return EBADF;
-
*type &= ~SELECT_URG;
return 0;
}
diff --git a/trans/new-fifo.c b/trans/new-fifo.c
index 0ceb842..f11ceca 100644
--- a/trans/new-fifo.c
+++ b/trans/new-fifo.c
@@ -623,7 +623,6 @@ io_select_common (struct trivfs_protid *cred,
}
else
{
- err = EBADF;
ready |= SELECT_READ; /* Error immediately available... */
}
if (err)
@@ -645,7 +644,6 @@ io_select_common (struct trivfs_protid *cred,
}
else
{
- err = EBADF;
ready |= SELECT_WRITE; /* Error immediately available... */
}
}
diff --git a/trans/null.c b/trans/null.c
index bd082dc..92717ed 100644
--- a/trans/null.c
+++ b/trans/null.c
@@ -204,11 +204,7 @@ trivfs_S_io_select (struct trivfs_protid *cred,
{
if (!cred)
return EOPNOTSUPP;
- else if (((*type & SELECT_READ) && !(cred->po->openmodes & O_READ))
- || ((*type & SELECT_WRITE) && !(cred->po->openmodes & O_WRITE)))
- return EBADF;
- else
- *type &= ~SELECT_URG;
+ *type &= ~SELECT_URG;
return 0;
}
diff --git a/trans/streamio.c b/trans/streamio.c
index a80975f..5539c8e 100644
--- a/trans/streamio.c
+++ b/trans/streamio.c
@@ -560,9 +560,6 @@ io_select_common (struct trivfs_protid *cred,
if (!cred)
return EOPNOTSUPP;
- if (!(cred->po->openmodes & O_WRITE) && (*type & SELECT_WRITE))
- return EBADF;
-
*type &= SELECT_READ | SELECT_WRITE;
if (*type == 0)
@@ -575,11 +572,10 @@ io_select_common (struct trivfs_protid *cred,
pthread_mutex_lock (&global_lock);
if ((*type & SELECT_READ) && buffer_readable (input_buffer))
available |= SELECT_READ;
- if (output_buffer)
- {
- if ((*type & SELECT_WRITE) && buffer_writable (output_buffer))
- available |= SELECT_WRITE;
- }
+ if ((*type & SELECT_WRITE) &&
+ (!(cred->po->openmodes & O_WRITE) ||
+ (buffer_writable && buffer_writable (output_buffer))))
+ available |= SELECT_WRITE;
if (available)
{
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git