summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2016-12-14 21:17:26 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2016-12-14 21:17:26 +0000
commit431456d9562b44beeb2bb8aed8dcb8e63f40a34a (patch)
treea9f83290b6dcdd2c453f0f4afad4256b6bbd612f
parentc09471df0ae18ca50af982c5fdda5f9c43f55220 (diff)
Allow to start disabled and pre-configured VMs by name, "vmctl start foo".
With testing from Jon Bernard OK mlarkin@
-rw-r--r--usr.sbin/vmctl/vmctl.c43
-rw-r--r--usr.sbin/vmd/parse.y8
-rw-r--r--usr.sbin/vmd/vmd.c21
-rw-r--r--usr.sbin/vmd/vmd.h7
4 files changed, 59 insertions, 20 deletions
diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c
index 3e845563979..352383c299f 100644
--- a/usr.sbin/vmctl/vmctl.c
+++ b/usr.sbin/vmctl/vmctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.c,v 1.20 2016/11/26 19:49:11 reyk Exp $ */
+/* $OpenBSD: vmctl.c,v 1.21 2016/12/14 21:17:25 reyk Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
@@ -67,27 +67,40 @@ start_vm(const char *name, int memsize, int nnics, char **nics,
{
struct vmop_create_params *vmc;
struct vm_create_params *vcp;
+ unsigned int flags = 0;
int i;
- if (memsize < 1)
- memsize = VM_DEFAULT_MEMORY;
- if (ndisks > VMM_MAX_DISKS_PER_VM)
- errx(1, "too many disks");
- else if (ndisks == 0)
- warnx("starting without disks");
- if (kernel == NULL && ndisks == 0)
- errx(1, "no kernel or disk specified");
- if (nnics == -1)
- nnics = 0;
- if (nnics > VMM_MAX_NICS_PER_VM)
- errx(1, "too many network interfaces");
- if (nnics == 0)
- warnx("starting without network interfaces");
+ if (memsize)
+ flags |= VMOP_CREATE_MEMORY;
+ if (nnics)
+ flags |= VMOP_CREATE_NETWORK;
+ if (ndisks)
+ flags |= VMOP_CREATE_DISK;
+ if (kernel)
+ flags |= VMOP_CREATE_KERNEL;
+ if (flags != 0) {
+ if (memsize < 1)
+ memsize = VM_DEFAULT_MEMORY;
+ if (ndisks > VMM_MAX_DISKS_PER_VM)
+ errx(1, "too many disks");
+ else if (ndisks == 0)
+ warnx("starting without disks");
+ if (kernel == NULL && ndisks == 0)
+ errx(1, "no kernel or disk specified");
+ if (nnics == -1)
+ nnics = 0;
+ if (nnics > VMM_MAX_NICS_PER_VM)
+ errx(1, "too many network interfaces");
+ if (nnics == 0)
+ warnx("starting without network interfaces");
+ }
vmc = calloc(1, sizeof(struct vmop_create_params));
if (vmc == NULL)
return (ENOMEM);
+ vmc->vmc_flags = flags;
+
/* vcp includes configuration that is shared with the kernel */
vcp = &vmc->vmc_params;
diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y
index 691f7c8e2b6..6cf06b02f44 100644
--- a/usr.sbin/vmd/parse.y
+++ b/usr.sbin/vmd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.16 2016/11/22 11:31:38 edd Exp $ */
+/* $OpenBSD: parse.y,v 1.17 2016/12/14 21:17:25 reyk Exp $ */
/*
* Copyright (c) 2007-2016 Reyk Floeter <reyk@openbsd.org>
@@ -306,6 +306,7 @@ vm_opts : disable {
YYERROR;
}
free($2);
+ vmc.vmc_flags |= VMOP_CREATE_DISK;
}
| INTERFACE optstring iface_opts_o {
unsigned int i;
@@ -337,6 +338,7 @@ vm_opts : disable {
}
}
free($2);
+ vmc.vmc_flags |= VMOP_CREATE_NETWORK;
}
| KERNEL string {
if (vcp->vcp_kernel[0] != '\0') {
@@ -353,6 +355,7 @@ vm_opts : disable {
YYERROR;
}
free($2);
+ vmc.vmc_flags |= VMOP_CREATE_KERNEL;
}
| NIFS NUMBER {
if (vcp->vcp_nnics != 0) {
@@ -364,6 +367,7 @@ vm_opts : disable {
YYERROR;
}
vcp->vcp_nnics = (size_t)$2;
+ vmc.vmc_flags |= VMOP_CREATE_NETWORK;
}
| MEMORY NUMBER {
ssize_t res;
@@ -376,6 +380,7 @@ vm_opts : disable {
YYERROR;
}
vcp->vcp_memranges[0].vmr_size = (size_t)res;
+ vmc.vmc_flags |= VMOP_CREATE_MEMORY;
}
| MEMORY STRING {
ssize_t res;
@@ -390,6 +395,7 @@ vm_opts : disable {
YYERROR;
}
vcp->vcp_memranges[0].vmr_size = (size_t)res;
+ vmc.vmc_flags |= VMOP_CREATE_MEMORY;
}
;
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index d572784bb05..26de91144d4 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.46 2016/12/14 06:59:12 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.47 2016/12/14 21:17:25 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -65,7 +65,7 @@ int
vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
{
struct privsep *ps = p->p_ps;
- int res = 0, cmd = 0;
+ int res = 0, ret = 0, cmd = 0;
unsigned int v = 0;
struct vmop_create_params vmc;
struct vmop_id vid;
@@ -79,7 +79,18 @@ 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));
- if (vm_register(ps, &vmc, &vm, 0) == -1 ||
+ ret = vm_register(ps, &vmc, &vm, 0);
+ if (vmc.vmc_flags == 0) {
+ /* start an existing VM with pre-configured options */
+ if (!(ret == -1 && errno == EALREADY)) {
+ res = errno;
+ cmd = IMSG_VMDOP_START_VM_RESPONSE;
+ }
+ } else if (ret != 0) {
+ res = errno;
+ cmd = IMSG_VMDOP_START_VM_RESPONSE;
+ }
+ if (res == 0 &&
config_setvm(ps, vm, imsg->hdr.peerid) == -1) {
res = errno;
cmd = IMSG_VMDOP_START_VM_RESPONSE;
@@ -698,6 +709,10 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc,
goto fail;
}
+ if (vmc->vmc_flags == 0) {
+ errno = ENOENT;
+ goto fail;
+ }
if (vcp->vcp_ncpus == 0)
vcp->vcp_ncpus = 1;
if (vcp->vcp_memranges[0].vmr_size == 0)
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 5053db79b5b..499f64388c8 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.39 2016/12/14 06:59:12 reyk Exp $ */
+/* $OpenBSD: vmd.h,v 1.40 2016/12/14 21:17:25 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -100,6 +100,11 @@ struct vmop_ifreq {
struct vmop_create_params {
struct vm_create_params vmc_params;
+ unsigned int vmc_flags;
+#define VMOP_CREATE_KERNEL 0x01
+#define VMOP_CREATE_MEMORY 0x02
+#define VMOP_CREATE_NETWORK 0x04
+#define VMOP_CREATE_DISK 0x08
/* userland-only part of the create params */
unsigned int vmc_ifflags[VMM_MAX_NICS_PER_VM];