blob: af39e9b5b594e30236a290c15f313af2a1bcb662 [file] [log] [blame]
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/cdefs.h>
#include <time.h>
__BEGIN_DECLS
/**
* Represents a handle on a virtual machine raw config.
*/
typedef struct AVirtualMachineRawConfig AVirtualMachineRawConfig;
/**
* Create a new virtual machine raw config object with no properties.
*
* This only creates the raw config object. `name` and `kernel` must be set with
* calls to {@link AVirtualMachineRawConfig_setName} and {@link AVirtualMachineRawConfig_setKernel}.
* Other properties, set by {@link AVirtualMachineRawConfig_setMemoryMiB},
* {@link AVirtualMachineRawConfig_setInitRd}, {@link AVirtualMachineRawConfig_addDisk},
* {@link AVirtualMachineRawConfig_setProtectedVm}, and {@link AVirtualMachineRawConfig_setBalloon}
* are optional.
*
* The caller takes ownership of the returned raw config object, and is responsible for creating a
* VM by calling {@link AVirtualMachine_createRaw} or releasing it by calling
* {@link AVirtualMachineRawConfig_destroy}.
*
* \return A new virtual machine raw config object. On failure (such as out of memory), it aborts.
*/
AVirtualMachineRawConfig* _Nonnull AVirtualMachineRawConfig_create(void) __INTRODUCED_IN(36);
/**
* Destroy a virtual machine config object.
*
* \param config a virtual machine config object.
*
* `AVirtualMachineRawConfig_destroy` does nothing if `config` is null. A destroyed config object
* must not be reused.
*/
void AVirtualMachineRawConfig_destroy(AVirtualMachineRawConfig* _Nullable config)
__INTRODUCED_IN(36);
/**
* Set a name of a virtual machine.
*
* \param config a virtual machine config object.
* \param name a pointer to a null-terminated, UTF-8 encoded string for the name.
*
* \return If successful, it returns 0. If `name` is not a null-terminated UTF-8 encoded string,
* it returns -EINVAL.
*/
int AVirtualMachineRawConfig_setName(AVirtualMachineRawConfig* _Nonnull config,
const char* _Nonnull name) __INTRODUCED_IN(36);
/**
* Set an instance ID of a virtual machine.
*
* \param config a virtual machine config object.
* \param instanceId a pointer to a 64-byte buffer for the instance ID.
* \param instanceIdSize the number of bytes in `instanceId`.
*
* \return If successful, it returns 0. If `instanceIdSize` is incorrect, it returns -EINVAL.
*/
int AVirtualMachineRawConfig_setInstanceId(AVirtualMachineRawConfig* _Nonnull config,
const int8_t* _Nonnull instanceId, size_t instanceIdSize)
__INTRODUCED_IN(36);
/**
* Set a kernel image of a virtual machine.
*
* \param config a virtual machine config object.
* \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
* descriptor containing the kernel image, or -1 to unset. `AVirtualMachineRawConfig_setKernel`
* takes ownership of `fd`.
*/
void AVirtualMachineRawConfig_setKernel(AVirtualMachineRawConfig* _Nonnull config, int fd)
__INTRODUCED_IN(36);
/**
* Set an init rd of a virtual machine.
*
* \param config a virtual machine config object.
* \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
* descriptor containing the init rd image, or -1 to unset. `AVirtualMachineRawConfig_setInitRd`
* takes ownership of `fd`.
*/
void AVirtualMachineRawConfig_setInitRd(AVirtualMachineRawConfig* _Nonnull config, int fd)
__INTRODUCED_IN(36);
/**
* Add a disk for a virtual machine.
*
* \param config a virtual machine config object.
* \param fd a readable, seekable, and sized (i.e. report a valid size using fstat()) file
* descriptor containing the disk. `fd` must be writable if If `writable` is true.
* `AVirtualMachineRawConfig_addDisk` takes ownership of `fd`.
* \param writable whether this disk should be writable by the virtual machine.
*
* \return If successful, it returns 0. If `fd` is invalid, it returns -EINVAL.
*/
int AVirtualMachineRawConfig_addDisk(AVirtualMachineRawConfig* _Nonnull config, int fd,
bool writable) __INTRODUCED_IN(36);
/**
* Set how much memory will be given to a virtual machine.
*
* When `AVirtualMachineRawConfig_setProtectedVm(..., true)` is set, the memory
* size provided here will be automatically augmented with the swiotlb size.
*
* \param config a virtual machine config object.
* \param memoryMiB the amount of RAM to give the virtual machine, in MiB. 0 or negative to use the
* default.
*/
void AVirtualMachineRawConfig_setMemoryMiB(AVirtualMachineRawConfig* _Nonnull config,
int32_t memoryMiB) __INTRODUCED_IN(36);
/**
* Set how much swiotlb will be given to a virtual machine.
*
* Only applicable when `AVirtualMachineRawConfig_setProtectedVm(..., true)` is
* set.
*
* For information on swiotlb, see https://docs.kernel.org/core-api/swiotlb.html.
*
* \param config a virtual machine config object.
* \param memoryMiB the amount of swiotlb to give the virtual machine, in MiB.
* 0 or negative to use the default.
*/
void AVirtualMachineRawConfig_setSwiotlbMiB(AVirtualMachineRawConfig* _Nonnull config,
int32_t swiotlbMiB) __INTRODUCED_IN(36);
/**
* Set vCPU count. The default is 1.
*
* \param config a virtual machine config object.
* \param n number of vCPUs. Must be positive.
*/
void AVirtualMachineRawConfig_setVCpuCount(AVirtualMachineRawConfig* _Nonnull config, int32_t n)
__INTRODUCED_IN(36);
/**
* Set whether the virtual machine's memory will be protected from the host, so the host can't
* access its memory.
*
* \param config a virtual machine config object.
* \param protectedVm whether the virtual machine should be protected.
*/
void AVirtualMachineRawConfig_setProtectedVm(AVirtualMachineRawConfig* _Nonnull config,
bool protectedVm) __INTRODUCED_IN(36);
/**
* Set whether to use an alternate, hypervisor-specific authentication method
* for protected VMs.
*
* This option is discouraged. Prefer to use the default authentication method, which is better
* tested and integrated into Android. This option must only be used from the vendor partition.
*
* \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't have an
* alternate auth mode.
*/
int AVirtualMachineRawConfig_setHypervisorSpecificAuthMethod(
AVirtualMachineRawConfig* _Nonnull config, bool enable) __INTRODUCED_IN(36);
/**
* Use the specified fd as the backing memfd for a range of the guest
* physical memory.
*
* \param config a virtual machine config object.
* \param fd a memfd
* \param rangeStart range start of guest memory addresses
* \param rangeEnd range end of guest memory addresses
*
* \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't support
* backing memfd.
*/
int AVirtualMachineRawConfig_addCustomMemoryBackingFile(AVirtualMachineRawConfig* _Nonnull config,
int fd, uint64_t rangeStart,
uint64_t rangeEnd) __INTRODUCED_IN(36);
/**
* Represents a handle on a virtualization service, responsible for managing virtual machines.
*/
typedef struct AVirtualizationService AVirtualizationService;
/**
* Spawn a new instance of `virtmgr`, a child process that will host the `VirtualizationService`
* service, and connect to the child process.
*
* The caller takes ownership of the returned service object, and is responsible for releasing it
* by calling {@link AVirtualizationService_destroy}.
*
* \param early set to true when running a service for early virtual machines. Early VMs are
* specialized virtual machines that can run even before the `/data` partition is mounted.
* Early VMs must be pre-defined in XML files located at `{partition}/etc/avf/early_vms*.xml`, and
* clients of early VMs must be pre-installed under the same partition.
* \param service an out parameter that will be set to the service handle.
*
* \return
* - If successful, it sets `service` and returns 0.
* - If it fails to spawn `virtmgr`, it leaves `service` untouched and returns a negative value
* representing the OS error code.
* - If it fails to connect to the spawned `virtmgr`, it leaves `service` untouched and returns
* `-ECONNREFUSED`.
*/
int AVirtualizationService_create(AVirtualizationService* _Null_unspecified* _Nonnull service,
bool early) __INTRODUCED_IN(36);
/**
* Destroy a VirtualizationService object.
*
* `AVirtualizationService_destroy` does nothing if `service` is null. A destroyed service object
* must not be reused.
*
* \param service a handle on a virtualization service.
*/
void AVirtualizationService_destroy(AVirtualizationService* _Nullable service) __INTRODUCED_IN(36);
/**
* Represents a handle on a virtual machine.
*/
typedef struct AVirtualMachine AVirtualMachine;
/**
* The reason why a virtual machine stopped.
* @see AVirtualMachine_waitForStop
*/
enum AVirtualMachineStopReason : int32_t {
/**
* VirtualizationService died.
*/
AVIRTUAL_MACHINE_VIRTUALIZATION_SERVICE_DIED = 1,
/**
* There was an error waiting for the virtual machine.
*/
AVIRTUAL_MACHINE_INFRASTRUCTURE_ERROR = 2,
/**
* The virtual machine was killed.
*/
AVIRTUAL_MACHINE_KILLED = 3,
/**
* The virtual machine stopped for an unknown reason.
*/
AVIRTUAL_MACHINE_UNKNOWN = 4,
/**
* The virtual machine requested to shut down.
*/
AVIRTUAL_MACHINE_SHUTDOWN = 5,
/**
* crosvm had an error starting the virtual machine.
*/
AVIRTUAL_MACHINE_START_FAILED = 6,
/**
* The virtual machine requested to reboot, possibly as the result of a kernel panic.
*/
AVIRTUAL_MACHINE_REBOOT = 7,
/**
* The virtual machine or crosvm crashed.
*/
AVIRTUAL_MACHINE_CRASH = 8,
/**
* The pVM firmware failed to verify the VM because the public key doesn't match.
*/
AVIRTUAL_MACHINE_PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 9,
/**
* The pVM firmware failed to verify the VM because the instance image changed.
*/
AVIRTUAL_MACHINE_PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED = 10,
/**
* The virtual machine was killed due to hangup.
*/
AVIRTUAL_MACHINE_HANGUP = 11,
/**
* VirtualizationService sent a stop reason which was not recognised by the client library.
*/
AVIRTUAL_MACHINE_UNRECOGNISED = 0,
};
/**
* Create a virtual machine with given raw `config`.
*
* The created virtual machine is in stopped state. To run the created virtual machine, call
* {@link AVirtualMachine_start}.
*
* The caller takes ownership of the returned virtual machine object, and is responsible for
* releasing it by calling {@link AVirtualMachine_destroy}.
*
* \param service a handle on a virtualization service.
* \param config a virtual machine config object. Ownership will always be transferred from the
* caller, even if unsuccessful. `config` must not be reused.
* \param consoleOutFd a writable file descriptor for the console output, or -1. Ownership will
* always be transferred from the caller, even if unsuccessful.
* \param consoleInFd a readable file descriptor for the console input, or -1. Ownership will always
* be transferred from the caller, even if unsuccessful.
* \param logFd a writable file descriptor for the log output, or -1. Ownership will always be
* transferred from the caller, even if unsuccessful.
* \param vm an out parameter that will be set to the virtual machine handle.
*
* \return If successful, it sets `vm` and returns 0. Otherwise, it leaves `vm` untouched and
* returns `-EIO`.
*/
int AVirtualMachine_createRaw(const AVirtualizationService* _Nonnull service,
AVirtualMachineRawConfig* _Nonnull config, int consoleOutFd,
int consoleInFd, int logFd,
AVirtualMachine* _Null_unspecified* _Nonnull vm) __INTRODUCED_IN(36);
/**
* Start a virtual machine. `AVirtualMachine_start` is synchronous and blocks until the virtual
* machine is initialized and free to start executing code, or until an error happens.
*
* \param vm a handle on a virtual machine.
*
* \return If successful, it returns 0. Otherwise, it returns `-EIO`.
*/
int AVirtualMachine_start(AVirtualMachine* _Nonnull vm) __INTRODUCED_IN(36);
/**
* Stop a virtual machine. Stopping a virtual machine is like pulling the plug on a real computer;
* the machine halts immediately. Software running on the virtual machine is not notified of the
* event, the instance might be left in an inconsistent state.
*
* For a graceful shutdown, you could request the virtual machine to exit itself, and wait for the
* virtual machine to stop by `AVirtualMachine_waitForStop`.
*
* A stopped virtual machine can be re-started by calling `AVirtualMachine_start`.
*
* `AVirtualMachine_stop` stops a virtual machine by sending a signal to the process. This operation
* is synchronous and `AVirtualMachine_stop` may block.
*
* \param vm a handle on a virtual machine.
*
* \return If successful, it returns 0. Otherwise, it returns `-EIO`.
*/
int AVirtualMachine_stop(AVirtualMachine* _Nonnull vm) __INTRODUCED_IN(36);
/**
* Open a vsock connection to the VM on the given port. The caller takes ownership of the returned
* file descriptor, and is responsible for closing the file descriptor.
*
* This operation is synchronous and `AVirtualMachine_connectVsock` may block.
*
* \param vm a handle on a virtual machine.
* \param port a vsock port number.
*
* \return If successful, it returns a valid file descriptor. Otherwise, it returns `-EIO`.
*/
int AVirtualMachine_connectVsock(AVirtualMachine* _Nonnull vm, uint32_t port) __INTRODUCED_IN(36);
/**
* Wait until a virtual machine stops or the given timeout elapses.
*
* \param vm a handle on a virtual machine.
* \param timeout the timeout, or null to wait indefinitely.
* \param reason An out parameter that will be set to the reason why the virtual machine stopped.
*
* \return
* - If the virtual machine stops within the timeout (or indefinitely if `timeout` is null), it
* sets `reason` and returns true.
* - If the timeout expired, it returns `false`.
*/
bool AVirtualMachine_waitForStop(AVirtualMachine* _Nonnull vm,
const struct timespec* _Nullable timeout,
enum AVirtualMachineStopReason* _Nonnull reason)
__INTRODUCED_IN(36);
/**
* Destroy a virtual machine object. If the virtual machine is still running,
* `AVirtualMachine_destroy` first stops the virtual machine by sending a signal to the process.
* This operation is synchronous and `AVirtualMachine_destroy` may block.
*
* `AVirtualMachine_destroy` does nothing if `vm` is null. A destroyed virtual machine must not be
* reused.
*
* \param vm a handle on a virtual machine.
*/
void AVirtualMachine_destroy(AVirtualMachine* _Nullable vm) __INTRODUCED_IN(36);
__END_DECLS