Skip to content

Commit 7ce8eba

Browse files
committed
Merge pull request #139 from alexcrichton/freebsd
FreeBSD and OpenBSD CI
2 parents 2575794 + bb6f198 commit 7ce8eba

File tree

19 files changed

+546
-103
lines changed

19 files changed

+546
-103
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ matrix:
4848
- os: linux
4949
env: TARGET=x86_64-rumprun-netbsd DOCKER=alexcrichton/rust-libc-rumprun:2015-11-27
5050
rust: nightly-2015-09-27
51+
- os: linux
52+
env: TARGET=x86_64-unknown-freebsd QEMU=freebsd.qcow2
53+
rust: nightly
54+
- os: linux
55+
env: TARGET=x86_64-unknown-openbsd QEMU=openbsd.qcow2
56+
rust: nightly
5157
notifications:
5258
email:
5359
on_success: never

ci/README.md

Lines changed: 147 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ this project.
88

99
First up, let's talk about the files in this directory:
1010

11-
* `msys2.ps1` - a PowerShell script which is used to install MSYS2 on the
12-
AppVeyor bots. As of this writing MSYS2 isn't installed by default, and this
13-
script will install the right version/arch of msys2 in preparation of using
14-
the contained C compiler to compile C shims.
15-
1611
* `run-travis.sh` - a shell script run by all Travis builders, this is
1712
responsible for setting up the rest of the environment such as installing new
1813
packages, downloading Rust target libraries, etc.
@@ -30,6 +25,11 @@ First up, let's talk about the files in this directory:
3025
* `landing-page-*.html` - used by `dox.sh` to generate a landing page for all
3126
architectures' documentation.
3227

28+
* `run-qemu.sh` - see discussion about QEMU below
29+
30+
* `mips`, `rumprun` - instructions to build the docker image for each respective
31+
CI target
32+
3333
# CI Systems
3434

3535
Currently this repository leverages a combination of Travis CI and AppVeyor for
@@ -38,11 +38,14 @@ running tests. The triples tested are:
3838
* AppVeyor
3939
* `{i686,x86_64}-pc-windows-{msvc,gnu}`
4040
* Travis
41-
* `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
42-
* `x86_64-unknown-linux-musl`
43-
* `arm-unknown-linux-gnueabihf`
44-
* `arm-linux-androideabi`
45-
* `{i686,x86_64}-apple-{darwin,ios}`
41+
* `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
42+
* `x86_64-unknown-linux-musl`
43+
* `arm-unknown-linux-gnueabihf`
44+
* `arm-linux-androideabi`
45+
* `{i686,x86_64}-apple-{darwin,ios}`
46+
* `x86_64-rumprun-netbsd`
47+
* `x86_64-unknown-freebsd`
48+
* `x86_64-unknown-openbsd`
4649

