summaryrefslogtreecommitdiff
path: root/usr.sbin/vmd/vmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/vmd/vmd.c')
-rw-r--r--usr.sbin/vmd/vmd.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index a9124f915ff..c06fe974877 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.145 2023/04/27 22:47:27 dv Exp $ */
+/* $OpenBSD: vmd.c,v 1.146 2023/04/28 19:46:42 dv Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -111,8 +111,10 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_VMDOP_START_VM_REQUEST:
IMSG_SIZE_CHECK(imsg, &vmc);
memcpy(&vmc, imsg->data, sizeof(vmc));
+ vmc.vmc_kernel = imsg->fd;
+
ret = vm_register(ps, &vmc, &vm, 0, vmc.vmc_owner.uid);
- if (vmc.vmc_flags == 0) {
+ if (vmc.vmc_flags == 0 || vmc.vmc_flags == VMOP_CREATE_KERNEL) {
/* start an existing VM with pre-configured options */
if (!(ret == -1 && errno == EALREADY &&
!(vm->vm_state & VM_STATE_RUNNING))) {
@@ -123,6 +125,7 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
res = errno;
cmd = IMSG_VMDOP_START_VM_RESPONSE;
}
+
if (res == 0) {
res = config_setvm(ps, vm, imsg->hdr.peerid,
vm->vm_params.vmc_owner.uid);
@@ -1290,6 +1293,8 @@ vm_remove(struct vmd_vm *vm, const char *caller)
TAILQ_REMOVE(env->vmd_vms, vm, vm_entry);
vm_stop(vm, 0, caller);
+ if (vm->vm_kernel_path != NULL && !vm->vm_from_config)
+ free(vm->vm_kernel_path);
free(vm);
}
@@ -1353,6 +1358,7 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
errno = EPERM;
goto fail;
}
+ vm->vm_kernel = vmc->vmc_kernel;
*ret_vm = vm;
errno = EALREADY;
goto fail;
@@ -1385,8 +1391,8 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
} else if (vmc->vmc_nnics > VM_MAX_NICS_PER_VM) {
log_warnx("invalid number of interfaces");
goto fail;
- } else if (strlen(vmc->vmc_kernel) == 0 &&
- vmc->vmc_ndisks == 0 && strlen(vmc->vmc_cdrom) == 0) {
+ } else if (vmc->vmc_kernel == -1 && vmc->vmc_ndisks == 0
+ && strlen(vmc->vmc_cdrom) == 0) {
log_warnx("no kernel or disk/cdrom specified");
goto fail;
} else if (strlen(vcp->vcp_name) == 0) {
@@ -1415,8 +1421,12 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
vm->vm_pid = -1;
vm->vm_tty = -1;
vm->vm_receive_fd = -1;
+ vm->vm_kernel = -1;
vm->vm_state &= ~VM_STATE_PAUSED;
+ if (vmc->vmc_kernel > -1)
+ vm->vm_kernel = vmc->vmc_kernel;
+
for (i = 0; i < VM_MAX_DISKS_PER_VM; i++)
for (j = 0; j < VM_MAX_BASE_PER_DISK; j++)
vm->vm_disks[i][j] = -1;
@@ -1445,7 +1455,6 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
vmc->vmc_macs[i][5] = rng >> 8;
}
}
- vm->vm_kernel = -1;
vm->vm_cdrom = -1;
vm->vm_iev.ibuf.fd = -1;
@@ -1593,17 +1602,14 @@ vm_instance(struct privsep *ps, struct vmd_vm **vm_parent,
}
/* kernel */
- if (strlen(vmc->vmc_kernel) > 0) {
+ if (vmc->vmc_kernel > -1 || (vm->vm_kernel_path != NULL &&
+ strnlen(vm->vm_kernel_path, PATH_MAX) < PATH_MAX)) {
if (vm_checkinsflag(vmcp, VMOP_CREATE_KERNEL, uid) != 0) {
log_warnx("vm \"%s\" no permission to set boot image",
name);
return (EPERM);
}
vmc->vmc_checkaccess |= VMOP_CREATE_KERNEL;
- } else if (strlcpy(vmc->vmc_kernel, vmcp->vmc_kernel,
- sizeof(vmc->vmc_kernel)) >= sizeof(vmc->vmc_kernel)) {
- log_warnx("vm \"%s\" kernel name too long", name);
- return (EINVAL);
}
/* cdrom */