Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139439814
D53729.id166351.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D53729.id166351.diff
View Options
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -115,6 +115,7 @@
struct vmctx *vm_open(const char *name);
#define VMMAPI_OPEN_CREATE 0x01 /* create if the VM does not exist */
#define VMMAPI_OPEN_REINIT 0x02 /* reinitialize the VM if it exists */
+#define VMMAPI_OPEN_CREATE_DESTROY_ON_CLOSE 0x04 /* Destroy the VM when closing vmm_ctl */
struct vmctx *vm_openf(const char *name, int flags);
void vm_close(struct vmctx *ctx);
void vm_destroy(struct vmctx *ctx);
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -100,11 +100,13 @@
}
static int
-vm_ctl_create(const char *name, int ctlfd)
+vm_ctl_create(const char *name, int flags, int ctlfd)
{
struct vmmctl_vm_create vmc;
memset(&vmc, 0, sizeof(vmc));
+ if ((flags & VMMAPI_OPEN_CREATE_DESTROY_ON_CLOSE) != 0)
+ vmc.flags |= VMMCTL_CREATE_DESTROY_ON_CLOSE;
if (strlcpy(vmc.name, name, sizeof(vmc.name)) >= sizeof(vmc.name)) {
errno = ENAMETOOLONG;
return (-1);
@@ -121,7 +123,7 @@
if (fd < 0)
return (-1);
- error = vm_ctl_create(name, fd);
+ error = vm_ctl_create(name, 0, fd);
if (error != 0) {
error = errno;
(void)close(fd);
@@ -162,7 +164,7 @@
vm->fd = vm_device_open(vm->name);
if (vm->fd < 0 && errno == ENOENT) {
if (flags & VMMAPI_OPEN_CREATE) {
- if (vm_ctl_create(vm->name, vm->ctlfd) != 0)
+ if (vm_ctl_create(vm->name, flags, vm->ctlfd) != 0)
goto err;
vm->fd = vm_device_open(vm->name);
created = true;
diff --git a/sys/dev/vmm/vmm_dev.h b/sys/dev/vmm/vmm_dev.h
--- a/sys/dev/vmm/vmm_dev.h
+++ b/sys/dev/vmm/vmm_dev.h
@@ -70,9 +70,13 @@
#endif /* _KERNEL */
+#define VMMCTL_CREATE_DESTROY_ON_CLOSE 0x1
+#define VMMCTL_FLAGS_MASK (VMMCTL_CREATE_DESTROY_ON_CLOSE)
+
struct vmmctl_vm_create {
char name[VM_MAX_NAMELEN + 1];
- int reserved[16];
+ uint32_t flags;
+ int reserved[15];
};
struct vmmctl_vm_destroy {
diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -77,10 +77,15 @@
struct cdev *cdev;
struct ucred *ucred;
SLIST_ENTRY(vmmdev_softc) link;
+ LIST_ENTRY(vmmdev_softc) priv_link;
SLIST_HEAD(, devmem_softc) devmem;
int flags;
};
+struct vmmctl_priv {
+ LIST_HEAD(, vmmdev_softc) softcs;
+};
+
static bool vmm_initialized = false;
static SLIST_HEAD(, vmmdev_softc) head;
@@ -103,6 +108,7 @@
static void devmem_destroy(void *arg);
static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem);
+static void vmmdev_destroy(struct vmmdev_softc *sc);
static int
vmm_priv_check(struct ucred *ucred)
@@ -910,6 +916,8 @@
sx_xlock(&vmmdev_mtx);
SLIST_REMOVE(&head, sc, vmmdev_softc, link);
+ if ((sc->flags & VMMCTL_CREATE_DESTROY_ON_CLOSE) != 0)
+ LIST_REMOVE(sc, priv_link);
sx_xunlock(&vmmdev_mtx);
free(sc, M_VMMDEV);
}
@@ -988,12 +996,13 @@
}
static int
-vmmdev_create(const char *name, struct thread *td)
+vmmdev_create(const char *name, uint32_t flags, struct thread *td)
{
struct make_dev_args mda;
struct cdev *cdev;
struct vmmdev_softc *sc;
struct ucred *cred;
+ struct vmmctl_priv *priv;
struct vm *vm;
int error;
@@ -1002,6 +1011,11 @@
return (EINVAL);
cred = td->td_ucred;
+ flags &= VMMCTL_FLAGS_MASK;
+ error = devfs_get_cdevpriv((void **)&priv);
+ if (error)
+ return (error);
+
sx_xlock(&vmmdev_mtx);
sc = vmmdev_lookup(name, cred);
if (sc != NULL) {
@@ -1021,6 +1035,9 @@
}
sc = vmmdev_alloc(vm, cred);
SLIST_INSERT_HEAD(&head, sc, link);
+ sc->flags = flags;
+ if ((flags & VMMCTL_CREATE_DESTROY_ON_CLOSE) != 0)
+ LIST_INSERT_HEAD(&priv->softcs, sc, priv_link);
make_dev_args_init(&mda);
mda.mda_devsw = &vmmdevsw;
@@ -1037,6 +1054,7 @@
return (error);
}
sc->cdev = cdev;
+
sx_xunlock(&vmmdev_mtx);
return (0);
}
@@ -1058,7 +1076,7 @@
buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
error = sysctl_handle_string(oidp, buf, buflen, req);
if (error == 0 && req->newptr != NULL)
- error = vmmdev_create(buf, req->td);
+ error = vmmdev_create(buf, 0, req->td);
free(buf, M_VMMDEV);
return (error);
}
@@ -1067,10 +1085,49 @@
NULL, 0, sysctl_vmm_create, "A",
"Create a vmm(4) instance (legacy interface)");
+static void
+vmmctl_dtor(void *arg)
+{
+ struct cdev *sc_cdev;
+ struct vmmdev_softc *sc;
+ struct vmmctl_priv *priv = arg;
+
+ /*
+ * Scan the softc list for any VMs associated with
+ * the current descriptor and destroy them.
+ */
+ sx_xlock(&vmmdev_mtx);
+ while (!LIST_EMPTY(&priv->softcs)) {
+ sc = LIST_FIRST(&priv->softcs);
+ sc_cdev = sc->cdev;
+ if (sc_cdev != NULL) {
+ sc->cdev = NULL;
+ } else {
+ /*
+ * Another thread has already
+ * started the removal process.
+ */
+ }
+ /* Temporarily drop the lock to allow vmmdev_destroy to run. */
+ sx_xunlock(&vmmdev_mtx);
+ if (sc_cdev != NULL) {
+ vm_suspend(sc->vm, VM_SUSPEND_DESTROY);
+ destroy_dev(sc_cdev);
+ /* vmmdev_destroy will unlink the 'priv_link' entry. */
+ vmmdev_destroy(sc);
+ }
+ sx_xlock(&vmmdev_mtx);
+ }
+ sx_xunlock(&vmmdev_mtx);
+
+ free(priv, M_VMMDEV);
+}
+
static int
vmmctl_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
{
int error;
+ struct vmmctl_priv *priv;
error = vmm_priv_check(td->td_ucred);
if (error != 0)
@@ -1079,6 +1136,14 @@
if ((flags & FWRITE) == 0)
return (EPERM);
+ priv = malloc(sizeof(*priv), M_VMMDEV, M_WAITOK | M_ZERO);
+ LIST_INIT(&priv->softcs);
+ error = devfs_set_cdevpriv(priv, vmmctl_dtor);
+ if (error != 0) {
+ free(priv, M_VMMDEV);
+ return (error);
+ }
+
return (0);
}
@@ -1101,7 +1166,7 @@
}
}
- error = vmmdev_create(vmc->name, td);
+ error = vmmdev_create(vmc->name, vmc->flags, td);
break;
}
case VMMCTL_VM_DESTROY: {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 13, 2:53 AM (11 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26919104
Default Alt Text
D53729.id166351.diff (5 KB)
Attached To
Mode
D53729: vmm: Add ability to destroy VMs on close
Attached
Detach File
Event Timeline
Log In to Comment