bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH hurd 3/5] proc: implement `proc_make_task_namespace'


From: Samuel Thibault
Subject: Re: [PATCH hurd 3/5] proc: implement `proc_make_task_namespace'
Date: Wed, 10 Dec 2014 01:45:40 +0100
User-agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30)

Justus Winter, le Thu 13 Nov 2014 13:26:17 +0100, a écrit :
> * proc/proc.h (struct proc): Add field `p_task_namespace'.
> * proc/mgt.c (S_proc_child): Propagate `p_task_namespace' to child.
> (allocate_proc): Initialize `p_task_namespace'.
> (namespace_terminate): New function.
> (process_has_exited): Reparent children of dead tasks in the namespace
> to the root process.  Terminate all tasks if the root process dies.
> Reap dead tasks.
> (S_mach_notify_new_task): For newly created tasks thats parent is in a
> namespace, call S_proc_child and forward the `mach_notify_new_task'
> message.
> (S_proc_make_task_namespace): New function.

Ack.

> ---
>  proc/mgt.c  | 112 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  proc/proc.h |   4 +++
>  2 files changed, 107 insertions(+), 9 deletions(-)
> 
> diff --git a/proc/mgt.c b/proc/mgt.c
> index 32408ae..bf400ba 100644
> --- a/proc/mgt.c
> +++ b/proc/mgt.c
> @@ -220,6 +220,13 @@ S_proc_child (struct proc *parentp,
>        childp->end_code = parentp->end_code;
>      }
>  
> +  if (MACH_PORT_VALID (parentp->p_task_namespace))
> +    {
> +      mach_port_mod_refs (mach_task_self (), parentp->p_task_namespace,
> +                       MACH_PORT_RIGHT_SEND, +1);
> +      childp->p_task_namespace = parentp->p_task_namespace;
> +    }
> +
>    return 0;
>  }
>  
> @@ -577,6 +584,7 @@ allocate_proc (task_t task)
>  
>    memset (&p->p_pi + 1, 0, sizeof *p - sizeof p->p_pi);
>    p->p_task = task;
> +  p->p_task_namespace = MACH_PORT_NULL;
>    p->p_msgport = MACH_PORT_NULL;
>  
>    pthread_cond_init (&p->p_wakeup, NULL);
> @@ -721,6 +729,16 @@ new_proc (task_t task)
>    return p;
>  }
>  
> +/* Used with prociterate to terminate all tasks in a task
> +   namespace.  */
> +static void
> +namespace_terminate (struct proc *p, void *cookie)
> +{
> +  mach_port_t *namespacep = cookie;
> +  if (p->p_task_namespace == *namespacep)
> +    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. */
> @@ -751,13 +769,39 @@ process_has_exited (struct proc *p)
>  
>    ids_rele (p->p_id);
>  
> -  /* Reparent our children to init by attaching the head and tail
> -     of our list onto init's.  */
> +  /* Reparent our children to init by attaching the head and tail of
> +     our list onto init's.  If the process is part of a task
> +     namespace, reparent to the process that created the namespace
> +     instead.  */
>    if (p->p_ochild)
>      {
> +      struct proc *reparent_to = init_proc;
>        struct proc *tp;               /* will point to the last one.  */
>        int isdead = 0;
>  
> +      if (MACH_PORT_VALID (p->p_task_namespace))
> +     {
> +       for (tp = p;
> +            MACH_PORT_VALID (tp->p_parent->p_task_namespace);
> +            tp = tp->p_parent)
> +         {
> +           /* Walk up the process hierarchy until we find the
> +              creator of the task namespace.  */
> +         }
> +
> +       if (p == tp)
> +         {
> +           /* The creator of the task namespace died.  Terminate
> +              all tasks.  */
> +           prociterate (namespace_terminate, &p->p_task_namespace);
> +
> +           mach_port_deallocate (mach_task_self (), p->p_task_namespace);
> +           p->p_task_namespace = MACH_PORT_NULL;
> +         }
> +       else
> +         reparent_to = tp;
> +     }
> +
>        /* first tell them their parent is changing */
>        for (tp = p->p_ochild; tp->p_sib; tp = tp->p_sib)
>       {
> @@ -765,7 +809,7 @@ process_has_exited (struct proc *p)
>           nowait_msg_proc_newids (tp->p_msgport, tp->p_task,
>                                   1, tp->p_pgrp->pg_pgid,
>                                   !tp->p_pgrp->pg_orphcnt);
> -       tp->p_parent = init_proc;
> +       tp->p_parent = reparent_to;
>         if (tp->p_dead)
>           isdead = 1;
>       }
> @@ -773,17 +817,17 @@ process_has_exited (struct proc *p)
>       nowait_msg_proc_newids (tp->p_msgport, tp->p_task,
>                               1, tp->p_pgrp->pg_pgid,
>                               !tp->p_pgrp->pg_orphcnt);
> -      tp->p_parent = init_proc;
> +      tp->p_parent = reparent_to;
>  
>        /* And now append the lists. */
> -      tp->p_sib = init_proc->p_ochild;
> +      tp->p_sib = reparent_to->p_ochild;
>        if (tp->p_sib)
>       tp->p_sib->p_prevsib = &tp->p_sib;
> -      init_proc->p_ochild = p->p_ochild;
> -      p->p_ochild->p_prevsib = &init_proc->p_ochild;
> +      reparent_to->p_ochild = p->p_ochild;
> +      p->p_ochild->p_prevsib = &reparent_to->p_ochild;
>  
>        if (isdead)
> -     alert_parent (init_proc);
> +     alert_parent (reparent_to);
>      }
>  
>    /* If an operation is in progress for this process, cause it
> @@ -795,6 +839,23 @@ process_has_exited (struct proc *p)
>  
>    /* Cancel any outstanding RPCs done on behalf of the dying process.  */
>    ports_interrupt_rpcs (p);
> +
> +  /* No one is going to wait for processes in a task namespace.  */
> +  if (MACH_PORT_VALID (p->p_task_namespace))
> +    {
> +      mach_port_t task;
> +      mach_port_deallocate (mach_task_self (), p->p_task_namespace);
> +      p->p_waited = 1;
> +
> +      /* XXX: `complete_exit' will destroy p->p_task if it is valid.
> +      Prevent this so that `do_mach_notify_dead_name' can
> +      deallocate the right.  The proper fix is not to use
> +      mach_port_destroy in the first place.  */
> +      task = p->p_task;
> +      p->p_task = MACH_PORT_NULL;
> +      complete_exit (p);
> +      mach_port_deallocate (mach_task_self (), task);
> +    }
>  }
>  
>  void
> @@ -1008,9 +1069,42 @@ S_mach_notify_new_task (mach_port_t notify,
>        childp = new_proc (task);
>      }
>  
> -  /* XXX do something interesting */
> +  if (MACH_PORT_VALID (parentp->p_task_namespace))
> +    {
> +      error_t err;
> +      /* Tasks in a task namespace are not expected to call
> +      proc_child, so we do it on their behalf.  */
> +      mach_port_mod_refs (mach_task_self (), task, MACH_PORT_RIGHT_SEND, +1);
> +      err = S_proc_child (parentp, task);
> +      if (! err)
> +     /* Relay the notification.  This consumes TASK and PARENT.  */
> +     return mach_notify_new_task (childp->p_task_namespace, task, parent);
> +    }
>  
>    mach_port_deallocate (mach_task_self (), task);
>    mach_port_deallocate (mach_task_self (), parent);
>    return 0;
>  }
> +
> +/* Implement proc_make_task_namespace as described in
> +   <hurd/process.defs>.  */
> +error_t
> +S_proc_make_task_namespace (struct proc *callerp,
> +                         mach_port_t notify)
> +{
> +  if (! callerp)
> +    return EOPNOTSUPP;
> +
> +  if (! MACH_PORT_VALID (notify))
> +    return EINVAL;
> +
> +  if (MACH_PORT_VALID (callerp->p_task_namespace))
> +    {
> +      mach_port_deallocate (mach_task_self (), notify);
> +      return EBUSY;
> +    }
> +
> +  callerp->p_task_namespace = notify;
> +
> +  return 0;
> +}
> diff --git a/proc/proc.h b/proc/proc.h
> index 6196697..a056d18 100644
> --- a/proc/proc.h
> +++ b/proc/proc.h
> @@ -58,6 +58,10 @@ struct proc
>    /* Process group structure */
>    struct pgrp *p_pgrp;
>  
> +  /* Processes may live in a task namespace identified by the
> +     notification port registered by proc_make_task_namespace.  */
> +  mach_port_t p_task_namespace;      /* send right */
> +
>    /* Communication */
>    mach_port_t p_msgport;     /* send right */
>  
> -- 
> 2.1.1
> 

-- 
Samuel
 SL> Au fait elle est mieux ma signature maintenant ?
 Oui. T'enlève encore les conneries que t'as écrit dedans et c'est bon.
 -+- JB in <http://neuneu.mine.nu> : Le neueuttoyage par le vide -+-



reply via email to

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