1. cloud hypervisor无法启动

直接启动会报错:

看提示已经能够显示出错的具体代码位置了.

加上RUST_BACKTRACE=1会更具体:

又提示RUST_BACKTRACE=full会更详细:

可以看到:

  • rust的调用层级很多, 和go有的一拼
  • RUST_BACKTRACE=1会过滤掉最近的0到12层调用栈, 这些都是rust_begin_unwind的内部流程, 一般用户不需要关心
  • 真正出问题的是vmm::vm::Vm::new, 即RUST_BACKTRACE=full时的第16层调用栈, 很奇怪的是在调用栈里没提示是哪一行. 但调用栈打印之前就有打印提示出错文件和行号:vmm/src/vm.rs:729:48
  • unwrap出错会直接panic
  • 用环境变量RUST_BACKTRACE=这招和go很像GOTRACEBACK=

1.1. 会是什么原因

突然想到这个机器本来就是kvm的虚拟机, 是否是kvm嵌套没打开呢? 参考:https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/

1.1.1. 检查kvm是否nested

cat /sys/module/kvm_intel/parameters/nested

果然这个机器显示N

1.1.2. enable nested KVM

To enable nested virtualization for Intel processors:

  1. Shut down all running VMs and unload the kvm_probe module:
    sudo modprobe -r kvm_intel
    
  2. Activate the nesting feature:
    sudo modprobe kvm_intel nested=1
    
  3. Nested virtualization is enabled until the host is rebooted. To enable it permanently, add the following line to the /etc/modprobe.d/kvm.conf file:
    options kvm_intel nested=1
    

AMD的CPU把上面的kvm_intel改成kvm_amd

1.1.3. 不是nested没开

按照上面的方法, 重新加载kvm_intel并使能nested=1, 也成功了. 但问题依旧.
那估计就是kernel版本太低了:
Linux spine.novalocal 3.10.0-1160.2.2.el7.x86_64 不支持KVM_CAP_IMMEDIATE_EXIT功能

https://github.com/rust-vmm/kvm-ioctls/src/cap.rs

ImmediateExit = KVM_CAP_IMMEDIATE_EXIT,

1.1.4. 升级kernel

centos 7的kernel比较老, 直接用标准方式升级版本还是3.10. 下面用epel升级kernel

yum --enablerepo=elrepo-kernel install kernel-lt

改grub默认从新kernel启动, 启动后版本是:

$ uname -a
Linux spine.novalocal 5.4.207-1.el7.elrepo.x86_64 #1 SMP Tue Jul 19 10:40:55 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux

使用新kernel问题解决!

2. 编译virtiofsd

virtiofsd是rust版本的daemon进程, 用来通过viriofs协议和VM共享host目录.

git clone https://gitlab.com/virtio-fs/virtiofsd
cargo build --release

错误:

/usr/bin/ld: cannot find -lseccomp
/usr/bin/ld: cannot find -lcap-ng
collect2: error: ld returned 1 exit status

解决:

sudo apt install libseccomp-dev libcap-ng-dev

2.1. target是musl也不总是完全的静态链接

比如这个virtiofsd, 用了musl libc之后, libc的部分是静态链接的. 但还是引用了libseccomp和libcap

2.2. 如何静态链接virtiofsd

virtiofsd的官方repo就可以编译出完全静态的二进制, 它是如何做到的? 见https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/.gitlab-ci.yml

apk add libcap-ng-static libseccomp-static musl-dev
RUSTFLAGS='-C target-feature=+crt-static -C link-self-contained=yes' LIBSECCOMP_LINK_TYPE=static LIBSECCOMP_LIB_PATH=/usr/lib LIBCAPNG_LINK_TYPE=static LIBCAPNG_LIB_PATH=/usr/lib cargo build --release --target x86_64-unknown-linux-musl

这篇文章说, rust的静态链接必须要显式指定--target xxxx, 这是个bug. 经过我的试验, 至少rustc 1.66.0, 还是必须要加--target x86_64-unknown-linux-musl, 否则出现错误 error: cannot produce proc-macro forfutures-macro v0.3.21as the target x86_64-unknown-linux-musl does not support these crate types, 即使我这里默认的tuple就是x86_64-unknown-linux-musl

results matching ""

    No results matching ""