mirror of
https://github.com/opnsense/src.git
synced 2026-06-12 10:10:24 -04:00
vmm: Fix error handling in vmm_handler()
In commita97f683fe3I didn't add code to remove the vmmctl device when vmm.ko is unloaded, so it would persist and prevent vmm.ko from being re-loaded. Extend vmmdev_cleanup() to destroy the vmmctl cdev. Also call vmmdev_cleanup() if vmm_init() fails. Reviewed by: corvink, andrew Fixes:a97f683fe3("vmm: Add a device file interface for creating and destroying VMs") Differential Revision: https://reviews.freebsd.org/D48269
This commit is contained in:
parent
7c94d515db
commit
4a46ece6c6
4 changed files with 37 additions and 21 deletions
|
|
@ -467,6 +467,8 @@ vmm_handler(module_t mod, int what, void *arg)
|
|||
error = vmm_init();
|
||||
if (error == 0)
|
||||
vmm_initialized = 1;
|
||||
else
|
||||
(void)vmmdev_cleanup();
|
||||
} else {
|
||||
error = ENXIO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,21 +361,26 @@ vmm_handler(module_t mod, int what, void *arg)
|
|||
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
/* TODO: if (vmm_is_hw_supported()) { */
|
||||
error = vmmdev_init();
|
||||
if (error != 0)
|
||||
break;
|
||||
error = vmm_init();
|
||||
if (error == 0)
|
||||
vmm_initialized = true;
|
||||
else
|
||||
(void)vmmdev_cleanup();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
/* TODO: if (vmm_is_hw_supported()) { */
|
||||
error = vmmdev_cleanup();
|
||||
if (error == 0 && vmm_initialized) {
|
||||
error = vmmops_modcleanup();
|
||||
if (error)
|
||||
if (error) {
|
||||
/*
|
||||
* Something bad happened - prevent new
|
||||
* VMs from being created
|
||||
*/
|
||||
vmm_initialized = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -979,6 +979,7 @@ vmmctl_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
|
|||
return (error);
|
||||
}
|
||||
|
||||
static struct cdev *vmmctl_cdev;
|
||||
static struct cdevsw vmmctlsw = {
|
||||
.d_name = "vmmctl",
|
||||
.d_version = D_VERSION,
|
||||
|
|
@ -989,31 +990,34 @@ static struct cdevsw vmmctlsw = {
|
|||
int
|
||||
vmmdev_init(void)
|
||||
{
|
||||
struct cdev *cdev;
|
||||
int error;
|
||||
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmctlsw, NULL,
|
||||
sx_xlock(&vmmdev_mtx);
|
||||
error = make_dev_p(MAKEDEV_CHECKNAME, &vmmctl_cdev, &vmmctlsw, NULL,
|
||||
UID_ROOT, GID_WHEEL, 0600, "vmmctl");
|
||||
if (error)
|
||||
return (error);
|
||||
if (error == 0)
|
||||
pr_allow_flag = prison_add_allow(NULL, "vmm", NULL,
|
||||
"Allow use of vmm in a jail.");
|
||||
sx_xunlock(&vmmdev_mtx);
|
||||
|
||||
pr_allow_flag = prison_add_allow(NULL, "vmm", NULL,
|
||||
"Allow use of vmm in a jail.");
|
||||
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
vmmdev_cleanup(void)
|
||||
{
|
||||
int error;
|
||||
sx_xlock(&vmmdev_mtx);
|
||||
if (!SLIST_EMPTY(&head)) {
|
||||
sx_xunlock(&vmmdev_mtx);
|
||||
return (EBUSY);
|
||||
}
|
||||
if (vmmctl_cdev != NULL) {
|
||||
destroy_dev(vmmctl_cdev);
|
||||
vmmctl_cdev = NULL;
|
||||
}
|
||||
sx_xunlock(&vmmdev_mtx);
|
||||
|
||||
if (SLIST_EMPTY(&head))
|
||||
error = 0;
|
||||
else
|
||||
error = EBUSY;
|
||||
|
||||
return (error);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -259,21 +259,26 @@ vmm_handler(module_t mod, int what, void *arg)
|
|||
|
||||
switch (what) {
|
||||
case MOD_LOAD:
|
||||
/* TODO: check if has_hyp here? */
|
||||
error = vmmdev_init();
|
||||
if (error != 0)
|
||||
break;
|
||||
error = vmm_init();
|
||||
if (error == 0)
|
||||
vmm_initialized = true;
|
||||
else
|
||||
(void)vmmdev_cleanup();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
/* TODO: check if has_hyp here? */
|
||||
error = vmmdev_cleanup();
|
||||
if (error == 0 && vmm_initialized) {
|
||||
error = vmmops_modcleanup();
|
||||
if (error)
|
||||
if (error) {
|
||||
/*
|
||||
* Something bad happened - prevent new
|
||||
* VMs from being created
|
||||
*/
|
||||
vmm_initialized = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in a new issue