1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright 2022 Oxide Computer Company
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <libgen.h>
#include <errno.h>
#include <err.h>
#include <assert.h>
#include <sys/vmm.h>
#include <sys/vmm_dev.h>
#include <sys/vmm_drv_test.h>
#include <vmmapi.h>
#include "common.h"
int
main(int argc, char *argv[])
{
const char *suite_name = basename(argv[0]);
struct vmctx *ctx;
ctx = create_test_vm(suite_name);
if (ctx == NULL) {
errx(EXIT_FAILURE, "could open test VM");
}
/*
* It would be odd if we had the freshly created VM instance, but it did
* not appear to exist.
*/
assert(check_instance_usable(suite_name));
/* Make sure that auto-destruct is off */
if (ioctl(vm_get_device_fd(ctx), VM_SET_AUTODESTRUCT, 0) != 0) {
errx(EXIT_FAILURE, "could not disable auto-destruct");
}
vm_close(ctx);
if (!check_instance_usable(suite_name)) {
err(EXIT_FAILURE, "instance missing after close");
}
ctx = NULL;
if (destroy_instance(suite_name) != 0) {
errx(EXIT_FAILURE, "could not clean up instance");
}
/* Now repeat that process, but enable auto-destruct */
ctx = create_test_vm(suite_name);
if (ctx == NULL) {
errx(EXIT_FAILURE, "could open test VM");
}
if (ioctl(vm_get_device_fd(ctx), VM_SET_AUTODESTRUCT, 1) != 0) {
errx(EXIT_FAILURE, "could not enable auto-destruct");
}
vm_close(ctx);
ctx = NULL;
/* At this point, the instance should be gone */
if (check_instance_usable(suite_name)) {
err(EXIT_FAILURE,
"instance did not auto-destruct as expected");
}
/*
* Repeat the test again, but establish a vmm_drv hold first.
* The instance should auto-destruct when the hold is released.
*/
ctx = create_test_vm(suite_name);
if (ctx == NULL) {
errx(EXIT_FAILURE, "could open test VM");
}
if (ioctl(vm_get_device_fd(ctx), VM_SET_AUTODESTRUCT, 1) != 0) {
errx(EXIT_FAILURE, "could not enable auto-destruct");
}
int vdtfd = open_drv_test();
if (vdtfd < 0) {
errx(EXIT_FAILURE, "could open drv_test device");
}
if (ioctl(vdtfd, VDT_IOC_HOLD, vm_get_device_fd(ctx)) != 0) {
errx(EXIT_FAILURE, "could not hold VM from vmm_drv device");
}
vm_close(ctx);
ctx = NULL;
/*
* With the vmm_drv hold remaining on the instance, we expect it to
* exist, but not be usable (due to in-progress destroy).
*/
if (!check_instance_exists(suite_name)) {
err(EXIT_FAILURE, "instance completed auto-destruct despite "
"existing vmm_drv hold");
}
if (check_instance_usable(suite_name)) {
err(EXIT_FAILURE, "instance still usable despite close() after "
"auto-destroy configured");
}
if (ioctl(vdtfd, VDT_IOC_RELE, 0) != 0) {
errx(EXIT_FAILURE, "could not release VM from vmm_drv device");
}
if (check_instance_usable(suite_name)) {
err(EXIT_FAILURE, "instance did not complete destruction "
"after vmm_drv release");
}
(void) printf("%s\tPASS\n", suite_name);
return (EXIT_SUCCESS);
}
|