深度探索Linux系统虚拟化:原理与实现
上QQ阅读APP看书,第一时间看更新

1.5.6 运行虚拟机

一切准备就绪,接下来该启动虚拟机了,KVM为此提供的命令是KVM_RUN。我们将发起虚拟机运行的指令放在一个无限的while循环中,如此,一旦Guest退出到用户空间,我们可以再次请求KVM切回Guest。启动虚拟机代码如下:


void run_vm(struct vm *vm) {
  int ret = 0;

  while (1) {
    if ((ioctl(vm->vcpu[0]->fd, KVM_RUN, 0)) < 0) {
      fprintf(stderr, "failed to run kvm.\n");
      exit(1);
    }
  }
}

读者只需要一条命令编译这个kvm用户空间实例即可:


gcc kvm.c -o kvm

然后运行这个kvm用户空间实例:


sudo ./kvm

在另外一个终端中,运行如下命令:


pidstat -p `pidof kvm` 1

如果一切正常,可以看到类似如下的输出:


UID       PID    %usr %system  %guest    %CPU   CPU  Command
  0     17742    0.00    0.00  100.00  100.00     7  kvm
  0     17742    0.00    0.00  100.00  100.00     3  kvm
  0     17742    0.00    0.00  100.00  100.00     1  kvm
  0     17742    0.00    0.00  100.00  100.00     0  kvm
  0     17742    0.00    0.00  100.00  100.00     4  kvm
  …

因为在Guest中只是简单地运行了一个空循环,没有任何敏感指令,我们可以看到这个VCPU的Guest态是100%,所以这台虚拟机基本没有主动地触发陷入。但是,有被动发生的VM退出,比如时钟中断、网卡中断落到这个CPU上时,但是因为这些中断导致VM退出后,VCPU在Host内核态停留的时间非常短暂,马上又再次切入Guest了。所以,VCPU线程的Host系统态占比非常少,统计中系统态(%system)的值也是0。