mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-06 03:56:34 +00:00
Merge pull request #10239 from fidencio/topic/remove-acrn
acrn: Drop support
This commit is contained in:
commit
77c844da12
@ -50,7 +50,7 @@ We provide `Dragonball` Sandbox to enable built-in VMM by integrating VMM's func
|
|||||||
#### How To Support Async
|
#### How To Support Async
|
||||||
The kata-runtime is controlled by TOKIO_RUNTIME_WORKER_THREADS to run the OS thread, which is 2 threads by default. For TTRPC and container-related threads run in the `tokio` thread in a unified manner, and related dependencies need to be switched to Async, such as Timer, File, Netlink, etc. With the help of Async, we can easily support no-block I/O and timer. Currently, we only utilize Async for kata-runtime. The built-in VMM keeps the OS thread because it can ensure that the threads are controllable.
|
The kata-runtime is controlled by TOKIO_RUNTIME_WORKER_THREADS to run the OS thread, which is 2 threads by default. For TTRPC and container-related threads run in the `tokio` thread in a unified manner, and related dependencies need to be switched to Async, such as Timer, File, Netlink, etc. With the help of Async, we can easily support no-block I/O and timer. Currently, we only utilize Async for kata-runtime. The built-in VMM keeps the OS thread because it can ensure that the threads are controllable.
|
||||||
|
|
||||||
**For N tokio worker threads and M containers**
|
**For N `tokio` worker threads and M containers**
|
||||||
|
|
||||||
- Sync runtime(both OS thread and `tokio` task are OS thread but without `tokio` worker thread) OS thread number: 4 + 12*M
|
- Sync runtime(both OS thread and `tokio` task are OS thread but without `tokio` worker thread) OS thread number: 4 + 12*M
|
||||||
- Async runtime(only OS thread is OS thread) OS thread number: 2 + N
|
- Async runtime(only OS thread is OS thread) OS thread number: 2 + N
|
||||||
@ -103,7 +103,6 @@ In our case, there will be a variety of resources, and every resource has severa
|
|||||||
| `Cgroup V2` | | Stage 2 | 🚧 |
|
| `Cgroup V2` | | Stage 2 | 🚧 |
|
||||||
| Hypervisor | `Dragonball` | Stage 1 | 🚧 |
|
| Hypervisor | `Dragonball` | Stage 1 | 🚧 |
|
||||||
| | QEMU | Stage 2 | 🚫 |
|
| | QEMU | Stage 2 | 🚫 |
|
||||||
| | ACRN | Stage 3 | 🚫 |
|
|
||||||
| | Cloud Hypervisor | Stage 3 | 🚫 |
|
| | Cloud Hypervisor | Stage 3 | 🚫 |
|
||||||
| | Firecracker | Stage 3 | 🚫 |
|
| | Firecracker | Stage 3 | 🚫 |
|
||||||
|
|
||||||
@ -166,4 +165,4 @@ In our case, there will be a variety of resources, and every resource has severa
|
|||||||
|
|
||||||
- What is the security boundary for the monolithic / "Built-in VMM" case?
|
- What is the security boundary for the monolithic / "Built-in VMM" case?
|
||||||
|
|
||||||
It has the security boundary of virtualization. More details will be provided in next stage.
|
It has the security boundary of virtualization. More details will be provided in next stage.
|
||||||
|
@ -20,12 +20,6 @@
|
|||||||
for the VM rootfs. Refer to the following guide for additional configuration
|
for the VM rootfs. Refer to the following guide for additional configuration
|
||||||
steps:
|
steps:
|
||||||
- [Setup Kata containers with `firecracker`](how-to-use-kata-containers-with-firecracker.md)
|
- [Setup Kata containers with `firecracker`](how-to-use-kata-containers-with-firecracker.md)
|
||||||
- `ACRN`
|
|
||||||
|
|
||||||
While `qemu` , `cloud-hypervisor` and `firecracker` work out of the box with installation of Kata,
|
|
||||||
some additional configuration is needed in case of `ACRN`.
|
|
||||||
Refer to the following guides for additional configuration steps:
|
|
||||||
- [Kata Containers with ACRN Hypervisor](how-to-use-kata-containers-with-acrn.md)
|
|
||||||
|
|
||||||
## Confidential Containers Policy
|
## Confidential Containers Policy
|
||||||
|
|
||||||
@ -52,4 +46,4 @@
|
|||||||
- [How to use EROFS to build rootfs in Kata Containers](how-to-use-erofs-build-rootfs.md)
|
- [How to use EROFS to build rootfs in Kata Containers](how-to-use-erofs-build-rootfs.md)
|
||||||
- [How to run Kata Containers with kinds of Block Volumes](how-to-run-kata-containers-with-kinds-of-Block-Volumes.md)
|
- [How to run Kata Containers with kinds of Block Volumes](how-to-run-kata-containers-with-kinds-of-Block-Volumes.md)
|
||||||
- [How to use the Kata Agent Policy](how-to-use-the-kata-agent-policy.md)
|
- [How to use the Kata Agent Policy](how-to-use-the-kata-agent-policy.md)
|
||||||
- [How to pull images in the guest](how-to-pull-images-in-guest-with-kata.md)
|
- [How to pull images in the guest](how-to-pull-images-in-guest-with-kata.md)
|
||||||
|
@ -46,7 +46,6 @@ There are several kinds of Kata configurations and they are listed below.
|
|||||||
| `io.katacontainers.config.hypervisor.block_device_cache_set` | `boolean` | cache-related options will be set to block devices or not |
|
| `io.katacontainers.config.hypervisor.block_device_cache_set` | `boolean` | cache-related options will be set to block devices or not |
|
||||||
| `io.katacontainers.config.hypervisor.block_device_driver` | string | the driver to be used for block device, valid values are `virtio-blk`, `virtio-scsi`, `nvdimm`|
|
| `io.katacontainers.config.hypervisor.block_device_driver` | string | the driver to be used for block device, valid values are `virtio-blk`, `virtio-scsi`, `nvdimm`|
|
||||||
| `io.katacontainers.config.hypervisor.cpu_features` | `string` | Comma-separated list of CPU features to pass to the CPU (QEMU) |
|
| `io.katacontainers.config.hypervisor.cpu_features` | `string` | Comma-separated list of CPU features to pass to the CPU (QEMU) |
|
||||||
| `io.katacontainers.config.hypervisor.ctlpath` (R) | `string` | Path to the `acrnctl` binary for the ACRN hypervisor |
|
|
||||||
| `io.katacontainers.config.hypervisor.default_max_vcpus` | uint32| the maximum number of vCPUs allocated for the VM by the hypervisor |
|
| `io.katacontainers.config.hypervisor.default_max_vcpus` | uint32| the maximum number of vCPUs allocated for the VM by the hypervisor |
|
||||||
| `io.katacontainers.config.hypervisor.default_memory` | uint32| the memory assigned for a VM by the hypervisor in `MiB` |
|
| `io.katacontainers.config.hypervisor.default_memory` | uint32| the memory assigned for a VM by the hypervisor in `MiB` |
|
||||||
| `io.katacontainers.config.hypervisor.default_vcpus` | float32| the default vCPUs assigned for a VM by the hypervisor |
|
| `io.katacontainers.config.hypervisor.default_vcpus` | float32| the default vCPUs assigned for a VM by the hypervisor |
|
||||||
@ -209,7 +208,6 @@ the configuration entry:
|
|||||||
|
|
||||||
| Key | Config file entry | Comments |
|
| Key | Config file entry | Comments |
|
||||||
|-------| ----- | ----- |
|
|-------| ----- | ----- |
|
||||||
| `ctlpath` | `valid_ctlpaths` | Valid paths for `acrnctl` binary |
|
|
||||||
| `entropy_source` | `valid_entropy_sources` | Valid entropy sources, e.g. `/dev/random` |
|
| `entropy_source` | `valid_entropy_sources` | Valid entropy sources, e.g. `/dev/random` |
|
||||||
| `file_mem_backend` | `valid_file_mem_backends` | Valid locations for the file-based memory backend root directory |
|
| `file_mem_backend` | `valid_file_mem_backends` | Valid locations for the file-based memory backend root directory |
|
||||||
| `jailer_path` | `valid_jailer_paths`| Valid paths for the jailer constraining the container VM (Firecracker) |
|
| `jailer_path` | `valid_jailer_paths`| Valid paths for the jailer constraining the container VM (Firecracker) |
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
# Kata Containers with ACRN
|
|
||||||
|
|
||||||
This document provides an overview on how to run Kata containers with ACRN hypervisor and device model.
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
ACRN is a flexible, lightweight Type-1 reference hypervisor built with real-time and safety-criticality in mind. ACRN uses an open source platform making it optimized to streamline embedded development.
|
|
||||||
|
|
||||||
Some of the key features being:
|
|
||||||
|
|
||||||
- Small footprint - Approx. 25K lines of code (LOC).
|
|
||||||
- Real Time - Low latency, faster boot time, improves overall responsiveness with hardware.
|
|
||||||
- Adaptability - Multi-OS support for guest operating systems like Linux, Android, RTOSes.
|
|
||||||
- Rich I/O mediators - Allows sharing of various I/O devices across VMs.
|
|
||||||
- Optimized for a variety of IoT (Internet of Things) and embedded device solutions.
|
|
||||||
|
|
||||||
Please refer to ACRN [documentation](https://projectacrn.github.io/latest/index.html) for more details on ACRN hypervisor and device model.
|
|
||||||
|
|
||||||
## Pre-requisites
|
|
||||||
|
|
||||||
This document requires the presence of the ACRN hypervisor and Kata Containers on your system. Install using the instructions available through the following links:
|
|
||||||
|
|
||||||
- ACRN supported [Hardware](https://projectacrn.github.io/latest/hardware.html#supported-hardware).
|
|
||||||
> **Note:** Please make sure to have a minimum of 4 logical processors (HT) or cores.
|
|
||||||
- ACRN [software](https://projectacrn.github.io/latest/tutorials/run_kata_containers.html) setup.
|
|
||||||
- For networking, ACRN supports either MACVTAP or TAP. If MACVTAP is not enabled in the Service OS, please follow the below steps to update the kernel:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ git clone https://github.com/projectacrn/acrn-kernel.git
|
|
||||||
$ cd acrn-kernel
|
|
||||||
$ cp kernel_config_sos .config
|
|
||||||
$ sed -i "s/# CONFIG_MACVLAN is not set/CONFIG_MACVLAN=y/" .config
|
|
||||||
$ sed -i '$ i CONFIG_MACVTAP=y' .config
|
|
||||||
$ make clean && make olddefconfig && make && sudo make modules_install INSTALL_MOD_PATH=out/
|
|
||||||
```
|
|
||||||
Login into Service OS and update the kernel with MACVTAP support:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ sudo mount /dev/sda1 /mnt
|
|
||||||
$ sudo scp -r <user name>@<host address>:<your workspace>/acrn-kernel/arch/x86/boot/bzImage /mnt/EFI/org.clearlinux/
|
|
||||||
$ sudo scp -r <user name>@<host address>:<your workspace>/acrn-kernel/out/lib/modules/* /lib/modules/
|
|
||||||
$ conf_file=$(sed -n '$ s/default //p' /mnt/loader/loader.conf).conf
|
|
||||||
$ kernel_img=$(sed -n 2p /mnt/loader/entries/$conf_file | cut -d'/' -f4)
|
|
||||||
$ sudo sed -i "s/$kernel_img/bzImage/g" /mnt/loader/entries/$conf_file
|
|
||||||
$ sync && sudo umount /mnt && sudo reboot
|
|
||||||
```
|
|
||||||
- Kata Containers installation: Automated installation does not seem to be supported for Clear Linux, so please use [manual installation](../Developer-Guide.md) steps.
|
|
||||||
|
|
||||||
> **Note:** Create rootfs image and not initrd image.
|
|
||||||
|
|
||||||
In order to run Kata with ACRN, your container stack must provide block-based storage, such as device-mapper.
|
|
||||||
|
|
||||||
> **Note:** Currently, by design you can only launch one VM from Kata Containers using ACRN hypervisor (SDC scenario). Based on feedback from community we can increase number of VMs.
|
|
||||||
|
|
||||||
## Configure Docker
|
|
||||||
|
|
||||||
To configure Docker for device-mapper and Kata,
|
|
||||||
|
|
||||||
1. Stop Docker daemon if it is already running.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ sudo systemctl stop docker
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Set `/etc/docker/daemon.json` with the following contents.
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"storage-driver": "devicemapper"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Restart docker.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ sudo systemctl daemon-reload
|
|
||||||
$ sudo systemctl restart docker
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Configure [Docker](../Developer-Guide.md#update-the-docker-systemd-unit-file) to use `kata-runtime`.
|
|
||||||
|
|
||||||
## Configure Kata Containers with ACRN
|
|
||||||
|
|
||||||
To configure Kata Containers with ACRN, copy the generated `configuration-acrn.toml` file when building the `kata-runtime` to either `/etc/kata-containers/configuration.toml` or `/usr/share/defaults/kata-containers/configuration.toml`.
|
|
||||||
|
|
||||||
The following command shows full paths to the `configuration.toml` files that the runtime loads. It will use the first path that exists. (Please make sure the kernel and image paths are set correctly in the `configuration.toml` file)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ sudo kata-runtime --show-default-config-paths
|
|
||||||
```
|
|
||||||
|
|
||||||
>**Warning:** Please offline CPUs using [this](offline_cpu.sh) script, else VM launches will fail.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ sudo ./offline_cpu.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Start an ACRN based Kata Container,
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ sudo docker run -ti --runtime=kata-runtime busybox sh
|
|
||||||
```
|
|
||||||
|
|
||||||
You will see ACRN(`acrn-dm`) is now running on your system, as well as a `kata-shim`. You should obtain an interactive shell prompt. Verify that all the Kata processes terminate once you exit the container.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ps -ef | grep -E "kata|acrn"
|
|
||||||
```
|
|
||||||
|
|
||||||
Validate ACRN hypervisor by using `kata-runtime kata-env`,
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ kata-runtime kata-env | awk -v RS= '/\[Hypervisor\]/'
|
|
||||||
[Hypervisor]
|
|
||||||
MachineType = ""
|
|
||||||
Version = "DM version is: 1.2-unstable-254577a6-dirty (daily tag:acrn-2019w27.4-140000p)
|
|
||||||
Path = "/usr/bin/acrn-dm"
|
|
||||||
BlockDeviceDriver = "virtio-blk"
|
|
||||||
EntropySource = "/dev/urandom"
|
|
||||||
Msize9p = 0
|
|
||||||
MemorySlots = 10
|
|
||||||
Debug = false
|
|
||||||
UseVSock = false
|
|
||||||
SharedFS = ""
|
|
||||||
```
|
|
@ -18,7 +18,6 @@ for i in $(ls -d /sys/devices/system/cpu/cpu[1-9]*); do
|
|||||||
echo 0 > $i/online
|
echo 0 > $i/online
|
||||||
online=`cat $i/online`
|
online=`cat $i/online`
|
||||||
done
|
done
|
||||||
echo $idx > /sys/class/vhm/acrn_vhm/offline_cpu
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ which hypervisors you may wish to investigate further.
|
|||||||
|
|
||||||
| Hypervisor | Written in | Architectures | Type |
|
| Hypervisor | Written in | Architectures | Type |
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|[ACRN] | C | `x86_64` | Type 1 (bare metal) |
|
|
||||||
|[Cloud Hypervisor] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) |
|
|[Cloud Hypervisor] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) |
|
||||||
|[Firecracker] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) |
|
|[Firecracker] | rust | `aarch64`, `x86_64` | Type 2 ([KVM]) |
|
||||||
|[QEMU] | C | all | Type 2 ([KVM]) | `configuration-qemu.toml` |
|
|[QEMU] | C | all | Type 2 ([KVM]) | `configuration-qemu.toml` |
|
||||||
@ -38,7 +37,6 @@ the hypervisors:
|
|||||||
|
|
||||||
| Hypervisor | Summary | Features | Limitations | Container Creation speed | Memory density | Use cases | Comment |
|
| Hypervisor | Summary | Features | Limitations | Container Creation speed | Memory density | Use cases | Comment |
|
||||||
|-|-|-|-|-|-|-|-|
|
|-|-|-|-|-|-|-|-|
|
||||||
|[ACRN] | Safety critical and real-time workloads | | | excellent | excellent | Embedded and IOT systems | For advanced users |
|
|
||||||
|[Cloud Hypervisor] | Low latency, small memory footprint, small attack surface | Minimal | | excellent | excellent | High performance modern cloud workloads | |
|
|[Cloud Hypervisor] | Low latency, small memory footprint, small attack surface | Minimal | | excellent | excellent | High performance modern cloud workloads | |
|
||||||
|[Firecracker] | Very slimline | Extremely minimal | Doesn't support all device types | excellent | excellent | Serverless / FaaS | |
|
|[Firecracker] | Very slimline | Extremely minimal | Doesn't support all device types | excellent | excellent | Serverless / FaaS | |
|
||||||
|[QEMU] | Lots of features | Lots | | good | good | Good option for most users | |
|
|[QEMU] | Lots of features | Lots | | good | good | Good option for most users | |
|
||||||
@ -57,7 +55,6 @@ are available, their default values and how each setting can be used.
|
|||||||
|
|
||||||
| Hypervisor | Golang runtime config file | golang runtime short name | golang runtime default | rust runtime config file | rust runtime short name | rust runtime default |
|
| Hypervisor | Golang runtime config file | golang runtime short name | golang runtime default | rust runtime config file | rust runtime short name | rust runtime default |
|
||||||
|-|-|-|-|-|-|-|
|
|-|-|-|-|-|-|-|
|
||||||
| [ACRN] | [`configuration-acrn.toml`](../src/runtime/config/configuration-acrn.toml.in) | `acrn` | | | | |
|
|
||||||
| [Cloud Hypervisor] | [`configuration-clh.toml`](../src/runtime/config/configuration-clh.toml.in) | `clh` | | [`configuration-cloud-hypervisor.toml`](../src/runtime-rs/config/configuration-cloud-hypervisor.toml.in) | `cloud-hypervisor` | |
|
| [Cloud Hypervisor] | [`configuration-clh.toml`](../src/runtime/config/configuration-clh.toml.in) | `clh` | | [`configuration-cloud-hypervisor.toml`](../src/runtime-rs/config/configuration-cloud-hypervisor.toml.in) | `cloud-hypervisor` | |
|
||||||
| [Firecracker] | [`configuration-fc.toml`](../src/runtime/config/configuration-fc.toml.in) | `fc` | | | | |
|
| [Firecracker] | [`configuration-fc.toml`](../src/runtime/config/configuration-fc.toml.in) | `fc` | | | | |
|
||||||
| [QEMU] | [`configuration-qemu.toml`](../src/runtime/config/configuration-qemu.toml.in) | `qemu` | yes | [`configuration-qemu.toml`](../src/runtime-rs/config/configuration-qemu-runtime-rs.toml.in) | `qemu` | |
|
| [QEMU] | [`configuration-qemu.toml`](../src/runtime/config/configuration-qemu.toml.in) | `qemu` | yes | [`configuration-qemu.toml`](../src/runtime-rs/config/configuration-qemu-runtime-rs.toml.in) | `qemu` | |
|
||||||
@ -93,10 +90,9 @@ are available, their default values and how each setting can be used.
|
|||||||
To switch the configured hypervisor, you only need to run a single command.
|
To switch the configured hypervisor, you only need to run a single command.
|
||||||
See [the `kata-manager` documentation](../utils/README.md#choose-a-hypervisor) for further details.
|
See [the `kata-manager` documentation](../utils/README.md#choose-a-hypervisor) for further details.
|
||||||
|
|
||||||
[ACRN]: https://projectacrn.org
|
|
||||||
[Cloud Hypervisor]: https://github.com/cloud-hypervisor/cloud-hypervisor
|
[Cloud Hypervisor]: https://github.com/cloud-hypervisor/cloud-hypervisor
|
||||||
[Firecracker]: https://github.com/firecracker-microvm/firecracker
|
[Firecracker]: https://github.com/firecracker-microvm/firecracker
|
||||||
[KVM]: https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine
|
[KVM]: https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine
|
||||||
[QEMU]: http://www.qemu-project.org
|
[QEMU]: http://www.qemu.org
|
||||||
[`Dragonball`]: https://github.com/kata-containers/kata-containers/blob/main/src/dragonball
|
[`Dragonball`]: https://github.com/kata-containers/kata-containers/blob/main/src/dragonball
|
||||||
[StratoVirt]: https://gitee.com/openeuler/stratovirt
|
[StratoVirt]: https://gitee.com/openeuler/stratovirt
|
||||||
|
@ -88,12 +88,6 @@ pub const KATA_ANNO_CFG_HYPERVISOR_PREFIX: &str = "io.katacontainers.config.hype
|
|||||||
pub const KATA_ANNO_CFG_HYPERVISOR_PATH: &str = "io.katacontainers.config.hypervisor.path";
|
pub const KATA_ANNO_CFG_HYPERVISOR_PATH: &str = "io.katacontainers.config.hypervisor.path";
|
||||||
/// A sandbox annotation for passing a container hypervisor binary SHA-512 hash value.
|
/// A sandbox annotation for passing a container hypervisor binary SHA-512 hash value.
|
||||||
pub const KATA_ANNO_CFG_HYPERVISOR_HASH: &str = "io.katacontainers.config.hypervisor.path_hash";
|
pub const KATA_ANNO_CFG_HYPERVISOR_HASH: &str = "io.katacontainers.config.hypervisor.path_hash";
|
||||||
/// A sandbox annotation for passing a per container path pointing at the hypervisor control binary
|
|
||||||
/// that will run the container VM.
|
|
||||||
pub const KATA_ANNO_CFG_HYPERVISOR_CTLPATH: &str = "io.katacontainers.config.hypervisor.ctlpath";
|
|
||||||
/// A sandbox annotation for passing a container hypervisor control binary SHA-512 hash value.
|
|
||||||
pub const KATA_ANNO_CFG_HYPERVISOR_CTLHASH: &str =
|
|
||||||
"io.katacontainers.config.hypervisor.hypervisorctl_hash";
|
|
||||||
/// A sandbox annotation for passing a per container path pointing at the jailer that will constrain
|
/// A sandbox annotation for passing a per container path pointing at the jailer that will constrain
|
||||||
/// the container VM.
|
/// the container VM.
|
||||||
pub const KATA_ANNO_CFG_HYPERVISOR_JAILER_PATH: &str =
|
pub const KATA_ANNO_CFG_HYPERVISOR_JAILER_PATH: &str =
|
||||||
@ -506,10 +500,6 @@ impl Annotation {
|
|||||||
hv.validate_hypervisor_path(value)?;
|
hv.validate_hypervisor_path(value)?;
|
||||||
hv.path = value.to_string();
|
hv.path = value.to_string();
|
||||||
}
|
}
|
||||||
KATA_ANNO_CFG_HYPERVISOR_CTLPATH => {
|
|
||||||
hv.validate_hypervisor_ctlpath(value)?;
|
|
||||||
hv.ctlpath = value.to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
KATA_ANNO_CFG_HYPERVISOR_JAILER_PATH => {
|
KATA_ANNO_CFG_HYPERVISOR_JAILER_PATH => {
|
||||||
hv.validate_jailer_path(value)?;
|
hv.validate_jailer_path(value)?;
|
||||||
|
@ -83,7 +83,6 @@ LOCALSTATEDIR := /var
|
|||||||
CONFIG_FILE = configuration.toml
|
CONFIG_FILE = configuration.toml
|
||||||
RUNTIMENAME := virt_container
|
RUNTIMENAME := virt_container
|
||||||
HYPERVISOR_DB = dragonball
|
HYPERVISOR_DB = dragonball
|
||||||
HYPERVISOR_ACRN = acrn
|
|
||||||
HYPERVISOR_FC = firecracker
|
HYPERVISOR_FC = firecracker
|
||||||
HYPERVISOR_QEMU = qemu
|
HYPERVISOR_QEMU = qemu
|
||||||
HYPERVISOR_CLH = cloud-hypervisor
|
HYPERVISOR_CLH = cloud-hypervisor
|
||||||
@ -92,7 +91,7 @@ HYPERVISOR_CLH = cloud-hypervisor
|
|||||||
DEFAULT_HYPERVISOR ?= $(HYPERVISOR_DB)
|
DEFAULT_HYPERVISOR ?= $(HYPERVISOR_DB)
|
||||||
|
|
||||||
##VAR HYPERVISOR=<hypervisor_name> List of hypervisors this build system can generate configuration for.
|
##VAR HYPERVISOR=<hypervisor_name> List of hypervisors this build system can generate configuration for.
|
||||||
HYPERVISORS := $(HYPERVISOR_DB) $(HYPERVISOR_ACRN) $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH)
|
HYPERVISORS := $(HYPERVISOR_DB) $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH)
|
||||||
|
|
||||||
CLHPATH := $(CLHBINDIR)/$(CLHCMD)
|
CLHPATH := $(CLHBINDIR)/$(CLHCMD)
|
||||||
CLHVALIDHYPERVISORPATHS := [\"$(CLHPATH)\"]
|
CLHVALIDHYPERVISORPATHS := [\"$(CLHPATH)\"]
|
||||||
@ -399,7 +398,6 @@ USER_VARS += SYSCONFDIR
|
|||||||
USER_VARS += DEFVCPUS
|
USER_VARS += DEFVCPUS
|
||||||
USER_VARS += DEFVCPUS_QEMU
|
USER_VARS += DEFVCPUS_QEMU
|
||||||
USER_VARS += DEFMAXVCPUS
|
USER_VARS += DEFMAXVCPUS
|
||||||
USER_VARS += DEFMAXVCPUS_ACRN
|
|
||||||
USER_VARS += DEFMAXVCPUS_DB
|
USER_VARS += DEFMAXVCPUS_DB
|
||||||
USER_VARS += DEFMAXVCPUS_QEMU
|
USER_VARS += DEFMAXVCPUS_QEMU
|
||||||
USER_VARS += DEFMEMSZ
|
USER_VARS += DEFMEMSZ
|
||||||
@ -647,9 +645,6 @@ ifneq (,$(findstring $(HYPERVISOR_CLH),$(KNOWN_HYPERVISORS)))
|
|||||||
endif
|
endif
|
||||||
ifneq (,$(findstring $(HYPERVISOR_FC),$(KNOWN_HYPERVISORS)))
|
ifneq (,$(findstring $(HYPERVISOR_FC),$(KNOWN_HYPERVISORS)))
|
||||||
@printf "\t$(HYPERVISOR_FC) hypervisor path (FCPATH) : %s\n" $(abspath $(FCPATH))
|
@printf "\t$(HYPERVISOR_FC) hypervisor path (FCPATH) : %s\n" $(abspath $(FCPATH))
|
||||||
endif
|
|
||||||
ifneq (,$(findstring $(HYPERVISOR_ACRN),$(KNOWN_HYPERVISORS)))
|
|
||||||
@printf "\t$(HYPERVISOR_ACRN) hypervisor path (ACRNPATH) : %s\n" $(abspath $(ACRNPATH))
|
|
||||||
endif
|
endif
|
||||||
@printf "\tassets path (PKGDATADIR) : %s\n" $(abspath $(PKGDATADIR))
|
@printf "\tassets path (PKGDATADIR) : %s\n" $(abspath $(PKGDATADIR))
|
||||||
@printf "\tshim path (PKGLIBEXECDIR) : %s\n" $(abspath $(PKGLIBEXECDIR))
|
@printf "\tshim path (PKGLIBEXECDIR) : %s\n" $(abspath $(PKGLIBEXECDIR))
|
||||||
|
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
||||||
pub struct HypervisorState {
|
pub struct HypervisorState {
|
||||||
// Type of hypervisor, E.g. dragonball/qemu/firecracker/acrn.
|
// Type of hypervisor, E.g. dragonball/qemu/firecracker.
|
||||||
pub hypervisor_type: String,
|
pub hypervisor_type: String,
|
||||||
pub pid: Option<i32>,
|
pub pid: Option<i32>,
|
||||||
pub uuid: String,
|
pub uuid: String,
|
||||||
|
@ -82,7 +82,6 @@ BINDIR := $(EXEC_PREFIX)/bin
|
|||||||
QEMUBINDIR := $(PREFIXDEPS)/bin
|
QEMUBINDIR := $(PREFIXDEPS)/bin
|
||||||
CLHBINDIR := $(PREFIXDEPS)/bin
|
CLHBINDIR := $(PREFIXDEPS)/bin
|
||||||
FCBINDIR := $(PREFIXDEPS)/bin
|
FCBINDIR := $(PREFIXDEPS)/bin
|
||||||
ACRNBINDIR := $(PREFIXDEPS)/bin
|
|
||||||
STRATOVIRTBINDIR := $(PREFIXDEPS)/bin
|
STRATOVIRTBINDIR := $(PREFIXDEPS)/bin
|
||||||
SYSCONFDIR := /etc
|
SYSCONFDIR := /etc
|
||||||
LOCALSTATEDIR := /var
|
LOCALSTATEDIR := /var
|
||||||
@ -99,7 +98,6 @@ RUNTIME_NAME = $(TARGET)
|
|||||||
GENERATED_FILES += $(COLLECT_SCRIPT)
|
GENERATED_FILES += $(COLLECT_SCRIPT)
|
||||||
GENERATED_VARS = \
|
GENERATED_VARS = \
|
||||||
VERSION \
|
VERSION \
|
||||||
CONFIG_ACRN_IN \
|
|
||||||
CONFIG_QEMU_IN \
|
CONFIG_QEMU_IN \
|
||||||
CONFIG_QEMU_COCO_DEV_IN \
|
CONFIG_QEMU_COCO_DEV_IN \
|
||||||
CONFIG_QEMU_NVIDIA_GPU_IN \
|
CONFIG_QEMU_NVIDIA_GPU_IN \
|
||||||
@ -159,7 +157,6 @@ KERNELTDXPARAMS += $(ROOTMEASURECONFIG)
|
|||||||
# Name of default configuration file the runtime will use.
|
# Name of default configuration file the runtime will use.
|
||||||
CONFIG_FILE = configuration.toml
|
CONFIG_FILE = configuration.toml
|
||||||
|
|
||||||
HYPERVISOR_ACRN = acrn
|
|
||||||
HYPERVISOR_FC = firecracker
|
HYPERVISOR_FC = firecracker
|
||||||
HYPERVISOR_QEMU = qemu
|
HYPERVISOR_QEMU = qemu
|
||||||
HYPERVISOR_CLH = cloud-hypervisor
|
HYPERVISOR_CLH = cloud-hypervisor
|
||||||
@ -170,7 +167,7 @@ HYPERVISOR_REMOTE = remote
|
|||||||
DEFAULT_HYPERVISOR ?= $(HYPERVISOR_QEMU)
|
DEFAULT_HYPERVISOR ?= $(HYPERVISOR_QEMU)
|
||||||
|
|
||||||
# List of hypervisors this build system can generate configuration for.
|
# List of hypervisors this build system can generate configuration for.
|
||||||
HYPERVISORS := $(HYPERVISOR_ACRN) $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH) $(HYPERVISOR_STRATOVIRT) $(HYPERVISOR_REMOTE)
|
HYPERVISORS := $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH) $(HYPERVISOR_STRATOVIRT) $(HYPERVISOR_REMOTE)
|
||||||
|
|
||||||
QEMUPATH := $(QEMUBINDIR)/$(QEMUCMD)
|
QEMUPATH := $(QEMUBINDIR)/$(QEMUCMD)
|
||||||
QEMUVALIDHYPERVISORPATHS := [\"$(QEMUPATH)\"]
|
QEMUVALIDHYPERVISORPATHS := [\"$(QEMUPATH)\"]
|
||||||
@ -193,11 +190,6 @@ FCVALIDHYPERVISORPATHS := [\"$(FCPATH)\"]
|
|||||||
FCJAILERPATH = $(FCBINDIR)/$(FCJAILERCMD)
|
FCJAILERPATH = $(FCBINDIR)/$(FCJAILERCMD)
|
||||||
FCVALIDJAILERPATHS = [\"$(FCJAILERPATH)\"]
|
FCVALIDJAILERPATHS = [\"$(FCJAILERPATH)\"]
|
||||||
|
|
||||||
ACRNPATH := $(ACRNBINDIR)/$(ACRNCMD)
|
|
||||||
ACRNVALIDHYPERVISORPATHS := [\"$(ACRNPATH)\"]
|
|
||||||
ACRNCTLPATH := $(ACRNBINDIR)/$(ACRNCTLCMD)
|
|
||||||
ACRNVALIDCTLPATHS := [\"$(ACRNCTLPATH)\"]
|
|
||||||
|
|
||||||
STRATOVIRTPATH = $(STRATOVIRTBINDIR)/$(STRATOVIRTCMD)
|
STRATOVIRTPATH = $(STRATOVIRTBINDIR)/$(STRATOVIRTCMD)
|
||||||
STRATOVIRTVALIDHYPERVISORPATHS := [\"$(STRATOVIRTPATH)\"]
|
STRATOVIRTVALIDHYPERVISORPATHS := [\"$(STRATOVIRTPATH)\"]
|
||||||
|
|
||||||
@ -538,30 +530,6 @@ ifneq (,$(FCCMD))
|
|||||||
KERNELPATH_FC = $(KERNELDIR)/$(KERNEL_NAME_FC)
|
KERNELPATH_FC = $(KERNELDIR)/$(KERNEL_NAME_FC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(ACRNCMD))
|
|
||||||
KNOWN_HYPERVISORS += $(HYPERVISOR_ACRN)
|
|
||||||
|
|
||||||
CONFIG_FILE_ACRN = configuration-acrn.toml
|
|
||||||
CONFIG_ACRN = config/$(CONFIG_FILE_ACRN)
|
|
||||||
CONFIG_ACRN_IN = $(CONFIG_ACRN).in
|
|
||||||
|
|
||||||
CONFIG_PATH_ACRN = $(abspath $(CONFDIR)/$(CONFIG_FILE_ACRN))
|
|
||||||
CONFIG_PATHS += $(CONFIG_PATH_ACRN)
|
|
||||||
|
|
||||||
SYSCONFIG_ACRN = $(abspath $(SYSCONFDIR)/$(CONFIG_FILE_ACRN))
|
|
||||||
SYSCONFIG_PATHS += $(SYSCONFIG_ACRN)
|
|
||||||
|
|
||||||
CONFIGS += $(CONFIG_ACRN)
|
|
||||||
|
|
||||||
# acrn-specific options (all should be suffixed by "_ACRN")
|
|
||||||
DEFMAXVCPUS_ACRN := 1
|
|
||||||
DEFBLOCKSTORAGEDRIVER_ACRN := virtio-blk
|
|
||||||
DEFNETWORKMODEL_ACRN := macvtap
|
|
||||||
KERNELTYPE_ACRN = compressed
|
|
||||||
KERNEL_NAME_ACRN = $(call MAKE_KERNEL_NAME,$(KERNELTYPE_ACRN))
|
|
||||||
KERNELPATH_ACRN = $(KERNELDIR)/$(KERNEL_NAME_ACRN)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (,$(KNOWN_HYPERVISORS))
|
ifeq (,$(KNOWN_HYPERVISORS))
|
||||||
$(error "ERROR: No hypervisors known for architecture $(ARCH) (looked for: $(HYPERVISORS))")
|
$(error "ERROR: No hypervisors known for architecture $(ARCH) (looked for: $(HYPERVISORS))")
|
||||||
endif
|
endif
|
||||||
@ -586,10 +554,6 @@ ifeq ($(DEFAULT_HYPERVISOR),$(HYPERVISOR_FC))
|
|||||||
DEFAULT_HYPERVISOR_CONFIG = $(CONFIG_FILE_FC)
|
DEFAULT_HYPERVISOR_CONFIG = $(CONFIG_FILE_FC)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(DEFAULT_HYPERVISOR),$(HYPERVISOR_ACRN))
|
|
||||||
DEFAULT_HYPERVISOR_CONFIG = $(CONFIG_FILE_ACRN)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEFAULT_HYPERVISOR),$(HYPERVISOR_CLH))
|
ifeq ($(DEFAULT_HYPERVISOR),$(HYPERVISOR_CLH))
|
||||||
DEFAULT_HYPERVISOR_CONFIG = $(CONFIG_FILE_CLH)
|
DEFAULT_HYPERVISOR_CONFIG = $(CONFIG_FILE_CLH)
|
||||||
endif
|
endif
|
||||||
@ -609,7 +573,6 @@ SHAREDIR := $(SHAREDIR)
|
|||||||
# list of variables the user may wish to override
|
# list of variables the user may wish to override
|
||||||
USER_VARS += ARCH
|
USER_VARS += ARCH
|
||||||
USER_VARS += BINDIR
|
USER_VARS += BINDIR
|
||||||
USER_VARS += CONFIG_ACRN_IN
|
|
||||||
USER_VARS += CONFIG_CLH_IN
|
USER_VARS += CONFIG_CLH_IN
|
||||||
USER_VARS += CONFIG_FC_IN
|
USER_VARS += CONFIG_FC_IN
|
||||||
USER_VARS += CONFIG_STRATOVIRT_IN
|
USER_VARS += CONFIG_STRATOVIRT_IN
|
||||||
@ -618,12 +581,6 @@ USER_VARS += CONFIG_QEMU_IN
|
|||||||
USER_VARS += CONFIG_REMOTE_IN
|
USER_VARS += CONFIG_REMOTE_IN
|
||||||
USER_VARS += DESTDIR
|
USER_VARS += DESTDIR
|
||||||
USER_VARS += DEFAULT_HYPERVISOR
|
USER_VARS += DEFAULT_HYPERVISOR
|
||||||
USER_VARS += ACRNCMD
|
|
||||||
USER_VARS += ACRNCTLCMD
|
|
||||||
USER_VARS += ACRNPATH
|
|
||||||
USER_VARS += ACRNVALIDHYPERVISORPATHS
|
|
||||||
USER_VARS += ACRNCTLPATH
|
|
||||||
USER_VARS += ACRNVALIDCTLPATHS
|
|
||||||
USER_VARS += CLHPATH
|
USER_VARS += CLHPATH
|
||||||
USER_VARS += CLHVALIDHYPERVISORPATHS
|
USER_VARS += CLHVALIDHYPERVISORPATHS
|
||||||
USER_VARS += FIRMWAREPATH_CLH
|
USER_VARS += FIRMWAREPATH_CLH
|
||||||
@ -667,9 +624,7 @@ USER_VARS += MACHINETYPE
|
|||||||
USER_VARS += KERNELDIR
|
USER_VARS += KERNELDIR
|
||||||
USER_VARS += KERNELTYPE
|
USER_VARS += KERNELTYPE
|
||||||
USER_VARS += KERNELTYPE_FC
|
USER_VARS += KERNELTYPE_FC
|
||||||
USER_VARS += KERNELTYPE_ACRN
|
|
||||||
USER_VARS += KERNELTYPE_CLH
|
USER_VARS += KERNELTYPE_CLH
|
||||||
USER_VARS += KERNELPATH_ACRN
|
|
||||||
USER_VARS += KERNELPATH
|
USER_VARS += KERNELPATH
|
||||||
USER_VARS += KERNELCONFIDENTIALPATH
|
USER_VARS += KERNELCONFIDENTIALPATH
|
||||||
USER_VARS += KERNELSEPATH
|
USER_VARS += KERNELSEPATH
|
||||||
@ -722,12 +677,10 @@ USER_VARS += SHAREDIR
|
|||||||
USER_VARS += SYSCONFDIR
|
USER_VARS += SYSCONFDIR
|
||||||
USER_VARS += DEFVCPUS
|
USER_VARS += DEFVCPUS
|
||||||
USER_VARS += DEFMAXVCPUS
|
USER_VARS += DEFMAXVCPUS
|
||||||
USER_VARS += DEFMAXVCPUS_ACRN
|
|
||||||
USER_VARS += DEFMEMSZ
|
USER_VARS += DEFMEMSZ
|
||||||
USER_VARS += DEFMEMSLOTS
|
USER_VARS += DEFMEMSLOTS
|
||||||
USER_VARS += DEFMAXMEMSZ
|
USER_VARS += DEFMAXMEMSZ
|
||||||
USER_VARS += DEFBRIDGES
|
USER_VARS += DEFBRIDGES
|
||||||
USER_VARS += DEFNETWORKMODEL_ACRN
|
|
||||||
USER_VARS += DEFNETWORKMODEL_CLH
|
USER_VARS += DEFNETWORKMODEL_CLH
|
||||||
USER_VARS += DEFNETWORKMODEL_FC
|
USER_VARS += DEFNETWORKMODEL_FC
|
||||||
USER_VARS += DEFNETWORKMODEL_QEMU
|
USER_VARS += DEFNETWORKMODEL_QEMU
|
||||||
@ -739,7 +692,6 @@ USER_VARS += DEFDISABLEGUESTSELINUX
|
|||||||
USER_VARS += DEFGUESTSELINUXLABEL
|
USER_VARS += DEFGUESTSELINUXLABEL
|
||||||
USER_VARS += DEFAULTEXPFEATURES
|
USER_VARS += DEFAULTEXPFEATURES
|
||||||
USER_VARS += DEFDISABLEBLOCK
|
USER_VARS += DEFDISABLEBLOCK
|
||||||
USER_VARS += DEFBLOCKSTORAGEDRIVER_ACRN
|
|
||||||
USER_VARS += DEFBLOCKSTORAGEDRIVER_FC
|
USER_VARS += DEFBLOCKSTORAGEDRIVER_FC
|
||||||
USER_VARS += DEFBLOCKSTORAGEDRIVER_QEMU
|
USER_VARS += DEFBLOCKSTORAGEDRIVER_QEMU
|
||||||
USER_VARS += DEFBLOCKSTORAGEDRIVER_STRATOVIRT
|
USER_VARS += DEFBLOCKSTORAGEDRIVER_STRATOVIRT
|
||||||
@ -1106,9 +1058,6 @@ endif
|
|||||||
ifneq (,$(findstring $(HYPERVISOR_FC),$(KNOWN_HYPERVISORS)))
|
ifneq (,$(findstring $(HYPERVISOR_FC),$(KNOWN_HYPERVISORS)))
|
||||||
@printf "\t$(HYPERVISOR_FC) hypervisor path (FCPATH) : %s\n" $(abspath $(FCPATH))
|
@printf "\t$(HYPERVISOR_FC) hypervisor path (FCPATH) : %s\n" $(abspath $(FCPATH))
|
||||||
endif
|
endif
|
||||||
ifneq (,$(findstring $(HYPERVISOR_ACRN),$(KNOWN_HYPERVISORS)))
|
|
||||||
@printf "\t$(HYPERVISOR_ACRN) hypervisor path (ACRNPATH) : %s\n" $(abspath $(ACRNPATH))
|
|
||||||
endif
|
|
||||||
ifneq (,$(findstring $(HYPERVISOR_STRATOVIRT),$(KNOWN_HYPERVISORS)))
|
ifneq (,$(findstring $(HYPERVISOR_STRATOVIRT),$(KNOWN_HYPERVISORS)))
|
||||||
@printf "\t$(HYPERVISOR_STRATOVIRT) hypervisor path (STRATOVIRTPATH) : %s\n" $(abspath $(STRATOVIRTPATH))
|
@printf "\t$(HYPERVISOR_STRATOVIRT) hypervisor path (STRATOVIRTPATH) : %s\n" $(abspath $(STRATOVIRTPATH))
|
||||||
endif
|
endif
|
||||||
|
@ -20,10 +20,6 @@ FCCMD := firecracker
|
|||||||
# Firecracker's jailer binary name
|
# Firecracker's jailer binary name
|
||||||
FCJAILERCMD := jailer
|
FCJAILERCMD := jailer
|
||||||
|
|
||||||
#ACRN binary name
|
|
||||||
ACRNCMD := acrn-dm
|
|
||||||
ACRNCTLCMD := acrnctl
|
|
||||||
|
|
||||||
# cloud-hypervisor binary name
|
# cloud-hypervisor binary name
|
||||||
CLHCMD := cloud-hypervisor
|
CLHCMD := cloud-hypervisor
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -45,41 +43,6 @@ const (
|
|||||||
cpuTypeUnknown = -1
|
cpuTypeUnknown = -1
|
||||||
)
|
)
|
||||||
|
|
||||||
const acrnDevice = "/dev/acrn_hsm"
|
|
||||||
|
|
||||||
// ioctl_ACRN_CREATE_VM is the IOCTL to create VM in ACRN.
|
|
||||||
// Current Linux mainstream kernel doesn't have support for ACRN.
|
|
||||||
// Due to this several macros are not defined in Linux headers.
|
|
||||||
// Until the support is available, directly use the value instead
|
|
||||||
// of macros.
|
|
||||||
// https://github.com/kata-containers/runtime/issues/1784
|
|
||||||
const ioctl_ACRN_CREATE_VM = 0xC030A210 //nolint
|
|
||||||
const ioctl_ACRN_PAUSE_VM = 0xA213 //nolint
|
|
||||||
const ioctl_ACRN_DESTROY_VM = 0xA211 //nolint
|
|
||||||
|
|
||||||
type acrn_vm_creation struct { //nolint
|
|
||||||
vmid uint16 //nolint
|
|
||||||
reserved0 uint16 //nolint
|
|
||||||
vcpu_num uint16 //nolint
|
|
||||||
reserved1 uint16 //nolint
|
|
||||||
name [16]uint8
|
|
||||||
vm_flag uint64 //nolint
|
|
||||||
ioreq_buf uint64 //nolint
|
|
||||||
cpu_affinity uint64 //nolint
|
|
||||||
}
|
|
||||||
|
|
||||||
var io_request_page [4096]byte
|
|
||||||
|
|
||||||
type acrn_io_request struct { // nolint
|
|
||||||
io_type uint32 // nolint
|
|
||||||
completion_polling uint32 // nolint
|
|
||||||
reserved0 [14]uint32 // nolint
|
|
||||||
data [8]uint64 // nolint
|
|
||||||
reserved1 uint32 // nolint
|
|
||||||
kernel_handled uint32 // nolint
|
|
||||||
processed uint32 // nolint
|
|
||||||
}
|
|
||||||
|
|
||||||
// cpuType save the CPU type
|
// cpuType save the CPU type
|
||||||
var cpuType int
|
var cpuType int
|
||||||
|
|
||||||
@ -155,28 +118,6 @@ func setCPUtype(hypervisorType vc.HypervisorType) error {
|
|||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
case vc.AcrnHypervisor:
|
|
||||||
archRequiredCPUFlags = map[string]string{
|
|
||||||
cpuFlagLM: "64Bit CPU",
|
|
||||||
cpuFlagSSE4_1: "SSE4.1",
|
|
||||||
}
|
|
||||||
archRequiredCPUAttribs = map[string]string{
|
|
||||||
archGenuineIntel: "Intel Architecture CPU",
|
|
||||||
}
|
|
||||||
archRequiredKernelModules = map[string]kernelModule{
|
|
||||||
kernelModvhost: {
|
|
||||||
desc: msgKernelVirtio,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
kernelModvhostnet: {
|
|
||||||
desc: msgKernelVirtioNet,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
kernelModvhostvsock: {
|
|
||||||
desc: msgKernelVirtioVhostVsock,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
case vc.MockHypervisor:
|
case vc.MockHypervisor:
|
||||||
archRequiredCPUFlags = map[string]string{
|
archRequiredCPUFlags = map[string]string{
|
||||||
cpuFlagVMX: "Virtualization support",
|
cpuFlagVMX: "Virtualization support",
|
||||||
@ -249,68 +190,6 @@ func kvmIsUsable() error {
|
|||||||
return genericKvmIsUsable()
|
return genericKvmIsUsable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// acrnIsUsable determines if it will be possible to create a full virtual machine
|
|
||||||
// by creating a minimal VM and then deleting it.
|
|
||||||
func acrnIsUsable() error {
|
|
||||||
flags := syscall.O_RDWR | syscall.O_CLOEXEC
|
|
||||||
|
|
||||||
f, err := syscall.Open(acrnDevice, flags, 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer syscall.Close(f)
|
|
||||||
kataLog.WithField("device", acrnDevice).Info("device available")
|
|
||||||
|
|
||||||
var createVM acrn_vm_creation
|
|
||||||
copy(createVM.name[:], "KataACRNVM")
|
|
||||||
ioreq_buf := (*acrn_io_request)(unsafe.Pointer(&io_request_page))
|
|
||||||
createVM.ioreq_buf = uint64(uintptr(unsafe.Pointer(ioreq_buf)))
|
|
||||||
|
|
||||||
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
|
||||||
uintptr(f),
|
|
||||||
uintptr(ioctl_ACRN_CREATE_VM),
|
|
||||||
uintptr(unsafe.Pointer(&createVM)))
|
|
||||||
if ret != 0 || errno != 0 {
|
|
||||||
if errno == syscall.EBUSY {
|
|
||||||
kataLog.WithField("reason", "another hypervisor running").Error("cannot create VM")
|
|
||||||
}
|
|
||||||
kataLog.WithFields(logrus.Fields{
|
|
||||||
"ret": ret,
|
|
||||||
"errno": errno,
|
|
||||||
"VM_name": createVM.name,
|
|
||||||
}).Info("Create VM Error")
|
|
||||||
return errno
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, _, errno = syscall.Syscall(syscall.SYS_IOCTL,
|
|
||||||
uintptr(f),
|
|
||||||
uintptr(ioctl_ACRN_PAUSE_VM),
|
|
||||||
0)
|
|
||||||
if ret != 0 || errno != 0 {
|
|
||||||
kataLog.WithFields(logrus.Fields{
|
|
||||||
"ret": ret,
|
|
||||||
"errno": errno,
|
|
||||||
}).Info("PAUSE VM Error")
|
|
||||||
return errno
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, _, errno = syscall.Syscall(syscall.SYS_IOCTL,
|
|
||||||
uintptr(f),
|
|
||||||
uintptr(ioctl_ACRN_DESTROY_VM),
|
|
||||||
0)
|
|
||||||
if ret != 0 || errno != 0 {
|
|
||||||
kataLog.WithFields(logrus.Fields{
|
|
||||||
"ret": ret,
|
|
||||||
"errno": errno,
|
|
||||||
}).Info("Destroy VM Error")
|
|
||||||
return errno
|
|
||||||
}
|
|
||||||
|
|
||||||
kataLog.WithField("feature", "create-vm").Info("feature available")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
||||||
switch hypervisorType {
|
switch hypervisorType {
|
||||||
case vc.QemuHypervisor:
|
case vc.QemuHypervisor:
|
||||||
@ -321,8 +200,6 @@ func archHostCanCreateVMContainer(hypervisorType vc.HypervisorType) error {
|
|||||||
fallthrough
|
fallthrough
|
||||||
case vc.FirecrackerHypervisor:
|
case vc.FirecrackerHypervisor:
|
||||||
return kvmIsUsable()
|
return kvmIsUsable()
|
||||||
case vc.AcrnHypervisor:
|
|
||||||
return acrnIsUsable()
|
|
||||||
case vc.RemoteHypervisor:
|
case vc.RemoteHypervisor:
|
||||||
return nil
|
return nil
|
||||||
case vc.MockHypervisor:
|
case vc.MockHypervisor:
|
||||||
|
@ -916,7 +916,6 @@ func TestGetHypervisorInfoSocket(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hypervisors := []TestHypervisorDetails{
|
hypervisors := []TestHypervisorDetails{
|
||||||
{vc.AcrnHypervisor, false},
|
|
||||||
{vc.ClhHypervisor, true},
|
{vc.ClhHypervisor, true},
|
||||||
{vc.FirecrackerHypervisor, true},
|
{vc.FirecrackerHypervisor, true},
|
||||||
{vc.MockHypervisor, false},
|
{vc.MockHypervisor, false},
|
||||||
|
@ -1,263 +0,0 @@
|
|||||||
# Copyright (c) 2017-2019 Intel Corporation
|
|
||||||
# Copyright (c) 2021 Adobe Inc.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
|
|
||||||
# XXX: WARNING: this file is auto-generated.
|
|
||||||
# XXX:
|
|
||||||
# XXX: Source file: "@CONFIG_ACRN_IN@"
|
|
||||||
# XXX: Project:
|
|
||||||
# XXX: Name: @PROJECT_NAME@
|
|
||||||
# XXX: Type: @PROJECT_TYPE@
|
|
||||||
|
|
||||||
[hypervisor.acrn]
|
|
||||||
path = "@ACRNPATH@"
|
|
||||||
ctlpath = "@ACRNCTLPATH@"
|
|
||||||
kernel = "@KERNELPATH_ACRN@"
|
|
||||||
image = "@IMAGEPATH@"
|
|
||||||
|
|
||||||
# rootfs filesystem type:
|
|
||||||
# - ext4 (default)
|
|
||||||
# - xfs
|
|
||||||
# - erofs
|
|
||||||
rootfs_type=@DEFROOTFSTYPE@
|
|
||||||
|
|
||||||
# List of valid annotation names for the hypervisor
|
|
||||||
# Each member of the list is a regular expression, which is the base name
|
|
||||||
# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"
|
|
||||||
enable_annotations = @DEFENABLEANNOTATIONS@
|
|
||||||
|
|
||||||
# List of valid annotations values for the hypervisor
|
|
||||||
# Each member of the list is a path pattern as described by glob(3).
|
|
||||||
# The default if not set is empty (all annotations rejected.)
|
|
||||||
# Your distribution recommends: @ACRNVALIDHYPERVISORPATHS@
|
|
||||||
valid_hypervisor_paths = @ACRNVALIDHYPERVISORPATHS@
|
|
||||||
|
|
||||||
# List of valid annotations values for ctlpath
|
|
||||||
# The default if not set is empty (all annotations rejected.)
|
|
||||||
# Your distribution recommends: @ACRNVALIDCTLPATHS@
|
|
||||||
valid_ctlpaths = @ACRNVALIDCTLPATHS@
|
|
||||||
|
|
||||||
# Optional space-separated list of options to pass to the guest kernel.
|
|
||||||
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
|
|
||||||
# trouble running pre-2.15 glibc.
|
|
||||||
#
|
|
||||||
# WARNING: - any parameter specified here will take priority over the default
|
|
||||||
# parameter value of the same name used to start the virtual machine.
|
|
||||||
# Do not set values here unless you understand the impact of doing so as you
|
|
||||||
# may stop the virtual machine from booting.
|
|
||||||
# To see the list of default parameters, enable hypervisor debug, create a
|
|
||||||
# container and look for 'default-kernel-parameters' log entries.
|
|
||||||
kernel_params = "@KERNELPARAMS@"
|
|
||||||
|
|
||||||
# Path to the firmware.
|
|
||||||
# If you want that acrn uses the default firmware leave this option empty
|
|
||||||
firmware = "@FIRMWAREPATH@"
|
|
||||||
|
|
||||||
# Default maximum number of vCPUs per SB/VM:
|
|
||||||
# unspecified or == 0 --> will be set to the actual number of physical cores or to the maximum number
|
|
||||||
# of vCPUs supported by KVM if that number is exceeded
|
|
||||||
# > 0 <= number of physical cores --> will be set to the specified number
|
|
||||||
# > number of physical cores --> will be set to the actual number of physical cores or to the maximum number
|
|
||||||
# of vCPUs supported by KVM if that number is exceeded
|
|
||||||
# WARNING: Depending of the architecture, the maximum number of vCPUs supported by KVM is used when
|
|
||||||
# the actual number of physical cores is greater than it.
|
|
||||||
# WARNING: Be aware that this value impacts the virtual machine's memory footprint and CPU
|
|
||||||
# the hotplug functionality. For example, `default_maxvcpus = 240` specifies that until 240 vCPUs
|
|
||||||
# can be added to a SB/VM, but the memory footprint will be big. Another example, with
|
|
||||||
# `default_maxvcpus = 8` the memory footprint will be small, but 8 will be the maximum number of
|
|
||||||
# vCPUs supported by the SB/VM. In general, we recommend that you do not edit this variable,
|
|
||||||
# unless you know what are you doing.
|
|
||||||
default_maxvcpus = @DEFMAXVCPUS_ACRN@
|
|
||||||
|
|
||||||
# Bridges can be used to hot plug devices.
|
|
||||||
# Limitations:
|
|
||||||
# * Currently only pci bridges are supported
|
|
||||||
# * Until 30 devices per bridge can be hot plugged.
|
|
||||||
# * Until 5 PCI bridges can be cold plugged per VM.
|
|
||||||
# This limitation could be a bug in the kernel
|
|
||||||
# Default number of bridges per SB/VM:
|
|
||||||
# unspecified or 0 --> will be set to @DEFBRIDGES@
|
|
||||||
# > 1 <= 5 --> will be set to the specified number
|
|
||||||
# > 5 --> will be set to 5
|
|
||||||
default_bridges = @DEFBRIDGES@
|
|
||||||
|
|
||||||
# Default memory size in MiB for SB/VM.
|
|
||||||
# If unspecified then it will be set @DEFMEMSZ@ MiB.
|
|
||||||
default_memory = @DEFMEMSZ@
|
|
||||||
|
|
||||||
# Block storage driver to be used for the hypervisor in case the container
|
|
||||||
# rootfs is backed by a block device. ACRN only supports virtio-blk.
|
|
||||||
block_device_driver = "@DEFBLOCKSTORAGEDRIVER_ACRN@"
|
|
||||||
|
|
||||||
# This option changes the default hypervisor and kernel parameters
|
|
||||||
# to enable debug output where available.
|
|
||||||
#
|
|
||||||
# Default false
|
|
||||||
#enable_debug = true
|
|
||||||
|
|
||||||
# Disable the customizations done in the runtime when it detects
|
|
||||||
# that it is running on top a VMM. This will result in the runtime
|
|
||||||
# behaving as it would when running on bare metal.
|
|
||||||
#
|
|
||||||
#disable_nesting_checks = true
|
|
||||||
|
|
||||||
# If host doesn't support vhost_net, set to true. Thus we won't create vhost fds for nics.
|
|
||||||
# Default false
|
|
||||||
#disable_vhost_net = true
|
|
||||||
|
|
||||||
# Path to OCI hook binaries in the *guest rootfs*.
|
|
||||||
# This does not affect host-side hooks which must instead be added to
|
|
||||||
# the OCI spec passed to the runtime.
|
|
||||||
#
|
|
||||||
# You can create a rootfs with hooks by customizing the osbuilder scripts:
|
|
||||||
# https://github.com/kata-containers/kata-containers/tree/main/tools/osbuilder
|
|
||||||
#
|
|
||||||
# Hooks must be stored in a subdirectory of guest_hook_path according to their
|
|
||||||
# hook type, i.e. "guest_hook_path/{prestart,poststart,poststop}".
|
|
||||||
# The agent will scan these directories for executable files and add them, in
|
|
||||||
# lexicographical order, to the lifecycle of the guest container.
|
|
||||||
# Hooks are executed in the runtime namespace of the guest. See the official documentation:
|
|
||||||
# https://github.com/opencontainers/runtime-spec/blob/v1.0.1/config.md#posix-platform-hooks
|
|
||||||
# Warnings will be logged if any error is encountered while scanning for hooks,
|
|
||||||
# but it will not abort container execution.
|
|
||||||
#guest_hook_path = "/usr/share/oci/hooks"
|
|
||||||
|
|
||||||
# disable applying SELinux on the VMM process (default false)
|
|
||||||
disable_selinux=@DEFDISABLESELINUX@
|
|
||||||
|
|
||||||
[agent.@PROJECT_TYPE@]
|
|
||||||
# If enabled, make the agent display debug-level messages.
|
|
||||||
# (default: disabled)
|
|
||||||
#enable_debug = true
|
|
||||||
|
|
||||||
# Enable agent tracing.
|
|
||||||
#
|
|
||||||
# If enabled, the agent will generate OpenTelemetry trace spans.
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
#
|
|
||||||
# - If the runtime also has tracing enabled, the agent spans will be
|
|
||||||
# associated with the appropriate runtime parent span.
|
|
||||||
# - If enabled, the runtime will wait for the container to shutdown,
|
|
||||||
# increasing the container shutdown time slightly.
|
|
||||||
#
|
|
||||||
# (default: disabled)
|
|
||||||
#enable_tracing = true
|
|
||||||
|
|
||||||
# Enable debug console.
|
|
||||||
|
|
||||||
# If enabled, user can connect guest OS running inside hypervisor
|
|
||||||
# through "kata-runtime exec <sandbox-id>" command
|
|
||||||
|
|
||||||
#debug_console_enabled = true
|
|
||||||
|
|
||||||
# Agent connection dialing timeout value in seconds
|
|
||||||
# (default: 45)
|
|
||||||
dial_timeout = 45
|
|
||||||
|
|
||||||
# Confidential Data Hub API timeout value in seconds
|
|
||||||
# (default: 50)
|
|
||||||
#cdh_api_timeout = 50
|
|
||||||
|
|
||||||
[runtime]
|
|
||||||
# If enabled, the runtime will log additional debug messages to the
|
|
||||||
# system log
|
|
||||||
# (default: disabled)
|
|
||||||
#enable_debug = true
|
|
||||||
#
|
|
||||||
# Internetworking model
|
|
||||||
# Determines how the VM should be connected to the
|
|
||||||
# the container network interface
|
|
||||||
# Options:
|
|
||||||
#
|
|
||||||
# - bridged (Deprecated)
|
|
||||||
# Uses a linux bridge to interconnect the container interface to
|
|
||||||
# the VM. Works for most cases except macvlan and ipvlan.
|
|
||||||
# ***NOTE: This feature has been deprecated with plans to remove this
|
|
||||||
# feature in the future. Please use other network models listed below.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# - macvtap
|
|
||||||
# Used when the Container network interface can be bridged using
|
|
||||||
# macvtap.
|
|
||||||
#
|
|
||||||
# - none
|
|
||||||
# Used when customize network. Only creates a tap device. No veth pair.
|
|
||||||
#
|
|
||||||
# - tcfilter
|
|
||||||
# Uses tc filter rules to redirect traffic from the network interface
|
|
||||||
# provided by plugin to a tap interface connected to the VM.
|
|
||||||
#
|
|
||||||
internetworking_model="@DEFNETWORKMODEL_ACRN@"
|
|
||||||
|
|
||||||
# disable guest seccomp
|
|
||||||
# Determines whether container seccomp profiles are passed to the virtual
|
|
||||||
# machine and applied by the kata agent. If set to true, seccomp is not applied
|
|
||||||
# within the guest
|
|
||||||
# (default: true)
|
|
||||||
disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
|
|
||||||
|
|
||||||
# If enabled, the runtime will create opentracing.io traces and spans.
|
|
||||||
# (See https://www.jaegertracing.io/docs/getting-started).
|
|
||||||
# (default: disabled)
|
|
||||||
#enable_tracing = true
|
|
||||||
|
|
||||||
# Set the full url to the Jaeger HTTP Thrift collector.
|
|
||||||
# The default if not set will be "http://localhost:14268/api/traces"
|
|
||||||
#jaeger_endpoint = ""
|
|
||||||
|
|
||||||
# Sets the username to be used if basic auth is required for Jaeger.
|
|
||||||
#jaeger_user = ""
|
|
||||||
|
|
||||||
# Sets the password to be used if basic auth is required for Jaeger.
|
|
||||||
#jaeger_password = ""
|
|
||||||
|
|
||||||
# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
|
|
||||||
# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
|
|
||||||
# `disable_new_netns` conflicts with `internetworking_model=bridged` and `internetworking_model=macvtap`. It works only
|
|
||||||
# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
|
|
||||||
# (like OVS) directly.
|
|
||||||
# (default: false)
|
|
||||||
#disable_new_netns = true
|
|
||||||
|
|
||||||
# if enabled, the runtime will add all the kata processes inside one dedicated cgroup.
|
|
||||||
# The container cgroups in the host are not created, just one single cgroup per sandbox.
|
|
||||||
# The runtime caller is free to restrict or collect cgroup stats of the overall Kata sandbox.
|
|
||||||
# The sandbox cgroup path is the parent cgroup of a container with the PodSandbox annotation.
|
|
||||||
# The sandbox cgroup is constrained if there is no container type annotation.
|
|
||||||
# See: https://pkg.go.dev/github.com/kata-containers/kata-containers/src/runtime/virtcontainers#ContainerType
|
|
||||||
sandbox_cgroup_only=@DEFSANDBOXCGROUPONLY@
|
|
||||||
|
|
||||||
# If enabled, the runtime will not create Kubernetes emptyDir mounts on the guest filesystem. Instead, emptyDir mounts will
|
|
||||||
# be created on the host and shared via virtio-fs. This is potentially slower, but allows sharing of files from host to guest.
|
|
||||||
disable_guest_empty_dir=@DEFDISABLEGUESTEMPTYDIR@
|
|
||||||
|
|
||||||
# Enabled experimental feature list, format: ["a", "b"].
|
|
||||||
# Experimental features are features not stable enough for production,
|
|
||||||
# they may break compatibility, and are prepared for a big version bump.
|
|
||||||
# Supported experimental features:
|
|
||||||
# (default: [])
|
|
||||||
experimental=@DEFAULTEXPFEATURES@
|
|
||||||
|
|
||||||
# If enabled, user can run pprof tools with shim v2 process through kata-monitor.
|
|
||||||
# (default: false)
|
|
||||||
# enable_pprof = true
|
|
||||||
|
|
||||||
# Indicates the CreateContainer request timeout needed for the workload(s)
|
|
||||||
# It using guest_pull this includes the time to pull the image inside the guest
|
|
||||||
# Defaults to @DEFCREATECONTAINERTIMEOUT@ second(s)
|
|
||||||
# Note: The effective timeout is determined by the lesser of two values: runtime-request-timeout from kubelet config
|
|
||||||
# (https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/#:~:text=runtime%2Drequest%2Dtimeout) and create_container_timeout.
|
|
||||||
# In essence, the timeout used for guest pull=runtime-request-timeout<create_container_timeout?runtime-request-timeout:create_container_timeout.
|
|
||||||
create_container_timeout = @DEFCREATECONTAINERTIMEOUT@
|
|
||||||
|
|
||||||
# Base directory of directly attachable network config.
|
|
||||||
# Network devices for VM-based containers are allowed to be placed in the
|
|
||||||
# host netns to eliminate as many hops as possible, which is what we
|
|
||||||
# called a "Directly Attachable Network". The config, set by special CNI
|
|
||||||
# plugins, is used to tell the Kata containers what devices are attached
|
|
||||||
# to the hypervisor.
|
|
||||||
# (default: /run/kata-containers/dans)
|
|
||||||
dan_conf = "@DEFDANCONF@"
|
|
@ -60,12 +60,6 @@ func (device *BlockDevice) Attach(ctx context.Context, devReceiver api.DeviceRec
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hypervisorType := devReceiver.GetHypervisorType()
|
|
||||||
if hypervisorType == "acrn" {
|
|
||||||
deviceLogger().Debug("Special casing for ACRN to increment BlockIndex")
|
|
||||||
index = index + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
drive := &config.BlockDrive{
|
drive := &config.BlockDrive{
|
||||||
File: device.DeviceInfo.HostPath,
|
File: device.DeviceInfo.HostPath,
|
||||||
Format: "raw",
|
Format: "raw",
|
||||||
|
@ -30,7 +30,7 @@ type CPUDevice struct {
|
|||||||
|
|
||||||
type HypervisorState struct {
|
type HypervisorState struct {
|
||||||
BlockIndexMap map[int]struct{}
|
BlockIndexMap map[int]struct{}
|
||||||
// Type of hypervisor, E.g. qemu/firecracker/acrn.
|
// Type of hypervisor, E.g. qemu/firecracker
|
||||||
Type string
|
Type string
|
||||||
UUID string
|
UUID string
|
||||||
// clh sepcific: refer to 'virtcontainers/clh.go:CloudHypervisorState'
|
// clh sepcific: refer to 'virtcontainers/clh.go:CloudHypervisorState'
|
||||||
|
@ -44,7 +44,6 @@ var DEFAULTRUNTIMECONFIGURATION = "@CONFIG_PATH@"
|
|||||||
// defaultRuntimeConfiguration.
|
// defaultRuntimeConfiguration.
|
||||||
var DEFAULTSYSCONFRUNTIMECONFIGURATION = "@SYSCONFIG@"
|
var DEFAULTSYSCONFRUNTIMECONFIGURATION = "@SYSCONFIG@"
|
||||||
var defaultHypervisorPath = "/usr/bin/qemu-system-x86_64"
|
var defaultHypervisorPath = "/usr/bin/qemu-system-x86_64"
|
||||||
var defaultHypervisorCtlPath = "/usr/bin/acrnctl"
|
|
||||||
var defaultJailerPath = "/usr/bin/jailer"
|
var defaultJailerPath = "/usr/bin/jailer"
|
||||||
var defaultImagePath = "/usr/share/kata-containers/kata-containers.img"
|
var defaultImagePath = "/usr/share/kata-containers/kata-containers.img"
|
||||||
var defaultKernelPath = "/usr/share/kata-containers/vmlinuz.container"
|
var defaultKernelPath = "/usr/share/kata-containers/vmlinuz.container"
|
||||||
|
@ -50,7 +50,6 @@ const (
|
|||||||
firecrackerHypervisorTableType = "firecracker"
|
firecrackerHypervisorTableType = "firecracker"
|
||||||
clhHypervisorTableType = "clh"
|
clhHypervisorTableType = "clh"
|
||||||
qemuHypervisorTableType = "qemu"
|
qemuHypervisorTableType = "qemu"
|
||||||
acrnHypervisorTableType = "acrn"
|
|
||||||
dragonballHypervisorTableType = "dragonball"
|
dragonballHypervisorTableType = "dragonball"
|
||||||
stratovirtHypervisorTableType = "stratovirt"
|
stratovirtHypervisorTableType = "stratovirt"
|
||||||
remoteHypervisorTableType = "remote"
|
remoteHypervisorTableType = "remote"
|
||||||
@ -83,7 +82,6 @@ type hypervisor struct {
|
|||||||
Path string `toml:"path"`
|
Path string `toml:"path"`
|
||||||
JailerPath string `toml:"jailer_path"`
|
JailerPath string `toml:"jailer_path"`
|
||||||
Kernel string `toml:"kernel"`
|
Kernel string `toml:"kernel"`
|
||||||
CtlPath string `toml:"ctlpath"`
|
|
||||||
Initrd string `toml:"initrd"`
|
Initrd string `toml:"initrd"`
|
||||||
Image string `toml:"image"`
|
Image string `toml:"image"`
|
||||||
RootfsType string `toml:"rootfs_type"`
|
RootfsType string `toml:"rootfs_type"`
|
||||||
@ -109,7 +107,6 @@ type hypervisor struct {
|
|||||||
SnpCertsPath string `toml:"snp_certs_path"`
|
SnpCertsPath string `toml:"snp_certs_path"`
|
||||||
HypervisorPathList []string `toml:"valid_hypervisor_paths"`
|
HypervisorPathList []string `toml:"valid_hypervisor_paths"`
|
||||||
JailerPathList []string `toml:"valid_jailer_paths"`
|
JailerPathList []string `toml:"valid_jailer_paths"`
|
||||||
CtlPathList []string `toml:"valid_ctlpaths"`
|
|
||||||
VirtioFSDaemonList []string `toml:"valid_virtio_fs_daemon_paths"`
|
VirtioFSDaemonList []string `toml:"valid_virtio_fs_daemon_paths"`
|
||||||
VirtioFSExtraArgs []string `toml:"virtio_fs_extra_args"`
|
VirtioFSExtraArgs []string `toml:"virtio_fs_extra_args"`
|
||||||
PFlashList []string `toml:"pflashes"`
|
PFlashList []string `toml:"pflashes"`
|
||||||
@ -225,16 +222,6 @@ func (h hypervisor) path() (string, error) {
|
|||||||
return ResolvePath(p)
|
return ResolvePath(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h hypervisor) ctlpath() (string, error) {
|
|
||||||
p := h.CtlPath
|
|
||||||
|
|
||||||
if h.CtlPath == "" {
|
|
||||||
p = defaultHypervisorCtlPath
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolvePath(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h hypervisor) jailerPath() (string, error) {
|
func (h hypervisor) jailerPath() (string, error) {
|
||||||
p := h.JailerPath
|
p := h.JailerPath
|
||||||
|
|
||||||
@ -1022,79 +1009,6 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAcrnHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
|
||||||
hypervisor, err := h.path()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
hypervisorctl, err := h.ctlpath()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel, err := h.kernel()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
image, err := h.image()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if image == "" {
|
|
||||||
return vc.HypervisorConfig{},
|
|
||||||
errors.New("image must be defined in the configuration file")
|
|
||||||
}
|
|
||||||
|
|
||||||
rootfsType, err := h.rootfsType()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
firmware, err := h.firmware()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
kernelParams := h.kernelParams()
|
|
||||||
|
|
||||||
blockDriver, err := h.blockDeviceDriver()
|
|
||||||
if err != nil {
|
|
||||||
return vc.HypervisorConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return vc.HypervisorConfig{
|
|
||||||
HypervisorPath: hypervisor,
|
|
||||||
HypervisorPathList: h.HypervisorPathList,
|
|
||||||
KernelPath: kernel,
|
|
||||||
ImagePath: image,
|
|
||||||
RootfsType: rootfsType,
|
|
||||||
HypervisorCtlPath: hypervisorctl,
|
|
||||||
HypervisorCtlPathList: h.CtlPathList,
|
|
||||||
FirmwarePath: firmware,
|
|
||||||
KernelParams: vc.DeserializeParams(vc.KernelParamFields(kernelParams)),
|
|
||||||
NumVCPUsF: h.defaultVCPUs(),
|
|
||||||
DefaultMaxVCPUs: h.defaultMaxVCPUs(),
|
|
||||||
MemorySize: h.defaultMemSz(),
|
|
||||||
MemSlots: h.defaultMemSlots(),
|
|
||||||
DefaultMaxMemorySize: h.defaultMaxMemSz(),
|
|
||||||
EntropySource: h.GetEntropySource(),
|
|
||||||
EntropySourceList: h.EntropySourceList,
|
|
||||||
DefaultBridges: h.defaultBridges(),
|
|
||||||
HugePages: h.HugePages,
|
|
||||||
Debug: h.Debug,
|
|
||||||
DisableNestingChecks: h.DisableNestingChecks,
|
|
||||||
BlockDeviceDriver: blockDriver,
|
|
||||||
DisableVhostNet: h.DisableVhostNet,
|
|
||||||
GuestHookPath: h.guestHookPath(),
|
|
||||||
DisableSeLinux: h.DisableSeLinux,
|
|
||||||
EnableAnnotations: h.EnableAnnotations,
|
|
||||||
DisableGuestSeLinux: true, // Guest SELinux is not supported in ACRN
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
||||||
hypervisor, err := h.path()
|
hypervisor, err := h.path()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1393,9 +1307,6 @@ func updateRuntimeConfigHypervisor(configPath string, tomlConf tomlConfig, confi
|
|||||||
case qemuHypervisorTableType:
|
case qemuHypervisorTableType:
|
||||||
config.HypervisorType = vc.QemuHypervisor
|
config.HypervisorType = vc.QemuHypervisor
|
||||||
hConfig, err = newQemuHypervisorConfig(hypervisor)
|
hConfig, err = newQemuHypervisorConfig(hypervisor)
|
||||||
case acrnHypervisorTableType:
|
|
||||||
config.HypervisorType = vc.AcrnHypervisor
|
|
||||||
hConfig, err = newAcrnHypervisorConfig(hypervisor)
|
|
||||||
case clhHypervisorTableType:
|
case clhHypervisorTableType:
|
||||||
config.HypervisorType = vc.ClhHypervisor
|
config.HypervisorType = vc.ClhHypervisor
|
||||||
hConfig, err = newClhHypervisorConfig(hypervisor)
|
hConfig, err = newClhHypervisorConfig(hypervisor)
|
||||||
|
@ -1770,9 +1770,6 @@ func TestUpdateRuntimeConfigHypervisor(t *testing.T) {
|
|||||||
|
|
||||||
configFile := "/some/where/configuration.toml"
|
configFile := "/some/where/configuration.toml"
|
||||||
|
|
||||||
// Note: We cannot test acrnHypervisorTableType since
|
|
||||||
// newAcrnHypervisorConfig() expects ACRN binaries to be
|
|
||||||
// installed.
|
|
||||||
var entries = []tableTypeEntry{
|
var entries = []tableTypeEntry{
|
||||||
{clhHypervisorTableType, true},
|
{clhHypervisorTableType, true},
|
||||||
{dragonballHypervisorTableType, true},
|
{dragonballHypervisorTableType, true},
|
||||||
|
@ -578,13 +578,6 @@ func addHypervisorPathOverrides(ocispec specs.Spec, config *vc.SandboxConfig, ru
|
|||||||
config.HypervisorConfig.JailerPath = value
|
config.HypervisorConfig.JailerPath = value
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := ocispec.Annotations[vcAnnotations.CtlPath]; ok {
|
|
||||||
if !checkPathIsInGlobs(runtime.HypervisorConfig.HypervisorCtlPathList, value) {
|
|
||||||
return fmt.Errorf("hypervisor control %v required from annotation is not valid", value)
|
|
||||||
}
|
|
||||||
config.HypervisorConfig.HypervisorCtlPath = value
|
|
||||||
}
|
|
||||||
|
|
||||||
if value, ok := ocispec.Annotations[vcAnnotations.KernelParams]; ok {
|
if value, ok := ocispec.Annotations[vcAnnotations.KernelParams]; ok {
|
||||||
if value != "" {
|
if value != "" {
|
||||||
params := vc.DeserializeParams(strings.Fields(value))
|
params := vc.DeserializeParams(strings.Fields(value))
|
||||||
|
@ -483,9 +483,6 @@ func TestAddAssetAnnotations(t *testing.T) {
|
|||||||
vcAnnotations.HypervisorPath: fakeAssetFile,
|
vcAnnotations.HypervisorPath: fakeAssetFile,
|
||||||
vcAnnotations.HypervisorHash: "bbbbb",
|
vcAnnotations.HypervisorHash: "bbbbb",
|
||||||
|
|
||||||
vcAnnotations.HypervisorCtlPath: fakeAssetFile,
|
|
||||||
vcAnnotations.HypervisorCtlHash: "cc",
|
|
||||||
|
|
||||||
vcAnnotations.ImagePath: fakeAssetFile,
|
vcAnnotations.ImagePath: fakeAssetFile,
|
||||||
vcAnnotations.ImageHash: "52ss2550983",
|
vcAnnotations.ImageHash: "52ss2550983",
|
||||||
|
|
||||||
@ -533,7 +530,6 @@ func TestAddAssetAnnotations(t *testing.T) {
|
|||||||
// Check that it works if all path lists are enabled
|
// Check that it works if all path lists are enabled
|
||||||
runtimeConfig.HypervisorConfig.HypervisorPathList = []string{tmpdirGlob}
|
runtimeConfig.HypervisorConfig.HypervisorPathList = []string{tmpdirGlob}
|
||||||
runtimeConfig.HypervisorConfig.JailerPathList = []string{tmpdirGlob}
|
runtimeConfig.HypervisorConfig.JailerPathList = []string{tmpdirGlob}
|
||||||
runtimeConfig.HypervisorConfig.HypervisorCtlPathList = []string{tmpdirGlob}
|
|
||||||
|
|
||||||
err = addAnnotations(ocispec, &config, runtimeConfig)
|
err = addAnnotations(ocispec, &config, runtimeConfig)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
@ -1,684 +0,0 @@
|
|||||||
//go:build linux
|
|
||||||
|
|
||||||
// Copyright (c) 2019 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
package virtcontainers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/prometheus/procfs"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
|
||||||
hv "github.com/kata-containers/kata-containers/src/runtime/pkg/hypervisors"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace"
|
|
||||||
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
// acrnTracingTags defines tags for the trace span
|
|
||||||
var acrnTracingTags = map[string]string{
|
|
||||||
"source": "runtime",
|
|
||||||
"package": "virtcontainers",
|
|
||||||
"subsystem": "hypervisor",
|
|
||||||
"type": "acrn",
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnState keeps track of VM UUID, PID.
|
|
||||||
type AcrnState struct {
|
|
||||||
PID int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acrn is an Hypervisor interface implementation for the Linux acrn hypervisor.
|
|
||||||
type Acrn struct {
|
|
||||||
sandbox *Sandbox
|
|
||||||
ctx context.Context
|
|
||||||
arch acrnArch
|
|
||||||
store persistapi.PersistDriver
|
|
||||||
id string
|
|
||||||
acrnConfig Config
|
|
||||||
config HypervisorConfig
|
|
||||||
state AcrnState
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
acrnConsoleSocket = "console.sock"
|
|
||||||
acrnStopSandboxTimeoutSecs = 15
|
|
||||||
)
|
|
||||||
|
|
||||||
// agnostic list of kernel parameters
|
|
||||||
var acrnDefaultKernelParameters = []Param{
|
|
||||||
{"panic", "1"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) kernelParameters() string {
|
|
||||||
// get a list of arch kernel parameters
|
|
||||||
params := a.arch.kernelParameters(a.config.Debug)
|
|
||||||
|
|
||||||
// use default parameters
|
|
||||||
params = append(params, acrnDefaultKernelParameters...)
|
|
||||||
|
|
||||||
// set the maximum number of vCPUs
|
|
||||||
params = append(params, Param{"maxcpus", fmt.Sprintf("%d", a.config.DefaultMaxVCPUs)})
|
|
||||||
|
|
||||||
// add the params specified by the provided config. As the kernel
|
|
||||||
// honours the last parameter value set and since the config-provided
|
|
||||||
// params are added here, they will take priority over the defaults.
|
|
||||||
params = append(params, a.config.KernelParams...)
|
|
||||||
|
|
||||||
paramsStr := SerializeParams(params, "=")
|
|
||||||
|
|
||||||
return strings.Join(paramsStr, " ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds all capabilities supported by Acrn implementation of hypervisor interface
|
|
||||||
func (a *Acrn) Capabilities(ctx context.Context) types.Capabilities {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "Capabilities", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return a.arch.capabilities(a.config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) HypervisorConfig() HypervisorConfig {
|
|
||||||
return a.config
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cpu apicid to identify vCPU that will be assigned for a VM by reading `proc/cpuinfo`
|
|
||||||
func (a *Acrn) getNextApicid() (string, error) {
|
|
||||||
fs, err := procfs.NewFS("/proc")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
cpuinfo, err := fs.CPUInfo()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
prevIdx := -1
|
|
||||||
fileName := filepath.Join(a.config.VMStorePath, "cpu_affinity_idx")
|
|
||||||
_, err = os.Stat(fileName)
|
|
||||||
if err == nil {
|
|
||||||
data, err := os.ReadFile(fileName)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("Loading cpu affinity index from file failed!")
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
prevIdx, err = strconv.Atoi(string(data))
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("CreateVM: Convert from []byte to integer failed!")
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if prevIdx >= (len(cpuinfo) - 1) {
|
|
||||||
prevIdx = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentIdx := prevIdx + 1
|
|
||||||
err = os.WriteFile(fileName, []byte(strconv.Itoa(currentIdx)), defaultFilePerms)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("Storing cpu affinity index from file failed!")
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cpuinfo[currentIdx].APICID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the acrn binary path
|
|
||||||
func (a *Acrn) acrnPath() (string, error) {
|
|
||||||
p, err := a.config.HypervisorAssetPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if p == "" {
|
|
||||||
p, err = a.arch.acrnPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = os.Stat(p); os.IsNotExist(err) {
|
|
||||||
return "", fmt.Errorf("acrn path (%s) does not exist", p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the ACRNCTL binary path
|
|
||||||
func (a *Acrn) acrnctlPath() (string, error) {
|
|
||||||
ctlpath, err := a.config.HypervisorCtlAssetPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctlpath == "" {
|
|
||||||
ctlpath, err = a.arch.acrnctlPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = os.Stat(ctlpath); os.IsNotExist(err) {
|
|
||||||
return "", fmt.Errorf("acrnctl path (%s) does not exist", ctlpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctlpath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logger returns a logrus logger appropriate for logging acrn messages
|
|
||||||
func (a *Acrn) Logger() *logrus.Entry {
|
|
||||||
return virtLog.WithField("subsystem", "acrn")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) memoryTopology() (Memory, error) {
|
|
||||||
memMb := uint64(a.config.MemorySize)
|
|
||||||
|
|
||||||
return a.arch.memoryTopology(memMb), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) appendImage(devices []Device, imagePath string) ([]Device, error) {
|
|
||||||
if imagePath == "" {
|
|
||||||
return nil, fmt.Errorf("Image path is empty: %s", imagePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
devices, err = a.arch.appendImage(devices, imagePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) buildDevices(ctx context.Context, imagePath string) ([]Device, error) {
|
|
||||||
var devices []Device
|
|
||||||
|
|
||||||
if imagePath == "" {
|
|
||||||
return nil, fmt.Errorf("Image Path should not be empty: %s", imagePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, console, err := a.GetVMConsole(ctx, a.id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add bridges before any other devices. This way we make sure that
|
|
||||||
// bridge gets the first available PCI address.
|
|
||||||
devices = a.arch.appendBridges(devices)
|
|
||||||
|
|
||||||
//Add LPC device to the list of other devices.
|
|
||||||
devices = a.arch.appendLPC(devices)
|
|
||||||
|
|
||||||
devices = a.arch.appendConsole(devices, console)
|
|
||||||
|
|
||||||
devices, err = a.appendImage(devices, imagePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create virtio blk devices with dummy backend as a place
|
|
||||||
// holder for container rootfs (as acrn doesn't support hot-plug).
|
|
||||||
// Once the container rootfs is known, replace the dummy backend
|
|
||||||
// with actual path (using block rescan feature in acrn)
|
|
||||||
devices, err = a.createDummyVirtioBlkDev(ctx, devices)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup sets the Acrn structure up.
|
|
||||||
func (a *Acrn) setup(ctx context.Context, id string, hypervisorConfig *HypervisorConfig) error {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "setup", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if err := a.setConfig(hypervisorConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
a.id = id
|
|
||||||
var err error
|
|
||||||
a.arch, err = newAcrnArch(a.config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) createDummyVirtioBlkDev(ctx context.Context, devices []Device) ([]Device, error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "createDummyVirtioBlkDev", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Since acrn doesn't support hot-plug, dummy virtio-blk
|
|
||||||
// devices are added and later replaced with container-rootfs.
|
|
||||||
// Starting from driveIndex 1, as 0 is allocated for VM rootfs.
|
|
||||||
for driveIndex := 1; driveIndex <= AcrnBlkDevPoolSz; driveIndex++ {
|
|
||||||
drive := config.BlockDrive{
|
|
||||||
File: "nodisk",
|
|
||||||
Index: driveIndex,
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = a.arch.appendBlockDevice(devices, drive)
|
|
||||||
}
|
|
||||||
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) setConfig(config *HypervisorConfig) error {
|
|
||||||
a.config = *config
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateVM is the VM creation
|
|
||||||
func (a *Acrn) CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error {
|
|
||||||
// Save the tracing context
|
|
||||||
a.ctx = ctx
|
|
||||||
|
|
||||||
span, ctx := katatrace.Trace(ctx, a.Logger(), "CreateVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if err := a.setup(ctx, id, hypervisorConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
memory, err := a.memoryTopology()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
kernelPath, err := a.config.KernelAssetPath()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
imagePath, err := a.config.ImageAssetPath()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
kernel := Kernel{
|
|
||||||
Path: kernelPath,
|
|
||||||
ImagePath: imagePath,
|
|
||||||
Params: a.kernelParameters(),
|
|
||||||
}
|
|
||||||
|
|
||||||
devices, err := a.buildDevices(ctx, imagePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
acrnPath, err := a.acrnPath()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
acrnctlPath, err := a.acrnctlPath()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vmName := fmt.Sprintf("sbx-%s", a.id)
|
|
||||||
if len(vmName) > 15 {
|
|
||||||
return fmt.Errorf("VM Name len is %d but ACRN supports max VM name len of 15.", len(vmName))
|
|
||||||
}
|
|
||||||
|
|
||||||
apicID, err := a.getNextApicid()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
acrnConfig := Config{
|
|
||||||
ACPIVirt: true,
|
|
||||||
Path: acrnPath,
|
|
||||||
CtlPath: acrnctlPath,
|
|
||||||
Memory: memory,
|
|
||||||
Devices: devices,
|
|
||||||
Kernel: kernel,
|
|
||||||
Name: vmName,
|
|
||||||
ApicID: apicID,
|
|
||||||
}
|
|
||||||
|
|
||||||
a.acrnConfig = acrnConfig
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartVM will start the Sandbox's VM.
|
|
||||||
func (a *Acrn) StartVM(ctx context.Context, timeoutSecs int) error {
|
|
||||||
span, ctx := katatrace.Trace(ctx, a.Logger(), "StartVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if a.config.Debug {
|
|
||||||
params := a.arch.kernelParameters(a.config.Debug)
|
|
||||||
strParams := SerializeParams(params, "=")
|
|
||||||
formatted := strings.Join(strParams, " ")
|
|
||||||
|
|
||||||
// The name of this field matches a similar one generated by
|
|
||||||
// the runtime and allows users to identify which parameters
|
|
||||||
// are set here, which come from the runtime and which are set
|
|
||||||
// by the user.
|
|
||||||
a.Logger().WithField("default-kernel-parameters", formatted).Debug()
|
|
||||||
}
|
|
||||||
|
|
||||||
vmPath := filepath.Join(a.config.VMStorePath, a.id)
|
|
||||||
err := os.MkdirAll(vmPath, DirMode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
if err := os.RemoveAll(vmPath); err != nil {
|
|
||||||
a.Logger().WithError(err).Error("Failed to clean up vm directory")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var strErr string
|
|
||||||
var PID int
|
|
||||||
a.Logger().Error("StartVM: LaunchAcrn() function called")
|
|
||||||
PID, strErr, err = LaunchAcrn(a.acrnConfig, virtLog.WithField("subsystem", "acrn-dm"))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s", strErr)
|
|
||||||
}
|
|
||||||
a.state.PID = PID
|
|
||||||
|
|
||||||
if err = a.waitVM(ctx, timeoutSecs); err != nil {
|
|
||||||
a.Logger().WithField("acrn wait failed:", err).Debug()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// waitVM will wait for the Sandbox's VM to be up and running.
|
|
||||||
func (a *Acrn) waitVM(ctx context.Context, timeoutSecs int) error {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "waitVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if timeoutSecs < 0 {
|
|
||||||
return fmt.Errorf("Invalid timeout %ds", timeoutSecs)
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(time.Duration(timeoutSecs) * time.Second)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopVM will stop the Sandbox's VM.
|
|
||||||
func (a *Acrn) StopVM(ctx context.Context, waitOnly bool) (err error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "StopVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
a.Logger().Info("Stopping acrn VM")
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Info("StopVM failed")
|
|
||||||
} else {
|
|
||||||
a.Logger().Info("acrn VM stopped")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
fileName := filepath.Join(a.config.VMStorePath, "cpu_affinity_idx")
|
|
||||||
data, err := os.ReadFile(fileName)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("Loading cpu affinity index from file failed!")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
currentIdx, err := strconv.Atoi(string(data))
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("Converting from []byte to integer failed!")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
currentIdx = currentIdx - 1
|
|
||||||
err = os.WriteFile(fileName, []byte(strconv.Itoa(currentIdx)), defaultFilePerms)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("Storing cpu affinity index from file failed!")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pid := a.state.PID
|
|
||||||
|
|
||||||
shutdownSignal := syscall.SIGINT
|
|
||||||
|
|
||||||
if waitOnly {
|
|
||||||
// NOP
|
|
||||||
shutdownSignal = syscall.Signal(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.WaitLocalProcess(pid, acrnStopSandboxTimeoutSecs, shutdownSignal, a.Logger())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) updateBlockDevice(drive *config.BlockDrive) error {
|
|
||||||
if drive.Swap {
|
|
||||||
return fmt.Errorf("Acrn doesn't support swap")
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
if drive.File == "" || drive.Index >= AcrnBlkDevPoolSz {
|
|
||||||
return fmt.Errorf("Empty filepath or invalid drive index, Dive ID:%s, Drive Index:%d",
|
|
||||||
drive.ID, drive.Index)
|
|
||||||
}
|
|
||||||
|
|
||||||
slot := AcrnBlkdDevSlot[drive.Index]
|
|
||||||
|
|
||||||
//Explicitly set PCIPath to NULL, so that VirtPath can be used
|
|
||||||
drive.PCIPath = types.PciPath{}
|
|
||||||
|
|
||||||
args := []string{"blkrescan", a.acrnConfig.Name, fmt.Sprintf("%d,%s", slot, drive.File)}
|
|
||||||
|
|
||||||
a.Logger().WithFields(logrus.Fields{
|
|
||||||
"drive": drive,
|
|
||||||
"path": a.config.HypervisorCtlPath,
|
|
||||||
}).Info("updateBlockDevice with acrnctl path")
|
|
||||||
cmd := exec.Command(a.config.HypervisorCtlPath, args...)
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
a.Logger().WithError(err).Error("updating Block device with newFile path")
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) HotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "HotplugAddDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
switch devType {
|
|
||||||
case BlockDev:
|
|
||||||
//The drive placeholder has to exist prior to Update
|
|
||||||
return nil, a.updateBlockDevice(devInfo.(*config.BlockDrive))
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("HotplugAddDevice: unsupported device: devInfo:%v, deviceType%v",
|
|
||||||
devInfo, devType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) HotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "HotplugRemoveDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Not supported. return success
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) PauseVM(ctx context.Context) error {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "PauseVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Not supported. return success
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) ResumeVM(ctx context.Context) error {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "ResumeVM", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Not supported. return success
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddDevice will add extra devices to acrn command line.
|
|
||||||
func (a *Acrn) AddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
|
||||||
var err error
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "AddDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
switch v := devInfo.(type) {
|
|
||||||
case types.Volume:
|
|
||||||
// Not supported. return success
|
|
||||||
err = nil
|
|
||||||
case types.Socket:
|
|
||||||
a.acrnConfig.Devices = a.arch.appendSocket(a.acrnConfig.Devices, v)
|
|
||||||
case types.VSock:
|
|
||||||
a.acrnConfig.Devices = a.arch.appendVSock(a.acrnConfig.Devices, v)
|
|
||||||
case Endpoint:
|
|
||||||
a.acrnConfig.Devices = a.arch.appendNetwork(a.acrnConfig.Devices, v)
|
|
||||||
case config.BlockDrive:
|
|
||||||
a.acrnConfig.Devices = a.arch.appendBlockDevice(a.acrnConfig.Devices, v)
|
|
||||||
case config.VhostUserDeviceAttrs:
|
|
||||||
// Not supported. return success
|
|
||||||
err = nil
|
|
||||||
case config.VFIODev:
|
|
||||||
// Not supported. return success
|
|
||||||
err = nil
|
|
||||||
default:
|
|
||||||
err = nil
|
|
||||||
a.Logger().WithField("unknown-device-type", devInfo).Error("Adding device")
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetVMConsole builds the path of the console where we can read logs coming
|
|
||||||
// from the sandbox.
|
|
||||||
func (a *Acrn) GetVMConsole(ctx context.Context, id string) (string, string, error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "GetVMConsole", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
consoleURL, err := utils.BuildSocketPath(a.config.VMStorePath, id, acrnConsoleSocket)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
a.Logger().Error("GetVMConsole returned error")
|
|
||||||
return consoleProtoUnix, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return consoleProtoUnix, consoleURL, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) SaveVM() error {
|
|
||||||
a.Logger().Info("Save sandbox")
|
|
||||||
|
|
||||||
// Not supported. return success
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) Disconnect(ctx context.Context) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "Disconnect", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Not supported.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) GetThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "GetThreadIDs", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
// Not supported. return success
|
|
||||||
//Just allocating an empty map
|
|
||||||
|
|
||||||
return VcpuThreadIDs{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) GetTotalMemoryMB(ctx context.Context) uint32 {
|
|
||||||
return a.config.MemorySize
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) ResizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
|
||||||
return 0, MemoryDevice{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) ResizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
|
||||||
return 0, 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) Cleanup(ctx context.Context) error {
|
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "Cleanup", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) GetPids() []int {
|
|
||||||
return []int{a.state.PID}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) GetVirtioFsPid() *int {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error {
|
|
||||||
return errors.New("acrn is not supported by VM cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) toGrpc(ctx context.Context) ([]byte, error) {
|
|
||||||
return nil, errors.New("acrn is not supported by VM cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) Save() (s hv.HypervisorState) {
|
|
||||||
s.Pid = a.state.PID
|
|
||||||
s.Type = string(AcrnHypervisor)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) Load(s hv.HypervisorState) {
|
|
||||||
a.state.PID = s.Pid
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) Check() error {
|
|
||||||
if err := syscall.Kill(a.state.PID, syscall.Signal(0)); err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to ping acrn process")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) GenerateSocket(id string) (interface{}, error) {
|
|
||||||
socket, err := generateVMSocket(id, a.config.VMStorePath)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
vsock, _ := socket.(types.VSock)
|
|
||||||
vsock.VhostFd.Close()
|
|
||||||
|
|
||||||
return socket, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Acrn) IsRateLimiterBuiltin() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
@ -1,802 +0,0 @@
|
|||||||
//go:build linux
|
|
||||||
|
|
||||||
// Copyright (c) 2019 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
package virtcontainers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type acrnArch interface {
|
|
||||||
|
|
||||||
// acrnPath returns the path to the acrn binary
|
|
||||||
acrnPath() (string, error)
|
|
||||||
|
|
||||||
// acrnctlPath returns the path to the acrnctl binary
|
|
||||||
acrnctlPath() (string, error)
|
|
||||||
|
|
||||||
// kernelParameters returns the kernel parameters
|
|
||||||
// if debug is true then kernel debug parameters are included
|
|
||||||
kernelParameters(debug bool) []Param
|
|
||||||
|
|
||||||
//capabilities returns the capabilities supported by acrn
|
|
||||||
capabilities(config HypervisorConfig) types.Capabilities
|
|
||||||
|
|
||||||
// memoryTopology returns the memory topology using the given amount of memoryMb and hostMemoryMb
|
|
||||||
memoryTopology(memMb uint64) Memory
|
|
||||||
|
|
||||||
// appendConsole appends a console to devices
|
|
||||||
appendConsole(devices []Device, path string) []Device
|
|
||||||
|
|
||||||
// appendImage appends an image to devices
|
|
||||||
appendImage(devices []Device, path string) ([]Device, error)
|
|
||||||
|
|
||||||
// appendBridges appends bridges to devices
|
|
||||||
appendBridges(devices []Device) []Device
|
|
||||||
|
|
||||||
// appendLPC appends LPC to devices
|
|
||||||
// UART device emulated by the acrn-dm is connected to the system by the LPC bus
|
|
||||||
appendLPC(devices []Device) []Device
|
|
||||||
|
|
||||||
// appendSocket appends a socket to devices
|
|
||||||
appendSocket(devices []Device, socket types.Socket) []Device
|
|
||||||
|
|
||||||
// appendVSock appends a vsock PCI to devices
|
|
||||||
appendVSock(devices []Device, vsock types.VSock) []Device
|
|
||||||
|
|
||||||
// appendNetwork appends a endpoint device to devices
|
|
||||||
appendNetwork(devices []Device, endpoint Endpoint) []Device
|
|
||||||
|
|
||||||
// appendBlockDevice appends a block drive to devices
|
|
||||||
appendBlockDevice(devices []Device, drive config.BlockDrive) []Device
|
|
||||||
|
|
||||||
// handleImagePath handles the Hypervisor Config image path
|
|
||||||
handleImagePath(config HypervisorConfig) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type acrnArchBase struct {
|
|
||||||
path string
|
|
||||||
ctlpath string
|
|
||||||
kernelParamsNonDebug []Param
|
|
||||||
kernelParamsDebug []Param
|
|
||||||
kernelParams []Param
|
|
||||||
}
|
|
||||||
|
|
||||||
const acrnPath = "/usr/bin/acrn-dm"
|
|
||||||
const acrnctlPath = "/usr/bin/acrnctl"
|
|
||||||
|
|
||||||
// acrn GVT-g slot is harded code to 2 as there is
|
|
||||||
// no simple way to pass arguments of PCI slots from
|
|
||||||
// device model (acrn-dm) to ACRNGT module.
|
|
||||||
const acrnGVTgReservedSlot = 2
|
|
||||||
|
|
||||||
const acrnLPCDev = "lpc"
|
|
||||||
const acrnHostBridge = "hostbridge"
|
|
||||||
|
|
||||||
var baselogger *logrus.Entry
|
|
||||||
|
|
||||||
// AcrnBlkDevPoolSz defines the number of dummy virtio-blk
|
|
||||||
// device that will be created for hot-plugging container
|
|
||||||
// rootfs. Since acrn doesn't support hot-plug, dummy virtio-blk
|
|
||||||
// devices are added and later replaced with container-rootfs.
|
|
||||||
var AcrnBlkDevPoolSz = 8
|
|
||||||
|
|
||||||
// AcrnBlkdDevSlot array provides translation between
|
|
||||||
// the vitio-blk device index and slot it is currently
|
|
||||||
// attached.
|
|
||||||
// Allocating extra 1 to accommodate for VM rootfs
|
|
||||||
// which is at driveIndex 0
|
|
||||||
var AcrnBlkdDevSlot = make([]int, AcrnBlkDevPoolSz+1)
|
|
||||||
|
|
||||||
// acrnKernelParamsNonDebug is a list of the default kernel
|
|
||||||
// parameters that will be used in standard (non-debug) mode.
|
|
||||||
var acrnKernelParamsNonDebug = []Param{
|
|
||||||
{"quiet", ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
// acrnKernelParamsSystemdNonDebug is a list of the default systemd related
|
|
||||||
// kernel parameters that will be used in standard (non-debug) mode.
|
|
||||||
var acrnKernelParamsSystemdNonDebug = []Param{
|
|
||||||
{"systemd.show_status", "false"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// acrnKernelParamsDebug is a list of the default kernel
|
|
||||||
// parameters that will be used in debug mode (as much boot output as
|
|
||||||
// possible).
|
|
||||||
var acrnKernelParamsDebug = []Param{
|
|
||||||
{"debug", ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
// acrnKernelParamsSystemdDebug is a list of the default systemd related kernel
|
|
||||||
// parameters that will be used in debug mode (as much boot output as
|
|
||||||
// possible).
|
|
||||||
var acrnKernelParamsSystemdDebug = []Param{
|
|
||||||
{"systemd.show_status", "true"},
|
|
||||||
{"systemd.log_level", "debug"},
|
|
||||||
{"systemd.log_target", "kmsg"},
|
|
||||||
{"printk.devkmsg", "on"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acrnKernelRootParams = []Param{
|
|
||||||
{"root", "/dev/vda1 rw rootwait"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acrnKernelParams = []Param{
|
|
||||||
{"tsc", "reliable"},
|
|
||||||
{"no_timer_check", ""},
|
|
||||||
{"nohpet", ""},
|
|
||||||
{"console", "tty0"},
|
|
||||||
{"console", "ttyS0"},
|
|
||||||
{"console", "hvc0"},
|
|
||||||
{"log_buf_len", "16M"},
|
|
||||||
{"consoleblank", "0"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device is the acrn device interface.
|
|
||||||
type Device interface {
|
|
||||||
Valid() bool
|
|
||||||
AcrnParams(slot int, config *Config) []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConsoleDeviceBackend is the character device backend for acrn
|
|
||||||
type ConsoleDeviceBackend string
|
|
||||||
|
|
||||||
const (
|
|
||||||
|
|
||||||
// Socket creates a 2 way stream socket (TCP or Unix).
|
|
||||||
Socket ConsoleDeviceBackend = "socket"
|
|
||||||
|
|
||||||
// Stdio sends traffic from the guest to acrn's standard output.
|
|
||||||
Stdio ConsoleDeviceBackend = "console"
|
|
||||||
|
|
||||||
// File backend only supports console output to a file (no input).
|
|
||||||
File ConsoleDeviceBackend = "file"
|
|
||||||
|
|
||||||
// TTY is an alias for Serial.
|
|
||||||
TTY ConsoleDeviceBackend = "tty"
|
|
||||||
|
|
||||||
// PTY creates a new pseudo-terminal on the host and connect to it.
|
|
||||||
PTY ConsoleDeviceBackend = "pty"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BEPortType marks the port as console port or virtio-serial port
|
|
||||||
type BEPortType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// SerialBE marks the port as serial port
|
|
||||||
SerialBE BEPortType = iota
|
|
||||||
|
|
||||||
//ConsoleBE marks the port as console port (append @)
|
|
||||||
ConsoleBE
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConsoleDevice represents a acrn console device.
|
|
||||||
type ConsoleDevice struct {
|
|
||||||
// Name of the socket
|
|
||||||
Name string
|
|
||||||
|
|
||||||
//Path to virtio-console backend (can be omitted for pty, tty, stdio)
|
|
||||||
Path string
|
|
||||||
|
|
||||||
//Backend device used for virtio-console
|
|
||||||
Backend ConsoleDeviceBackend
|
|
||||||
|
|
||||||
// PortType marks the port as serial or console port (@)
|
|
||||||
PortType BEPortType
|
|
||||||
}
|
|
||||||
|
|
||||||
// VSOCKDevice represents a AF_VSOCK socket.
|
|
||||||
type VSOCKDevice struct {
|
|
||||||
//Guest CID assigned by Host.
|
|
||||||
ContextID uint64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetDeviceType is a acrn networking device type.
|
|
||||||
type NetDeviceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// TAP is a TAP networking device type.
|
|
||||||
TAP NetDeviceType = "tap"
|
|
||||||
|
|
||||||
// MACVTAP is a macvtap networking device type.
|
|
||||||
MACVTAP NetDeviceType = "macvtap"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NetDevice represents a guest networking device
|
|
||||||
type NetDevice struct {
|
|
||||||
// Type is the netdev type (e.g. tap).
|
|
||||||
Type NetDeviceType
|
|
||||||
|
|
||||||
// IfName is the interface name
|
|
||||||
IFName string
|
|
||||||
|
|
||||||
//MACAddress is the networking device interface MAC address
|
|
||||||
MACAddress string
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlockDevice represents a acrn block device.
|
|
||||||
type BlockDevice struct {
|
|
||||||
|
|
||||||
// mem path to block device
|
|
||||||
FilePath string
|
|
||||||
|
|
||||||
//BlkIndex - Blk index corresponding to slot
|
|
||||||
Index int
|
|
||||||
}
|
|
||||||
|
|
||||||
// BridgeDevice represents a acrn bridge device like pci-bridge, pxb, etc.
|
|
||||||
type BridgeDevice struct {
|
|
||||||
// Emul is a string describing the type of PCI device e.g. virtio-net
|
|
||||||
Emul string
|
|
||||||
|
|
||||||
// Config is an optional string, depending on the device, that can be
|
|
||||||
// used for configuration
|
|
||||||
Config string
|
|
||||||
|
|
||||||
// Function is PCI function. Func can be from 0 to 7
|
|
||||||
Function int
|
|
||||||
}
|
|
||||||
|
|
||||||
// LPCDevice represents a acrn LPC device
|
|
||||||
type LPCDevice struct {
|
|
||||||
// Emul is a string describing the type of PCI device e.g. virtio-net
|
|
||||||
Emul string
|
|
||||||
|
|
||||||
// Function is PCI function. Func can be from 0 to 7
|
|
||||||
Function int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Memory is the guest memory configuration structure.
|
|
||||||
type Memory struct {
|
|
||||||
// Size is the amount of memory made available to the guest.
|
|
||||||
// It should be suffixed with M or G for sizes in megabytes or
|
|
||||||
// gigabytes respectively.
|
|
||||||
Size string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kernel is the guest kernel configuration structure.
|
|
||||||
type Kernel struct {
|
|
||||||
// Path is the guest kernel path on the host filesystem.
|
|
||||||
Path string
|
|
||||||
|
|
||||||
// InitrdPath is the guest initrd path on the host filesystem.
|
|
||||||
ImagePath string
|
|
||||||
|
|
||||||
// Params is the kernel parameters string.
|
|
||||||
Params string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config is the acrn configuration structure.
|
|
||||||
// It allows for passing custom settings and parameters to the acrn-dm API.
|
|
||||||
type Config struct {
|
|
||||||
// Devices is a list of devices for acrn to create and drive.
|
|
||||||
Devices []Device
|
|
||||||
|
|
||||||
// Path is the acrn binary path.
|
|
||||||
Path string
|
|
||||||
|
|
||||||
// Path is the acrn binary path.
|
|
||||||
CtlPath string
|
|
||||||
|
|
||||||
// Name is the acrn guest name
|
|
||||||
Name string
|
|
||||||
|
|
||||||
// APICID to identify vCPU that will be assigned for this VM.
|
|
||||||
ApicID string
|
|
||||||
|
|
||||||
// Kernel is the guest kernel configuration.
|
|
||||||
Kernel Kernel
|
|
||||||
|
|
||||||
// Memory is the guest memory configuration.
|
|
||||||
Memory Memory
|
|
||||||
|
|
||||||
acrnParams []string
|
|
||||||
|
|
||||||
// ACPI virtualization support
|
|
||||||
ACPIVirt bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxAcrnVCPUs returns the maximum number of vCPUs supported
|
|
||||||
func MaxAcrnVCPUs() uint32 {
|
|
||||||
return uint32(8)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAcrnArch(config HypervisorConfig) (acrnArch, error) {
|
|
||||||
a := &acrnArchBase{
|
|
||||||
path: acrnPath,
|
|
||||||
ctlpath: acrnctlPath,
|
|
||||||
kernelParamsNonDebug: acrnKernelParamsNonDebug,
|
|
||||||
kernelParamsDebug: acrnKernelParamsDebug,
|
|
||||||
kernelParams: acrnKernelParams,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := a.handleImagePath(config); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return a, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) acrnPath() (string, error) {
|
|
||||||
p := a.path
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) acrnctlPath() (string, error) {
|
|
||||||
ctlpath := a.ctlpath
|
|
||||||
return ctlpath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) kernelParameters(debug bool) []Param {
|
|
||||||
params := a.kernelParams
|
|
||||||
|
|
||||||
if debug {
|
|
||||||
params = append(params, a.kernelParamsDebug...)
|
|
||||||
} else {
|
|
||||||
params = append(params, a.kernelParamsNonDebug...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) memoryTopology(memoryMb uint64) Memory {
|
|
||||||
mem := fmt.Sprintf("%dM", memoryMb)
|
|
||||||
memory := Memory{
|
|
||||||
Size: mem,
|
|
||||||
}
|
|
||||||
|
|
||||||
return memory
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) capabilities(config HypervisorConfig) types.Capabilities {
|
|
||||||
var caps types.Capabilities
|
|
||||||
|
|
||||||
caps.SetBlockDeviceSupport()
|
|
||||||
caps.SetBlockDeviceHotplugSupport()
|
|
||||||
caps.SetNetworkDeviceHotplugSupported()
|
|
||||||
|
|
||||||
return caps
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns true if the CharDevice structure is valid and complete.
|
|
||||||
func (cdev ConsoleDevice) Valid() bool {
|
|
||||||
if cdev.Backend != "tty" && cdev.Backend != "pty" &&
|
|
||||||
cdev.Backend != "console" && cdev.Backend != "socket" &&
|
|
||||||
cdev.Backend != "file" {
|
|
||||||
return false
|
|
||||||
} else if cdev.PortType != ConsoleBE && cdev.PortType != SerialBE {
|
|
||||||
return false
|
|
||||||
} else if cdev.Path == "" {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this console device.
|
|
||||||
func (cdev ConsoleDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
var deviceParams []string
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf("%d,virtio-console,", slot))
|
|
||||||
|
|
||||||
if cdev.PortType == ConsoleBE {
|
|
||||||
deviceParams = append(deviceParams, "@")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch cdev.Backend {
|
|
||||||
case "pty":
|
|
||||||
deviceParams = append(deviceParams, "pty:pty_port")
|
|
||||||
case "tty":
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf("tty:tty_port=%s", cdev.Path))
|
|
||||||
case "socket":
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf("socket:%s=%s", cdev.Name, cdev.Path))
|
|
||||||
case "file":
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf("file:file_port=%s", cdev.Path))
|
|
||||||
case "stdio":
|
|
||||||
deviceParams = append(deviceParams, "stdio:stdio_port")
|
|
||||||
default:
|
|
||||||
// do nothing. Error should be already caught
|
|
||||||
}
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, strings.Join(deviceParams, ""))
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnNetdevParam converts to the acrn type to string
|
|
||||||
func (netdev NetDevice) AcrnNetdevParam() []string {
|
|
||||||
var deviceParams []string
|
|
||||||
|
|
||||||
switch netdev.Type {
|
|
||||||
case TAP:
|
|
||||||
deviceParams = append(deviceParams, netdev.IFName)
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress))
|
|
||||||
case MACVTAP:
|
|
||||||
deviceParams = append(deviceParams, netdev.IFName)
|
|
||||||
deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress))
|
|
||||||
default:
|
|
||||||
deviceParams = append(deviceParams, netdev.IFName)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return deviceParams
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MinimalGuestCID is the smallest valid context ID for a guest.
|
|
||||||
MinimalGuestCID uint64 = 3
|
|
||||||
|
|
||||||
// MaxGuestCID is the largest valid context ID for a guest.
|
|
||||||
MaxGuestCID uint64 = 1<<32 - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// Valid returns true if the VSOCKDevice structure is valid and complete.
|
|
||||||
func (vsock VSOCKDevice) Valid() bool {
|
|
||||||
if vsock.ContextID < MinimalGuestCID || vsock.ContextID > MaxGuestCID {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this vsock device.
|
|
||||||
func (vsock VSOCKDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
acrnParams = append(acrnParams, fmt.Sprintf("%d,vhost-vsock,cid=%d", slot, uint32(vsock.ContextID)))
|
|
||||||
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns true if the NetDevice structure is valid and complete.
|
|
||||||
func (netdev NetDevice) Valid() bool {
|
|
||||||
if netdev.IFName == "" {
|
|
||||||
return false
|
|
||||||
} else if netdev.MACAddress == "" {
|
|
||||||
return false
|
|
||||||
} else if netdev.Type != TAP && netdev.Type != MACVTAP {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this network device.
|
|
||||||
func (netdev NetDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
acrnParams = append(acrnParams, fmt.Sprintf("%d,virtio-net,%s", slot, strings.Join(netdev.AcrnNetdevParam(), "")))
|
|
||||||
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns true if the BlockDevice structure is valid and complete.
|
|
||||||
func (blkdev BlockDevice) Valid() bool {
|
|
||||||
return blkdev.FilePath != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this block device.
|
|
||||||
func (blkdev BlockDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
|
|
||||||
device := "virtio-blk"
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
acrnParams = append(acrnParams, fmt.Sprintf("%d,%s,%s",
|
|
||||||
slot, device, blkdev.FilePath))
|
|
||||||
|
|
||||||
// Update the global array (BlkIndex<->slot)
|
|
||||||
// Used to identify slots for the hot-plugged virtio-blk devices
|
|
||||||
if blkdev.Index <= AcrnBlkDevPoolSz {
|
|
||||||
AcrnBlkdDevSlot[blkdev.Index] = slot
|
|
||||||
} else {
|
|
||||||
baselogger.WithFields(logrus.Fields{
|
|
||||||
"device": device,
|
|
||||||
"index": blkdev.Index,
|
|
||||||
}).Info("Invalid index device")
|
|
||||||
}
|
|
||||||
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns true if the BridgeDevice structure is valid and complete.
|
|
||||||
func (bridgeDev BridgeDevice) Valid() bool {
|
|
||||||
if bridgeDev.Function != 0 || bridgeDev.Emul != acrnHostBridge {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this bridge device.
|
|
||||||
func (bridgeDev BridgeDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
acrnParams = append(acrnParams, fmt.Sprintf("%d:%d,%s", slot,
|
|
||||||
bridgeDev.Function, bridgeDev.Emul))
|
|
||||||
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid returns true if the BridgeDevice structure is valid and complete.
|
|
||||||
func (lpcDev LPCDevice) Valid() bool {
|
|
||||||
return lpcDev.Emul == acrnLPCDev
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcrnParams returns the acrn parameters built out of this bridge device.
|
|
||||||
func (lpcDev LPCDevice) AcrnParams(slot int, config *Config) []string {
|
|
||||||
var acrnParams []string
|
|
||||||
var deviceParams []string
|
|
||||||
|
|
||||||
acrnParams = append(acrnParams, "-s")
|
|
||||||
acrnParams = append(acrnParams, fmt.Sprintf("%d:%d,%s", slot,
|
|
||||||
lpcDev.Function, lpcDev.Emul))
|
|
||||||
|
|
||||||
//define UART port
|
|
||||||
deviceParams = append(deviceParams, "-l")
|
|
||||||
deviceParams = append(deviceParams, "com1,stdio")
|
|
||||||
acrnParams = append(acrnParams, strings.Join(deviceParams, ""))
|
|
||||||
|
|
||||||
return acrnParams
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendName() {
|
|
||||||
if config.Name != "" {
|
|
||||||
config.acrnParams = append(config.acrnParams, config.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendDevices() {
|
|
||||||
slot := 0
|
|
||||||
for _, d := range config.Devices {
|
|
||||||
if !d.Valid() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if slot == acrnGVTgReservedSlot {
|
|
||||||
slot++ /*Slot 2 is assigned for GVT-g in acrn, so skip 2 */
|
|
||||||
baselogger.Info("Slot 2 is assigned for GVT-g in acrn, so skipping this slot")
|
|
||||||
|
|
||||||
}
|
|
||||||
config.acrnParams = append(config.acrnParams, d.AcrnParams(slot, config)...)
|
|
||||||
slot++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendACPI() {
|
|
||||||
if config.ACPIVirt {
|
|
||||||
config.acrnParams = append(config.acrnParams, "-A")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendMemory() {
|
|
||||||
if config.Memory.Size != "" {
|
|
||||||
config.acrnParams = append(config.acrnParams, "-m")
|
|
||||||
config.acrnParams = append(config.acrnParams, config.Memory.Size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendCPUAffinity() {
|
|
||||||
if config.ApicID == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
config.acrnParams = append(config.acrnParams, "--cpu_affinity")
|
|
||||||
config.acrnParams = append(config.acrnParams, config.ApicID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) appendKernel() {
|
|
||||||
if config.Kernel.Path == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
config.acrnParams = append(config.acrnParams, "-k")
|
|
||||||
config.acrnParams = append(config.acrnParams, config.Kernel.Path)
|
|
||||||
|
|
||||||
if config.Kernel.Params == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
config.acrnParams = append(config.acrnParams, "-B")
|
|
||||||
config.acrnParams = append(config.acrnParams, config.Kernel.Params)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LaunchAcrn can be used to launch a new acrn instance.
|
|
||||||
//
|
|
||||||
// The Config parameter contains a set of acrn parameters and settings.
|
|
||||||
//
|
|
||||||
// This function writes its log output via logger parameter.
|
|
||||||
func LaunchAcrn(config Config, logger *logrus.Entry) (int, string, error) {
|
|
||||||
baselogger = logger
|
|
||||||
config.appendACPI()
|
|
||||||
config.appendMemory()
|
|
||||||
config.appendDevices()
|
|
||||||
config.appendCPUAffinity()
|
|
||||||
config.appendKernel()
|
|
||||||
config.appendName()
|
|
||||||
|
|
||||||
return LaunchCustomAcrn(context.Background(), config.Path, config.acrnParams, logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LaunchCustomAcrn can be used to launch a new acrn instance.
|
|
||||||
//
|
|
||||||
// The path parameter is used to pass the acrn executable path.
|
|
||||||
//
|
|
||||||
// params is a slice of options to pass to acrn-dm
|
|
||||||
//
|
|
||||||
// This function writes its log output via logger parameter.
|
|
||||||
func LaunchCustomAcrn(ctx context.Context, path string, params []string,
|
|
||||||
logger *logrus.Entry) (int, string, error) {
|
|
||||||
|
|
||||||
errStr := ""
|
|
||||||
|
|
||||||
if path == "" {
|
|
||||||
path = "acrn-dm"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* #nosec */
|
|
||||||
cmd := exec.CommandContext(ctx, path, params...)
|
|
||||||
|
|
||||||
var stderr bytes.Buffer
|
|
||||||
cmd.Stderr = &stderr
|
|
||||||
logger.WithFields(logrus.Fields{
|
|
||||||
"Path": path,
|
|
||||||
"Params": params,
|
|
||||||
}).Info("launching acrn with:")
|
|
||||||
|
|
||||||
err := cmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("Unable to launch %s: %v", path, err)
|
|
||||||
errStr = stderr.String()
|
|
||||||
logger.Errorf("%s", errStr)
|
|
||||||
}
|
|
||||||
return cmd.Process.Pid, errStr, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendImage(devices []Device, path string) ([]Device, error) {
|
|
||||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ImgBlkdevice := BlockDevice{
|
|
||||||
FilePath: path,
|
|
||||||
Index: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = append(devices, ImgBlkdevice)
|
|
||||||
|
|
||||||
return devices, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendBridges appends to devices the given bridges
|
|
||||||
func (a *acrnArchBase) appendBridges(devices []Device) []Device {
|
|
||||||
devices = append(devices,
|
|
||||||
BridgeDevice{
|
|
||||||
Function: 0,
|
|
||||||
Emul: acrnHostBridge,
|
|
||||||
Config: "",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendBridges appends to devices the given bridges
|
|
||||||
func (a *acrnArchBase) appendLPC(devices []Device) []Device {
|
|
||||||
devices = append(devices,
|
|
||||||
LPCDevice{
|
|
||||||
Function: 0,
|
|
||||||
Emul: acrnLPCDev,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendConsole(devices []Device, path string) []Device {
|
|
||||||
console := ConsoleDevice{
|
|
||||||
Name: "console0",
|
|
||||||
Backend: Socket,
|
|
||||||
PortType: ConsoleBE,
|
|
||||||
Path: path,
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = append(devices, console)
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendSocket(devices []Device, socket types.Socket) []Device {
|
|
||||||
serailsocket := ConsoleDevice{
|
|
||||||
Name: socket.Name,
|
|
||||||
Backend: Socket,
|
|
||||||
PortType: SerialBE,
|
|
||||||
Path: socket.HostPath,
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = append(devices, serailsocket)
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendVSock(devices []Device, vsock types.VSock) []Device {
|
|
||||||
vmsock := VSOCKDevice{
|
|
||||||
ContextID: vsock.ContextID,
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = append(devices, vmsock)
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func networkModelToAcrnType(model NetInterworkingModel) NetDeviceType {
|
|
||||||
switch model {
|
|
||||||
case NetXConnectMacVtapModel:
|
|
||||||
return MACVTAP
|
|
||||||
default:
|
|
||||||
//TAP should work for most other cases
|
|
||||||
return TAP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendNetwork(devices []Device, endpoint Endpoint) []Device {
|
|
||||||
switch ep := endpoint.(type) {
|
|
||||||
case *VethEndpoint:
|
|
||||||
netPair := ep.NetworkPair()
|
|
||||||
devices = append(devices,
|
|
||||||
NetDevice{
|
|
||||||
Type: networkModelToAcrnType(netPair.NetInterworkingModel),
|
|
||||||
IFName: netPair.TAPIface.Name,
|
|
||||||
MACAddress: netPair.TAPIface.HardAddr,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
case *MacvtapEndpoint:
|
|
||||||
devices = append(devices,
|
|
||||||
NetDevice{
|
|
||||||
Type: MACVTAP,
|
|
||||||
IFName: ep.Name(),
|
|
||||||
MACAddress: ep.HardwareAddr(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
default:
|
|
||||||
// Return devices as is for unsupported endpoint.
|
|
||||||
baselogger.WithField("Endpoint", endpoint).Error("Unsupported N/W Endpoint")
|
|
||||||
}
|
|
||||||
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) appendBlockDevice(devices []Device, drive config.BlockDrive) []Device {
|
|
||||||
if drive.File == "" {
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = append(devices,
|
|
||||||
BlockDevice{
|
|
||||||
FilePath: drive.File,
|
|
||||||
Index: drive.Index,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return devices
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrnArchBase) handleImagePath(config HypervisorConfig) error {
|
|
||||||
if config.ImagePath != "" {
|
|
||||||
a.kernelParams = append(a.kernelParams, acrnKernelRootParams...)
|
|
||||||
a.kernelParamsNonDebug = append(a.kernelParamsNonDebug, acrnKernelParamsSystemdNonDebug...)
|
|
||||||
a.kernelParamsDebug = append(a.kernelParamsDebug, acrnKernelParamsSystemdDebug...)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,305 +0,0 @@
|
|||||||
// Copyright (c) 2019 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
//go:build linux
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package virtcontainers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/fs"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
acrnArchBaseAcrnPath = "/usr/bin/acrn"
|
|
||||||
acrnArchBaseAcrnCtlPath = "/usr/bin/acrnctl"
|
|
||||||
)
|
|
||||||
|
|
||||||
var acrnArchBaseKernelParamsNonDebug = []Param{
|
|
||||||
{"quiet", ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acrnArchBaseKernelParamsDebug = []Param{
|
|
||||||
{"debug", ""},
|
|
||||||
}
|
|
||||||
|
|
||||||
var acrnArchBaseKernelParams = []Param{
|
|
||||||
{"root", "/dev/vda"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAcrnArchBase() *acrnArchBase {
|
|
||||||
return &acrnArchBase{
|
|
||||||
path: acrnArchBaseAcrnPath,
|
|
||||||
ctlpath: acrnArchBaseAcrnCtlPath,
|
|
||||||
kernelParamsNonDebug: acrnArchBaseKernelParamsNonDebug,
|
|
||||||
kernelParamsDebug: acrnArchBaseKernelParamsDebug,
|
|
||||||
kernelParams: acrnArchBaseKernelParams,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAcrnPaths(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
p, err := acrnArchBase.acrnPath()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(p, acrnArchBaseAcrnPath)
|
|
||||||
|
|
||||||
ctlp, err := acrnArchBase.acrnctlPath()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(ctlp, acrnArchBaseAcrnCtlPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseKernelParameters(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
// with debug params
|
|
||||||
expectedParams := acrnArchBaseKernelParams
|
|
||||||
debugParams := acrnArchBaseKernelParamsDebug
|
|
||||||
expectedParams = append(expectedParams, debugParams...)
|
|
||||||
p := acrnArchBase.kernelParameters(true)
|
|
||||||
assert.Equal(expectedParams, p)
|
|
||||||
|
|
||||||
// with non-debug params
|
|
||||||
expectedParams = acrnArchBaseKernelParams
|
|
||||||
nonDebugParams := acrnArchBaseKernelParamsNonDebug
|
|
||||||
expectedParams = append(expectedParams, nonDebugParams...)
|
|
||||||
p = acrnArchBase.kernelParameters(false)
|
|
||||||
assert.Equal(expectedParams, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseCapabilities(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
config := HypervisorConfig{}
|
|
||||||
|
|
||||||
c := acrnArchBase.capabilities(config)
|
|
||||||
assert.True(c.IsBlockDeviceSupported())
|
|
||||||
assert.True(c.IsBlockDeviceHotplugSupported())
|
|
||||||
assert.False(c.IsFsSharingSupported())
|
|
||||||
assert.True(c.IsNetworkDeviceHotplugSupported())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseMemoryTopology(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
mem := uint64(8192)
|
|
||||||
|
|
||||||
expectedMemory := Memory{
|
|
||||||
Size: fmt.Sprintf("%dM", mem),
|
|
||||||
}
|
|
||||||
|
|
||||||
m := acrnArchBase.memoryTopology(mem)
|
|
||||||
assert.Equal(expectedMemory, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendConsoles(t *testing.T) {
|
|
||||||
var devices []Device
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
path := filepath.Join(filepath.Join(fs.MockRunStoragePath(), "test"), consoleSocket)
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
ConsoleDevice{
|
|
||||||
Name: "console0",
|
|
||||||
Backend: Socket,
|
|
||||||
PortType: ConsoleBE,
|
|
||||||
Path: path,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = acrnArchBase.appendConsole(devices, path)
|
|
||||||
assert.Equal(expectedOut, devices)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendImage(t *testing.T) {
|
|
||||||
var devices []Device
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
image, err := os.CreateTemp("", "img")
|
|
||||||
assert.NoError(err)
|
|
||||||
defer os.Remove(image.Name())
|
|
||||||
err = image.Close()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
devices, err = acrnArchBase.appendImage(devices, image.Name())
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Len(devices, 1)
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
BlockDevice{
|
|
||||||
FilePath: image.Name(),
|
|
||||||
Index: 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(expectedOut, devices)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendBridges(t *testing.T) {
|
|
||||||
function := 0
|
|
||||||
emul := acrnHostBridge
|
|
||||||
config := ""
|
|
||||||
|
|
||||||
var devices []Device
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
devices = acrnArchBase.appendBridges(devices)
|
|
||||||
assert.Len(devices, 1)
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
BridgeDevice{
|
|
||||||
Function: function,
|
|
||||||
Emul: emul,
|
|
||||||
Config: config,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(expectedOut, devices)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendLpcDevice(t *testing.T) {
|
|
||||||
function := 0
|
|
||||||
emul := acrnLPCDev
|
|
||||||
|
|
||||||
var devices []Device
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
devices = acrnArchBase.appendLPC(devices)
|
|
||||||
assert.Len(devices, 1)
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
LPCDevice{
|
|
||||||
Function: function,
|
|
||||||
Emul: emul,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(expectedOut, devices)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAcrnArchBaseAppend(t *testing.T, structure interface{}, expected []Device) {
|
|
||||||
var devices []Device
|
|
||||||
var err error
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
switch s := structure.(type) {
|
|
||||||
case types.Socket:
|
|
||||||
devices = acrnArchBase.appendSocket(devices, s)
|
|
||||||
case config.BlockDrive:
|
|
||||||
devices = acrnArchBase.appendBlockDevice(devices, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(devices, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendSocket(t *testing.T) {
|
|
||||||
name := "archserial.test"
|
|
||||||
hostPath := "/tmp/archserial.sock"
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
ConsoleDevice{
|
|
||||||
Name: name,
|
|
||||||
Backend: Socket,
|
|
||||||
PortType: SerialBE,
|
|
||||||
Path: hostPath,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
socket := types.Socket{
|
|
||||||
HostPath: hostPath,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
testAcrnArchBaseAppend(t, socket, expectedOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendBlockDevice(t *testing.T) {
|
|
||||||
path := "/tmp/archtest.img"
|
|
||||||
index := 5
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
BlockDevice{
|
|
||||||
FilePath: path,
|
|
||||||
Index: index,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
drive := config.BlockDrive{
|
|
||||||
File: path,
|
|
||||||
Index: index,
|
|
||||||
}
|
|
||||||
|
|
||||||
testAcrnArchBaseAppend(t, drive, expectedOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnArchBaseAppendNetwork(t *testing.T) {
|
|
||||||
var devices []Device
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnArchBase := newAcrnArchBase()
|
|
||||||
|
|
||||||
macAddr := net.HardwareAddr{0x02, 0x00, 0xCA, 0xFE, 0x00, 0x04}
|
|
||||||
|
|
||||||
vethEp := &VethEndpoint{
|
|
||||||
NetPair: NetworkInterfacePair{
|
|
||||||
TapInterface: TapInterface{
|
|
||||||
ID: "uniqueTestID0",
|
|
||||||
Name: "br0_kata",
|
|
||||||
TAPIface: NetworkInterface{
|
|
||||||
Name: "tap0_kata",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
VirtIface: NetworkInterface{
|
|
||||||
Name: "eth0",
|
|
||||||
HardAddr: macAddr.String(),
|
|
||||||
},
|
|
||||||
NetInterworkingModel: DefaultNetInterworkingModel,
|
|
||||||
},
|
|
||||||
EndpointType: VethEndpointType,
|
|
||||||
}
|
|
||||||
|
|
||||||
macvtapEp := &MacvtapEndpoint{
|
|
||||||
EndpointType: MacvtapEndpointType,
|
|
||||||
EndpointProperties: NetworkInfo{
|
|
||||||
Iface: NetlinkIface{
|
|
||||||
Type: "macvtap",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
NetDevice{
|
|
||||||
Type: TAP,
|
|
||||||
IFName: vethEp.NetPair.TAPIface.Name,
|
|
||||||
MACAddress: vethEp.NetPair.TAPIface.HardAddr,
|
|
||||||
},
|
|
||||||
NetDevice{
|
|
||||||
Type: MACVTAP,
|
|
||||||
IFName: macvtapEp.Name(),
|
|
||||||
MACAddress: macvtapEp.HardwareAddr(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
devices = acrnArchBase.appendNetwork(devices, vethEp)
|
|
||||||
devices = acrnArchBase.appendNetwork(devices, macvtapEp)
|
|
||||||
assert.Equal(expectedOut, devices)
|
|
||||||
}
|
|
@ -1,287 +0,0 @@
|
|||||||
//go:build linux
|
|
||||||
|
|
||||||
// Copyright (c) 2019 Intel Corporation
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
//
|
|
||||||
|
|
||||||
package virtcontainers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/device/config"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newAcrnConfig() HypervisorConfig {
|
|
||||||
return HypervisorConfig{
|
|
||||||
KernelPath: testAcrnKernelPath,
|
|
||||||
ImagePath: testAcrnImagePath,
|
|
||||||
HypervisorPath: testAcrnPath,
|
|
||||||
HypervisorCtlPath: testAcrnCtlPath,
|
|
||||||
NumVCPUsF: defaultVCPUs,
|
|
||||||
MemorySize: defaultMemSzMiB,
|
|
||||||
BlockDeviceDriver: config.VirtioBlock,
|
|
||||||
DefaultBridges: defaultBridges,
|
|
||||||
DefaultMaxVCPUs: MaxAcrnVCPUs(),
|
|
||||||
// Adding this here, as hypervisorconfig.valid()
|
|
||||||
// forcefully adds it even when 9pfs is not supported
|
|
||||||
Msize9p: defaultMsize9p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAcrnKernelParameters(t *testing.T, kernelParams []Param, debug bool) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnConfig := newAcrnConfig()
|
|
||||||
acrnConfig.KernelParams = kernelParams
|
|
||||||
|
|
||||||
if debug == true {
|
|
||||||
acrnConfig.Debug = true
|
|
||||||
}
|
|
||||||
|
|
||||||
a := &Acrn{
|
|
||||||
config: acrnConfig,
|
|
||||||
arch: &acrnArchBase{},
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := fmt.Sprintf("panic=1 maxcpus=%d foo=foo bar=bar", a.config.DefaultMaxVCPUs)
|
|
||||||
|
|
||||||
params := a.kernelParameters()
|
|
||||||
assert.Equal(params, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnKernelParameters(t *testing.T) {
|
|
||||||
params := []Param{
|
|
||||||
{
|
|
||||||
Key: "foo",
|
|
||||||
Value: "foo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Key: "bar",
|
|
||||||
Value: "bar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
testAcrnKernelParameters(t, params, true)
|
|
||||||
testAcrnKernelParameters(t, params, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnCapabilities(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
arch: &acrnArchBase{},
|
|
||||||
}
|
|
||||||
|
|
||||||
caps := a.Capabilities(a.ctx)
|
|
||||||
assert.True(caps.IsBlockDeviceSupported())
|
|
||||||
assert.True(caps.IsBlockDeviceHotplugSupported())
|
|
||||||
assert.True(caps.IsNetworkDeviceHotplugSupported())
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAcrnAddDevice(t *testing.T, devInfo interface{}, devType DeviceType, expected []Device) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
arch: &acrnArchBase{},
|
|
||||||
}
|
|
||||||
|
|
||||||
err := a.AddDevice(context.Background(), devInfo, devType)
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Exactly(a.acrnConfig.Devices, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnAddDeviceSerialPortDev(t *testing.T) {
|
|
||||||
name := "serial.test"
|
|
||||||
hostPath := "/tmp/serial.sock"
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
ConsoleDevice{
|
|
||||||
Name: name,
|
|
||||||
Backend: Socket,
|
|
||||||
PortType: SerialBE,
|
|
||||||
Path: hostPath,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
socket := types.Socket{
|
|
||||||
HostPath: hostPath,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
testAcrnAddDevice(t, socket, SerialPortDev, expectedOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnAddDeviceBlockDev(t *testing.T) {
|
|
||||||
path := "/tmp/test.img"
|
|
||||||
index := 1
|
|
||||||
|
|
||||||
expectedOut := []Device{
|
|
||||||
BlockDevice{
|
|
||||||
FilePath: path,
|
|
||||||
Index: index,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
drive := config.BlockDrive{
|
|
||||||
File: path,
|
|
||||||
Index: index,
|
|
||||||
}
|
|
||||||
|
|
||||||
testAcrnAddDevice(t, drive, BlockDev, expectedOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnHotplugUnsupportedDeviceType(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "acrnTest",
|
|
||||||
config: acrnConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := a.HotplugAddDevice(a.ctx, &MemoryDevice{0, 128, uint64(0), false}, FsDev)
|
|
||||||
assert.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnUpdateBlockDeviceInvalidPath(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
path := ""
|
|
||||||
index := 1
|
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "acrnBlkTest",
|
|
||||||
config: acrnConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
drive := &config.BlockDrive{
|
|
||||||
File: path,
|
|
||||||
Index: index,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := a.updateBlockDevice(drive)
|
|
||||||
assert.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnUpdateBlockDeviceInvalidIdx(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
path := "/tmp/test.img"
|
|
||||||
index := AcrnBlkDevPoolSz + 1
|
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "acrnBlkTest",
|
|
||||||
config: acrnConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
drive := &config.BlockDrive{
|
|
||||||
File: path,
|
|
||||||
Index: index,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := a.updateBlockDevice(drive)
|
|
||||||
assert.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnGetSandboxConsole(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
store, err := persist.GetDriver()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
a := &Acrn{
|
|
||||||
ctx: context.Background(),
|
|
||||||
config: HypervisorConfig{
|
|
||||||
VMStorePath: store.RunVMStoragePath(),
|
|
||||||
RunStorePath: store.RunStoragePath(),
|
|
||||||
},
|
|
||||||
store: store,
|
|
||||||
}
|
|
||||||
sandboxID := "testSandboxID"
|
|
||||||
expected := filepath.Join(store.RunVMStoragePath(), sandboxID, consoleSocket)
|
|
||||||
|
|
||||||
proto, result, err := a.GetVMConsole(a.ctx, sandboxID)
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Equal(result, expected)
|
|
||||||
assert.Equal(proto, consoleProtoUnix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnCreateVM(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
acrnConfig := newAcrnConfig()
|
|
||||||
store, err := persist.GetDriver()
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
a := &Acrn{
|
|
||||||
store: store,
|
|
||||||
config: HypervisorConfig{
|
|
||||||
VMStorePath: store.RunVMStoragePath(),
|
|
||||||
RunStorePath: store.RunStoragePath(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
sandbox := &Sandbox{
|
|
||||||
ctx: context.Background(),
|
|
||||||
id: "testSandbox",
|
|
||||||
config: &SandboxConfig{
|
|
||||||
HypervisorConfig: acrnConfig,
|
|
||||||
},
|
|
||||||
state: types.SandboxState{BlockIndexMap: make(map[int]struct{})},
|
|
||||||
}
|
|
||||||
|
|
||||||
a.sandbox = sandbox
|
|
||||||
|
|
||||||
a.state.PID = 1
|
|
||||||
network, err := NewNetwork()
|
|
||||||
assert.NoError(err)
|
|
||||||
err = a.CreateVM(context.Background(), sandbox.id, network, &sandbox.config.HypervisorConfig)
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Exactly(acrnConfig, a.config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnMemoryTopology(t *testing.T) {
|
|
||||||
mem := uint32(1000)
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
a := &Acrn{
|
|
||||||
arch: &acrnArchBase{},
|
|
||||||
config: HypervisorConfig{
|
|
||||||
MemorySize: mem,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedOut := Memory{
|
|
||||||
Size: fmt.Sprintf("%dM", mem),
|
|
||||||
}
|
|
||||||
|
|
||||||
memory, err := a.memoryTopology()
|
|
||||||
assert.NoError(err)
|
|
||||||
assert.Exactly(memory, expectedOut)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAcrnSetConfig(t *testing.T) {
|
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
config := newAcrnConfig()
|
|
||||||
|
|
||||||
a := &Acrn{}
|
|
||||||
|
|
||||||
assert.Equal(a.config, HypervisorConfig{})
|
|
||||||
|
|
||||||
err := a.setConfig(&config)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
assert.Equal(a.config, config)
|
|
||||||
}
|
|
@ -102,9 +102,6 @@ const (
|
|||||||
// QemuHypervisor is the QEMU hypervisor.
|
// QemuHypervisor is the QEMU hypervisor.
|
||||||
QemuHypervisor HypervisorType = "qemu"
|
QemuHypervisor HypervisorType = "qemu"
|
||||||
|
|
||||||
// AcrnHypervisor is the ACRN hypervisor.
|
|
||||||
AcrnHypervisor HypervisorType = "acrn"
|
|
||||||
|
|
||||||
// ClhHypervisor is the ICH hypervisor.
|
// ClhHypervisor is the ICH hypervisor.
|
||||||
ClhHypervisor HypervisorType = "clh"
|
ClhHypervisor HypervisorType = "clh"
|
||||||
|
|
||||||
@ -173,12 +170,6 @@ type HypervisorConfig struct {
|
|||||||
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
||||||
HypervisorPathList []string
|
HypervisorPathList []string
|
||||||
|
|
||||||
// HypervisorCtlPathList is the list of hypervisor control paths names allowed in annotations
|
|
||||||
HypervisorCtlPathList []string
|
|
||||||
|
|
||||||
// HypervisorCtlPath is the hypervisor ctl executable host path.
|
|
||||||
HypervisorCtlPath string
|
|
||||||
|
|
||||||
// JailerPath is the jailer executable host path.
|
// JailerPath is the jailer executable host path.
|
||||||
JailerPath string
|
JailerPath string
|
||||||
|
|
||||||
|
@ -589,11 +589,7 @@ func (f *FilesystemShare) ShareRootFilesystem(ctx context.Context, c *Container)
|
|||||||
rootfsStorage.Source = blockDrive.DevNo
|
rootfsStorage.Source = blockDrive.DevNo
|
||||||
case f.sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioBlock:
|
case f.sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioBlock:
|
||||||
rootfsStorage.Driver = kataBlkDevType
|
rootfsStorage.Driver = kataBlkDevType
|
||||||
if f.sandbox.config.HypervisorType == AcrnHypervisor {
|
rootfsStorage.Source = blockDrive.PCIPath.String()
|
||||||
rootfsStorage.Source = blockDrive.VirtPath
|
|
||||||
} else {
|
|
||||||
rootfsStorage.Source = blockDrive.PCIPath.String()
|
|
||||||
}
|
|
||||||
case f.sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioSCSI:
|
case f.sandbox.config.HypervisorConfig.BlockDeviceDriver == config.VirtioSCSI:
|
||||||
rootfsStorage.Driver = kataSCSIDevType
|
rootfsStorage.Driver = kataSCSIDevType
|
||||||
rootfsStorage.Source = blockDrive.SCSIAddr
|
rootfsStorage.Source = blockDrive.SCSIAddr
|
||||||
|
@ -42,9 +42,6 @@ const (
|
|||||||
// QemuHypervisor is the QEMU hypervisor.
|
// QemuHypervisor is the QEMU hypervisor.
|
||||||
QemuHypervisor HypervisorType = "qemu"
|
QemuHypervisor HypervisorType = "qemu"
|
||||||
|
|
||||||
// AcrnHypervisor is the ACRN hypervisor.
|
|
||||||
AcrnHypervisor HypervisorType = "acrn"
|
|
||||||
|
|
||||||
// ClhHypervisor is the ICH hypervisor.
|
// ClhHypervisor is the ICH hypervisor.
|
||||||
ClhHypervisor HypervisorType = "clh"
|
ClhHypervisor HypervisorType = "clh"
|
||||||
|
|
||||||
@ -231,9 +228,6 @@ func (hType *HypervisorType) Set(value string) error {
|
|||||||
case "firecracker":
|
case "firecracker":
|
||||||
*hType = FirecrackerHypervisor
|
*hType = FirecrackerHypervisor
|
||||||
return nil
|
return nil
|
||||||
case "acrn":
|
|
||||||
*hType = AcrnHypervisor
|
|
||||||
return nil
|
|
||||||
case "clh":
|
case "clh":
|
||||||
*hType = ClhHypervisor
|
*hType = ClhHypervisor
|
||||||
return nil
|
return nil
|
||||||
@ -261,8 +255,6 @@ func (hType *HypervisorType) String() string {
|
|||||||
return string(QemuHypervisor)
|
return string(QemuHypervisor)
|
||||||
case FirecrackerHypervisor:
|
case FirecrackerHypervisor:
|
||||||
return string(FirecrackerHypervisor)
|
return string(FirecrackerHypervisor)
|
||||||
case AcrnHypervisor:
|
|
||||||
return string(AcrnHypervisor)
|
|
||||||
case ClhHypervisor:
|
case ClhHypervisor:
|
||||||
return string(ClhHypervisor)
|
return string(ClhHypervisor)
|
||||||
case StratovirtHypervisor:
|
case StratovirtHypervisor:
|
||||||
@ -357,9 +349,6 @@ type HypervisorConfig struct {
|
|||||||
// HypervisorPath is the hypervisor executable host path.
|
// HypervisorPath is the hypervisor executable host path.
|
||||||
HypervisorPath string
|
HypervisorPath string
|
||||||
|
|
||||||
// HypervisorCtlPath is the hypervisor ctl executable host path.
|
|
||||||
HypervisorCtlPath string
|
|
||||||
|
|
||||||
// JailerPath is the jailer executable host path.
|
// JailerPath is the jailer executable host path.
|
||||||
JailerPath string
|
JailerPath string
|
||||||
|
|
||||||
@ -430,9 +419,6 @@ type HypervisorConfig struct {
|
|||||||
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
||||||
HypervisorPathList []string
|
HypervisorPathList []string
|
||||||
|
|
||||||
// HypervisorCtlPathList is the list of hypervisor control paths names allowed in annotations
|
|
||||||
HypervisorCtlPathList []string
|
|
||||||
|
|
||||||
// JailerPathList is the list of jailer paths names allowed in annotations
|
// JailerPathList is the list of jailer paths names allowed in annotations
|
||||||
JailerPathList []string
|
JailerPathList []string
|
||||||
|
|
||||||
@ -809,8 +795,6 @@ func (conf *HypervisorConfig) assetPath(t types.AssetType) (string, error) {
|
|||||||
return conf.InitrdPath, nil
|
return conf.InitrdPath, nil
|
||||||
case types.HypervisorAsset:
|
case types.HypervisorAsset:
|
||||||
return conf.HypervisorPath, nil
|
return conf.HypervisorPath, nil
|
||||||
case types.HypervisorCtlAsset:
|
|
||||||
return conf.HypervisorCtlPath, nil
|
|
||||||
case types.JailerAsset:
|
case types.JailerAsset:
|
||||||
return conf.JailerPath, nil
|
return conf.JailerPath, nil
|
||||||
case types.FirmwareAsset:
|
case types.FirmwareAsset:
|
||||||
@ -866,11 +850,6 @@ func (conf *HypervisorConfig) IfPVPanicEnabled() bool {
|
|||||||
return conf.GuestMemoryDumpPath != ""
|
return conf.GuestMemoryDumpPath != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// HypervisorCtlAssetPath returns the VM hypervisor ctl path
|
|
||||||
func (conf *HypervisorConfig) HypervisorCtlAssetPath() (string, error) {
|
|
||||||
return conf.assetPath(types.HypervisorCtlAsset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CustomHypervisorAsset returns true if the hypervisor asset is a custom one, false otherwise.
|
// CustomHypervisorAsset returns true if the hypervisor asset is a custom one, false otherwise.
|
||||||
func (conf *HypervisorConfig) CustomHypervisorAsset() bool {
|
func (conf *HypervisorConfig) CustomHypervisorAsset() bool {
|
||||||
return conf.isCustomAsset(types.HypervisorAsset)
|
return conf.isCustomAsset(types.HypervisorAsset)
|
||||||
|
@ -32,8 +32,6 @@ func NewHypervisor(hType HypervisorType) (Hypervisor, error) {
|
|||||||
return &qemu{}, nil
|
return &qemu{}, nil
|
||||||
case FirecrackerHypervisor:
|
case FirecrackerHypervisor:
|
||||||
return &firecracker{}, nil
|
return &firecracker{}, nil
|
||||||
case AcrnHypervisor:
|
|
||||||
return &Acrn{}, nil
|
|
||||||
case ClhHypervisor:
|
case ClhHypervisor:
|
||||||
return &cloudHypervisor{}, nil
|
return &cloudHypervisor{}, nil
|
||||||
case StratovirtHypervisor:
|
case StratovirtHypervisor:
|
||||||
|
@ -476,8 +476,7 @@ func TestAssetPath(t *testing.T) {
|
|||||||
// The values are "paths" (start with a slash), but end with the
|
// The values are "paths" (start with a slash), but end with the
|
||||||
// annotation name.
|
// annotation name.
|
||||||
cfg := HypervisorConfig{
|
cfg := HypervisorConfig{
|
||||||
HypervisorPath: "/" + "io.katacontainers.config.hypervisor.path",
|
HypervisorPath: "/" + "io.katacontainers.config.hypervisor.path",
|
||||||
HypervisorCtlPath: "/" + "io.katacontainers.config.hypervisor.ctlpath",
|
|
||||||
|
|
||||||
KernelPath: "/" + "io.katacontainers.config.hypervisor.kernel",
|
KernelPath: "/" + "io.katacontainers.config.hypervisor.kernel",
|
||||||
|
|
||||||
|
@ -217,8 +217,6 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
|
|||||||
CPUFeatures: sconfig.HypervisorConfig.CPUFeatures,
|
CPUFeatures: sconfig.HypervisorConfig.CPUFeatures,
|
||||||
HypervisorPath: sconfig.HypervisorConfig.HypervisorPath,
|
HypervisorPath: sconfig.HypervisorConfig.HypervisorPath,
|
||||||
HypervisorPathList: sconfig.HypervisorConfig.HypervisorPathList,
|
HypervisorPathList: sconfig.HypervisorConfig.HypervisorPathList,
|
||||||
HypervisorCtlPath: sconfig.HypervisorConfig.HypervisorCtlPath,
|
|
||||||
HypervisorCtlPathList: sconfig.HypervisorConfig.HypervisorCtlPathList,
|
|
||||||
JailerPath: sconfig.HypervisorConfig.JailerPath,
|
JailerPath: sconfig.HypervisorConfig.JailerPath,
|
||||||
JailerPathList: sconfig.HypervisorConfig.JailerPathList,
|
JailerPathList: sconfig.HypervisorConfig.JailerPathList,
|
||||||
BlockDeviceDriver: sconfig.HypervisorConfig.BlockDeviceDriver,
|
BlockDeviceDriver: sconfig.HypervisorConfig.BlockDeviceDriver,
|
||||||
@ -457,8 +455,6 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
|
|||||||
CPUFeatures: hconf.CPUFeatures,
|
CPUFeatures: hconf.CPUFeatures,
|
||||||
HypervisorPath: hconf.HypervisorPath,
|
HypervisorPath: hconf.HypervisorPath,
|
||||||
HypervisorPathList: hconf.HypervisorPathList,
|
HypervisorPathList: hconf.HypervisorPathList,
|
||||||
HypervisorCtlPath: hconf.HypervisorCtlPath,
|
|
||||||
HypervisorCtlPathList: hconf.HypervisorCtlPathList,
|
|
||||||
JailerPath: hconf.JailerPath,
|
JailerPath: hconf.JailerPath,
|
||||||
JailerPathList: hconf.JailerPathList,
|
JailerPathList: hconf.JailerPathList,
|
||||||
BlockDeviceDriver: hconf.BlockDeviceDriver,
|
BlockDeviceDriver: hconf.BlockDeviceDriver,
|
||||||
|
@ -36,10 +36,6 @@ type HypervisorConfig struct {
|
|||||||
// HypervisorPath is the hypervisor executable host path.
|
// HypervisorPath is the hypervisor executable host path.
|
||||||
HypervisorPath string
|
HypervisorPath string
|
||||||
|
|
||||||
// HypervisorCtlPath is the hypervisor ctl executable host path.
|
|
||||||
HypervisorCtlPath string
|
|
||||||
|
|
||||||
// HypervisorCtlPath is the hypervisor ctl executable host path.
|
|
||||||
// JailerPath is the jailer executable host path.
|
// JailerPath is the jailer executable host path.
|
||||||
JailerPath string
|
JailerPath string
|
||||||
|
|
||||||
@ -94,9 +90,6 @@ type HypervisorConfig struct {
|
|||||||
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
|
||||||
HypervisorPathList []string
|
HypervisorPathList []string
|
||||||
|
|
||||||
// HypervisorCtlPathList is the list of hypervisor control paths names allowed in annotations
|
|
||||||
HypervisorCtlPathList []string
|
|
||||||
|
|
||||||
// JailerPathList is the list of jailer paths names allowed in annotations
|
// JailerPathList is the list of jailer paths names allowed in annotations
|
||||||
JailerPathList []string
|
JailerPathList []string
|
||||||
|
|
||||||
|
@ -18,14 +18,6 @@ type PersistDriver interface {
|
|||||||
// It returns Unlock Function and errors
|
// It returns Unlock Function and errors
|
||||||
Lock(sid string, exclusive bool) (func() error, error)
|
Lock(sid string, exclusive bool) (func() error, error)
|
||||||
|
|
||||||
// GlobalWrite writes "data" to "StorageRootPath"/"relativePath";
|
|
||||||
// GlobalRead reads "data" from "StorageRootPath"/"relativePath";
|
|
||||||
// these functions are used for writing/reading some global data,
|
|
||||||
// they are specially designed for ACRN so far.
|
|
||||||
// Don't use them too much unless you have no other choice! @weizhang555
|
|
||||||
GlobalWrite(relativePath string, data []byte) error
|
|
||||||
GlobalRead(relativePath string) ([]byte, error)
|
|
||||||
|
|
||||||
// RunStoragePath is the sandbox runtime directory.
|
// RunStoragePath is the sandbox runtime directory.
|
||||||
// It will contain one state.json and one lock file for each created sandbox.
|
// It will contain one state.json and one lock file for each created sandbox.
|
||||||
RunStoragePath() string
|
RunStoragePath() string
|
||||||
|
@ -43,15 +43,9 @@ const (
|
|||||||
// HypervisorPath is a sandbox annotation for passing a per container path pointing at the hypervisor that will run the container VM.
|
// HypervisorPath is a sandbox annotation for passing a per container path pointing at the hypervisor that will run the container VM.
|
||||||
HypervisorPath = kataAnnotHypervisorPrefix + "path"
|
HypervisorPath = kataAnnotHypervisorPrefix + "path"
|
||||||
|
|
||||||
// HypervisorCtlPath is a sandbox annotation for passing a per container path pointing at the hypervisor control binary that will run the container VM.
|
|
||||||
HypervisorCtlPath = kataAnnotHypervisorPrefix + "ctlpath"
|
|
||||||
|
|
||||||
// JailerPath is a sandbox annotation for passing a per container path pointing at the jailer that will constrain the container VM.
|
// JailerPath is a sandbox annotation for passing a per container path pointing at the jailer that will constrain the container VM.
|
||||||
JailerPath = kataAnnotHypervisorPrefix + "jailer_path"
|
JailerPath = kataAnnotHypervisorPrefix + "jailer_path"
|
||||||
|
|
||||||
// CtlPath is a sandbox annotation for passing a per container path pointing at the acrn ctl binary
|
|
||||||
CtlPath = kataAnnotHypervisorPrefix + "ctlpath"
|
|
||||||
|
|
||||||
// FirmwarePath is a sandbox annotation for passing a per container path pointing at the guest firmware that will run the container VM.
|
// FirmwarePath is a sandbox annotation for passing a per container path pointing at the guest firmware that will run the container VM.
|
||||||
FirmwarePath = kataAnnotHypervisorPrefix + "firmware"
|
FirmwarePath = kataAnnotHypervisorPrefix + "firmware"
|
||||||
|
|
||||||
@ -71,9 +65,6 @@ const (
|
|||||||
// HypervisorHash is an sandbox annotation for passing a container hypervisor binary SHA-512 hash value.
|
// HypervisorHash is an sandbox annotation for passing a container hypervisor binary SHA-512 hash value.
|
||||||
HypervisorHash = kataAnnotHypervisorPrefix + "hypervisor_hash"
|
HypervisorHash = kataAnnotHypervisorPrefix + "hypervisor_hash"
|
||||||
|
|
||||||
// HypervisorCtlHash is a sandbox annotation for passing a container hypervisor control binary SHA-512 hash value.
|
|
||||||
HypervisorCtlHash = kataAnnotHypervisorPrefix + "hypervisorctl_hash"
|
|
||||||
|
|
||||||
// JailerHash is an sandbox annotation for passing a jailer binary SHA-512 hash value.
|
// JailerHash is an sandbox annotation for passing a jailer binary SHA-512 hash value.
|
||||||
JailerHash = kataAnnotHypervisorPrefix + "jailer_hash"
|
JailerHash = kataAnnotHypervisorPrefix + "jailer_hash"
|
||||||
|
|
||||||
|
@ -673,17 +673,15 @@ func TestSandboxCreateAssets(t *testing.T) {
|
|||||||
originalInitrdPath := filepath.Join(testDir, testInitrd)
|
originalInitrdPath := filepath.Join(testDir, testInitrd)
|
||||||
originalFirmwarePath := filepath.Join(testDir, testFirmware)
|
originalFirmwarePath := filepath.Join(testDir, testFirmware)
|
||||||
originalHypervisorPath := filepath.Join(testDir, testHypervisor)
|
originalHypervisorPath := filepath.Join(testDir, testHypervisor)
|
||||||
originalHypervisorCtlPath := filepath.Join(testDir, testHypervisorCtl)
|
|
||||||
originalJailerPath := filepath.Join(testDir, testJailer)
|
originalJailerPath := filepath.Join(testDir, testJailer)
|
||||||
|
|
||||||
hc := HypervisorConfig{
|
hc := HypervisorConfig{
|
||||||
KernelPath: originalKernelPath,
|
KernelPath: originalKernelPath,
|
||||||
ImagePath: originalImagePath,
|
ImagePath: originalImagePath,
|
||||||
InitrdPath: originalInitrdPath,
|
InitrdPath: originalInitrdPath,
|
||||||
FirmwarePath: originalFirmwarePath,
|
FirmwarePath: originalFirmwarePath,
|
||||||
HypervisorPath: originalHypervisorPath,
|
HypervisorPath: originalHypervisorPath,
|
||||||
HypervisorCtlPath: originalHypervisorCtlPath,
|
JailerPath: originalJailerPath,
|
||||||
JailerPath: originalJailerPath,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data := []testData{
|
data := []testData{
|
||||||
@ -701,13 +699,6 @@ func TestSandboxCreateAssets(t *testing.T) {
|
|||||||
annotations.HypervisorHash: assetContentHash,
|
annotations.HypervisorHash: assetContentHash,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
types.HypervisorCtlAsset,
|
|
||||||
map[string]string{
|
|
||||||
annotations.HypervisorCtlPath: filename,
|
|
||||||
annotations.HypervisorCtlHash: assetContentHash,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
types.ImageAsset,
|
types.ImageAsset,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
@ -35,9 +35,6 @@ const (
|
|||||||
// HypervisorAsset is an hypervisor asset.
|
// HypervisorAsset is an hypervisor asset.
|
||||||
HypervisorAsset AssetType = "hypervisor"
|
HypervisorAsset AssetType = "hypervisor"
|
||||||
|
|
||||||
// HypervisorCtlAsset is a hypervisor control asset.
|
|
||||||
HypervisorCtlAsset AssetType = "hypervisorctl"
|
|
||||||
|
|
||||||
// JailerAsset is a jailer asset.
|
// JailerAsset is a jailer asset.
|
||||||
JailerAsset AssetType = "jailer"
|
JailerAsset AssetType = "jailer"
|
||||||
|
|
||||||
@ -57,7 +54,6 @@ func AssetTypes() []AssetType {
|
|||||||
FirmwareAsset,
|
FirmwareAsset,
|
||||||
FirmwareVolumeAsset,
|
FirmwareVolumeAsset,
|
||||||
HypervisorAsset,
|
HypervisorAsset,
|
||||||
HypervisorCtlAsset,
|
|
||||||
ImageAsset,
|
ImageAsset,
|
||||||
InitrdAsset,
|
InitrdAsset,
|
||||||
JailerAsset,
|
JailerAsset,
|
||||||
@ -92,8 +88,6 @@ func (t AssetType) Annotations() (string, string, error) {
|
|||||||
return annotations.InitrdPath, annotations.InitrdHash, nil
|
return annotations.InitrdPath, annotations.InitrdHash, nil
|
||||||
case HypervisorAsset:
|
case HypervisorAsset:
|
||||||
return annotations.HypervisorPath, annotations.HypervisorHash, nil
|
return annotations.HypervisorPath, annotations.HypervisorHash, nil
|
||||||
case HypervisorCtlAsset:
|
|
||||||
return annotations.HypervisorCtlPath, annotations.HypervisorCtlHash, nil
|
|
||||||
case JailerAsset:
|
case JailerAsset:
|
||||||
return annotations.JailerPath, annotations.JailerHash, nil
|
return annotations.JailerPath, annotations.JailerHash, nil
|
||||||
case FirmwareAsset:
|
case FirmwareAsset:
|
||||||
|
@ -115,7 +115,6 @@ func TestAssetNew(t *testing.T) {
|
|||||||
{annotations.ImagePath, annotations.ImageHash, ImageAsset, assetContentHash, false, false},
|
{annotations.ImagePath, annotations.ImageHash, ImageAsset, assetContentHash, false, false},
|
||||||
{annotations.InitrdPath, annotations.InitrdHash, InitrdAsset, assetContentHash, false, false},
|
{annotations.InitrdPath, annotations.InitrdHash, InitrdAsset, assetContentHash, false, false},
|
||||||
{annotations.HypervisorPath, annotations.HypervisorHash, HypervisorAsset, assetContentHash, false, false},
|
{annotations.HypervisorPath, annotations.HypervisorHash, HypervisorAsset, assetContentHash, false, false},
|
||||||
{annotations.HypervisorCtlPath, annotations.HypervisorCtlHash, HypervisorCtlAsset, assetContentHash, false, false},
|
|
||||||
{annotations.JailerPath, annotations.JailerHash, JailerAsset, assetContentHash, false, false},
|
{annotations.JailerPath, annotations.JailerHash, JailerAsset, assetContentHash, false, false},
|
||||||
{annotations.FirmwarePath, annotations.FirmwareHash, FirmwareAsset, assetContentHash, false, false},
|
{annotations.FirmwarePath, annotations.FirmwareHash, FirmwareAsset, assetContentHash, false, false},
|
||||||
{annotations.FirmwareVolumePath, annotations.FirmwareVolumeHash, FirmwareVolumeAsset, assetContentHash, false, false},
|
{annotations.FirmwareVolumePath, annotations.FirmwareVolumeHash, FirmwareVolumeAsset, assetContentHash, false, false},
|
||||||
@ -125,7 +124,6 @@ func TestAssetNew(t *testing.T) {
|
|||||||
{annotations.ImagePath, annotations.ImageHash, ImageAsset, assetContentWrongHash, true, false},
|
{annotations.ImagePath, annotations.ImageHash, ImageAsset, assetContentWrongHash, true, false},
|
||||||
{annotations.InitrdPath, annotations.InitrdHash, InitrdAsset, assetContentWrongHash, true, false},
|
{annotations.InitrdPath, annotations.InitrdHash, InitrdAsset, assetContentWrongHash, true, false},
|
||||||
{annotations.HypervisorPath, annotations.HypervisorHash, HypervisorAsset, assetContentWrongHash, true, false},
|
{annotations.HypervisorPath, annotations.HypervisorHash, HypervisorAsset, assetContentWrongHash, true, false},
|
||||||
{annotations.HypervisorCtlPath, annotations.HypervisorCtlHash, HypervisorCtlAsset, assetContentWrongHash, true, false},
|
|
||||||
{annotations.JailerPath, annotations.JailerHash, JailerAsset, assetContentWrongHash, true, false},
|
{annotations.JailerPath, annotations.JailerHash, JailerAsset, assetContentWrongHash, true, false},
|
||||||
{annotations.FirmwarePath, annotations.FirmwareHash, FirmwareAsset, assetContentWrongHash, true, false},
|
{annotations.FirmwarePath, annotations.FirmwareHash, FirmwareAsset, assetContentWrongHash, true, false},
|
||||||
{annotations.FirmwareVolumePath, annotations.FirmwareVolumeHash, FirmwareVolumeAsset, assetContentWrongHash, true, false},
|
{annotations.FirmwareVolumePath, annotations.FirmwareVolumeHash, FirmwareVolumeAsset, assetContentWrongHash, true, false},
|
||||||
|
@ -28,7 +28,6 @@ const testHypervisor = "hypervisor"
|
|||||||
const testJailer = "jailer"
|
const testJailer = "jailer"
|
||||||
const testFirmware = "firmware"
|
const testFirmware = "firmware"
|
||||||
const testVirtiofsd = "virtiofsd"
|
const testVirtiofsd = "virtiofsd"
|
||||||
const testHypervisorCtl = "hypervisorctl"
|
|
||||||
const testBundle = "bundle"
|
const testBundle = "bundle"
|
||||||
|
|
||||||
const testDisabledAsNonRoot = "Test disabled as requires root privileges"
|
const testDisabledAsNonRoot = "Test disabled as requires root privileges"
|
||||||
@ -44,10 +43,6 @@ var testClhKernelPath = ""
|
|||||||
var testClhImagePath = ""
|
var testClhImagePath = ""
|
||||||
var testClhInitrdPath = ""
|
var testClhInitrdPath = ""
|
||||||
var testClhPath = ""
|
var testClhPath = ""
|
||||||
var testAcrnKernelPath = ""
|
|
||||||
var testAcrnImagePath = ""
|
|
||||||
var testAcrnPath = ""
|
|
||||||
var testAcrnCtlPath = ""
|
|
||||||
var testStratovirtKernelPath = ""
|
var testStratovirtKernelPath = ""
|
||||||
var testStratovirtImagePath = ""
|
var testStratovirtImagePath = ""
|
||||||
var testStratovirtInitrdPath = ""
|
var testStratovirtInitrdPath = ""
|
||||||
@ -69,18 +64,6 @@ func setup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupAcrn() {
|
|
||||||
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
|
||||||
|
|
||||||
for _, filename := range []string{testAcrnKernelPath, testAcrnImagePath, testAcrnPath, testAcrnCtlPath} {
|
|
||||||
_, err := os.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Could not recreate %s:%v", filename, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupClh() {
|
func setupClh() {
|
||||||
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
os.Mkdir(filepath.Join(testDir, testBundle), DirMode)
|
||||||
|
|
||||||
@ -150,13 +133,6 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
testAcrnKernelPath = filepath.Join(testDir, testKernel)
|
|
||||||
testAcrnImagePath = filepath.Join(testDir, testImage)
|
|
||||||
testAcrnPath = filepath.Join(testDir, testHypervisor)
|
|
||||||
testAcrnCtlPath = filepath.Join(testDir, testHypervisorCtl)
|
|
||||||
|
|
||||||
setupAcrn()
|
|
||||||
|
|
||||||
testVirtiofsdPath = filepath.Join(testDir, testBundle, testVirtiofsd)
|
testVirtiofsdPath = filepath.Join(testDir, testBundle, testVirtiofsd)
|
||||||
testClhKernelPath = filepath.Join(testDir, testBundle, testKernel)
|
testClhKernelPath = filepath.Join(testDir, testBundle, testKernel)
|
||||||
testClhImagePath = filepath.Join(testDir, testBundle, testImage)
|
testClhImagePath = filepath.Join(testDir, testBundle, testImage)
|
||||||
|
Loading…
Reference in New Issue
Block a user