gitee.com/leisunstar/runtime@v0.0.0-20200521203717-5cef3e7b53f9/virtcontainers/hypervisor.go (about) 1 // Copyright (c) 2016 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 package virtcontainers 7 8 import ( 9 "bufio" 10 "context" 11 "fmt" 12 "os" 13 "path/filepath" 14 "runtime" 15 "strconv" 16 "strings" 17 18 "github.com/kata-containers/runtime/virtcontainers/device/config" 19 "github.com/kata-containers/runtime/virtcontainers/persist" 20 persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api" 21 "github.com/kata-containers/runtime/virtcontainers/types" 22 "github.com/kata-containers/runtime/virtcontainers/utils" 23 ) 24 25 // HypervisorType describes an hypervisor type. 26 type HypervisorType string 27 28 type operation int 29 30 const ( 31 addDevice operation = iota 32 removeDevice 33 ) 34 35 const ( 36 // FirecrackerHypervisor is the FC hypervisor. 37 FirecrackerHypervisor HypervisorType = "firecracker" 38 39 // QemuHypervisor is the QEMU hypervisor. 40 QemuHypervisor HypervisorType = "qemu" 41 42 // AcrnHypervisor is the ACRN hypervisor. 43 AcrnHypervisor HypervisorType = "acrn" 44 45 // ClhHypervisor is the ICH hypervisor. 46 ClhHypervisor HypervisorType = "clh" 47 48 // MockHypervisor is a mock hypervisor for testing purposes 49 MockHypervisor HypervisorType = "mock" 50 ) 51 52 const ( 53 procMemInfo = "/proc/meminfo" 54 procCPUInfo = "/proc/cpuinfo" 55 ) 56 57 const ( 58 defaultVCPUs = 1 59 // 2 GiB 60 defaultMemSzMiB = 2048 61 62 defaultBridges = 1 63 64 defaultBlockDriver = config.VirtioSCSI 65 66 defaultSocketName = "kata.sock" 67 defaultSocketDeviceID = "channel0" 68 defaultSocketChannelName = "agent.channel.0" 69 defaultSocketID = "charch0" 70 71 // port numbers below 1024 are called privileged ports. Only a process with 72 // CAP_NET_BIND_SERVICE capability may bind to these port numbers. 73 vSockPort = 1024 74 75 // Port where the agent will send the logs. Logs are sent through the vsock in cases 76 // where the hypervisor has no console.sock, i.e firecracker 77 vSockLogsPort = 1025 78 79 // MinHypervisorMemory is the minimum memory required for a VM. 80 MinHypervisorMemory = 256 81 ) 82 83 // In some architectures the maximum number of vCPUs depends on the number of physical cores. 84 var defaultMaxQemuVCPUs = MaxQemuVCPUs() 85 86 // agnostic list of kernel root parameters for NVDIMM 87 var commonNvdimmKernelRootParams = []Param{ //nolint: unused, deadcode, varcheck 88 {"root", "/dev/pmem0p1"}, 89 {"rootflags", "dax,data=ordered,errors=remount-ro ro"}, 90 {"rootfstype", "ext4"}, 91 } 92 93 // agnostic list of kernel root parameters for NVDIMM 94 var commonNvdimmNoDAXKernelRootParams = []Param{ //nolint: unused, deadcode, varcheck 95 {"root", "/dev/pmem0p1"}, 96 {"rootflags", "data=ordered,errors=remount-ro ro"}, 97 {"rootfstype", "ext4"}, 98 } 99 100 // agnostic list of kernel root parameters for virtio-blk 101 var commonVirtioblkKernelRootParams = []Param{ //nolint: unused, deadcode, varcheck 102 {"root", "/dev/vda1"}, 103 {"rootflags", "data=ordered,errors=remount-ro ro"}, 104 {"rootfstype", "ext4"}, 105 } 106 107 // deviceType describes a virtualized device type. 108 type deviceType int 109 110 const ( 111 // ImgDev is the image device type. 112 imgDev deviceType = iota 113 114 // FsDev is the filesystem device type. 115 fsDev 116 117 // NetDev is the network device type. 118 netDev 119 120 // BlockDev is the block device type. 121 blockDev 122 123 // SerialPortDev is the serial port device type. 124 serialPortDev 125 126 // vSockPCIDev is the vhost vsock PCI device type. 127 vSockPCIDev 128 129 // VFIODevice is VFIO device type 130 vfioDev 131 132 // vhostuserDev is a Vhost-user device type 133 vhostuserDev 134 135 // CPUDevice is CPU device type 136 cpuDev 137 138 // memoryDevice is memory device type 139 memoryDev 140 141 // hybridVirtioVsockDev is a hybrid virtio-vsock device supported 142 // only on certain hypervisors, like firecracker. 143 hybridVirtioVsockDev 144 ) 145 146 type memoryDevice struct { 147 slot int 148 sizeMB int 149 addr uint64 150 probe bool 151 } 152 153 // Set sets an hypervisor type based on the input string. 154 func (hType *HypervisorType) Set(value string) error { 155 switch value { 156 case "qemu": 157 *hType = QemuHypervisor 158 return nil 159 case "firecracker": 160 *hType = FirecrackerHypervisor 161 return nil 162 case "acrn": 163 *hType = AcrnHypervisor 164 return nil 165 case "clh": 166 *hType = ClhHypervisor 167 return nil 168 case "mock": 169 *hType = MockHypervisor 170 return nil 171 default: 172 return fmt.Errorf("Unknown hypervisor type %s", value) 173 } 174 } 175 176 // String converts an hypervisor type to a string. 177 func (hType *HypervisorType) String() string { 178 switch *hType { 179 case QemuHypervisor: 180 return string(QemuHypervisor) 181 case FirecrackerHypervisor: 182 return string(FirecrackerHypervisor) 183 case AcrnHypervisor: 184 return string(AcrnHypervisor) 185 case ClhHypervisor: 186 return string(ClhHypervisor) 187 case MockHypervisor: 188 return string(MockHypervisor) 189 default: 190 return "" 191 } 192 } 193 194 // newHypervisor returns an hypervisor from and hypervisor type. 195 func newHypervisor(hType HypervisorType) (hypervisor, error) { 196 store, err := persist.GetDriver() 197 if err != nil { 198 return nil, err 199 } 200 201 switch hType { 202 case QemuHypervisor: 203 return &qemu{ 204 store: store, 205 }, nil 206 case FirecrackerHypervisor: 207 return &firecracker{}, nil 208 case AcrnHypervisor: 209 return &Acrn{ 210 store: store, 211 }, nil 212 case ClhHypervisor: 213 return &cloudHypervisor{ 214 store: store, 215 }, nil 216 case MockHypervisor: 217 return &mockHypervisor{}, nil 218 default: 219 return nil, fmt.Errorf("Unknown hypervisor type %s", hType) 220 } 221 } 222 223 // Param is a key/value representation for hypervisor and kernel parameters. 224 type Param struct { 225 Key string 226 Value string 227 } 228 229 // HypervisorConfig is the hypervisor configuration. 230 type HypervisorConfig struct { 231 // NumVCPUs specifies default number of vCPUs for the VM. 232 NumVCPUs uint32 233 234 //DefaultMaxVCPUs specifies the maximum number of vCPUs for the VM. 235 DefaultMaxVCPUs uint32 236 237 // DefaultMem specifies default memory size in MiB for the VM. 238 MemorySize uint32 239 240 // DefaultBridges specifies default number of bridges for the VM. 241 // Bridges can be used to hot plug devices 242 DefaultBridges uint32 243 244 // Msize9p is used as the msize for 9p shares 245 Msize9p uint32 246 247 // MemSlots specifies default memory slots the VM. 248 MemSlots uint32 249 250 // MemOffset specifies memory space for nvdimm device 251 MemOffset uint32 252 253 // VirtioFSCacheSize is the DAX cache size in MiB 254 VirtioFSCacheSize uint32 255 256 // KernelParams are additional guest kernel parameters. 257 KernelParams []Param 258 259 // HypervisorParams are additional hypervisor parameters. 260 HypervisorParams []Param 261 262 // KernelPath is the guest kernel host path. 263 KernelPath string 264 265 // ImagePath is the guest image host path. 266 ImagePath string 267 268 // InitrdPath is the guest initrd image host path. 269 // ImagePath and InitrdPath cannot be set at the same time. 270 InitrdPath string 271 272 // FirmwarePath is the bios host path 273 FirmwarePath string 274 275 // MachineAccelerators are machine specific accelerators 276 MachineAccelerators string 277 278 // CPUFeatures are cpu specific features 279 CPUFeatures string 280 281 // HypervisorPath is the hypervisor executable host path. 282 HypervisorPath string 283 284 // HypervisorCtlPath is the hypervisor ctl executable host path. 285 HypervisorCtlPath string 286 287 // JailerPath is the jailer executable host path. 288 JailerPath string 289 290 // BlockDeviceDriver specifies the driver to be used for block device 291 // either VirtioSCSI or VirtioBlock with the default driver being defaultBlockDriver 292 BlockDeviceDriver string 293 294 // HypervisorMachineType specifies the type of machine being 295 // emulated. 296 HypervisorMachineType string 297 298 // MemoryPath is the memory file path of VM memory. Used when either BootToBeTemplate or 299 // BootFromTemplate is true. 300 MemoryPath string 301 302 // DevicesStatePath is the VM device state file path. Used when either BootToBeTemplate or 303 // BootFromTemplate is true. 304 DevicesStatePath string 305 306 // EntropySource is the path to a host source of 307 // entropy (/dev/random, /dev/urandom or real hardware RNG device) 308 EntropySource string 309 310 // Shared file system type: 311 // - virtio-9p (default) 312 // - virtio-fs 313 SharedFS string 314 315 // VirtioFSDaemon is the virtio-fs vhost-user daemon path 316 VirtioFSDaemon string 317 318 // VirtioFSCache cache mode for fs version cache or "none" 319 VirtioFSCache string 320 321 // VirtioFSExtraArgs passes options to virtiofsd daemon 322 VirtioFSExtraArgs []string 323 324 // File based memory backend root directory 325 FileBackedMemRootDir string 326 327 // customAssets is a map of assets. 328 // Each value in that map takes precedence over the configured assets. 329 // For example, if there is a value for the "kernel" key in this map, 330 // it will be used for the sandbox's kernel path instead of KernelPath. 331 customAssets map[types.AssetType]*types.Asset 332 333 // BlockDeviceCacheSet specifies cache-related options will be set to block devices or not. 334 BlockDeviceCacheSet bool 335 336 // BlockDeviceCacheDirect specifies cache-related options for block devices. 337 // Denotes whether use of O_DIRECT (bypass the host page cache) is enabled. 338 BlockDeviceCacheDirect bool 339 340 // BlockDeviceCacheNoflush specifies cache-related options for block devices. 341 // Denotes whether flush requests for the device are ignored. 342 BlockDeviceCacheNoflush bool 343 344 // DisableBlockDeviceUse disallows a block device from being used. 345 DisableBlockDeviceUse bool 346 347 // EnableIOThreads enables IO to be processed in a separate thread. 348 // Supported currently for virtio-scsi driver. 349 EnableIOThreads bool 350 351 // Debug changes the default hypervisor and kernel parameters to 352 // enable debug output where available. 353 Debug bool 354 355 // MemPrealloc specifies if the memory should be pre-allocated 356 MemPrealloc bool 357 358 // HugePages specifies if the memory should be pre-allocated from huge pages 359 HugePages bool 360 361 // VirtioMem is used to enable/disable virtio-mem 362 VirtioMem bool 363 364 // Realtime Used to enable/disable realtime 365 Realtime bool 366 367 // Mlock is used to control memory locking when Realtime is enabled 368 // Realtime=true and Mlock=false, allows for swapping out of VM memory 369 // enabling higher density 370 Mlock bool 371 372 // DisableNestingChecks is used to override customizations performed 373 // when running on top of another VMM. 374 DisableNestingChecks bool 375 376 // UseVSock use a vsock for agent communication 377 UseVSock bool 378 379 // DisableImageNvdimm is used to disable guest rootfs image nvdimm devices 380 DisableImageNvdimm bool 381 382 // HotplugVFIOOnRootBus is used to indicate if devices need to be hotplugged on the 383 // root bus instead of a bridge. 384 HotplugVFIOOnRootBus bool 385 386 // PCIeRootPort is used to indicate the number of PCIe Root Port devices 387 // The PCIe Root Port device is used to hot-plug the PCIe device 388 PCIeRootPort uint32 389 390 // BootToBeTemplate used to indicate if the VM is created to be a template VM 391 BootToBeTemplate bool 392 393 // BootFromTemplate used to indicate if the VM should be created from a template VM 394 BootFromTemplate bool 395 396 // DisableVhostNet is used to indicate if host supports vhost_net 397 DisableVhostNet bool 398 399 // EnableVhostUserStore is used to indicate if host supports vhost-user-blk/scsi 400 EnableVhostUserStore bool 401 402 // VhostUserStorePath is the directory path where vhost-user devices 403 // related folders, sockets and device nodes should be. 404 VhostUserStorePath string 405 406 // GuestHookPath is the path within the VM that will be used for 'drop-in' hooks 407 GuestHookPath string 408 409 // VMid is the id of the VM that create the hypervisor if the VM is created by the factory. 410 // VMid is "" if the hypervisor is not created by the factory. 411 VMid string 412 413 // SELinux label for the VM 414 SELinuxProcessLabel string 415 } 416 417 // vcpu mapping from vcpu number to thread number 418 type vcpuThreadIDs struct { 419 vcpus map[int]int 420 } 421 422 func (conf *HypervisorConfig) checkTemplateConfig() error { 423 if conf.BootToBeTemplate && conf.BootFromTemplate { 424 return fmt.Errorf("Cannot set both 'to be' and 'from' vm tempate") 425 } 426 427 if conf.BootToBeTemplate || conf.BootFromTemplate { 428 if conf.MemoryPath == "" { 429 return fmt.Errorf("Missing MemoryPath for vm template") 430 } 431 432 if conf.BootFromTemplate && conf.DevicesStatePath == "" { 433 return fmt.Errorf("Missing DevicesStatePath to load from vm template") 434 } 435 } 436 437 return nil 438 } 439 440 func (conf *HypervisorConfig) valid() error { 441 if conf.KernelPath == "" { 442 return fmt.Errorf("Missing kernel path") 443 } 444 445 if conf.ImagePath == "" && conf.InitrdPath == "" { 446 return fmt.Errorf("Missing image and initrd path") 447 } 448 449 if err := conf.checkTemplateConfig(); err != nil { 450 return err 451 } 452 453 if conf.NumVCPUs == 0 { 454 conf.NumVCPUs = defaultVCPUs 455 } 456 457 if conf.MemorySize == 0 { 458 conf.MemorySize = defaultMemSzMiB 459 } 460 461 if conf.DefaultBridges == 0 { 462 conf.DefaultBridges = defaultBridges 463 } 464 465 if conf.BlockDeviceDriver == "" { 466 conf.BlockDeviceDriver = defaultBlockDriver 467 } 468 469 if conf.DefaultMaxVCPUs == 0 { 470 conf.DefaultMaxVCPUs = defaultMaxQemuVCPUs 471 } 472 473 if conf.Msize9p == 0 && conf.SharedFS != config.VirtioFS { 474 conf.Msize9p = defaultMsize9p 475 } 476 477 return nil 478 } 479 480 // AddKernelParam allows the addition of new kernel parameters to an existing 481 // hypervisor configuration. 482 func (conf *HypervisorConfig) AddKernelParam(p Param) error { 483 if p.Key == "" { 484 return fmt.Errorf("Empty kernel parameter") 485 } 486 487 conf.KernelParams = append(conf.KernelParams, p) 488 489 return nil 490 } 491 492 func (conf *HypervisorConfig) addCustomAsset(a *types.Asset) error { 493 if a == nil || a.Path() == "" { 494 // We did not get a custom asset, we will use the default one. 495 return nil 496 } 497 498 if !a.Valid() { 499 return fmt.Errorf("Invalid %s at %s", a.Type(), a.Path()) 500 } 501 502 virtLog.Debugf("Using custom %v asset %s", a.Type(), a.Path()) 503 504 if conf.customAssets == nil { 505 conf.customAssets = make(map[types.AssetType]*types.Asset) 506 } 507 508 conf.customAssets[a.Type()] = a 509 510 return nil 511 } 512 513 func (conf *HypervisorConfig) assetPath(t types.AssetType) (string, error) { 514 // Custom assets take precedence over the configured ones 515 a, ok := conf.customAssets[t] 516 if ok { 517 return a.Path(), nil 518 } 519 520 // We could not find a custom asset for the given type, let's 521 // fall back to the configured ones. 522 switch t { 523 case types.KernelAsset: 524 return conf.KernelPath, nil 525 case types.ImageAsset: 526 return conf.ImagePath, nil 527 case types.InitrdAsset: 528 return conf.InitrdPath, nil 529 case types.HypervisorAsset: 530 return conf.HypervisorPath, nil 531 case types.HypervisorCtlAsset: 532 return conf.HypervisorCtlPath, nil 533 case types.JailerAsset: 534 return conf.JailerPath, nil 535 case types.FirmwareAsset: 536 return conf.FirmwarePath, nil 537 default: 538 return "", fmt.Errorf("Unknown asset type %v", t) 539 } 540 } 541 542 func (conf *HypervisorConfig) isCustomAsset(t types.AssetType) bool { 543 _, ok := conf.customAssets[t] 544 return ok 545 } 546 547 // KernelAssetPath returns the guest kernel path 548 func (conf *HypervisorConfig) KernelAssetPath() (string, error) { 549 return conf.assetPath(types.KernelAsset) 550 } 551 552 // CustomKernelAsset returns true if the kernel asset is a custom one, false otherwise. 553 func (conf *HypervisorConfig) CustomKernelAsset() bool { 554 return conf.isCustomAsset(types.KernelAsset) 555 } 556 557 // ImageAssetPath returns the guest image path 558 func (conf *HypervisorConfig) ImageAssetPath() (string, error) { 559 return conf.assetPath(types.ImageAsset) 560 } 561 562 // CustomImageAsset returns true if the image asset is a custom one, false otherwise. 563 func (conf *HypervisorConfig) CustomImageAsset() bool { 564 return conf.isCustomAsset(types.ImageAsset) 565 } 566 567 // InitrdAssetPath returns the guest initrd path 568 func (conf *HypervisorConfig) InitrdAssetPath() (string, error) { 569 return conf.assetPath(types.InitrdAsset) 570 } 571 572 // CustomInitrdAsset returns true if the initrd asset is a custom one, false otherwise. 573 func (conf *HypervisorConfig) CustomInitrdAsset() bool { 574 return conf.isCustomAsset(types.InitrdAsset) 575 } 576 577 // HypervisorAssetPath returns the VM hypervisor path 578 func (conf *HypervisorConfig) HypervisorAssetPath() (string, error) { 579 return conf.assetPath(types.HypervisorAsset) 580 } 581 582 // HypervisorCtlAssetPath returns the VM hypervisor ctl path 583 func (conf *HypervisorConfig) HypervisorCtlAssetPath() (string, error) { 584 return conf.assetPath(types.HypervisorCtlAsset) 585 } 586 587 // JailerAssetPath returns the VM Jailer path 588 func (conf *HypervisorConfig) JailerAssetPath() (string, error) { 589 return conf.assetPath(types.JailerAsset) 590 } 591 592 // CustomHypervisorAsset returns true if the hypervisor asset is a custom one, false otherwise. 593 func (conf *HypervisorConfig) CustomHypervisorAsset() bool { 594 return conf.isCustomAsset(types.HypervisorAsset) 595 } 596 597 // FirmwareAssetPath returns the guest firmware path 598 func (conf *HypervisorConfig) FirmwareAssetPath() (string, error) { 599 return conf.assetPath(types.FirmwareAsset) 600 } 601 602 // CustomFirmwareAsset returns true if the firmware asset is a custom one, false otherwise. 603 func (conf *HypervisorConfig) CustomFirmwareAsset() bool { 604 return conf.isCustomAsset(types.FirmwareAsset) 605 } 606 607 func appendParam(params []Param, parameter string, value string) []Param { 608 return append(params, Param{parameter, value}) 609 } 610 611 // SerializeParams converts []Param to []string 612 func SerializeParams(params []Param, delim string) []string { 613 var parameters []string 614 615 for _, p := range params { 616 if p.Key == "" && p.Value == "" { 617 continue 618 } else if p.Key == "" { 619 parameters = append(parameters, fmt.Sprint(p.Value)) 620 } else if p.Value == "" { 621 parameters = append(parameters, fmt.Sprint(p.Key)) 622 } else if delim == "" { 623 parameters = append(parameters, fmt.Sprint(p.Key)) 624 parameters = append(parameters, fmt.Sprint(p.Value)) 625 } else { 626 parameters = append(parameters, fmt.Sprintf("%s%s%s", p.Key, delim, p.Value)) 627 } 628 } 629 630 return parameters 631 } 632 633 // DeserializeParams converts []string to []Param 634 func DeserializeParams(parameters []string) []Param { 635 var params []Param 636 637 for _, param := range parameters { 638 if param == "" { 639 continue 640 } 641 p := strings.SplitN(param, "=", 2) 642 if len(p) == 2 { 643 params = append(params, Param{Key: p[0], Value: p[1]}) 644 } else { 645 params = append(params, Param{Key: p[0], Value: ""}) 646 } 647 } 648 649 return params 650 } 651 652 func getHostMemorySizeKb(memInfoPath string) (uint64, error) { 653 f, err := os.Open(memInfoPath) 654 if err != nil { 655 return 0, err 656 } 657 defer f.Close() 658 659 scanner := bufio.NewScanner(f) 660 for scanner.Scan() { 661 // Expected format: ["MemTotal:", "1234", "kB"] 662 parts := strings.Fields(scanner.Text()) 663 664 // Sanity checks: Skip malformed entries. 665 if len(parts) < 3 || parts[0] != "MemTotal:" || parts[2] != "kB" { 666 continue 667 } 668 669 sizeKb, err := strconv.ParseUint(parts[1], 0, 64) 670 if err != nil { 671 continue 672 } 673 674 return sizeKb, nil 675 } 676 677 // Handle errors that may have occurred during the reading of the file. 678 if err := scanner.Err(); err != nil { 679 return 0, err 680 } 681 682 return 0, fmt.Errorf("unable get MemTotal from %s", memInfoPath) 683 } 684 685 // RunningOnVMM checks if the system is running inside a VM. 686 func RunningOnVMM(cpuInfoPath string) (bool, error) { 687 if runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" { 688 virtLog.Info("Unable to know if the system is running inside a VM") 689 return false, nil 690 } 691 692 flagsField := "flags" 693 694 f, err := os.Open(cpuInfoPath) 695 if err != nil { 696 return false, err 697 } 698 defer f.Close() 699 700 scanner := bufio.NewScanner(f) 701 for scanner.Scan() { 702 // Expected format: ["flags", ":", ...] or ["flags:", ...] 703 fields := strings.Fields(scanner.Text()) 704 if len(fields) < 2 { 705 continue 706 } 707 708 if !strings.HasPrefix(fields[0], flagsField) { 709 continue 710 } 711 712 for _, field := range fields[1:] { 713 if field == "hypervisor" { 714 return true, nil 715 } 716 } 717 718 // As long as we have been able to analyze the fields from 719 // "flags", there is no reason to check what comes next from 720 // /proc/cpuinfo, because we already know we are not running 721 // on a VMM. 722 return false, nil 723 } 724 725 if err := scanner.Err(); err != nil { 726 return false, err 727 } 728 729 return false, fmt.Errorf("Couldn't find %q from %q output", flagsField, cpuInfoPath) 730 } 731 732 func getHypervisorPid(h hypervisor) int { 733 pids := h.getPids() 734 if len(pids) == 0 { 735 return 0 736 } 737 return pids[0] 738 } 739 740 func generateVMSocket(id string, useVsock bool, vmStogarePath string) (interface{}, error) { 741 if useVsock { 742 vhostFd, contextID, err := utils.FindContextID() 743 if err != nil { 744 return nil, err 745 } 746 747 return types.VSock{ 748 VhostFd: vhostFd, 749 ContextID: contextID, 750 Port: uint32(vSockPort), 751 }, nil 752 } 753 754 path, err := utils.BuildSocketPath(filepath.Join(vmStogarePath, id), defaultSocketName) 755 if err != nil { 756 return nil, err 757 } 758 759 return types.Socket{ 760 DeviceID: defaultSocketDeviceID, 761 ID: defaultSocketID, 762 HostPath: path, 763 Name: defaultSocketChannelName, 764 }, nil 765 } 766 767 // hypervisor is the virtcontainers hypervisor interface. 768 // The default hypervisor implementation is Qemu. 769 type hypervisor interface { 770 createSandbox(ctx context.Context, id string, networkNS NetworkNamespace, hypervisorConfig *HypervisorConfig, stateful bool) error 771 startSandbox(timeout int) error 772 stopSandbox() error 773 pauseSandbox() error 774 saveSandbox() error 775 resumeSandbox() error 776 addDevice(devInfo interface{}, devType deviceType) error 777 hotplugAddDevice(devInfo interface{}, devType deviceType) (interface{}, error) 778 hotplugRemoveDevice(devInfo interface{}, devType deviceType) (interface{}, error) 779 resizeMemory(memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) 780 resizeVCPUs(vcpus uint32) (uint32, uint32, error) 781 getSandboxConsole(sandboxID string) (string, error) 782 disconnect() 783 capabilities() types.Capabilities 784 hypervisorConfig() HypervisorConfig 785 getThreadIDs() (vcpuThreadIDs, error) 786 cleanup() error 787 // getPids returns a slice of hypervisor related process ids. 788 // The hypervisor pid must be put at index 0. 789 getPids() []int 790 fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error 791 toGrpc() ([]byte, error) 792 check() error 793 794 save() persistapi.HypervisorState 795 load(persistapi.HypervisorState) 796 797 // generate the socket to communicate the host and guest 798 generateSocket(id string, useVsock bool) (interface{}, error) 799 }