l4-hurd
[Top][All Lists]
Advanced

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

Re: Task destruction


From: Niels Möller
Subject: Re: Task destruction
Date: 05 Aug 2002 23:23:34 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Wolfgang Jährling <address@hidden> writes:

> Niels Möller <address@hidden> wrote:
> > One issue that has been discussed earlier is that all tasks, even ones
> > that haven't registered with any proc server, need some kind of
> > owner/identity.
> 
> Sure, that's a task-id.

Not quite, the thing I talk about does not identify the task itself,
it identifies a *process* (or possibly a user) that is somehow
responsible for the task.

> Except for that we want more something like an association
> <master's-task-id,task-id>, where the master is permitted to kill the
> task "task-id", I agree.

I think it makes sense to require that what you call the "master" is a
process. This way, we can associate the task with some user
identities, namely the ones of the master, and use that to determine
who may kill the task.

> I have not given it too much thought, but my idea was to add an
> argument to the task_create RPC to specify the master.

Following Roland's plan, I think it makes more sense to have a new
task inherit the "master process" from the task that created it. That
should be the default behaviour, only overridable by the proc server.

> The task-server would notify this "master" about creation and
> death of the task.

I think such notifications (in particular death notifications) are
important, but other tasks need to be able to ask for notifications
too, for no-senders notifications to work. Perhaps it's simplest to
allow any task to register for death notifications for *any* other
task in the system.

> When creating a new task, we would usually specify our own proc server
> as the "master" (i.e. the task we will get from getproc (), which I just
> assume we will, as an object handle alone is never enough).

Now it sounds like the proc server will need to know about every task.
I think the problem is that if both you and I create some tasks that
in turn create some tasks that don't register with proc, I should be
able to kill my tasks but not yours. And it seems natural to put the
per-task book-keeping in the task server rather than in proc.

> > One important responsibility of the task server ought to be to
> > maintain that identity so that it is reliably inherited when new tasks
> > are created.
> 
> Do we have a reason to use inheritance here?

Yes. If a process of mine creates some task that creates more tasks
and so on, all of those tasks are mine. Therefore the ownership must
be inherited, no matter what the tasks do. The tasks' "owner" could be
a user (me) or a process (the closest ancestor that is registered with
proc). Using a process seems fine to me and provides a little more
information, for example I'd like to be able to kill a process and all
tasks it owns, and I also suspect that it will work better with the
"login group" concept (processes in a login group have no uid:s, but
are allowed to signal processes only within the group. I hope I got
the terinology right here).

> > (This is on the assumption that the process
> > server wants to deal only with tasks that register with it
> > voluntarily, but I guess there are several ways to divide the work
> > between the task server and the proc server).
> 
> I am not sure what you mean.

The two ends of the scale are:

A. The proc server knows only tasks that has registered
   with it voluntarily. Information about other tasks must be somebody
   else's responsibility (e.g. the task server's).

B. All tasks are known to some proc server. In this case, we could
   assign a pid to each and every task in the system. Then there's
   very little left to do for the task server.

> > If we have a process P that has spawned, directly or indirectly, a
> > task T that is not associated with any proc server, I think it makes
> > sense, when it comes to resource limits and license to kill, to treat
> > T in a similar way as a thread within P.
> 
> I assume that with "associated", you mean "registered"?

I do.

> Care to explain why you think it makes sense to treat T similar to a
> thread in P?

Like a thread, a task has no hurd:ish or unix:ish attributes (e.g. a
uid) by itself. And when looking at access control issues (like who is
allowed to terminate execution or attach a debugger), basing those
decisions on the properties of an associated process seems like a
solution that will be easy to use and understand.

One way to view a task that's not a process is to say that it's just a
collection of threads that are part of the process but happens to also
have their own address space. The border between tasks is a little
floating, as two different address spaces can share all mappings but a
page or two.

> And what we do in the case of P dieing early could be left up to the
> proc server, where I would prefer the default value not to be
> killing.

On the other hand, "kill pid" may be a convenient way to kill a
process and any non-process tasks it has spawn. A compromise is to
keep the process in some kind of near-death state, where it stays
until T has died. The resource information reported by wait* on P
should include resources consumed by T.

But one could have two different SIGKILL signals, one that kills the
process and its tasks, and a different one that puts the process in
the near-death state. There are plenty of variations, perhaps tasks
associated with a near-dead process should not be allowed to spawn new
tasks?

> > In the case of neigbour hurds, I think it makes sense to deal with the
> > entire neighbour hurd, including all its tasks, as associated with a
> > single process in the parent hurd, namely boot. This implies that a
> > task may need several identities or associateions: A task in the
> > neighbour hurd needs to be associated with both some process in the
> > neighbour hurd's proc server, and with the proc server and the boot
> > process in the parent hurd.
> 
> Depends on what kind of "association" you are speaking about.

I'll try to draw a picture:

 Parent hurd      Child hurd

  proc          ,-  proc  auth  ...
    |          /     |
   boot(nisse)  --- foo(kalle)
                     |
                     T

We have a parent hurd with a proc server and a boot process owned by
me that is the root of the tasks in a child hurd. In the child hurd,
there's a different user "kalle" who's running a process "foo". That
process has spawned a task T that has not registered with either proc
server. The question is: who is allowed to kill T?

My answer is that a task is allowed to kill T, or attach a debugger to
T, if either

 * It is allowed to send signals to my boot process (which implies
   that it's a registered process in the parent hurd), using the
   ordinary POSIX rules, or

 * It is a allowed to send signals to the foo process, according the
   the usual POSIX rules as implemented by proc, auth etc in the child
   hurd.

Thus T needs to have two "associations", <parent-proc, boot> and
<child-proc, foo>, and both these associations must be inherited by
tasks that T spawn.

What if T registers with either proc server? Then the proc server is
allowed to change the association between T and processes managed byt
that proc server. But child-proc is not allowed to change the
<parent-proc, boot> association. parent-proc should not really be able
to change the <child-proc, foo> association either, but we can't
enforce that as parent-proc does have enough privileges to attach a
debugger to child-proc.

>From this example, I also think it is clear that the relationship
between the two hurds is assymetric, and I think the
parent-hurd/child-hurd terminology makes more sense than
"neighbour-hurd".

Regards,
/Niels



reply via email to

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