kvm vm操作

在介绍KVM操作之前,先了解几个重要的数据对象:
 
对应设备文件/dev/kvm
static struct file_operations kvm_chardev_ops = {
 .unlocked_ioctl = kvm_dev_ioctl,
 .compat_ioctl   = kvm_dev_ioctl,
 .llseek  = noop_llseek,
};
 
对应文件描述符fd,管理虚拟机使用
static struct file_operations kvm_vm_fops = {
.release        = kvm_vm_release,
.unlocked_ioctl = kvm_vm_ioctl,
#ifdef CONFIG_KVM_COMPAT
.compat_ioctl   = kvm_vm_compat_ioctl,
#endif
.llseek = noop_llseek,
};
 
对应文件描述符fd,管理CPU虚拟化使用
static struct file_operations kvm_vcpu_fops = {
 .release        = kvm_vcpu_release,
 .unlocked_ioctl = kvm_vcpu_ioctl,
#ifdef CONFIG_KVM_COMPAT
 .compat_ioctl   = kvm_vcpu_compat_ioctl,
#endif
 .mmap           = kvm_vcpu_mmap,
 .llseek  = noop_llseek,
};
 
对应文件描述符fd,管理设备虚拟化使用,如IO,timer等。
static const struct file_operations kvm_device_fops = {
 .unlocked_ioctl = kvm_device_ioctl,
#ifdef CONFIG_KVM_COMPAT
 .compat_ioctl = kvm_device_ioctl,
#endif
 .release = kvm_device_release,
};
 
可以看到,对于KVM来说,在通过用户空间创建虚拟机时,它是通过设备文件和一些普通文件来与内核交互的。
我们下面了解一些主要操作:
 

在用户空间工具打开/dev/kvm后,使用ioctl操作内核的kvm模块,对于qemu-kvm的介绍我们后面进行。 static long kvm_dev_ioctl(struct file *filp,      unsigned int ioctl, unsigned long arg) {  long r = -EINVAL;

 switch (ioctl) {  case KVM_GET_API_VERSION:   if (arg)    goto out;   r = KVM_API_VERSION;   break;  case KVM_CREATE_VM:   r = kvm_dev_ioctl_create_vm(arg);   break;  case KVM_CHECK_EXTENSION:   r = kvm_vm_ioctl_check_extension_generic(NULL, arg);   break;  case KVM_GET_VCPU_MMAP_SIZE:   if (arg)    goto out;   r = PAGE_SIZE;     /* struct kvm_run */ #ifdef CONFIG_X86   r += PAGE_SIZE;    /* pio data page */ #endif #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET   r += PAGE_SIZE;    /* coalesced mmio ring page */ #endif   break;  case KVM_TRACE_ENABLE:  case KVM_TRACE_PAUSE:  case KVM_TRACE_DISABLE:   r = -EOPNOTSUPP;   break;  default:   return kvm_arch_dev_ioctl(filp, ioctl, arg);  } out:  return r; }

可以看到,这里ioctl需要提供KVM_CREATE_VM,之后内核调用函数kvm_dev_ioctl_create_vm()函数 static int kvm_dev_ioctl_create_vm(unsigned long type) {  int r;  struct kvm *kvm;  struct file *file;

 kvm = kvm_create_vm(type);分配虚拟机对象的内存  if (IS_ERR(kvm))   return PTR_ERR(kvm); #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET  r = kvm_coalesced_mmio_init(kvm);  if (r < 0) {   kvm_put_kvm(kvm);   return r;  } #endif  r = get_unused_fd_flags(O_CLOEXEC);获取一个未使用的fd,即文件描述fd,这是个整数。  if (r < 0) {   kvm_put_kvm(kvm);   return r;  }  file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);我们创建一个文件,这个是anon类型的文件系统,

这个文件我们称之为管理虚拟机的文件,即kvm-vm文件。这个文件对外提供的操作为kvm_vm_fops。这样我们可以采用类似文件的操作来管理虚拟机了。  if (IS_ERR(file)) {   put_unused_fd(r);   kvm_put_kvm(kvm);   return PTR_ERR(file);  }

 if (kvm_create_vm_debugfs(kvm, r) < 0) {   put_unused_fd(r);   fput(file);   return -ENOMEM;  }

 fd_install(r, file);我们刚刚创建了一个文件file对象,并且也申请了一个fd,这里我们把两者关联起来,即安装到进程的files_struct的files表里面。

这样我们就可以通过文件描述符fd来管理kvm-vm的虚拟机了。  return r; }

从上面可以看到,在通过ioctl创建虚拟机时,内核的kvm模块创建了struct kvm对象,并创建一个文件,文件是用户空间管理内核kvm的接口,函数ioctl返回这个文件的fd。

这里对虚拟机kvm对象的分配和初始化由kvm_create_vm()处理。我们在后面继续介绍。

 
 
 
 
 
 

 


 

 


 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值