Skip to content

Advanced Configuration Features

Stefan Lankes edited this page Dec 12, 2020 · 14 revisions

You are not happy with Hello World yet?

Link Time Optimization (LTO)

To enable Link Time Optimization (LTO), please extend the release configuration in Cargo.toml as follows:

# Cargo.toml
[profile.release]
opt-level = 3
lto = "thin"

In addition, the Linker-plugin LTO have to be enabled by setting the compiler flag linker-plugin-lto. In this case, the release version have to build as follows:

RUSTFLAGS="-Clinker-plugin-lto" cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit --release

Controlling kernel message verbosity

RustyHermit uses the lightweight logging crate log to print kernel messages. If the environment variable HERMIT_LOG_LEVEL_FILTER is set at compile time to a string matching the name of a LevelFilter, then that value is used for the LevelFilter. If the environment variable is not set, or the name doesn't match, then LevelFilter::Info is used by default, which is the same as it was before.

For instance, the following command build RustyHermit with debug messages:

$ HERMIT_LOG_LEVEL_FILTER=Debug cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit

Network support

To enable an ethernet device, we have to setup a tap device on the host system. For instance, the following command establish the tap device tap10 on Linux:

$ sudo ip tuntap add tap10 mode tap
$ sudo ip addr add 10.0.5.1/24 broadcast 10.0.5.255 dev tap10
$ sudo ip link set dev tap10 up
$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/conf/tap10/proxy_arp'

Add the feature smoltcp in the Cargo.toml. This includes the network stack smoltcp and offers TCP/UDP communication.

# Cargo.toml

[target.'cfg(target_os = "hermit")'.dependencies]
hermit-sys = "0.1.*"
default-features = false
features = ["smoltcp"]

Per default, RustyHermit's network interface uses 10.0.5.3 as IP address, 10.0.5.1 for the gateway and 255.255.255.0 as network mask. The default configuration could be overloaded at compile time by the environment variables HERMIT_IP, HERMIT_GATEWAY and HERMIT_MASK. For instance, the following command sets the IP address to 10.0.5.100.

$ HERMIT_IP="10.0.5.100" cargo build -Z build-std=std,core,alloc,panic_abort --target x86_64-unknown-hermit

Currently, RustyHermit does only support network interfaces through virtio. To use it, you have to start RustyHermit in Qemu with following command:

$ qemu-system-x86_64 -cpu qemu64,apic,fsgsbase,rdtscp,xsave,fxsr \
        -enable-kvm -display none -smp 1 -m 1G -serial stdio \
        -kernel path_to_loader/rusty-loader \
        -initrd path_to_app/app \
        -netdev tap,id=net0,ifname=tap10,script=no,downscript=no,vhost=on \
        -device virtio-net-pci,netdev=net0,disable-legacy=on

Using VirtioFS to share a file system (only required when using QEMU)

It is possible to share the host file system with RustyHermit when using Qemu, but you must use QEMU with VirtioFS support to do this.

Building Qemu with VirtioFS support

  1. Download the source code from the VirtioFS project: git clone https://gitlab.com/virtio-fs/qemu.git
  2. cd qemu
  3. Switch to the branch with VirtioFS and DAX support: git checkout qemu5.0-virtiofs-dax
  4. mkdir build && cd build
  5. Configure source code: ../configure --prefix=$PATH_TO_INSTALL_DIRECTORY --target-list=x86_64-softmmu
  6. Please check if VirtioFS support is activated
  7. Build Qemu: make -j 4
  8. Install Qemu: make install

Run Unikernel with VirtioFS support

  1. Prepare a filesystem for the guest. For instance, create a directory within /tmp, which will serve as the mountable directory within the guest, e.g. execute mkdir /tmp/guestfs
  2. Start the VirtioFS daemon and export the current working directory to the guest: sudo virtiofsd --thread-pool-size=1 --socket-path=/tmp/vhostqemu -o source=/tmp/guestfs --daemonize &
  3. Give non-root-users access to the socket: sudo chmod 777 /tmp/vhostqemu
  4. Start the application, e.g. the following will execute the RustyHermit demo: qemu-system-x86_64 -enable-kvm -cpu host -display none -smp 1 -m 256M -serial stdio -kernel loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd target/x86_64-unknown-hermit/debug/rusty_demo -chardev socket,id=char0,path=/tmp/vhostqemu -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=root -object memory-backend-file,id=mem,size=256M,mem-path=/dev/shm,share=on -numa node,memdev=mem

These commands mount the host directory /tmp/guestfs in the guest as /root. Per default /root is the working directory of RustyHermit. The working directory can changed by setting the environment variable HERMIT_WD before compiling RustyHermit. In addition, the tag root in argument list of Qemu specifies the path within the guest.

Note: The demo application will try to read /etc/hostname, which still fails because the directory etc isn't mounted within the quest.

Enabling DAX support

DAX mapping allows RustyHermit direct access to file content from the host file cache.

The device section of the Qemu command line must be changed as follows: qemu-system-x86_64 -enable-kvm -cpu host -display none -smp 1 -m 256M -serial stdio -kernel loader/target/x86_64-unknown-hermit-loader/debug/rusty-loader -initrd target/x86_64-unknown-hermit/debug/rusty_demo -chardev socket,id=char0,path=/tmp/vhostqemu -device vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=root,cache-size=256M -object memory-backend-file,id=mem,size=256M,mem-path=/dev/shm,share=on -numa node,memdev=mem

Clone this wiki locally