67 |
rootserver. The rootserver has to deal with the other modules. |
rootserver. The rootserver has to deal with the other modules. |
68 |
|
|
69 |
|
|
70 |
|
\subsection{System bootstrap} |
71 |
|
|
72 |
|
The initial part of the boot procedure is system specific. |
73 |
|
|
74 |
|
|
75 |
|
\subsubsection{Booting the ia32} |
76 |
|
|
77 |
|
On the ia32, the BIOS will be one of the first things to run. |
78 |
|
Eventually, the BIOS will start the bootloader. The Hurd requires a |
79 |
|
multiboot-compliant bootloader, such as GRUB. A typical configuration |
80 |
|
file entry in the \verb/menu.list/ file of GRUB will look like this: |
81 |
|
|
82 |
|
\begin{verbatim} |
83 |
|
title = The GNU Hurd on L4 |
84 |
|
root = (hd0,0) |
85 |
|
kernel = /boot/laden |
86 |
|
module = /boot/ia32-kernel |
87 |
|
module = /boot/sigma0 |
88 |
|
module = /boot/rootserver |
89 |
|
module = ...more servers... |
90 |
|
\end{verbatim} |
91 |
|
|
92 |
|
\begin{comment} |
93 |
|
The name of the rootserver and the further modules are not specified |
94 |
|
yet. |
95 |
|
\end{comment} |
96 |
|
|
97 |
|
GRUB loads the binary image files into memory and jumps to the entry |
98 |
|
point of \texttt{laden}. |
99 |
|
|
100 |
|
|
101 |
\subsection{The loader \texttt{laden}} |
\subsection{The loader \texttt{laden}} |
102 |
|
|
103 |
\texttt{laden} is a multiboot compliant kernel from the perspective of |
\texttt{laden} is a multiboot compliant kernel from the perspective of |
209 |
|
|
210 |
|
|
211 |
\subsection{The rootserver} |
\subsection{The rootserver} |
212 |
|
\label{rootserver} |
213 |
|
|
214 |
The rootserver is the only task in the system which threads can |
The rootserver is the only task in the system which threads can |
215 |
perform privileged system calls. So the rootserver must provide |
perform privileged system calls. So the rootserver must provide |
235 |
|
|
236 |
\item The priority is set to the 255, the maximum value. |
\item The priority is set to the 255, the maximum value. |
237 |
|
|
238 |
|
\begin{comment} |
239 |
|
The rootserver, or at least the system call wrapper, should run at |
240 |
|
a very high priority. |
241 |
|
\end{comment} |
242 |
|
|
243 |
\item The instruction pointer \verb/%eip/ is set to the entry point, |
\item The instruction pointer \verb/%eip/ is set to the entry point, |
244 |
all other registers are undefined (including the stack pointer). |
all other registers are undefined (including the stack pointer). |
245 |
|
|
263 |
\begin{comment} |
\begin{comment} |
264 |
The exact number and type of initial tasks necessary to boot the |
The exact number and type of initial tasks necessary to boot the |
265 |
Hurd are not yet known. Chances are that this list includes the |
Hurd are not yet known. Chances are that this list includes the |
266 |
task server, the physical memory server, the device servers, and the |
\texttt{task} server, the physical memory server, the device |
267 |
boot filesystem. The boot filesystem might be a small simple |
servers, and the boot filesystem. The boot filesystem might be a |
268 |
filesystem, which also includes the device drivers needed to access |
small simple filesystem, which also includes the device drivers |
269 |
the real root filesystem. |
needed to access the real root filesystem. |
270 |
\end{comment} |
\end{comment} |
271 |
|
|
272 |
|
|
273 |
\section{Inter-process communication (IPC)} |
\section{Inter-process communication (IPC)} |
274 |
|
\label{ipc} |
275 |
|
|
276 |
The Hurd requires a capability system. Capabilities are used to proof |
The Hurd requires a capability system. Capabilities are used to proof |
277 |
your identity to other servers (authentication), and access |
your identity to other servers (authentication), and access |
374 |
unreliable data from an imposter, or sends sensitive data to it. |
unreliable data from an imposter, or sends sensitive data to it. |
375 |
|
|
376 |
\begin{comment} |
\begin{comment} |
377 |
The task server wants to reuse thread numbers because that makes |
The \texttt{task} server wants to reuse thread numbers because that |
378 |
best use of kernel memory. Reusing task IDs, the version field of a |
makes best use of kernel memory. Reusing task IDs, the version |
379 |
thread ID, is not so important, but there are only 14 bits for the |
field of a thread ID, is not so important, but there are only 14 |
380 |
version field (and the lower six bits must not be all zero). So a |
bits for the version field (and the lower six bits must not be all |
381 |
thread ID is bound to be reused eventually. |
zero). So a thread ID is bound to be reused eventually. |
382 |
|
|
383 |
Using the version field in a thread ID as a generation number is not |
Using the version field in a thread ID as a generation number is not |
384 |
good enough, because it is so small. Even on 64-bit architectures, |
good enough, because it is so small. Even on 64-bit architectures, |
386 |
\end{comment} |
\end{comment} |
387 |
|
|
388 |
The best way to prevent that a task can be tricked into talking to an |
The best way to prevent that a task can be tricked into talking to an |
389 |
imposter is to have the task server notify the task if the |
imposter is to have the \texttt{task} server notify the task if the |
390 |
communication partner dies. The task server must guarantee that the |
communication partner dies. The \texttt{task} server must guarantee |
391 |
task ID is not reused until all tasks that got such a notification |
that the task ID is not reused until all tasks that got such a |
392 |
acknowledge that it is processed, and thus no danger of confusion |
notification acknowledge that it is processed, and thus no danger of |
393 |
exists anymore. |
confusion exists anymore. |
394 |
|
|
395 |
The task server will provide references to task IDs in form of |
The \texttt{task} server provides references to task IDs in form of |
396 |
\emph{task info capabilities}. If a task has a task info capability |
\emph{task info capabilities}. If a task has a task info capability |
397 |
for another task, it will prevent that this other task's task ID is |
for another task, it prevents that this other task's task ID is reused |
398 |
reused even if that task dies, and it will also make sure that task |
even if that task dies, and it also makes sure that task death |
399 |
death notifications are delivered in that case. |
notifications are delivered in that case. |
400 |
|
|
401 |
\begin{comment} |
\begin{comment} |
402 |
Because only the task server can create and destroy tasks, and |
Because only the \texttt{task} server can create and destroy tasks, |
403 |
assign task IDs, there is no need to hold such task info |
and assign task IDs, there is no need to hold such task info |
404 |
capabilities for the task server, nor does the task server need to |
capabilities for the \texttt{task} server, nor does the |
405 |
hold task info capabilities for its clients. This avoids the |
\texttt{task} server need to hold task info capabilities for its |
406 |
obvious bootstrap problem in providing capabilities in the task |
clients. This avoids the obvious bootstrap problem in providing |
407 |
server. This will even work if the task server is not the real task |
capabilities in the \texttt{task} server. This will even work if |
408 |
server, but a proxy task server (see section \ref{proxytaskserver} |
the \texttt{task} server is not the real \texttt{task} server, but a |
409 |
on page \pageref{proxytaskserver}). |
proxy task server (see section \ref{proxytaskserver} on page |
410 |
|
\pageref{proxytaskserver}). |
411 |
\end{comment} |
\end{comment} |
412 |
|
|
413 |
As task IDs are a global resource, care has to be taken that this |
As task IDs are a global resource, care has to be taken that this |
414 |
approach does not allow for a DoS-attack by exhausting the task ID |
approach does not allow for a DoS-attack by exhausting the task ID |
415 |
number space. |
number space, see section \ref{taskinfocap} on page |
416 |
|
\pageref{taskinfocap} for more details. |
|
\begin{comment} |
|
|
Several strategies can be taken: |
|
|
|
|
|
\begin{itemize} |
|
|
\item Task death notifications can be monitored. If there is no |
|
|
acknowdgement within a certain time period, the task server could |
|
|
be allowed to reuse the task ID anyway. This is not a good |
|
|
strategy because it can considerably weaken the security of the |
|
|
system (capabilities might be leaked to tasks which reuse such a |
|
|
task ID reclaimed by force). |
|
|
\item The proc server can show dead task IDs which are not released |
|
|
yet, in analogy to the zombie processes in Unix. It can also make |
|
|
available the list of tasks which prevent reusing the task ID, to |
|
|
allow users or the system administrator to clean up manually. |
|
|
\item Quotas can be used to punish users which do not acknowledge |
|
|
task death timely. For example, if the number of tasks the user |
|
|
is allowed to create is restricted, the task info caps that the |
|
|
user holds for dead tasks could be counted toward that limit. |
|
|
\item Any task could be restricted to as many task ID references as |
|
|
there are live tasks in the system, plus some slack. That would |
|
|
prevent the task from creating new task info caps if it does not |
|
|
release old ones from death tasks. The slack would be provided to |
|
|
not unnecessarily slow down a task that processes task death |
|
|
notifications asynchronously to making connections with new tasks. |
|
|
\end{itemize} |
|
|
|
|
|
In particular the last two approaches should proof to be effective |
|
|
in providing an incentive for tasks to release task info caps they |
|
|
do not need anymore. |
|
|
\end{comment} |
|
417 |
|
|
418 |
|
|
419 |
\subsection{Capabilities} |
\subsection{Capabilities} |
468 |
|
|
469 |
This is not enough if several systems run in parallel on the same |
This is not enough if several systems run in parallel on the same |
470 |
host. Then the version ID for the threads in the other systems will |
host. Then the version ID for the threads in the other systems will |
471 |
not be under the control of the Hurd's task server, and can thus not |
not be under the control of the Hurd's \texttt{task} server, and can |
472 |
be trusted. The server can still use the version field to find out |
thus not be trusted. The server can still use the version field to |
473 |
the task ID, which will be correct \emph{if the thread is part of |
find out the task ID, which will be correct \emph{if the thread is |
474 |
the same subsystem}. It also has to verify that the thread |
part of the same subsystem}. It also has to verify that the |
475 |
belongs to this subsystem. Hopefully the subsystem will be encoded |
thread belongs to this subsystem. Hopefully the subsystem will be |
476 |
in the thread ID. Otherwise, the task server has to be consulted |
encoded in the thread ID. Otherwise, the \texttt{task} server has |
477 |
(and, assuming that thread numbers are not shared by the different |
to be consulted (and, assuming that thread numbers are not shared by |
478 |
systems, the result can be cached). |
the different systems, the result can be cached). |
479 |
\end{comment} |
\end{comment} |
480 |
|
|
481 |
The server reads out the capability associated with the capability ID, |
The server reads out the capability associated with the capability ID, |
502 |
|
|
503 |
If the client and the server do not know about each other yet, then |
If the client and the server do not know about each other yet, then |
504 |
they can bootstrap a connection without support from any other task |
they can bootstrap a connection without support from any other task |
505 |
except the task server. The purpose of the initial handshake is to |
except the \texttt{task} server. The purpose of the initial handshake |
506 |
give both participants a chance to acquire a task info cap for the |
is to give both participants a chance to acquire a task info cap for |
507 |
other participants task ID, so they can be sure that from there on |
the other participants task ID, so they can be sure that from there on |
508 |
they will always talk to the same task as they talked to before. |
they will always talk to the same task as they talked to before. |
509 |
|
|
510 |
\paragraph{Preconditions} |
\paragraph{Preconditions} |
533 |
\begin{enumerate} |
\begin{enumerate} |
534 |
|
|
535 |
\item The client acquires a task info capability for the server's task |
\item The client acquires a task info capability for the server's task |
536 |
ID, either directly from the task server, or from another task in a |
ID, either directly from the \texttt{task} server, or from another |
537 |
capability copy. From that point on, the client can be sure to |
task in a capability copy. From that point on, the client can be |
538 |
always talk to the same task when talking to the server. |
sure to always talk to the same task when talking to the server. |
539 |
|
|
540 |
Of course, if the client already has a task info cap for the server |
Of course, if the client already has a task info cap for the server |
541 |
it does not need to do anything in this step. |
it does not need to do anything in this step. |
550 |
handshake. |
handshake. |
551 |
|
|
552 |
\item The server receives the message, and acquires a task info cap |
\item The server receives the message, and acquires a task info cap |
553 |
for the client task (directly from the task server). |
for the client task (directly from the \texttt{task} server). |
554 |
|
|
555 |
Of course, if the server already has a task info cap for the client |
Of course, if the server already has a task info cap for the client |
556 |
it does not need to do anything in this step. |
it does not need to do anything in this step. |
701 |
the capability that $C$ wants to give to $D$. $S$ does not trust |
the capability that $C$ wants to give to $D$. $S$ does not trust |
702 |
either $C$ or $D$. |
either $C$ or $D$. |
703 |
|
|
704 |
The task server is also involved, because it provides the task info |
The \texttt{task} server is also involved, because it provides the |
705 |
capabilities. Everyone trusts the task server they use. This does |
task info capabilities. Everyone trusts the \texttt{task} server they |
706 |
not need to be the same one for every participant. |
use. This does not need to be the same one for every participant. |
707 |
|
|
708 |
FIXME: Here should be the pseudo code for the protocol. For now, you |
FIXME: Here should be the pseudo code for the protocol. For now, you |
709 |
have to take it out of the long version. |
have to take it out of the long version. |
719 |
|
|
720 |
\begin{comment} |
\begin{comment} |
721 |
A task can provide a constraint when creating a task info cap in |
A task can provide a constraint when creating a task info cap in |
722 |
the task server. The constraint is a task ID. The task server |
the \texttt{task} server. The constraint is a task ID. The task |
723 |
will only create the task info cap and return it if the task with |
server will only create the task info cap and return it if the |
724 |
the constraint task ID is not destroyed. This allows for a task |
task with the constraint task ID is not destroyed. This allows |
725 |
requesting a task info capability to make sure that another task, |
for a task requesting a task info capability to make sure that |
726 |
which also holds this task info cap, is not destroyed. This is |
another task, which also holds this task info cap, is not |
727 |
important, because if a task is destroyed, all the task info caps |
destroyed. This is important, because if a task is destroyed, all |
728 |
it held are released. |
the task info caps it held are released. |
729 |
|
|
730 |
In this case, the server relies on the client to hold a task info |
In this case, the server relies on the client to hold a task info |
731 |
cap for $D$ until it established its own. See below for what can |
cap for $D$ until it established its own. See below for what can |
943 |
\end{comment} |
\end{comment} |
944 |
|
|
945 |
\paragraph{The server $S$ dies} |
\paragraph{The server $S$ dies} |
946 |
What happens if the server S dies unexpectedly sometime throughout the |
What happens if the server $S$ dies unexpectedly sometime throughout |
947 |
protocol? |
the protocol? |
948 |
|
|
949 |
\begin{comment} |
\begin{comment} |
950 |
At any time a task dies, the task info caps it held are released. |
At any time a task dies, the task info caps it held are released. |
1237 |
your own protocols, and improvements to the above protocol against. |
your own protocols, and improvements to the above protocol against. |
1238 |
|
|
1239 |
|
|
|
|
|
1240 |
\subsection{Synchronous IPC} |
\subsection{Synchronous IPC} |
1241 |
|
|
1242 |
The Hurd only needs synchronous IPC. Asynchronous IPC is usually not |
The Hurd only needs synchronous IPC. Asynchronous IPC is usually not |
1243 |
required. An exception are notifications (see below). |
required. An exception are notifications (see below). |
1244 |
|
|
1245 |
There are possibly some places in the Hurd source code where |
There are possibly some places in the Hurd source code where |
1246 |
asynchronous IPC is assumed. These must be replaced with different |
asynchronous IPC is assumed. These must be replaced with different |
1247 |
strategies. One example is the implementation of select() in the GNU |
strategies. One example is the implementation of select() in the GNU |
1265 |
|
|
1266 |
|
|
1267 |
\subsection{Notifications} |
\subsection{Notifications} |
1268 |
|
|
1269 |
Notifications to untrusted tasks happen frequently. One case is |
Notifications to untrusted tasks happen frequently. One case is |
1270 |
object death notifications, in particular task death notifications. |
object death notifications, in particular task death notifications. |
1271 |
Other cases might be select() or notifications of changes to the |
Other cases might be select() or notifications of changes to the |
1281 |
|
|
1282 |
From the servers point of view, notifications are simply messages with |
From the servers point of view, notifications are simply messages with |
1283 |
a send and xfer timeout of 0 and without a receive phase. |
a send and xfer timeout of 0 and without a receive phase. |
1284 |
|
|
1285 |
For the client, however, there is only one way to ensure that it will |
For the client, however, there is only one way to ensure that it will |
1286 |
receive the notification: It must have the receiving thread in the |
receive the notification: It must have the receiving thread in the |
1287 |
receive phase of an IPC. While this thread is processing the |
receive phase of an IPC. While this thread is processing the |
1288 |
notification (even if it is only delegating), it might be preempted |
notification (even if it is only delegating it), it might be preempted |
1289 |
and another (or the same) server might try to send a second |
and another (or the same) server might try to send a second |
1290 |
notification. |
notification. |
1291 |
|
|
1292 |
It is an open challenge how the client can ensure that it either |
\begin{comment} |
1293 |
receives the notification or at least knows that it missed it, while |
It is an open challenge how the client can ensure that it either |
1294 |
the server remains save from potential DoS attacks. The usual |
receives the notification or at least knows that it missed it, while |
1295 |
strategy, to give receivers of notifications a higher scheduling |
the server remains save from potential DoS attacks. The usual |
1296 |
priority than the sender, is not usable in a system with untrusted |
strategy, to give receivers of notifications a higher scheduling |
1297 |
receivers (like the Hurd). The best strategy determined so far is to |
priority than the sender, is not usable in a system with untrusted |
1298 |
have the servers retry to send the notification several times with |
receivers (like the Hurd). The best strategy determined so far is |
1299 |
small delays inbetween. This can increase the chance that a client is |
to have the servers retry to send the notification several times |
1300 |
able to receive the notification. However, there is still the |
with small delays inbetween. This can increase the chance that a |
1301 |
question what a server can do if the client is not ready. |
client is able to receive the notification. However, there is still |
1302 |
|
the question what a server can do if the client is not ready. |
1303 |
An alternative might be a global trusted notification server that runs |
|
1304 |
at a higher scheduling priority and records which servers have |
An alternative might be a global trusted notification server that |
1305 |
notifications for which clients, and that can be used by clients to be |
runs at a higher scheduling priority and records which servers have |
1306 |
notified of pending notifications. Then the clients can poll the |
notifications for which clients, and that can be used by clients to |
1307 |
notifications from the servers. |
be notified of pending notifications. Then the clients can poll the |
1308 |
|
notifications from the servers. |
1309 |
|
\end{comment} |
1310 |
|
|
1311 |
|
|
1312 |
\section{Threads and Tasks} |
\section{Threads and Tasks} |
1313 |
|
|
1314 |
|
The \texttt{task} server will provide the ability to create tasks and |
1315 |
|
threads, and to destroy them. |
1316 |
|
|
1317 |
|
\begin{comment} |
1318 |
|
In L4, only threads in the privileged address space (the rootserver) |
1319 |
|
are allowed to manipulate threads and address spaces (using the |
1320 |
|
\textsc{ThreadControl} and \textsc{SpaceControl} system calls). The |
1321 |
|
\texttt{task} server will use the system call wrappers provided by |
1322 |
|
the rootserver, see section \ref{rootserver} on page |
1323 |
|
\pageref{rootserver}. |
1324 |
|
\end{comment} |
1325 |
|
|
1326 |
|
The \texttt{task} server provides three different capability types. |
1327 |
|
|
1328 |
|
\paragraph{Task control capabilities} |
1329 |
|
If a new task is created, it is always associated with a task control |
1330 |
|
capability. The task control capability can be used to create and |
1331 |
|
destroy threads in the task, and destroy the task itself. So the task |
1332 |
|
control capability gives the owner of a task control over it. Task |
1333 |
|
control capabilities have the side effect that the task ID of this |
1334 |
|
task is not reused, as long as the task control capability is not |
1335 |
|
released. Thus, having a task control capability affects the global |
1336 |
|
namespace of task IDs. If a task is destroyed, task death |
1337 |
|
notifications are sent to holders of task control capabilities for |
1338 |
|
that task. |
1339 |
|
|
1340 |
|
\begin{comment} |
1341 |
|
A task is also implicitely destroyed when the last task control |
1342 |
|
capability reference is released. |
1343 |
|
\end{comment} |
1344 |
|
|
1345 |
|
\paragraph{Task info capabilities} |
1346 |
|
\label{taskinfocap} |
1347 |
|
Any task can create task info capabilities for other tasks. Such task |
1348 |
|
info capabilities are used mainly in the IPC system (see section |
1349 |
|
\ref{ipc} on page \pageref{ipc}). Task info capabilities have the |
1350 |
|
side effect that the task ID of this task is not reused, as long as |
1351 |
|
the task info capability is not released. Thus, having a task info |
1352 |
|
capability affects the global namespace of task IDs. If a task is |
1353 |
|
destroyed, task death notifications are sent to holders of task info |
1354 |
|
capabilities for that task. |
1355 |
|
|
1356 |
|
\begin{comment} |
1357 |
|
Because of that, holding task info capabilities must be restricted |
1358 |
|
somehow. Several strategies can be taken: |
1359 |
|
|
1360 |
|
\begin{itemize} |
1361 |
|
\item Task death notifications can be monitored. If there is no |
1362 |
|
acknowdgement within a certain time period, the \texttt{task} |
1363 |
|
server could be allowed to reuse the task ID anyway. This is not |
1364 |
|
a good strategy because it can considerably weaken the security of |
1365 |
|
the system (capabilities might be leaked to tasks which reuse such |
1366 |
|
a task ID reclaimed by force). |
1367 |
|
\item The proc server can show dead task IDs which are not released |
1368 |
|
yet, in analogy to the zombie processes in Unix. It can also make |
1369 |
|
available the list of tasks which prevent reusing the task ID, to |
1370 |
|
allow users or the system administrator to clean up manually. |
1371 |
|
\item Quotas can be used to punish users which do not acknowledge |
1372 |
|
task death timely. For example, if the number of tasks the user |
1373 |
|
is allowed to create is restricted, the task info caps that the |
1374 |
|
user holds for dead tasks could be counted toward that limit. |
1375 |
|
\item Any task could be restricted to as many task ID references as |
1376 |
|
there are live tasks in the system, plus some slack. That would |
1377 |
|
prevent the task from creating new task info caps if it does not |
1378 |
|
release old ones from death tasks. The slack would be provided to |
1379 |
|
not unnecessarily slow down a task that processes task death |
1380 |
|
notifications asynchronously to making connections with new tasks. |
1381 |
|
\end{itemize} |
1382 |
|
|
1383 |
The Hurd will encode the task ID in the version part of the L4 thread |
In particular the last two approaches should proof to be effective |
1384 |
ID. The version part can only be changed by the privileged system |
in providing an incentive for tasks to release task info caps they |
1385 |
code, so it is protected by the kernel. This allows recipients of a |
do not need anymore. |
1386 |
message to quickly determine the task from the sender's thread ID. |
\end{comment} |
1387 |
|
|
1388 |
Task IDs will not be reused as long as there are still tasks that |
|
1389 |
might actively communicate with the (now destroyed) task. Task info |
|
1390 |
capabilities provided by the task server can be used for that. The |
\paragraph{Task manager capability} |
1391 |
task info capability will also receive the task death notification (as |
A task is a relatively simple object, compared to a full blown POSIX |
1392 |
a normap capability death notification). The task server will reuse a |
process, for example. As the \texttt{task} server is enforced system |
1393 |
task ID only when all task info capabilities for the task with that ID |
code, the Hurd does not impose POSIX process semantics in the task |
1394 |
have been released. |
server. Instead, POSIX process semantics are implemented in a |
1395 |
|
different server, the proc server (see also section \ref{proc} on page |
1396 |
This of course can open a DoS attack. Programs can attempt to acquire |
\pageref{proc}). To allow the \texttt{proc} server to do its work, it |
1397 |
task info capabilities and never release them. Several strategies can |
needs to be able to get the task control capability for any task, and |
1398 |
be applied to compensate that: The task server can automatically time |
gather other statistics about them. Furthermore, there must be the |
1399 |
out task info capability references to dead tasks. The proc server |
possibility to install quota mechanisms and other monitoring systems. |
1400 |
can show dead task IDs with task info capability references as some |
The \texttt{task} server provides a task manager capability, that |
1401 |
variant of zombie tasks, and provide a way to list all tasks |
allows the holder of that capability to control the behaviour of the |
1402 |
preventing the task ID from being reused, allowing the system |
\texttt{task} server and get access to the information and objects it |
1403 |
administrator to identify malicious or faulty users. Task ID |
provides. |
1404 |
references can be taken into account in quota restrictions, to |
|
1405 |
encourage a user to release them when they are not needed anymore (in |
\begin{comment} |
1406 |
particular, a user holding a task ID reference to a dead task could be |
For example, the task manager capability could be used to install a |
1407 |
punished with the same costs as for an additional normal task owned by |
policy capability that is used by the \texttt{task} server to make |
1408 |
the user). Another idea is to not allow any task to allocate more |
upcalls to a policy server whenever a new task or thread is created. |
1409 |
task info capabilities than there are live tasks in the system, plus |
The policy server could then indicate if the creation of the task or |
1410 |
some slack. This provides a high incentive for tasks to release their |
thread is allowed by that user. For this to work, the \texttt{task} |
1411 |
info caps (and if they get an error, they could block until their |
server itself does not need to know about the concept of a user, or |
1412 |
notification system has processed the task death notification and |
the policies that the policy server implements. |
1413 |
released the reference, and try again). |
|
1414 |
|
Now that I am writing this, I realize that without any further |
1415 |
Access to task info capabilities can be open to everyone. The above |
support by the \texttt{task} server, the policy server would be |
1416 |
strategies to prevent tasks from allocating too many of them for too |
restricted to the task and thread ID of the caller (or rather the |
1417 |
long work even if access to task info capabilities is given out |
task control capability used) to make its decision. A more |
1418 |
without any preconditions, and there is no real incentive other than |
capability oriented approach would then not be possible. This |
1419 |
those above for a task to not pass on a task info capability to any |
requires more thought. |
1420 |
interested task anyway. Allowing every task to create task info |
|
1421 |
capabilities for other tasks simplifies the protocols involved and |
The whole task manager interface is not written yet. |
1422 |
allows for some optimizations. |
\end{comment} |
1423 |
|
|
1424 |
|
When creating a new task, the \texttt{task} server allocates a new |
1425 |
|
task ID for it. The task ID will be used as the version field of the |
1426 |
|
thread ID of all threads created in the task. This allows the |
1427 |
|
recipient of a message to verify the sender's task ID efficiently and |
1428 |
|
easily. |
1429 |
|
|
1430 |
|
\begin{comment} |
1431 |
|
The version field is 14 bit on 32-bit architectures, and 32 bit on |
1432 |
|
64 bit architectures. Because the lower six bits must not be all |
1433 |
|
zero (to make global thread IDs different from local thread IDs), |
1434 |
|
the number of available task IDs is $2^{14} - 2^6$ resp. $2^{32} - |
1435 |
|
2^6$. |
1436 |
|
|
1437 |
|
If several systems are running in parallel on the same host, they |
1438 |
|
might share thread IDs by encoding the system ID in the upper bits |
1439 |
|
of the thread number. |
1440 |
|
\end{comment} |
1441 |
|
|
1442 |
|
Task IDs will be reused only if there are no task control or info |
1443 |
|
capabilities for that task ID held by any task in the system. |
1444 |
|
|
1445 |
|
\begin{comment} |
1446 |
|
If the \texttt{task} server never ignores this rule, even if a task |
1447 |
|
does not release task control or info capabilities voluntarily, then |
1448 |
|
there is no need for the \texttt{task} server to not keep task IDs |
1449 |
|
small and reuse them as early as possible. |
1450 |
|
\end{comment} |
1451 |
|
|
1452 |
|
When creating a new task, the \texttt{task} server also has to create |
1453 |
|
the initial thread. This thread will be inactive. Once the creation |
1454 |
|
and activation of the initial thread has been requested by the user, |
1455 |
|
it will be activated. When the user requests to destroy the last |
1456 |
|
thread in a task, the \texttt{task} server makes that thread inactive |
1457 |
|
again. |
1458 |
|
|
1459 |
|
\begin{comment} |
1460 |
|
In L4, an address space can only be implicitely created (resp. |
1461 |
|
destroyed) with the first (resp. last) thread in that address space. |
1462 |
|
\end{comment} |
1463 |
|
|
1464 |
|
Some operations, like starting and stopping threads in a task, can not |
1465 |
|
be supported by the task server, but have to be implemented locally in |
1466 |
|
each task because of the minimality of L4. If external control over |
1467 |
|
the threads in a task at this level is required, the debugger |
1468 |
|
interface might be used (see section \ref{debug} on page |
1469 |
|
\pageref{debug}). |
1470 |
|
|
1471 |
|
|
1472 |
|
\subsection{Accounting} |
1473 |
|
|
1474 |
|
We want to allow the users of the system to use the \texttt{task} |
1475 |
|
server directly, and ignore other task management facilities like the |
1476 |
|
\texttt{proc} server. However, the system administrator still needs |
1477 |
|
to be able to identify the user who created such anonymous tasks. |
1478 |
|
|
1479 |
|
For this, a simple accounting mechanism is provided by the task |
1480 |
|
server. An identifier can be set for a task by the task manager |
1481 |
|
capability, which is inherited at task creation time from the parent |
1482 |
|
task. This accounting ID can not be changed without the task manager |
1483 |
|
capability. |
1484 |
|
|
1485 |
|
The \texttt{proc} server sets the accounting ID to the process ID |
1486 |
|
(PID) of the task whenever a task registers itself with the |
1487 |
|
\texttt{proc} server. This means that all tasks which do not register |
1488 |
|
themself with the \texttt{proc} server will be grouped together with |
1489 |
|
the first parent task that did. This allows to easily kill all |
1490 |
|
unregistered tasks together with its registered parent. |
1491 |
|
|
1492 |
|
The \texttt{task} server does not interpret or use the accounting ID |
1493 |
|
in any way. |
1494 |
|
|
1495 |
|
|
1496 |
\subsection{Proxy Task Server} |
\subsection{Proxy Task Server} |
1497 |
\label{proxytaskserver} |
\label{proxytaskserver} |
1498 |
|
|
1499 |
The task server can be safely proxied, and the users of such a proxy |
The \texttt{task} server can be safely proxied, and the users of such |
1500 |
task server can use it like the real task server, even though |
a proxy task server can use it like the real \texttt{task} server, |
1501 |
capabilities work a bit different for the task server than for other |
even though capabilities work a bit differently for the \texttt{task} |
1502 |
servers. |
server than for other servers. |
1503 |
|
|
1504 |
The problem exists because the proxy task server would hold the real |
The problem exists because the proxy task server would hold the real |
1505 |
task info capabilities for the task info capabilities that it provides |
task info capabilities for the task info capabilities that it provides |
1513 |
tasks that use it. When the proxy task server dies, all tasks that |
tasks that use it. When the proxy task server dies, all tasks that |
1514 |
were created with it will be destroyed when these tak control |
were created with it will be destroyed when these tak control |
1515 |
capabilities are released. The proxy task server is a vital system |
capabilities are released. The proxy task server is a vital system |
1516 |
component for the tasks that use it, just as the real task server is a |
component for the tasks that use it, just as the real \texttt{task} |
1517 |
vital system component for the whole system. |
server is a vital system component for the whole system. |
1518 |
|
|
1519 |
|
|
1520 |
|
\subsection{Scheduling} |
1521 |
|
|
1522 |
|
The task server is the natural place to implement a simple, initial |
1523 |
|
scheduler for the Hurd. A first version can at least collect some |
1524 |
|
information about the cpu time of a task and its threads. Later a |
1525 |
|
proper scheduler has to be written that also has SMP support. |
1526 |
|
|
1527 |
|
The scheduler should run at a higher priority than normal threads. |
1528 |
|
|
1529 |
|
\begin{comment} |
1530 |
|
This might require that the whole task server must run at a higher |
1531 |
|
priority, which makes sense anyway. |
1532 |
|
|
1533 |
|
Not much thought has been given to the scheduler so far. This is |
1534 |
|
work that still needs to be done. |
1535 |
|
\end{comment} |
1536 |
|
|
1537 |
|
There is no way to get at the ``system time'' in L4, it is assumed |
1538 |
|
that no time is spent in the kernel (which is mostly true). So system |
1539 |
|
time will always be reported as $0.00$, or $0.01$. |
1540 |
|
|
1541 |
|
|
1542 |
\section{Virtual Memory Management} |
\section{Virtual Memory Management} |
1565 |
between device drivers and (untrusted) user tasks. |
between device drivers and (untrusted) user tasks. |
1566 |
|
|
1567 |
|
|
1568 |
\section{Task Management} |
\section{Authentication} |
1569 |
|
\label{auth} |
1570 |
|
|
1571 |
A task server will provide the ability to create and destroy tasks and |
The auth server gives out auth objects that contain zero or more of |
1572 |
threads, nd get some basic information about them. The task server |
effective user IDs, available user IDs, effective group IDs and |
1573 |
might also server as the initial scheduler for simple usage statistics |
available group IDs. New objects can be created from existing |
1574 |
(cpu time of a process), which is not otherwise provided by L4. Of |
objects, but only as subsets from the union of the IDs a user |
1575 |
course, other information like creation time of a process will also be |
possesses. If an auth object has an effective or available user ID 0, |
1576 |
provided. |
then arbitrary new auth objects can be created from that. |
|
|
|
|
A proc server (which is logically different but might be implemented |
|
|
in the same process as the task server) will provide POSIX process |
|
|
semantics for tasks. Registration with the proc server is optional. |
|
|
|
|
|
An accounting ID that can be set by the proc server and is inherited |
|
|
at task creation allows to kill a group of (from proc's point of view) |
|
|
unregistered tasks at once. This is also useful to prevent left-over |
|
|
of child processes that are incapable of running with exec() (see |
|
|
below). The accounting ID will usually be set to the PID of a process |
|
|
as soon as it registers itself with proc. |
|
|
|
|
|
If the last reference to a task control capability is released, the |
|
|
task should be destroyed and the task server should release all task |
|
|
control and info capabilities it held. This should happen |
|
|
recursively, of course. However, it is important that the task |
|
|
control capabilities are released before the info capabilities (so |
|
|
that tasks for which this tasked had the only control capability, |
|
|
which relied on this task to hold info capabilities for them, are |
|
|
killed and not attackable by an imposter). This is important for |
|
|
tasks creating new tasks (which have to talk to other tasks, for |
|
|
example their parent, before they get their own control capability), |
|
|
or for proxy task servers (which hold the task control and info |
|
|
capabilities for all tasks they proxy). |
|
|
|
|
|
Other operations, like starting and stopping threads in a task, can |
|
|
not be supported by the task server, but have to be implemented in |
|
|
locally in each task because of the minimality of L4. |
|
1577 |
|
|
1578 |
|
A passport can be created from an auth object that can be used by |
1579 |
|
everyone who possesses a handle to the passport object to verify the |
1580 |
|
IDs of the auth object that the passport was created from, and if the |
1581 |
|
auth object is owned by any particular task (normally the user |
1582 |
|
requesting the. |
1583 |
|
|
1584 |
|
The auth server should always create new passport objects for |
1585 |
|
different tasks, even if the underlying auth object is the same, so |
1586 |
|
that a task having the passport capability can not spy on other tasks |
1587 |
|
unless they were given the passport object by that task. |
1588 |
|
|
1589 |
|
|
1590 |
|
\section{Process Management} |
1591 |
|
\label{proc} |
1592 |
|
|
1593 |
|
The \texttt{proc} server. |
1594 |
|
|
1595 |
|
|
1596 |
|
\section{Miscs} |
1597 |
|
|
1598 |
\subsection{Exec} |
\subsection{Exec} |
1599 |
|
|
1679 |
idea. The details will depend a lot on the actual implementation. |
idea. The details will depend a lot on the actual implementation. |
1680 |
|
|
1681 |
|
|
|
\section{Authentication} |
|
|
\label{auth} |
|
|
|
|
|
The auth server gives out auth objects that contain zero or more of |
|
|
effective user IDs, available user IDs, effective group IDs and |
|
|
available group IDs. New objects can be created from existing |
|
|
objects, but only as subsets from the union of the IDs a user |
|
|
possesses. If an auth object has an effective or available user ID 0, |
|
|
then arbitrary new auth objects can be created from that. |
|
|
|
|
|
A passport can be created from an auth object that can be used by |
|
|
everyone who possesses a handle to the passport object to verify the |
|
|
IDs of the auth object that the passport was created from, and if the |
|
|
auth object is owned by any particular task (normally the user |
|
|
requesting the. |
|
|
|
|
|
The auth server should always create new passport objects for |
|
|
different tasks, even if the underlying auth object is the same, so |
|
|
that a task having the passport capability can not spy on other tasks |
|
|
unless they were given the passport object by that task. |
|
|
|
|
|
|
|
1682 |
\section{Unix Domain Sockets and Pipes} |
\section{Unix Domain Sockets and Pipes} |
1683 |
|
|
1684 |
In the Hurd on Mach, there was a global pflocal server that provided |
In the Hurd on Mach, there was a global pflocal server that provided |
1771 |
it could be redirected to another (that means: for all filesystems |
it could be redirected to another (that means: for all filesystems |
1772 |
for which it does not use \verb/O_NOTRANS/). This is quite an |
for which it does not use \verb/O_NOTRANS/). This is quite an |
1773 |
overhead to the common case. |
overhead to the common case. |
1774 |
|
|
1775 |
|
\begin{verbatim} |
1776 |
|
<marcus> I have another idea |
1777 |
|
<marcus> the client does not give a container |
1778 |
|
<marcus> server sees child fs, no container -> returns O_NOTRANS node |
1779 |
|
<marcus> then client sees error, uses O_NOTRANS node, "" and container |
1780 |
|
<marcus> problem solved |
1781 |
|
<marcus> this seems to be the optimum |
1782 |
|
<neal> hmm. |
1783 |
|
<neal> So lazily supply a container. |
1784 |
|
<marcus> yeah |
1785 |
|
<neal> Hoping you won't need one. |
1786 |
|
<marcus> and the server helps you by doing as much as it can usefully |
1787 |
|
<neal> And that is the normal case. |
1788 |
|
<neal> Yeah, that seems reasonable. |
1789 |
|
<marcus> the trick is that the server won't fail completely |
1790 |
|
<marcus> it will give you at least the underlying node |
1791 |
|
\end{verbatim} |
1792 |
\end{comment} |
\end{comment} |
1793 |
|
|
1794 |
The actual creation of the child filesystem can be performed much like |
The actual creation of the child filesystem can be performed much like |
1807 |
|
|
1808 |
|
|
1809 |
\section{Debugging} |
\section{Debugging} |
1810 |
|
\label{debug} |
1811 |
|
|
1812 |
L4 does not support debugging. So every task has to implement a debug |
L4 does not support debugging. So every task has to implement a debug |
1813 |
interface and implement debugging locally. gdb needs to be changed to |
interface and implement debugging locally. gdb needs to be changed to |
1816 |
the debug interface should look like, are all open questions. |
the debug interface should look like, are all open questions. |
1817 |
|
|
1818 |
|
|
|
\section{Scheduling} |
|
|
|
|
|
The task server might implement an initial scheduler that just keeps |
|
|
track of consumed CPU time, so we have some statistics. Later, a |
|
|
scheduler has to be written, that also can do SMP. All of this is |
|
|
still in the open. |
|
|
|
|
|
There is no way to get at the ``system time'' in L4, it is assumed |
|
|
that no time is spent in the kernel (which is mostly true). So system |
|
|
time will always be reported as 0.00, or 0.01. |
|
|
|
|
1819 |
\section{Device Drivers} |
\section{Device Drivers} |
1820 |
|
|
1821 |
This section written by Peter De Schrijver and Daniel Wagner. |
This section written by Peter De Schrijver and Daniel Wagner. |