Open YanWQ-monad opened 5 months ago
Nix has a package for gVisor. It is very likely that you just need to change the package definition to use the forked repository. For RISC-V compatibility, it is true that you will need to apply some patches. I think Nix should have the required mechanisms in place. Is that the case?
Nix has a package for gVisor.
This package is based on the go
branch of gVisor, which only contains the necessary files to build gVisor binary, and other files such as bazel configurations and syscall tests code are missing, thus the branch can be used to build gVisor without bazel.
This approach is OK if one only wants to build the gVisor binary. But we want its syscall tests, which are built by bazel, so this package seems cannot be reused.
Summary
Use Nix build system to build initrd image (and it can also be used to manage the development environment).
Motivation
Currently, Asterinas uses Makefile to build initrd, but with the following drawbacks.
Hard to support cross-compilation. As we are introducing RISC-V support, so our initrd builder should be able to build initrd of different architectures. In current Makefile system, we need to add cross compiler in
asterinas
Docker image, and add corresponding config in Makefile, which may be increasingly hard to maintain if we introduce ARM and other architectures.Hard to build complex software. For example, to build Python, we need to install the dependencies like
libgdbm-dev
,libgdbm-compat-dev
, and etc, and copy necessary shared objects to initrd. The shared objects are manually chosen and are hard to maintain. What's worse, in cross compilation, we need to build all the dependencies by ourselves, because it can't simply be installed byapt-get
, and this could be a recursion hell.Imperative. Currently, The recipe to build initrd is imperative. This could cause some problems. For example, for the recipe
if interrupt it when
cp
ingpasswd
, and runmake
again, Makefile will skip this recipe since/etc
exists, despite its content is not properly created.Besides, current
Makefile
contains lots of hardcoded paths, likeVDSO_DIR := /root/dependency
andwhich could make it hard to build initrd in a more general Linux environment.
So we need a another build system to build initrd that has better cross compilation support, and can manage initrd's content in a more clear way.
Proposal
Nix is a package manager, and the introduction is on https://nix.dev/manual/nix/2.18/.
With Nix, a basic initrd with only
busybox
can be build with the following Nix script:And then Nix will build all the dependencies and then copy binaries and necessary shared objects to initrd. This dependencies building and resolving are done by Nix, without human intervention.
To build RISC-V initrd, we can replace
with
then it will build RISC-V's packages.
What's more, using Nix can make it easy to add packages to initrd. For example, adding Python only needs to add
pkgs.python3
inpkgs.buildEnv
andstorePaths
, and it works. We don't need to care about how to recursively build its dependencies.Besides initrd, with nix-direnv, Nix can also be used to setup a local development environment for Asterinas. This could be better than Docker because Docker is too isolated, it's suitable for deployment but not development, while using Nix can reuse our friendly shell.
Known Issues
Currently syscall tests are built with Bazel, but both Nix and Bazel are "complete" systems, they don't cooperate well. The issue itself can be solved by patching gVisor, but it's not elegant. What's more, gVisor's syscall tests seem don't support RISC-V architecture (though there some "RISC-V" pieces in its build scripts, the README says "_gVisor builds on x8664 and ARM64"). But how to deal with syscall tests with RISC-V may be beyond the scope of this RFC.
The build unit in Nix is package, so it doesn't support increment build very well currently. That is, if one modifies a file of a package, Nix will build the whole package again instead of the changed ones. This issue may be mitigated by building the package manually and copying the binaries in Nix script.