summaryrefslogtreecommitdiff
path: root/hurd/subhurd.mdwn
blob: f2117ead452c2b8dff669fc1f6b51cb9ce463c35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
[[!meta copyright="Copyright © 2007, 2008, 2010, 2011 Free Software Foundation,
Inc."]]

[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable
id="license" text="Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
is included in the section entitled [[GNU Free Documentation
License|/fdl]]."]]"""]]

A sub-Hurd is like a [[neighbor_Hurd|neighborhurd]], however, makes use of some
resources provided by another Hurd.  For instance, backing store and the
console.

Sub-hurds are extremely useful for debugging core servers as it is possible to
attach to them with gdb from the parent
([[debugging_via_subhurds|debugging/subhurd]]).  This avoids deadlock, e.g.,
when the instance of gdb stops the server but requires its use.  (Note: it is
possible to use [[debugging/gdb/noninvasive_debugging]], but this is less
flexible.)  Vice versa, it is also possible to use a subhurd to debug the
*main* Hurd system, for example, the latter's root file system.

[[!toc levels=2]]


# Howto

## Preparing

To run a subhurd, you need an additional partition with an installed Hurd
system.  In principle, you can also use your main partition in read-only mode;
but this obviously will create severe limitations.  Usually, you will want a
complete independent system.

The system for the subhurd is a normal Hurd installation, which could just as
well run standalone.  You can use any of the various possible installation
methods, or reuse an existing installation if you already have several.  If
using [[Debian_GNU/Hurd|running/debian]], the easiest is probably to use
[[running/debian/crosshurd]], which you can run directly from your main Hurd to
set up another Hurd on a different partition, without ever rebooting.  (You can
run the `native-install` step from a chroot or already in a subhurd.)


## Booting

To boot the subhurd, you need a boot script.  For historical reasons, usually
`/boot/servers.boot` is used. (Originally, this was also used to boot the main
Hurd, using "serverboot".  Nowadays, this isn't used for the main boot anymore,
as GRUB can directly load all the necessary modules.)

However, the canonical `/boot/servers.boot` file is no longer distributed with
[[Debian_GNU/Hurd|running/debian]].  Here is a slightly adopted version:

       # Boot script file for booting GNU Hurd.  Each line specifies a file to be
       # loaded by the boot loader (the first word), and actions to be done with it.

       # First, the bootstrap filesystem.  It needs several ports as arguments,
       # as well as the user flags from the boot loader.
       /hurd/ext2fs.static --bootflags=${boot-args} --host-priv-port=${host-port} --device-master-port=${device-port} --exec-server-task=${exec-task} -Tdevice ${root-device} $(task-create) $(task-resume)

       # Now the exec server; to load the dynamically-linked exec server program,
       # we have the boot loader in fact load and run ld.so, which in turn
       # loads and runs /hurd/exec.  This task is created, and its task port saved
       # in ${exec-task} to be passed to the fs above, but it is left suspended;
       # the fs will resume the exec task once it is ready.
       /lib/ld.so.1 /hurd/exec $(exec-task=task-create)

       ## default pager
       #/dev/sd0b $(add-paging-file)

/!\ It's very important not to introduce spurious line breaks, so be very
careful when copying!  All the options following `ext2fs.static` have to be on
a single line.

Now actually booting the subhurd is a simple matter of issuing (as root):

       boot servers.boot /dev/hd0s6

(Replace `hd0s6` by the name of your partition for the subhurd.)

/!\ The partition must be unmounted (or mounted read-only) before you boot from
it!

(In theory it shouldn't be neccessary to run the subhurd as user `root`, but in
practice [that doesn't work at the
moment](http://savannah.gnu.org/bugs/?17341).)

Now the subhurd should boot just like a normal Hurd started directly from GRUB,
finally presenting a login prompt.  The `boot` program serves as proxy for the
subhurd, so you can control it from the terminal where you issued the boot
command.

To exit the subhurd, issue `halt` or `reboot`.  This should exit it cleanly,
but for some reason it doesn't always work; sometimes it will output various
errors and then hang.  If that happens, you need to kill the subhurd processes
manually from a different terminal.


## Using

In the subhurd, you can do basically all the same things as in the main Hurd.

You can even set up networking: Just invoke `settrans` on the
`/servers/socket/2` as usual inside the subhurd, only using a different local
IP than in the main Hurd.  This way, the subhurd will be able to communicate to
the outside world with its own IP -- allowing for example to do `apt-get`
inside the subhurd, or to `ssh` directly into the subhurd.

If you want to access the subhurd processes from the outside, e.g. for
[[debugging_purposes|debugging/subhurd]] (or to get rid of a subhurd that
didn't exit cleanly...), you need to find out how main Hurd [[PID]]s correspond to
subhurd processes: the subhurd processes appear in the main Hurd (e.g. if doing
`ps -e`) as unknown processes, and vice versa, but the [[PID]]s are different!  To
find out which process is which, you can simply compare the order -- while the
numbers are different, the order should usually match.  Often it also helps to
look at the number of threads (e.g. using `ps -l`), as many servers have very
characteristic thread counts.


# Further Info

Read about using a subhurd for [[debugging_purposes|debugging/subhurd]].

Roland's tutorial about [[running_a_subhurd]].


# Use Cases

<a name="debugging_main_hurd_system"></a>
## Debugging the *Main* Hurd System

A subhurd can be used for debugging the *main* Hurd system.  This works as long
as the subhurd doesn't use any services provided by the main Hurd.  For
example, if you already have a subhurd running at the time it happens, you can
use that one to debug a deadlocked [[translator/ext2fs]] root file system in
the *main* Hurd.

For this, you need to get a handle to the main Hurd's [[ext2fs
translator|translator/ext2fs]]'s [[PID]], but this is no problem, as currently
[[PID]]s are visible across subhurd boundaries.  (It is a [[!taglink
open_issue_hurd]] whether this is the right thing to do in
[[open_issues/virtualization]] contexts, but that's how it currently is.)


<a name="unit_testing"></a>
## Unit Testing

freenode, #hurd channel, 2011-03-06:

From [[open_issues/unit_testing]].

    <youpi> it could be interesting to have scripts that automatically start a
      sub-hurd to do the tests
    <youpi> though that'd catch sub-hurd issues :)
    <foocraft> so a sub-hurd is a hurd that I can run on something that I know
      works(like linux)?
    <foocraft> Virtual machine I would think
    <foocraft> and over a network connection it would submit results back to
      the host :p
    * foocraft brain damage
    <youpi> sub-hurd is a bit like chroot
    <youpi> except that it's more complete
    <foocraft> oh okay
    <youpi> i.e. almost everything gets replaced with what you want, except the
      micro-kernel
    <youpi> that way you can even test the exec server for instance, without
      risks of damaging the host OS
    <foocraft> and we know the micro-kernel works correctly, right youpi?
    <youpi> well, at least it's small enough that most bugs are not there
    <foocraft> 1) all tests run in subhurd 2) output results in a place in the
      subhurd 3) tester in the host checks the result and pretty-prints it 4)
      rinse & repeat
    <youpi> the output can actually be redirected iirc
    <youpi> since you give the sub-hurd a "console"
    <foocraft> youpi, yup yeah, so now it's more like chroot if that's the case
    <youpi> it really looks like chroot, yes
    <foocraft> but again, there's this subset of tests that we need to have
      that ensures that even the tester running on the subhurd is valid, and it
      didn't break because of a bug in the subhurd
    <tschwinge> As long as you do in-system testing, you'll always (have to)
      rely on some functionality provided by the host system.
    <foocraft> the worst thing that could happen with unit testing is false
      results that lead someone to try to fix something that isn't broken :p
    <tschwinge> Yes.
    <youpi> usually one tries to repeat the test by hand in a normal
      environment