aboutsummaryrefslogtreecommitdiff
path: root/proc/info.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/info.c
parentbaf7e5c8ce176aead15c2559952d8bdf0da41ffd (diff)
downloadhurd-34a94ce86b1bada9c0768f631540735d44f41100.tar.gz
hurd-34a94ce86b1bada9c0768f631540735d44f41100.tar.bz2
hurd-34a94ce86b1bada9c0768f631540735d44f41100.zip
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/info.c')
-rw-r--r--proc/info.c216
1 files changed, 215 insertions, 1 deletions
diff --git a/proc/info.c b/proc/info.c
index 97321408..79a4c37f 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -109,6 +109,28 @@ 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);
@@ -151,6 +173,27 @@ 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;
@@ -345,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);
}
@@ -362,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);
}
@@ -398,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);
@@ -644,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);
@@ -674,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;