summaryrefslogtreecommitdiff
path: root/proc/mgt.c
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2017-03-09 23:55:12 +0100
committerJustus Winter <justus@gnupg.org>2017-03-11 18:07:23 +0100
commit34a94ce86b1bada9c0768f631540735d44f41100 (patch)
treec0e2871ecb2466ea001d9be505b05fdc10702087 /proc/mgt.c
parentbaf7e5c8ce176aead15c2559952d8bdf0da41ffd (diff)
proc: Hierarchical proc servers.
Previously, a Subhurd's tasks were shown as weird processes in the Motherhurd. This change connects the proc server in the Motherhurd with the proc server in the Subhurd, embedding the Subhurd's process hierarchy. Subhurd's processes can now be inspected and debugged like any other process. * NEWS: Update. * boot/boot.c (mach_msg_forward): New function. (boot_demuxer): Forward messages arriving on the new task notification port from the proc server, and forward them to the proc server inside the Subhurd via the notification port. * proc/info.c (S_proc_task2proc): Relay request for processes in a task namespace to the Subhurd's proc server. (S_proc_pid2proc): Likewise. (S_proc_getprocargs): Likewise. (S_proc_getprocenv): Likewise. (S_proc_getprocinfo): Likewise. Translate PIDs. (S_proc_getloginid): Likewise. (S_proc_getloginpids): Likewise. * proc/mgt.c (namespace_is_subprocess): New function. (namespace_translate_pids): Likewise. * proc/msg.c (S_proc_getmsgport): Relay request for processes in a task namespace to the Subhurd's proc server. * proc/pgrp.c (S_proc_getsid): Likewise. Translate PIDs. (S_proc_getsessionpids): Likewise. (S_proc_getsessionpgids): Likewise. (S_proc_getpgrppids): Likewise. * proc/proc.h (namespace_is_subprocess): New prototype. (namespace_translate_pids): Likewise.
Diffstat (limited to 'proc/mgt.c')
-rw-r--r--proc/mgt.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/proc/mgt.c b/proc/mgt.c
index 87a7c96b..a9015ccc 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. */