commit-hurd
[Top][All Lists]
Advanced

[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: Sat, 10 Jun 2017 00:38:17 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository hurd.

commit 3ed467d065271f84f56ffaf4907340021b7cc2e3
Author: Samuel Thibault <address@hidden>
Date:   Fri Jun 9 19:21:55 2017 +0000

    New upstream snapshot
---
 NEWS                         |   6 ++
 boot/boot.c                  |  57 +++++++++++
 eth-multiplexer/Makefile     |   2 +-
 ext2fs/xattr.c               |   4 +-
 hurd/process.defs            |   6 +-
 hurd/process_reply.defs      |   6 +-
 libdiskfs/boot-start.c       |  44 +++++++--
 libdiskfs/opts-std-startup.c |   5 +
 proc/info.c                  | 224 ++++++++++++++++++++++++++++++++++++++++++-
 proc/main.c                  |  42 +++++++-
 proc/mgt.c                   |  56 +++++++++++
 proc/msg.c                   |  32 ++++++-
 proc/pgrp.c                  | 100 +++++++++++++++++++
 proc/proc.h                  |   2 +
 release/servers.boot         |   2 +-
 startup/startup.c            | 109 +++++++++++++++++----
 16 files changed, 646 insertions(+), 51 deletions(-)

diff --git a/NEWS b/NEWS
index 05e04d5..1b500be 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+Version X (2017-06-XX)
+
+Subhurd's processes are now properly embedded in the Motherhurds
+process hierarchy.  They can be inspected and debugged just like any
+other process.
+
 Version 0.9 (2016-12-18)
 
 The 'boot' program can now be run as unprivileged user, allowing any
diff --git a/boot/boot.c b/boot/boot.c
index 950aedb..978f56e 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -196,12 +196,66 @@ mig_reply_setup (
 #undef OutP
 }
 
+error_t
+mach_msg_forward (mach_msg_header_t *inp,
+                  mach_port_t destination, mach_msg_type_name_t 
destination_type)
+{
+  /* Put the reply port back at the correct position, insert new
+     destination.  */
+  inp->msgh_local_port = inp->msgh_remote_port;
+  inp->msgh_remote_port = destination;
+  inp->msgh_bits =
+    MACH_MSGH_BITS (destination_type, MACH_MSGH_BITS_REMOTE (inp->msgh_bits))
+    | MACH_MSGH_BITS_OTHER (inp->msgh_bits);
+
+  /* A word about resources carried in complex messages.
+
+     "In a received message, msgt_deallocate is TRUE in type
+     descriptors for out-of-line memory".  Therefore, "[the
+     out-of-line memory] is implicitly deallocated from the sender
+     [when we resend the message], as if by vm_deallocate".
+
+     Similarly, rights in messages will be either
+     MACH_MSG_TYPE_PORT_SEND, MACH_MSG_TYPE_PORT_SEND_ONCE, or
+     MACH_MSG_TYPE_PORT_RECEIVE.  These types are aliases for,
+     respectively, MACH_MSG_TYPE_MOVE_SEND,
+     MACH_MSG_TYPE_MOVE_SEND_ONCE, and MACH_MSG_TYPE_MOVE_RECEIVE.
+     Therefore, the rights are moved when we resend the message.  */
+
+  return mach_msg (inp, MACH_SEND_MSG, inp->msgh_size,
+                   0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+}
+
 int
 boot_demuxer (mach_msg_header_t *inp,
              mach_msg_header_t *outp)
 {
+  error_t err;
   mig_routine_t routine;
   mig_reply_setup (inp, outp);
+
+  if (inp->msgh_local_port == task_notification_port
+      && MACH_PORT_VALID (new_task_notification)
+      && 24000 <= inp->msgh_id && inp->msgh_id < 24100)
+    {
+      /* This is a message of the Process subsystem.  We relay this to
+         allow the "outer" proc servers to communicate with the "inner"
+         one.  */
+      mig_reply_header_t *reply = (mig_reply_header_t *) outp;
+
+      if (MACH_PORT_VALID (new_task_notification))
+        err = mach_msg_forward (inp, new_task_notification, 
MACH_MSG_TYPE_COPY_SEND);
+      else
+        err = EOPNOTSUPP;
+
+      if (err)
+        reply->RetCode = err;
+      else
+        reply->RetCode = MIG_NO_REPLY;
+
+      return TRUE;
+    }
+
   if ((routine = io_server_routine (inp)) ||
       (routine = device_server_routine (inp)) ||
       (routine = notify_server_routine (inp)) ||
@@ -466,6 +520,7 @@ const char *default_boot_script =
   " --multiboot-command-line=${kernel-command-line}"
   " --host-priv-port=${host-port}"
   " --device-master-port=${device-port}"
+  " --kernel-task=${kernel-task}"
   " --exec-server-task=${exec-task}"
   " -T device ${root-device} $(task-create) $(task-resume)"
   "\n"
@@ -595,6 +650,8 @@ main (int argc, char **argv, char **envp)
                                : (int) pseudo_privileged_host_port)
       || boot_script_set_variable ("device-port", VAL_PORT,
                                   (integer_t) pseudo_master_device_port)
+      || boot_script_set_variable ("kernel-task", VAL_PORT,
+                                  (integer_t) pseudo_kernel)
       || boot_script_set_variable ("kernel-command-line", VAL_STR,
                                   (integer_t) kernel_command_line)
       || boot_script_set_variable ("root-device",
diff --git a/eth-multiplexer/Makefile b/eth-multiplexer/Makefile
index 07f909e..cefa0ab 100644
--- a/eth-multiplexer/Makefile
+++ b/eth-multiplexer/Makefile
@@ -26,7 +26,7 @@ MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 LCLHDRS = ethernet.h util.h vdev.h netfs_impl.h
-HURDLIBS = ports ihash fshelp shouldbeinlibc netfs bpf
+HURDLIBS = ports ihash iohelp fshelp shouldbeinlibc netfs bpf
 LDLIBS = -lpthread
 
 CFLAGS += -I$(top_srcdir)/libbpf
diff --git a/ext2fs/xattr.c b/ext2fs/xattr.c
index 5ce84ce..c703717 100644
--- a/ext2fs/xattr.c
+++ b/ext2fs/xattr.c
@@ -512,7 +512,7 @@ ext2_list_xattr (struct node *np, char *buffer, size_t *len)
 
   if (!EXT2_HAS_COMPAT_FEATURE (sblock, EXT2_FEATURE_COMPAT_EXT_ATTR))
     {
-      ext2_warning ("Filesystem has no support for extended attributes.");
+      ext2_debug ("Filesystem has no support for extended attributes.");
       return EOPNOTSUPP;
     }
 
@@ -587,7 +587,7 @@ ext2_get_xattr (struct node *np, const char *name, char 
*value, size_t *len)
 
   if (!EXT2_HAS_COMPAT_FEATURE (sblock, EXT2_FEATURE_COMPAT_EXT_ATTR))
     {
-      ext2_warning ("Filesystem has no support for extended attributes.");
+      ext2_debug ("Filesystem has no support for extended attributes.");
       return EOPNOTSUPP;
     }
 
diff --git a/hurd/process.defs b/hurd/process.defs
index 4ceb69e..df70eb9 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -156,7 +156,7 @@ routine proc_getmsgport (
        process: process_t;
        sreplyport reply_port: sreply_port_t;
        pid: pid_t;
-       out msgport: mach_port_t);
+       out msgport: mach_port_poly_t);
 
 /* Wait for a child process to exit.  If pid is zero, it waits for any
    child in the same pgrp as the parent.  If pid is -1, it waits for
@@ -246,7 +246,7 @@ routine proc_task2pid (
 routine proc_task2proc (
        process: process_t;
        task: task_t;
-       out proc: mach_port_make_send_t);
+       out proc: mach_port_poly_t);
 
 routine proc_proc2task (
        process: process_t;
@@ -255,7 +255,7 @@ routine proc_proc2task (
 routine proc_pid2proc (
        process: process_t;
        pid: pid_t;
-       out proc: mach_port_make_send_t);
+       out proc: mach_port_poly_t);
 
 routine proc_getprocinfo (
        process: process_t;
diff --git a/hurd/process_reply.defs b/hurd/process_reply.defs
index 15282fe..2fc21c9 100644
--- a/hurd/process_reply.defs
+++ b/hurd/process_reply.defs
@@ -51,7 +51,7 @@ skip; /* get_arg_locations */
 simpleroutine proc_getmsgport_reply (
        reply_port: reply_port_t;
        RETURN_CODE_ARG;
-       in msgports: mach_port_t);
+       in msgports: mach_port_poly_t);
 
 simpleroutine proc_wait_reply (
        reply_port: reply_port_t;
@@ -83,7 +83,7 @@ simpleroutine proc_task2pid_reply (
 simpleroutine proc_task2proc_reply (
        reply_port: reply_port_t;
        RETURN_CODE_ARG;
-       proc: mach_port_make_send_t);
+       proc: mach_port_poly_t);
 
 simpleroutine proc_proc2task_reply (
        reply_port: reply_port_t;
@@ -93,7 +93,7 @@ simpleroutine proc_proc2task_reply (
 simpleroutine proc_pid2proc_reply (
        reply_port: reply_port_t;
        RETURN_CODE_ARG;
-       proc: mach_port_make_send_t);
+       proc: mach_port_poly_t);
 
 simpleroutine proc_getprocinfo_reply (
        reply_port: reply_port_t;
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index 0fb3e89..f048bad 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -40,6 +40,7 @@
 
 static mach_port_t diskfs_exec_ctl;
 extern task_t diskfs_exec_server_task;
+extern task_t diskfs_kernel_task;
 static task_t parent_task = MACH_PORT_NULL;
 
 static pthread_mutex_t execstartlock;
@@ -206,9 +207,6 @@ diskfs_start_bootstrap ()
       /* We have a boot command line to run instead of init.  */
       err = argz_create (_diskfs_boot_command, &exec_argv, &exec_argvlen);
       assert_perror (err);
-      initname = exec_argv;
-      while (*initname == '/')
-       initname++;
     }
   else
     {
@@ -223,10 +221,42 @@ diskfs_start_bootstrap ()
       err = argz_add_sep (&exec_argv, &exec_argvlen,
                          diskfs_boot_command_line, ' ');
       assert_perror (err);
+    }
+
+  err = task_create (mach_task_self (),
+#ifdef KERN_INVALID_LEDGER
+                    NULL, 0,   /* OSF Mach */
+#endif
+                    0, &newt);
+  assert_perror (err);
 
-      initname = exec_argv + 1;
+  if (MACH_PORT_VALID (diskfs_kernel_task))
+    {
+      mach_port_t kernel_task_name = MACH_PORT_NULL;
+      char buf[20];
+      int len;
+
+      do
+        {
+          kernel_task_name += 1;
+          err = mach_port_insert_right (newt, kernel_task_name,
+                                        diskfs_kernel_task, 
MACH_MSG_TYPE_MOVE_SEND);
+        }
+      while (err == KERN_NAME_EXISTS);
+      diskfs_kernel_task = MACH_PORT_NULL;
+
+      len = snprintf (buf, sizeof buf, "--kernel-task=%d", kernel_task_name);
+      assert (len < sizeof buf);
+      /* Insert as second argument.  */
+      err = argz_insert (&exec_argv, &exec_argvlen,
+                         argz_next (exec_argv, exec_argvlen, exec_argv), buf);
+      assert_perror (err);
     }
 
+  initname = exec_argv;
+  while (*initname == '/')
+    initname++;
+
  lookup_init:
   err = dir_lookup (root_pt, (char *) initname, O_READ, 0, &retry, pathbuf,
                     &startup_pt);
@@ -270,12 +300,6 @@ diskfs_start_bootstrap ()
   err = argz_create (environ, &exec_env, &exec_envlen);
   assert_perror (err);
 
-  err = task_create (mach_task_self (),
-#ifdef KERN_INVALID_LEDGER
-                    NULL, 0,   /* OSF Mach */
-#endif
-                    0, &newt);
-  assert_perror (err);
   if (_diskfs_boot_pause)
     {
       printf ("pausing for %s...\n", exec_argv);
diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c
index ed25a18..a38db99 100644
--- a/libdiskfs/opts-std-startup.c
+++ b/libdiskfs/opts-std-startup.c
@@ -35,6 +35,7 @@ int _diskfs_boot_pause;
 extern char **diskfs_argv;
 
 mach_port_t diskfs_exec_server_task = MACH_PORT_NULL;
+mach_port_t diskfs_kernel_task = MACH_PORT_NULL;
 
 /* ---------------------------------------------------------------- */
 
@@ -45,6 +46,7 @@ mach_port_t diskfs_exec_server_task = MACH_PORT_NULL;
 #define OPT_BOOT_COMMAND       (-5)
 #define OPT_BOOT_INIT_PROGRAM  (-6)
 #define OPT_BOOT_PAUSE         (-7)
+#define OPT_KERNEL_TASK                (-8)
 
 static const struct argp_option
 startup_options[] =
@@ -68,6 +70,7 @@ startup_options[] =
   {"host-priv-port",     OPT_HOST_PRIV_PORT,     "PORT"},
   {"device-master-port", OPT_DEVICE_MASTER_PORT, "PORT"},
   {"exec-server-task",   OPT_EXEC_SERVER_TASK,   "PORT"},
+  {"kernel-task",        OPT_KERNEL_TASK,        "PORT"},
 
   {0}
 };
@@ -106,6 +109,8 @@ parse_startup_opt (int opt, char *arg, struct argp_state 
*state)
       _hurd_host_priv = atoi (arg); break;
     case OPT_EXEC_SERVER_TASK:
       diskfs_exec_server_task = atoi (arg); break;
+    case OPT_KERNEL_TASK:
+      diskfs_kernel_task = atoi (arg); break;
     case OPT_BOOT_CMDLINE:
       diskfs_boot_command_line = arg; break;
     case OPT_BOOT_INIT_PROGRAM:
diff --git a/proc/info.c b/proc/info.c
index 0f5ca0f..79a4c37 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -99,7 +99,8 @@ S_proc_task2pid (struct proc *callerp,
 kern_return_t
 S_proc_task2proc (struct proc *callerp,
                  task_t t,
-                 mach_port_t *outproc)
+                 mach_port_t *outproc,
+                 mach_msg_type_name_t *outproc_type)
 {
   struct proc *p = task_find (t);
 
@@ -108,7 +109,30 @@ S_proc_task2proc (struct proc *callerp,
   if (!p)
     return ESRCH;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2proc (p->p_task_namespace, t, outproc);
+
+      pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       {
+         *outproc_type = MACH_MSG_TYPE_MOVE_SEND;
+         mach_port_deallocate (mach_task_self (), t);
+         return 0;
+       }
+
+      /* Fallback.  */
+    }
+
   *outproc = ports_get_right (p);
+  *outproc_type = MACH_MSG_TYPE_MAKE_SEND;
   mach_port_deallocate (mach_task_self (), t);
   return 0;
 }
@@ -128,7 +152,8 @@ S_proc_proc2task (struct proc *p,
 kern_return_t
 S_proc_pid2proc (struct proc *callerp,
                 pid_t pid,
-                mach_port_t *outproc)
+                mach_port_t *outproc,
+                mach_msg_type_name_t *outproc_type)
 {
   struct proc *p;
 
@@ -148,7 +173,29 @@ S_proc_pid2proc (struct proc *callerp,
   if (! check_owner (callerp, p))
     return EPERM;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2proc (p->p_task_namespace, p->p_task, outproc);
+
+      pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       {
+         *outproc_type = MACH_MSG_TYPE_MOVE_SEND;
+         return 0;
+       }
+
+      /* Fallback.  */
+    }
+
   *outproc = ports_get_right (p);
+  *outproc_type = MACH_MSG_TYPE_MAKE_SEND;
   return 0;
 }
 
@@ -341,6 +388,27 @@ S_proc_getprocargs (struct proc *callerp,
   if (!p)
     return ESRCH;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+       err = proc_getprocargs (p->p_task_namespace, pid_sub, buf, buflen);
+
+      pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   return get_string_array (p->p_task, p->p_argv, (vm_address_t *) buf, buflen);
 }
 
@@ -358,6 +426,27 @@ S_proc_getprocenv (struct proc *callerp,
   if (!p)
     return ESRCH;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+       err = proc_getprocenv (p->p_task_namespace, pid_sub, buf, buflen);
+
+      pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   return get_string_array (p->p_task, p->p_envp, (vm_address_t *)buf, buflen);
 }
 
@@ -394,6 +483,82 @@ S_proc_getprocinfo (struct proc *callerp,
   if (!p)
     return ESRCH;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+       err = proc_getprocinfo (p->p_task_namespace, pid_sub, flags,
+                               piarray, piarraylen, waits, waits_len);
+
+      if (! err && *piarray && *piarraylen * sizeof (int) >= sizeof *pi)
+       {
+         /* Fixup the PIDs to refer to this Hurd's processes.  */
+         task_t t_ppid = MACH_PORT_NULL;
+         task_t t_pgrp = MACH_PORT_NULL;
+         task_t t_session = MACH_PORT_NULL;
+         task_t t_logincollection = MACH_PORT_NULL;
+
+         pi = (struct procinfo *) *piarray;
+
+         /* We handle errors by checking each returned task.  */
+         if (pi->ppid != pid_sub)
+           proc_pid2task (p->p_task_namespace, pi->ppid, &t_ppid);
+         proc_pid2task (p->p_task_namespace, pi->pgrp, &t_pgrp);
+         proc_pid2task (p->p_task_namespace, pi->session, &t_session);
+         proc_pid2task (p->p_task_namespace, pi->logincollection,
+                        &t_logincollection);
+
+         /* Reacquire the global lock for the hash table lookups.  */
+         pthread_mutex_lock (&global_lock);
+
+         if (MACH_PORT_VALID (t_ppid))
+           {
+             struct proc *q = task_find (t_ppid);
+             pi->ppid = q ? q->p_pid : (pid_t) -1;
+             mach_port_deallocate (mach_task_self (), t_ppid);
+           }
+         else
+           {
+             /* Either the pid2task lookup failed, or this process is
+                a root of a process hierarchy in the Subhurd.  Either
+                way, we attach it to the creator of the task
+                namespace.  */
+             pi->ppid = namespace_find_root (p)->p_pid;
+           }
+         if (MACH_PORT_VALID (t_pgrp))
+           {
+             struct proc *q = task_find (t_pgrp);
+             pi->pgrp = q ? q->p_pid : (pid_t) -1;
+             mach_port_deallocate (mach_task_self (), t_pgrp);
+           }
+         if (MACH_PORT_VALID (t_session))
+           {
+             struct proc *q = task_find (t_session);
+             pi->session = q ? q->p_pid : (pid_t) -1;
+             mach_port_deallocate (mach_task_self (), t_session);
+           }
+         if (MACH_PORT_VALID (t_logincollection))
+           {
+             struct proc *q = task_find (t_logincollection);
+             pi->logincollection = q ? q->p_pid : (pid_t) -1;
+             mach_port_deallocate (mach_task_self (), t_logincollection);
+           }
+
+         return 0;
+       }
+
+      pthread_mutex_lock (&global_lock);
+      err = 0;
+      /* Fallback.  */
+    }
+
   task = p->p_task;
 
   check_msgport_death (p);
@@ -640,13 +805,37 @@ S_proc_getloginid (struct proc *callerp,
                   pid_t *leader)
 {
   struct proc *proc = pid_find (pid);
-  struct proc *p;
+  struct proc *p = proc;
 
   /* No need to check CALLERP here; we don't use it. */
 
   if (!proc)
     return ESRCH;
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+       err = proc_getloginid (p->p_task_namespace, pid_sub, leader);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (p->p_task_namespace, leader, 1);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   for (p = proc; !p->p_loginleader; p = p->p_parent)
     assert (p);
 
@@ -670,6 +859,35 @@ S_proc_getloginpids (struct proc *callerp,
 
   /* No need to check CALLERP here; we don't use it. */
 
+  if (!l)
+    return ESRCH;
+
+  if (namespace_is_subprocess (l))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+      pid_t leader_sub;
+      task_t leader_task;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (l->p_task_namespace, l->p_task, &pid_sub);
+      if (! err)
+       err = proc_getloginpids (l->p_task_namespace, pid_sub, pids, npids);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (l->p_task_namespace, *pids, *npids);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   if (!l || !l->p_loginleader)
     return ESRCH;
 
diff --git a/proc/main.c b/proc/main.c
index d97650f..e615f36 100644
--- a/proc/main.c
+++ b/proc/main.c
@@ -123,6 +123,32 @@ open_console (mach_port_t device_master)
   return 0;
 }
 
+
+
+static task_t kernel_task;
+
+#define OPT_KERNEL_TASK        -1
+
+static struct argp_option
+options[] =
+{
+  {"kernel-task", OPT_KERNEL_TASK, "PORT"},
+  {0}
+};
+
+static int
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case OPT_KERNEL_TASK:
+      kernel_task = atoi (arg);
+      break;
+    default: return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
 int
 main (int argc, char **argv, char **envp)
 {
@@ -131,7 +157,8 @@ main (int argc, char **argv, char **envp)
   void *genport;
   process_t startup_port;
   mach_port_t startup;
-  struct argp argp = { 0, 0, 0, "Hurd process server" };
+  char **original_argv;
+  struct argp argp = { options, parse_opt, 0, "Hurd process server" };
 
   argp_parse (&argp, argc, argv, 0, 0, 0);
 
@@ -191,10 +218,15 @@ main (int argc, char **argv, char **envp)
   if (err && err != EPERM)
     error (0, err, "Increasing priority failed");
 
-  /* Get a list of all tasks to find the kernel.  */
-  /* XXX: I't be nice if GNU Mach would hand us the task port.  */
-  add_tasks (MACH_PORT_NULL);
-  kernel_proc = pid_find (HURD_PID_KERNEL);
+  /* Find the kernel.  */
+  if (MACH_PORT_VALID (kernel_task))
+    kernel_proc = task_find (kernel_task);
+  else
+    {
+      /* Get a list of all tasks to find the kernel.  */
+      add_tasks (MACH_PORT_NULL);
+      kernel_proc = pid_find (HURD_PID_KERNEL);
+    }
 
   /* Register for new task notifications using the kernel's process as
      the port.  */
diff --git a/proc/mgt.c b/proc/mgt.c
index 87a7c96..a9015cc 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -732,7 +732,61 @@ new_proc (task_t task)
     complete_proc (p, genpid ());
   return p;
 }
+
 
+
+/* Task namespace support.  */
+
+/* Check if a given process is part of a task namespace but is not the
+   root.  The root is managed by us, while all other tasks are managed
+   by the root itself.  */
+int
+namespace_is_subprocess (struct proc *p)
+{
+  return (p
+          && MACH_PORT_VALID (p->p_task_namespace)
+          && p->p_parent
+          && MACH_PORT_VALID (p->p_parent->p_task_namespace));
+}
+
+/* Translate PIDs valid in NAMESPACE into PIDs valid in our own
+   process space.
+
+   Conditions: global_lock is unlocked before calling, and is locked
+   afterwards.  */
+error_t
+namespace_translate_pids (mach_port_t namespace, pid_t *pids, size_t pids_len)
+{
+  size_t i;
+  task_t *tasks;
+
+  tasks = calloc (pids_len, sizeof *tasks);
+  if (tasks == NULL)
+    {
+      pthread_mutex_lock (&global_lock);
+      return ENOMEM;
+    }
+
+  for (i = 0; i < pids_len; i++)
+    /* We handle errors by checking each returned task.  */
+    proc_pid2task (namespace, pids[i], &tasks[i]);
+
+  pthread_mutex_lock (&global_lock);
+
+  for (i = 0; i < pids_len; i++)
+    if (MACH_PORT_VALID (tasks[i]))
+      {
+        struct proc *p = task_find_nocreate (tasks[i]);
+        mach_port_deallocate (mach_task_self (), tasks[i]);
+        pids[i] = p ? p->p_pid : (pid_t) -1;
+      }
+    else
+      pids[i] = (pid_t) -1;
+
+  free (tasks);
+  return 0;
+}
+
 /* Find the creator of the task namespace that P is in.  */
 struct proc *
 namespace_find_root (struct proc *p)
@@ -759,6 +813,8 @@ namespace_terminate (struct proc *p, void *cookie)
     task_terminate (p->p_task);
 }
 
+
+
 /* The task associated with process P has died.  Drop most state,
    and then record us as dead.  Our parent will eventually complete the
    deallocation. */
diff --git a/proc/msg.c b/proc/msg.c
index 1f132cd..8efc993 100644
--- a/proc/msg.c
+++ b/proc/msg.c
@@ -126,7 +126,8 @@ S_proc_getmsgport (struct proc *callerp,
                   mach_port_t reply_port,
                   mach_msg_type_name_t reply_port_type,
                   pid_t pid,
-                  mach_port_t *msgport)
+                  mach_port_t *msgport,
+                   mach_msg_type_name_t *msgport_type)
 {
   int cancel;
   struct proc *p;
@@ -136,7 +137,31 @@ S_proc_getmsgport (struct proc *callerp,
 
   p = pid_find_allow_zombie (pid);
 
-restart:  
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+        err = proc_getmsgport (p->p_task_namespace, pid_sub, msgport);
+
+      pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       {
+         *msgport_type = MACH_MSG_TYPE_MOVE_SEND;
+         return 0;
+       }
+
+      /* Fallback.  */
+    }
+
+ restart:
   while (p && p->p_deadmsg && !p->p_dead)
     {
       callerp->p_msgportwait = 1;
@@ -156,7 +181,8 @@ restart:
 
   if (check_msgport_death (p))
     goto restart;
-  
+
+  *msgport_type = MACH_MSG_TYPE_COPY_SEND;
   *msgport = p->p_msgport;
 
   return 0;
diff --git a/proc/pgrp.c b/proc/pgrp.c
index d7c562f..9db1dba 100644
--- a/proc/pgrp.c
+++ b/proc/pgrp.c
@@ -147,6 +147,30 @@ S_proc_getsid (struct proc *callerp,
 
   /* No need to check CALLERP; we don't use it. */
 
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+        err = proc_getsid (p->p_task_namespace, pid_sub, sid);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (p->p_task_namespace, sid, 1);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   *sid = p->p_pgrp->pg_session->s_sid;
   return 0;
 }
@@ -167,6 +191,31 @@ S_proc_getsessionpids (struct proc *callerp,
 
   /* No need to check CALLERP; we don't use it. */
 
+  p = pid_find (sid);
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+        err = proc_getsessionpids (p->p_task_namespace, pid_sub, pids, npidsp);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (p->p_task_namespace, *pids, *npidsp);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   s = session_find (sid);
   if (!s)
     return ESRCH;
@@ -206,6 +255,7 @@ S_proc_getsessionpgids (struct proc *callerp,
                        size_t *npgidsp)
 {
   int count;
+  struct proc *p;
   struct pgrp *pg;
   struct session *s;
   pid_t *pp = *pgids;
@@ -213,6 +263,31 @@ S_proc_getsessionpgids (struct proc *callerp,
 
   /* No need to check CALLERP; we don't use it. */
 
+  p = pid_find (sid);
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+        err = proc_getsessionpgids (p->p_task_namespace, pid_sub, pgids, 
npgidsp);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (p->p_task_namespace, *pgids, *npgidsp);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   s = session_find (sid);
   if (!s)
     return ESRCH;
@@ -254,6 +329,31 @@ S_proc_getpgrppids (struct proc *callerp,
 
   /* No need to check CALLERP; we don't use it. */
 
+  p = pid_find (pgid);
+  if (namespace_is_subprocess (p))
+    {
+      /* Relay it to the Subhurd's proc server (if any).  */
+      error_t err;
+      pid_t pid_sub;
+
+      /* Release global lock while talking to the other proc server.  */
+      pthread_mutex_unlock (&global_lock);
+
+      err = proc_task2pid (p->p_task_namespace, p->p_task, &pid_sub);
+      if (! err)
+        err = proc_getpgrppids (p->p_task_namespace, pid_sub, pids, npidsp);
+      if (! err)
+       /* Acquires global_lock.  */
+       err = namespace_translate_pids (p->p_task_namespace, *pids, *npidsp);
+      else
+       pthread_mutex_lock (&global_lock);
+
+      if (! err)
+       return 0;
+
+      /* Fallback.  */
+    }
+
   if (pgid == 0)
     pg = callerp->p_pgrp;
   else
diff --git a/proc/proc.h b/proc/proc.h
index c069614..333e884 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -201,6 +201,8 @@ void leave_pgrp (struct proc *);
 void join_pgrp (struct proc *);
 void boot_setsid (struct proc *);
 
+int namespace_is_subprocess (struct proc *p);
+error_t namespace_translate_pids (mach_port_t namespace, pid_t *pids, size_t 
pids_len);
 struct proc *namespace_find_root (struct proc *);
 void process_has_exited (struct proc *);
 void alert_parent (struct proc *);
diff --git a/release/servers.boot b/release/servers.boot
index 9ba7f6a..8b66743 100644
--- a/release/servers.boot
+++ b/release/servers.boot
@@ -3,7 +3,7 @@
 
 # First, the bootstrap filesystem.  It needs several ports as arguments,
 # as well as the user flags from the boot loader.
-/hurd/ext2fs.static --multiboot-command-line=${kernel-command-line} 
--host-priv-port=${host-port} --device-master-port=${device-port} 
--exec-server-task=${exec-task} -T typed ${root} $(task-create) $(task-resume)
+/hurd/ext2fs.static --multiboot-command-line=${kernel-command-line} 
--host-priv-port=${host-port} --device-master-port=${device-port} 
--exec-server-task=${exec-task} --kernel-task=${kernel-task} -T typed ${root} 
$(task-create) $(task-resume)
 
 
 # Now the exec server; to load the dynamically-linked exec server program,
diff --git a/startup/startup.c b/startup/startup.c
index 913742c..3c3ead4 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -72,6 +72,8 @@ static int verbose = 0;
 
 const char *argp_program_version = STANDARD_HURD_VERSION (startup);
 
+#define OPT_KERNEL_TASK        -1
+
 static struct argp_option
 options[] =
 {
@@ -83,6 +85,7 @@ options[] =
   {"fake-boot",   'f', 0, 0, "This hurd hasn't been booted on the raw 
machine"},
   {"verbose",     'v', 0, 0, "be verbose"},
   {0,             'x', 0, OPTION_HIDDEN},
+  {"kernel-task", OPT_KERNEL_TASK, "PORT"},
   {0}
 };
 
@@ -136,6 +139,7 @@ static int fakeboot;
 
 /* The tasks of auth and proc and the bootstrap filesystem. */
 static task_t authtask, proctask, fstask;
+static task_t kernel_task;
 
 static mach_port_t default_ports[INIT_PORT_MAX];
 static mach_port_t default_dtable[3];
@@ -344,10 +348,13 @@ record_essential_task (const char *name, task_t task)
 
 /** Starting programs **/
 
+typedef error_t (*insert_ports_fnc_t) (char **argv, size_t *argv_len, task_t 
task);
+
 /* Run SERVER, giving it INIT_PORT_MAX initial ports from PORTS.
    Set TASK to be the task port of the new image. */
 void
-run (const char *server, mach_port_t *ports, task_t *task)
+run (const char *server, mach_port_t *ports, task_t *task,
+     insert_ports_fnc_t insert_ports)
 {
   char buf[BUFSIZ];
   const char *prog = server;
@@ -369,18 +376,31 @@ run (const char *server, mach_port_t *ports, task_t *task)
        error (0, errno, "%s", prog);
       else
        {
-         task_create (mach_task_self (),
+          char *argz = NULL;
+          size_t argz_len = 0;
+          err = argz_create_sep (prog, ' ', &argz, &argz_len);
+          assert_perror (err);
+
+          err = task_create (mach_task_self (),
 #ifdef KERN_INVALID_LEDGER
-                      NULL, 0, /* OSF Mach */
+                             NULL, 0,  /* OSF Mach */
 #endif
-                      0, task);
+                             0, task);
+          assert_perror (err);
+
+          if (insert_ports)
+            {
+              err = insert_ports (&argz, &argz_len, *task);
+              assert_perror (err);
+            }
+
          if (bootstrap_args & RB_KDB)
            {
              fprintf (stderr, "Pausing for %s\n", prog);
              getchar ();
            }
          err = file_exec (file, *task, 0,
-                          (char *)prog, strlen (prog) + 1, /* Args.  */
+                          argz, argz_len, /* Args.  */
                           startup_envz, startup_envz_len,
                           default_dtable, MACH_MSG_TYPE_COPY_SEND, 3,
                           ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
@@ -408,6 +428,50 @@ run (const char *server, mach_port_t *ports, task_t *task)
   request_dead_name (*task);
 }
 
+/* Insert PORT of type PORT_TYPE into TASK, adding '--ARGUMENT=<name>'
+   to ARGZ (with <name> being the name valid in TASK).  */
+error_t
+argz_task_insert_right (char **argz, size_t *argz_len, task_t task,
+                        const char *argument,
+                        mach_port_t port, mach_msg_type_name_t port_type)
+{
+  error_t err;
+  mach_port_t name;
+  char *arg;
+
+  name = MACH_PORT_NULL;
+  do
+    {
+      name += 1;
+      err = mach_port_insert_right (task, name, port, port_type);
+    }
+  while (err == KERN_NAME_EXISTS);
+
+  if (asprintf (&arg, "--%s=%d", argument, name) < 0)
+    return errno;
+
+  err = argz_add (argz, argz_len, arg);
+  free (arg);
+  return err;
+}
+
+error_t
+proc_insert_ports (char **argz, size_t *argz_len, task_t task)
+{
+  error_t err;
+
+  if (MACH_PORT_VALID (kernel_task))
+    {
+      err = argz_task_insert_right (argz, argz_len, task,
+                                    "kernel-task",
+                                    kernel_task, MACH_MSG_TYPE_COPY_SEND);
+      if (err)
+        return err;
+    }
+
+  return 0;
+}
+
 /* Run FILENAME as root with ARGS as its argv (length ARGLEN).  Return
    the task that we started.  If CTTY is set, then make that the
    controlling terminal of the new process and put it in its own login
@@ -597,6 +661,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'H': crash_flags = RB_DEBUGGER; break;
     case 'v': verbose++; break;
     case 'x': /* NOP */ break;
+    case OPT_KERNEL_TASK:
+      kernel_task = atoi (arg);
+      break;
     default: return ARGP_ERR_UNKNOWN;
     }
   return 0;
@@ -685,10 +752,10 @@ main (int argc, char **argv, char **envp)
                               | sigmask (SIGTTOU));
 
   default_ports[INIT_PORT_BOOTSTRAP] = startup;
-  run ("/hurd/proc", default_ports, &proctask);
+  run ("/hurd/proc", default_ports, &proctask, proc_insert_ports);
   if (! verbose)
     fprintf (stderr, " proc");
-  run ("/hurd/auth", default_ports, &authtask);
+  run ("/hurd/auth", default_ports, &authtask, NULL);
   if (! verbose)
     fprintf (stderr, " auth");
   default_ports[INIT_PORT_BOOTSTRAP] = MACH_PORT_NULL;
@@ -755,9 +822,7 @@ launch_core_servers (void)
     fprintf (stderr, "Installed on /servers/startup\n");
 
   err = startup_authinit_reply (authreply, authreplytype, 0, authproc,
-                               MACH_MSG_TYPE_COPY_SEND);
-  assert_perror (err);
-  err = mach_port_deallocate (mach_task_self (), authproc);
+                               MACH_MSG_TYPE_MOVE_SEND);
   assert_perror (err);
 
   if (verbose)
@@ -818,8 +883,7 @@ launch_core_servers (void)
     fprintf (stderr, "Message port registered\n");
 
   /* Give the bootstrap FS its proc and auth ports.  */
-  err = fsys_init (bootport, fsproc, MACH_MSG_TYPE_COPY_SEND, authserver);
-  mach_port_deallocate (mach_task_self (), fsproc);
+  err = fsys_init (bootport, fsproc, MACH_MSG_TYPE_MOVE_SEND, authserver);
   if (err)
     error (0, err, "fsys_init"); /* Not necessarily fatal.  */
 
@@ -836,7 +900,6 @@ init_stdarrays ()
   mach_port_t ref;
   mach_port_t *std_port_array;
   int *std_int_array;
-  int i;
 
   std_port_array = alloca (sizeof (mach_port_t) * INIT_PORT_MAX);
   std_int_array = alloca (sizeof (int) * INIT_INT_MAX);
@@ -870,10 +933,8 @@ init_stdarrays ()
   std_int_array[INIT_UMASK] = CMASK;
 
   __USEPORT (PROC, proc_setexecdata (port, std_port_array,
-                                    MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX,
+                                    MACH_MSG_TYPE_MOVE_SEND, INIT_PORT_MAX,
                                     std_int_array, INIT_INT_MAX));
-  for (i = 0; i < INIT_PORT_MAX; i++)
-    mach_port_deallocate (mach_task_self (), std_port_array[i]);
 }
 
 /* Frobnicate the kernel task and the proc server's idea of it (PID 2),
@@ -911,11 +972,19 @@ frob_kernel_process (void)
   if (verbose)
     fprintf (stderr, "Frobbing kernel process\n");
 
-  err = proc_pid2task (procserver, HURD_PID_KERNEL, &task);
-  if (err)
+  if (MACH_PORT_VALID (kernel_task))
     {
-      error (0, err, "cannot get kernel task port");
-      return;
+      task = kernel_task;
+      kernel_task = MACH_PORT_NULL;
+    }
+  else
+    {
+      err = proc_pid2task (procserver, HURD_PID_KERNEL, &task);
+      if (err)
+        {
+          error (0, err, "cannot get kernel task port");
+          return;
+        }
     }
 
   /* Make the kernel our child.  */

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]