1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 
22 __BEGIN_DECLS
23 
24 /**
25  * Represents a handle on a virtual machine raw config.
26  */
27 typedef struct AVirtualMachineRawConfig AVirtualMachineRawConfig;
28 
29 /**
30  * Create a new virtual machine raw config object with no properties.
31  *
32  * This only creates the raw config object. `name` and `kernel` must be set with
33  * calls to {@link AVirtualMachineRawConfig_setName} and {@link AVirtualMachineRawConfig_setKernel}.
34  * Other properties, set by {@link AVirtualMachineRawConfig_setMemoryMib},
35  * {@link AVirtualMachineRawConfig_setInitRd}, {@link AVirtualMachineRawConfig_addDisk},
36  * {@link AVirtualMachineRawConfig_setProtectedVm}, and {@link AVirtualMachineRawConfig_setBalloon}
37  * are optional.
38  *
39  * The caller takes ownership of the returned raw config object, and is responsible for creating a
40  * VM by calling {@link AVirtualMachine_createRaw} or releasing it by calling
41  * {@link AVirtualMachineRawConfig_destroy}.
42  *
43  * \return A new virtual machine raw config object.
44  */
45 AVirtualMachineRawConfig* AVirtualMachineRawConfig_create();
46 
47 /**
48  * Destroy a virtual machine config object.
49  *
50  * \param config a virtual machine config object.
51  *
52  * `AVirtualMachineRawConfig_destroy` does nothing if `config` is null. A destroyed config object
53  * must not be reused.
54  */
55 void AVirtualMachineRawConfig_destroy(AVirtualMachineRawConfig* config);
56 
57 /**
58  * Set a name of a virtual machine.
59  *
60  * \param config a virtual machine config object.
61  * \param name a pointer to a null-terminated string for the name.
62  *
63  * \return If successful, it returns 0.
64  */
65 int AVirtualMachineRawConfig_setName(AVirtualMachineRawConfig* config, const char* name);
66 
67 /**
68  * Set an instance ID of a virtual machine.
69  *
70  * \param config a virtual machine config object.
71  * \param instanceId a pointer to a 64-byte buffer for the instance ID.
72  *
73  * \return If successful, it returns 0.
74  */
75 int AVirtualMachineRawConfig_setInstanceId(AVirtualMachineRawConfig* config,
76                                            const int8_t* instanceId);
77 
78 /**
79  * Set a kernel image of a virtual machine.
80  *
81  * \param config a virtual machine config object.
82  * \param fd a readable file descriptor containing the kernel image, or -1 to unset.
83  *   `AVirtualMachineRawConfig_setKernel` takes ownership of `fd`.
84  *
85  * \return If successful, it returns 0.
86  */
87 int AVirtualMachineRawConfig_setKernel(AVirtualMachineRawConfig* config, int fd);
88 
89 /**
90  * Set an init rd of a virtual machine.
91  *
92  * \param config a virtual machine config object.
93  * \param fd a readable file descriptor containing the kernel image, or -1 to unset.
94  *   `AVirtualMachineRawConfig_setInitRd` takes ownership of `fd`.
95  *
96  * \return If successful, it returns 0.
97  */
98 int AVirtualMachineRawConfig_setInitRd(AVirtualMachineRawConfig* config, int fd);
99 
100 /**
101  * Add a disk for a virtual machine.
102  *
103  * \param config a virtual machine config object.
104  * \param fd a readable file descriptor containing the disk image.
105  * `AVirtualMachineRawConfig_addDisk` takes ownership of `fd`.
106  *
107  * \return If successful, it returns 0. If `fd` is invalid, it returns -EINVAL.
108  */
109 int AVirtualMachineRawConfig_addDisk(AVirtualMachineRawConfig* config, int fd);
110 
111 /**
112  * Set how much memory will be given to a virtual machine.
113  *
114  * \param config a virtual machine config object.
115  * \param memoryMib the amount of RAM to give the virtual machine, in MiB. 0 or negative to use the
116  *   default.
117  *
118  * \return If successful, it returns 0.
119  */
120 int AVirtualMachineRawConfig_setMemoryMib(AVirtualMachineRawConfig* config, int32_t memoryMib);
121 
122 /**
123  * Set whether a virtual machine is protected or not.
124  *
125  * \param config a virtual machine config object.
126  * \param protectedVm whether the virtual machine should be protected.
127  *
128  * \return If successful, it returns 0.
129  */
130 int AVirtualMachineRawConfig_setProtectedVm(AVirtualMachineRawConfig* config, bool protectedVm);
131 
132 /**
133  * Set whether a virtual machine uses memory ballooning or not.
134  *
135  * \param config a virtual machine config object.
136  * \param balloon whether the virtual machine should use memory ballooning.
137  *
138  * \return If successful, it returns 0.
139  */
140 int AVirtualMachineRawConfig_setBalloon(AVirtualMachineRawConfig* config, bool balloon);
141 
142 /**
143  * Set whether to use an alternate, hypervisor-specific authentication method
144  * for protected VMs. You don't want to use this.
145  *
146  * \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't have an
147  *   alternate auth mode.
148  */
149 int AVirtualMachineRawConfig_setHypervisorSpecificAuthMethod(AVirtualMachineRawConfig* config,
150                                                              bool enable);
151 
152 /**
153  * Use the specified fd as the backing memfd for a range of the guest
154  * physical memory.
155  *
156  * \param config a virtual machine config object.
157  * \param fd a memfd
158  * \param rangeStart range start IPA
159  * \param rangeEnd range end IPA
160  *
161  * \return If successful, it returns 0. It returns `-ENOTSUP` if the hypervisor doesn't support
162  *   backing memfd.
163  */
164 int AVirtualMachineRawConfig_addCustomMemoryBackingFile(AVirtualMachineRawConfig* config, int fd,
165                                                         size_t rangeStart, size_t rangeEnd);
166 
167 /**
168  * Represents a handle on a virtualization service, responsible for managing virtual machines.
169  */
170 typedef struct AVirtualizationService AVirtualizationService;
171 
172 /**
173  * Spawn a new instance of `virtmgr`, a child process that will host the `VirtualizationService`
174  * service, and connect to the child process.
175  *
176  * The caller takes ownership of the returned service object, and is responsible for releasing it
177  * by calling {@link AVirtualizationService_destroy}.
178  *
179  * \param early set to true when running a service for early virtual machines. See
180  *   [`early_vm.md`](../../../../docs/early_vm.md) for more details on early virtual machines.
181  * \param service an out parameter that will be set to the service handle.
182  *
183  * \return
184  *   - If successful, it sets `service` and returns 0.
185  *   - If it fails to spawn `virtmgr`, it leaves `service` untouched and returns a negative value
186  *     representing the OS error code.
187  *   - If it fails to connect to the spawned `virtmgr`, it leaves `service` untouched and returns
188  *     `-ECONNREFUSED`.
189  */
190 int AVirtualizationService_create(AVirtualizationService** service, bool early);
191 
192 /**
193  * Destroy a VirtualizationService object.
194  *
195  * `AVirtualizationService_destroy` does nothing if `service` is null. A destroyed service object
196  * must not be reused.
197  *
198  * \param service a handle on a virtualization service.
199  */
200 void AVirtualizationService_destroy(AVirtualizationService* service);
201 
202 /**
203  * Represents a handle on a virtual machine.
204  */
205 typedef struct AVirtualMachine AVirtualMachine;
206 
207 /**
208  * The reason why a virtual machine stopped.
209  * @see AVirtualMachine_waitForStop
210  */
211 enum StopReason : int32_t {
212     /**
213      * VirtualizationService died.
214      */
215     VIRTUALIZATION_SERVICE_DIED = 1,
216     /**
217      * There was an error waiting for the virtual machine.
218      */
219     INFRASTRUCTURE_ERROR = 2,
220     /**
221      * The virtual machine was killed.
222      */
223     KILLED = 3,
224     /**
225      * The virtual machine stopped for an unknown reason.
226      */
227     UNKNOWN = 4,
228     /**
229      * The virtual machine requested to shut down.
230      */
231     SHUTDOWN = 5,
232     /**
233      * crosvm had an error starting the virtual machine.
234      */
235     START_FAILED = 6,
236     /**
237      * The virtual machine requested to reboot, possibly as the result of a kernel panic.
238      */
239     REBOOT = 7,
240     /**
241      * The virtual machine or crosvm crashed.
242      */
243     CRASH = 8,
244     /**
245      * The pVM firmware failed to verify the VM because the public key doesn't match.
246      */
247     PVM_FIRMWARE_PUBLIC_KEY_MISMATCH = 9,
248     /**
249      * The pVM firmware failed to verify the VM because the instance image changed.
250      */
251     PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED = 10,
252     /**
253      * The virtual machine was killed due to hangup.
254      */
255     HANGUP = 11,
256     /**
257      * VirtualizationService sent a stop reason which was not recognised by the client library.
258      */
259     UNRECOGNISED = 0,
260 };
261 
262 /**
263  * Create a virtual machine with given raw `config`.
264  *
265  * The created virtual machine is in stopped state. To run the created virtual machine, call
266  * {@link AVirtualMachine_start}.
267  *
268  * The caller takes ownership of the returned virtual machine object, and is responsible for
269  * releasing it by calling {@link AVirtualMachine_destroy}.
270  *
271  * \param service a handle on a virtualization service.
272  * \param config a virtual machine config object. Ownership will always be transferred from the
273  *   caller, even if unsuccessful. `config` must not be reused.
274  * \param consoleOutFd a writable file descriptor for the console output, or -1. Ownership will
275  *   always be transferred from the caller, even if unsuccessful.
276  * \param consoleInFd a readable file descriptor for the console input, or -1. Ownership will always
277  *   be transferred from the caller, even if unsuccessful.
278  * \param logFd a writable file descriptor for the log output, or -1. Ownership will always be
279  *   transferred from the caller, even if unsuccessful.
280  * \param vm an out parameter that will be set to the virtual machine handle.
281  *
282  * \return If successful, it sets `vm` and returns 0. Otherwise, it leaves `vm` untouched and
283  *   returns `-EIO`.
284  */
285 int AVirtualMachine_createRaw(const AVirtualizationService* service,
286                               AVirtualMachineRawConfig* config, int consoleOutFd, int consoleInFd,
287                               int logFd, AVirtualMachine** vm);
288 
289 /**
290  * Start a virtual machine.
291  *
292  * \param vm a handle on a virtual machine.
293  *
294  * \return If successful, it returns 0. Otherwise, it returns `-EIO`.
295  */
296 int AVirtualMachine_start(AVirtualMachine* vm);
297 
298 /**
299  * Stop a virtual machine.
300  *
301  * \param vm a handle on a virtual machine.
302  *
303  * \return If successful, it returns 0. Otherwise, it returns `-EIO`.
304  */
305 int AVirtualMachine_stop(AVirtualMachine* vm);
306 
307 /**
308  * Wait until a virtual machine stops.
309  *
310  * \param vm a handle on a virtual machine.
311  *
312  * \return The reason why the virtual machine stopped.
313  */
314 enum StopReason AVirtualMachine_waitForStop(AVirtualMachine* vm);
315 
316 /**
317  * Destroy a virtual machine.
318  *
319  * `AVirtualMachine_destroy` does nothing if `vm` is null. A destroyed virtual machine must not be
320  * reused.
321  *
322  * \param vm a handle on a virtual machine.
323  */
324 void AVirtualMachine_destroy(AVirtualMachine* vm);
325 
326 __END_DECLS
327