commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 04/06: Pass the kernel's task port to proc.


From: Samuel Thibault
Subject: [hurd] 04/06: Pass the kernel's task port to proc.
Date: Sat, 10 Jun 2017 00:38:18 +0000

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

sthibault pushed a commit to branch upstream
in repository hurd.

commit 4089f37cdd776e046d51604041c3fe62a2bc1435
Author: Justus Winter <address@hidden>
Date:   Sun Mar 12 17:16:40 2017 +0100

    Pass the kernel's task port to proc.
    
    Previously, the early server bootstrap relied upon a specific task
    layout to determine the kernels task port.  Explicitly pass it from
    the kernel instead.
    
    * boot/boot.c (default_boot_script): Add '--kernel-task' parameter to
    ext2fs.
    (main): New bootscript variable 'kernel-task'.
    * libdiskfs/boot-start.c (diskfs_kernel_task): Declaration variable.
    (diskfs_start_bootstrap): If '--kernel-task' was given to us, pass it
    along to startup.
    * libdiskfs/opts-std-startup.c (diskfs_kernel_task): New variable.
    (startup_options): Add '--kernel-task' option.
    (parse_startup_opt): Handle option.
    * proc/main.c (kernel_task): New variable.
    (OPT_KERNEL_TASK): New macro.
    (options): New variable.
    (parse_opt): New function.
    (main): Parse options.  Use 'kernel_task' if provided.
    * release/servers.boot: Add '--kernel-task' parameter to ext2fs.
    * startup/startup.c (OPT_KERNEL_TASK): New macro.
    (options): Add '--kernel-task' option.
    (kernel_task): New variable.
    (insert_ports_fnc_t): New declaration.
    (run): Add argument for a function that inserts rights into the newly
    created task and adds arguments to the argument vector.
    (argz_task_insert_right): New function.
    (proc_insert_ports): Likewise.
    (parse_opt): New function.
    (main): Pass the kernel's task port to proc.
    (frob_kernel_process): Use the kernel's task port.
---
 boot/boot.c                  |  3 ++
 libdiskfs/boot-start.c       | 44 +++++++++++++++-----
 libdiskfs/opts-std-startup.c |  5 +++
 proc/main.c                  | 42 ++++++++++++++++---
 release/servers.boot         |  2 +-
 startup/startup.c            | 97 +++++++++++++++++++++++++++++++++++++++-----
 6 files changed, 166 insertions(+), 27 deletions(-)

diff --git a/boot/boot.c b/boot/boot.c
index 13a19d2..978f56e 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -520,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"
@@ -649,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/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/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/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 4a0304e..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;
@@ -905,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]