This repository provides an overview of the rust-vmm project, its crates, guiding principles, and the development model.
rust-vmm is an open-source project that empowers the community to build custom Virtual Machine Monitors (VMMs) and hypervisors. It provides a set of virtualization components that any project can use to quickly develop virtualization solutions while focusing on the key differentiators of their product rather than re-implementing common components like KVM wrappers, virtio devices and other VMM libraries.
The rust-vmm project is organized as a shared effort, shared ownership open-source project that includes (so far) contributors from Alibaba, AWS, Cloud Base, Crowdstrike, Intel, Google, Linaro, Red Hat as well as individual contributors.
Each virtualization component lives in a separate GitHub repository under the rust-vmm organization. One repository corresponds usually to one Rust crate.
- Reduce code duplication. The initial idea behind rust-vmm was to create a place for sharing common virtualization components between two existing VMMs written in Rust: CrosVM and Firecracker. These two projects have similar code for calling KVM ioctls, managing the virtual machine memory, interacting with virtio devices and others. Instead of having these components live in each of the projects repositories, they can be shared through the rust-vmm project. Since the beginning of the project, other initiatives have enabled expanding the scope of the project to accommodate the needs of the Xen and Hyper-v hypervisor by way of bindings and low level access libraries. Other open source projects such as Cloud Hypervisor, the Qemu virtiofsd implementation and vhost-device have also been integrated.
- Faster development. rust-vmm provides a base of virtualization components which are meant to be generic such that they can be consumed by multiple projects. The project aims to allow building custom virtualization solutions by reusing the rust-vmm components. On top of these components, a custom solution should only need to care about its specialized component, an API and the glue code that provides the interactions between them.
- Security & Testability. One of the most salient feature of rust-vmm is its high quality components. We want to keep a high quality standard as these virtualization packages are used in production by multiple projects. Each component is individually tested with a set of common build time tests responsible for running unit tests, linters (including coding style checks), and computing the coverage. For critical components that handle untrusted input we also run fuzzing (i.e in vm-virtio), and provide a threat model documentation that customers can use to improve the security of their solutions.
- Clean interface. As crates are shared between multiple VMMs, the reviews for interface changes will typically go through a few rounds of reviews to make sure they are flexible enough to be used by multiple products.
When we first started the rust-vmm project each of the crate was living in its own repository. As the number of crates grew quickly, we reverted this decision, and started having related crates as part of a single workspace. Now, we have one workspace per repository. For example, the vm-virtio repository accommodates multiple crates including virtio-queue, and different virtio device implementations. The reasoning behind having multiple crates in a single repository comes from the maintenance cost of repositories. To give an example, whenever we update the rust-vmm-ci, Dependabot will open a PR in each rust-vmm repository to update to the latest version. While in most cases the reviews are trivial as very few changes are required, you still need to go through a long list of PRs that need to be approved. In rare cases when changes to the infrastructure impact the CI, propagating them to individual repositories quickly adds up. You need to clone the repository, create a branch, provide the update, follow up on the PRs, and so on.
A rust-vmm crate can have one of the following states:
-
empty
: The crate repo exists but there is no code there yet. This means the crate was created after a community acknowledgement about its relevance to the project, but either no code has been submitted yet or the initial code base is being reviewed through a pull request. -
rust-vmm
: The code is a work in progress. Once it meets the production requirements, the crate will be pushed to crates.io. -
crates.io
: The crate is considered to be production ready. It can be consumed from Rust's canonical crate registry: crates.io. The crate repository in rust-vmm is as a staging area until the next push to crates.io. In other words, the production ready version of the code lives in crates.io while development happens in the rust-vmm git repo.
These are the empty repositories that have PRs waiting to be merged.
- vmm-vcpu: a hypervisor-agnostic abstraction for Virtual CPUs (vCPUs).
- acpi_tables: code for generating ACPI tables.
- mshv: workspace for Microsoft Hypervisor safe wrappers.
- vm-virtio: workspace for virtio devices and related helpers.
- vmm-reference: reference VMM
built solely with
rust-vmm
crates and minimal glue. - vhost-device: A workspace for devices implemented using the vhost-user-backend.
- event-manager: abstractions for implementing event based systems.
- kvm-bindings: Rust FFI bindings to KVM generated using bindgen.
- kvm-ioctls: Safe wrappers over the KVM API.
- linux-loader: parser and loader for vmlinux and bzImage images as well as some other helpers for kernel commandline.
- seccompiler: Linux seccomp-bpf jailing utilities.
- vfio-bindings: Rust FFI bindings for using the VFIO framework.
- vfio-ioctls: safe wrappers over the VFIO framework.
- vhost: a crate to support vhost backend drivers for virtio devices.
- vhost-user-backend: provides a framework to implement vhost-user backend services
- virtio-bindings: Rust FFI bindings to virtio kernel headers generated using bindgen.
- virtio-queue: virtio queue implementation.
- virtio-queue-ser: version aware serialization support for virtio-queue.
- virtio-vsock: virtio vsock device implementation.
- vm-allocator: abstractions for allocating resources needed by the VMM while running (such as GSI numbers, MMIO ranges).
- vm-device: a virtual machine device model crate.
- vm-fdt: a Flattened Device Tree writer.
- vm-memory: abstractions over a virtual machine's memory.
- vm-superio: emulation for legacy devices.
- vm-superio-ser: provides version aware serialization for the emulated devices in vm-superio.
- vmm-sys-util: collection of modules providing helpers and utilities for building VMMs and hypervisors.
The rust-vmm project is maintained by repository maintainers and gatekeepers. More details about their responsibilities are available in the Maintainers Docs.
You can join our community discussions on any of the following places:
- Join our mailing list.
- Join our Slack channel.
All the rust-vmm repositories accept contributions by a GitHub Pull Request (PR). For more details, please check the contributing document.
For other processes (like setting up repos), please check the extended documentation.
If you want to become a rust-vmm maintainer, or you're curious about the role,
please check the documentation available in MAINTAINERS.md
.
If you have a proposal about a new rust-vmm component, please open a review request issue. The issue must provide the explanations and justifications behind the need for a new component, highlighting the purpose of this new repository, how will it be used by other VMMs or hypervisors, and other information that you find relevant.
Discussions about the proposal will take place on the same issue, and once an agreement is reached on the new crate name (this part is hard!) and design, an empty repository will be created in the rust-vmm GitHub organization.
To add functionality you will need to send Pull Requests (PRs) against the newly created repository. While we do not expect the code to be perfect from the first try, we do enforce a high standard in terms of quality for all existing repositories under rust-vmm.
We consider crates published on crates.io to be production ready. In order to maintain a high security and quality standard, the following list of requirements must be checked before having the first version published:
- High level documentation. This documentation should be added
to
src/lib.rs
and it will end up being the home page of the crate on docs.rs. Include information about what this crate does, how can it be used in other projects, as well as usage examples. Check out the kvm-ioctls docs for an example. - Documentation for the public interface. Everything belonging to the
public interface of the crate must be properly documented. Where applicable,
the methods should also have
usage examples.
The code examples are particularly useful because they are run on
cargo test
. It is a nice way to ensure that your comments and examples don't go out of sync with the code. To make sure we don't miss anything this rule is enforceable by using#![deny(missing-docs)]
insrc/lib.rs
. - Unit Tests.
- Coverage. We expect all crates to enable a coverage test that doesn't allow the coverage to drop on new PRs. See the coverage docs for more details. For most of the crates in rust-vmm we keep the coverage to above 80% before publishing them on crates.io. This coverage target can be slightly adjusted in rare cases, and depending on the use case.
- Build Time Tests. All components must have a running CI that includes checks for style, linters, build, coverage, and in some cases benchmarks and fuzzing sessions. These tests are running with various feature configurations, and on different architecture and operating systems. In their majority, the rust-vmm components are tested using the rust-vmm-ci, running on Buildkite. This makes sure that the same quality bar is kept across the rust-vmm project. When using Buildkite and rust-vmm-ci is not feasible, the same tests should be recreated using different CI providers.
- README.md. The readme contains high-level information about the crate. The readme is the front page of the package on crates.io so ideally it also has minimal examples on how to use the crate. For in-depth design details, a DESIGN.md file can be created.
- LICENSE. The suggested license for the rust-vmm crates is Apache 2.0 OR BSD-3-Clause as this is a permissive license which allows various projects to consume the crates.
- CODEOWNERS. This file provides transparency in terms of whom the maintainers of the various crates are. By default, the @rust-vmm/gatekeepers are maintainers for all rust-vmm crates, but this should be used as an exceptional situation rather than the norm.
- Complete
Cargo.toml
. Check thecargo
reference for the requirements that a crate must meet to be published to crates.io. - Unsafe Code. Go over the code and make sure you are limiting the usage of unsafe code. Unsafe code blocks should be limited to the code that is unsafe. When the unsafe functions also have safe equivalents, these should be used instead.
We ensure that all rust-vmm components keep the same quality bar by using the rust-vmm-ci. The rust-vmm-ci is built on top of Buildkite, and added as a submodule to all rust-vmm repositories. For more details, please check the rust-vmm-ci README.
For more details about certain aspects of developing in rust-vmm, please check the extended development documentation.