#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");
}
assert(check_instance_usable(suite_name));
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");
}
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;
if (check_instance_usable(suite_name)) {
err(EXIT_FAILURE,
"instance did not auto-destruct as expected");
}
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;
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);
}