4750
The Windows triples are all pretty standard, they just set up their environment
4851
then run tests, no need for downloading any extra target libs (we just download
@@ -54,15 +57,147 @@ The remaining architectures look like:
5457

5558
* Android runs in a [docker image][android-docker] with an emulator, the NDK,
5659
and the SDK already set up. The entire build happens within the docker image.
57-
* The MIPS, ARM, and AArch64 builds all use QEMU to run the generated binary to
58-
actually verify the tests pass.
60+
* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run
61+
the generated binary to actually verify the tests pass.
5962
* The MUSL build just has to download a MUSL compiler and target libraries and
6063
then otherwise runs tests normally.
6164
* iOS builds need an extra linker flag currently, but beyond that they're built
6265
as standard as everything else.
66+
* The rumprun target builds an entire kernel from the test suite and then runs
67+
it inside QEMU using the serial console to test whether it succeeded or
68+
failed.
69+
* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system
70+
and compile/run tests. More information on that below.
6371

6472
[android-docker]: https://github.com/rust-lang/rust-buildbot/blob/master/slaves/android/Dockerfile
6573

74+
## QEMU
75+
76+
Lots of the architectures tested here use QEMU in the tests, so it's worth going
77+
over all the crazy capabilities QEMU has and the various flavors in which we use
78+
it!
79+
80+
First up, QEMU has userspace emulation where it doesn't boot a full kernel, it
81+
just runs a binary from another architecture (using the `qemu-<arch>` wrappers).
82+
We provide it the runtime path for the dynamically loaded system libraries,
83+
however. This strategy is used for all Linux architectures that aren't intel.
84+
Note that one downside of this QEMU system is that threads are barely
85+
implemented, so we're careful to not spawn many threads.
86+
87+
For the rumprun target the only output is a kernel image, so we just use that
88+
plus the `rumpbake` command to create a full kernel image which is then run from
89+
within QEMU.
90+
91+
Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI
92+
working for these platforms, but the gist of it looks like:
93+
94+
* Cross compiling from Linux to any of the BSDs seems to be quite non-standard.
95+
We may be able to get it working but it might be difficult at that point to
96+
ensure that the libc definitions align with what you'd get on the BSD itself.
97+
As a result, we try to do compiles within the BSD distro.
98+
* On Travis we can't run a VM-in-a-VM, so we resort to userspace emulation
99+
(QEMU).
100+
* Unfortunately on Travis we also can't use KVM, so the emulation is super slow.
101+
102+
With all that in mind, the way BSD is tested looks like:
103+
104+
1. Download a pre-prepared image for the OS being tested.
105+
2. Generate the tests for the OS being tested. This involves running the `ctest`
106+
library over libc to generate a Rust file and a C file which will then be
107+
compiled into the final test.
108+
3. Generate a disk image which will later be mounted by the OS being tested.
109+
This image is mostly just the libc directory, but some modifications are made
110+
to compile the generated files from step 2.
111+
4. The kernel is booted in QEMU, and it is configured to detect the libc-test
112+
image being available, run the test script, and then shut down afterwards.
113+
5. Look for whether the tests passed in the serial console output of the kernel.
114+
115+
There's some pretty specific instructions for setting up each image (detailed
116+
below), but the main gist of this is that we must avoid a vanilla `cargo run`
117+
inside of the `libc-test` directory (which is what it's intended for) because
118+
that would compile `syntex_syntax`, a large library, with userspace emulation.
119+
This invariably times out on Travis, so we can't do that.
120+
121+
Once all those hoops are jumped through, however, we can be happy that we're
122+
testing almost everything!
123+
124+
Below are some details of how to set up the initial OS images which are
125+
downloaded. Each image must be enabled have input/output over the serial
126+
console, log in automatically at the serial console, detect if a second drive in
127+
QEMU is available, and if so mount it, run a script (it'll specifically be
128+
`run-qemu.sh` in this folder which is copied into the generated image talked
129+
about above), and then shut down.
130+
131+
### QEMU setup - FreeBSD
132+
133+
1. Download CD installer (most minimal is fine)
134+
2. `qemu-img create -f qcow2 foo.qcow2 2G`
135+
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
136+
4. run installer
137+
5. `echo 'console="comconsole"' >> /boot/loader.conf`
138+
6. `echo 'autoboot_delay="0"' >> /boot/loader.conf`
139+
7. look at /etc/ttys, see what getty argument is for ttyu0
140+
8. edit /etc/gettytab, look for ttyu0 argument, prepend `:al=root` to line
141+
beneath
142+
143+
(note that the current image has a `freebsd` user, but this isn't really
144+
necessary)
145+
146+
Once that's done, arrange for this script to run at login:
147+
148+
```
149+
#!/bin/sh
150+
151+
sudo kldload ext2fs
152+
[ -e /dev/vtbd1 ] || exit 0
153+
sudo mount -t ext2fs /dev/vtbd1 /mnt
154+
sh /mnt/run.sh /mnt
155+
sudo poweroff
156+
```
157+
158+
Helpful links
159+
160+
* https://en.wikibooks.org/wiki/QEMU/Images
161+
* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html
162+
* https://www.freebsd.org/doc/handbook/serialconsole-setup.html
163+
164+
165+
### QEMU setup - OpenBSD
166+
167+
1. Download CD installer
168+
2. `qemu-img create -f qcow2 foo.qcow2 2G`
169+
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
170+
4. run installer
171+
5. `echo 'set tty com0' >> /etc/boot.conf`
172+
6. `echo 'boot' >> /etc/boot.conf`
173+
7. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to
174+
'vt220 on secure'
175+
8. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell
176+
9. Add this script to `/root/foo.sh`
177+
178+
```
179+
#!/bin/sh
180+
exec 1>/dev/tty00
181+
exec 2>&1
182+
183+
if mount -t ext2fs /dev/sd1c /mnt; then
184+
sh /mnt/run.sh /mnt
185+
shutdown -ph now
186+
fi
187+
188+
# limited shell...
189+
exec /bin/sh < /dev/tty00
190+
```
191+
192+
10. `chmod +x /root/foo.sh`
193+
194+
Helpful links:
195+
196+
* https://en.wikibooks.org/wiki/QEMU/Images
197+
* http://www.openbsd.org/faq/faq7.html#SerCon
198+
199+
# Questions?
200+
66201
Hopefully that's at least somewhat of an introduction to everything going on
67202
here, and feel free to ping @alexcrichton with questions!
68203

ci/Vagrantfile

Lines changed: 0 additions & 38 deletions
This file was deleted.

ci/run-qemu.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Initial script which is run inside of all qemu images. The first argument to
2+
# this script (as arranged by the qemu image itself) is the path to where the
3+
# libc crate is mounted.
4+
#
5+
# For qemu images we currently need to install Rust manually as this wasn't done
6+
# by the initial run-travis.sh script
7+
#
8+
# FIXME: feels like run-travis.sh should be responsible for downloading the
9+
# compiler.
10+
11+
set -ex
12+
13+
ROOT=$1
14+
cp -r $ROOT/libc /tmp/libc
15+
cd /tmp/libc
16+
17+
TARGET=$(cat $ROOT/TARGET)
18+
19+
case $TARGET in
20+
*-freebsd)
21+
sudo pkg install -y rust cargo
22+
;;
23+
24+
*-openbsd)
25+
pkg_add rust curl gcc-4.8.4p4
26+
curl https://static.rust-lang.org/cargo-dist/2015-04-02/cargo-nightly-x86_64-unknown-openbsd.tar.gz | \
27+
tar xzf - -C /tmp
28+
export PATH=$PATH:/tmp/cargo-nightly-x86_64-unknown-openbsd/cargo/bin
29+
export CC=egcc
30+
;;
31+
32+
*)
33+
echo "Unknown target: $TARGET"
34+
exit 1
35+
;;
36+
esac
37+
38+
exec sh ci/run.sh $TARGET

0 commit comments

Comments
 (0)