summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2016-10-12 19:10:03 +0000
committerreyk <reyk@openbsd.org>2016-10-12 19:10:03 +0000
commit1f7fe034fc219c994ea2c612a3a6031d48e24b62 (patch)
treeab08720e0749d697798264699894105e4d400e30
parentStart reworking the "device" support in switchd: Once connected, a (diff)
downloadwireguard-openbsd-1f7fe034fc219c994ea2c612a3a6031d48e24b62.tar.xz
wireguard-openbsd-1f7fe034fc219c994ea2c612a3a6031d48e24b62.zip
Fix functionality and semantics of vmctl load/reload/reset.
OK rzalamena@
-rw-r--r--usr.sbin/vmctl/main.c62
-rw-r--r--usr.sbin/vmctl/vmctl.814
-rw-r--r--usr.sbin/vmctl/vmctl.h4
-rw-r--r--usr.sbin/vmd/control.c3
-rw-r--r--usr.sbin/vmd/vmd.c41
-rw-r--r--usr.sbin/vmd/vmd.h4
-rw-r--r--usr.sbin/vmd/vmm.c15
7 files changed, 102 insertions, 41 deletions
diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c
index 83b6fab3b8f..44db2347a6d 100644
--- a/usr.sbin/vmctl/main.c
+++ b/usr.sbin/vmctl/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.17 2016/05/10 11:00:54 mlarkin Exp $ */
+/* $OpenBSD: main.c,v 1.18 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -50,6 +50,8 @@ int vmm_action(struct parse_result *);
int ctl_console(struct parse_result *, int, char *[]);
int ctl_create(struct parse_result *, int, char *[]);
int ctl_load(struct parse_result *, int, char *[]);
+int ctl_reload(struct parse_result *, int, char *[]);
+int ctl_reset(struct parse_result *, int, char *[]);
int ctl_start(struct parse_result *, int, char *[]);
int ctl_status(struct parse_result *, int, char *[]);
int ctl_stop(struct parse_result *, int, char *[]);
@@ -57,8 +59,9 @@ int ctl_stop(struct parse_result *, int, char *[]);
struct ctl_command ctl_commands[] = {
{ "console", CMD_CONSOLE, ctl_console, "id" },
{ "create", CMD_CREATE, ctl_create, "\"path\" -s size", 1 },
- { "load", CMD_LOAD, ctl_load, "[path]" },
- { "reload", CMD_RELOAD, ctl_load, "[path]" },
+ { "load", CMD_LOAD, ctl_load, "\"path\"" },
+ { "reload", CMD_RELOAD, ctl_reload, "" },
+ { "reset", CMD_RESET, ctl_reset, "[all|vms|switches]" },
{ "start", CMD_START, ctl_start, "\"name\""
" [-c] -k kernel -m size [-i count] [-d disk]*" },
{ "status", CMD_STATUS, ctl_status, "[id]" },
@@ -204,14 +207,18 @@ vmmaction(struct parse_result *res)
case CMD_CONSOLE:
get_info_vm(res->id, res->name, 1);
break;
+ case CMD_LOAD:
+ imsg_compose(ibuf, IMSG_VMDOP_LOAD, 0, 0, -1,
+ res->path, strlen(res->path) + 1);
+ done = 1;
+ break;
case CMD_RELOAD:
- imsg_compose(ibuf, IMSG_VMDOP_RELOAD, 0, 0, -1,
- res->path, res->path == NULL ? 0 : strlen(res->path) + 1);
+ imsg_compose(ibuf, IMSG_VMDOP_RELOAD, 0, 0, -1, NULL, 0);
done = 1;
break;
- case CMD_LOAD:
- imsg_compose(ibuf, IMSG_VMDOP_LOAD, 0, 0, -1,
- res->path, res->path == NULL ? 0 : strlen(res->path) + 1);
+ case CMD_RESET:
+ imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1,
+ &res->mode, sizeof(res->mode));
done = 1;
break;
case CMD_CREATE:
@@ -431,21 +438,46 @@ ctl_status(struct parse_result *res, int argc, char *argv[])
int
ctl_load(struct parse_result *res, int argc, char *argv[])
{
- char *config_file = NULL;
-
- if (argc == 2)
- config_file = argv[1];
- else if (argc > 2)
+ if (argc != 2)
ctl_usage(res->ctl);
- if (config_file != NULL &&
- (res->path = strdup(config_file)) == NULL)
+ if ((res->path = strdup(argv[1])) == NULL)
err(1, "strdup");
return (vmmaction(res));
}
int
+ctl_reload(struct parse_result *res, int argc, char *argv[])
+{
+ if (argc != 1)
+ ctl_usage(res->ctl);
+
+ return (vmmaction(res));
+}
+
+int
+ctl_reset(struct parse_result *res, int argc, char *argv[])
+{
+ if (argc == 2) {
+ if (strcasecmp("all", argv[1]) == 0)
+ res->mode = CONFIG_ALL;
+ else if (strcasecmp("vms", argv[1]) == 0)
+ res->mode = CONFIG_VMS;
+ else if (strcasecmp("switches", argv[1]) == 0)
+ res->mode = CONFIG_SWITCHES;
+ else
+ ctl_usage(res->ctl);
+ } else if (argc > 2)
+ ctl_usage(res->ctl);
+
+ if (res->mode == 0)
+ res->mode = CONFIG_ALL;
+
+ return (vmmaction(res));
+}
+
+int
ctl_start(struct parse_result *res, int argc, char *argv[])
{
int ch;
diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8
index fa066a01206..d5beb36b4a8 100644
--- a/usr.sbin/vmctl/vmctl.8
+++ b/usr.sbin/vmctl/vmctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vmctl.8,v 1.15 2016/10/04 17:25:52 reyk Exp $
+.\" $OpenBSD: vmctl.8,v 1.16 2016/10/12 19:10:03 reyk Exp $
.\"
.\" Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: October 4 2016 $
+.Dd $Mdocdate: October 12 2016 $
.Dt VMCTL 8
.Os
.Sh NAME
@@ -56,10 +56,16 @@ Creates a VM disk image file with the specified
and
.Ar size ,
rounded to megabytes.
-.It Cm load Op Ar filename
+.It Cm load Ar filename
Load the configuration from the specified file.
-.It Cm reload Op Ar filename
+.It Cm reload
Reload the configuration from the default configuration file.
+.It Cm reset Op Cm all
+Reset the running state.
+.It Cm reset switches
+Reset the configured switches.
+.It Cm reset vms
+Reset and terminate all VMs.
.It Xo Cm start Op Ar name
.Op Fl c
.Fl k Ar path
diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h
index 7cb6d956835..68d70233c73 100644
--- a/usr.sbin/vmctl/vmctl.h
+++ b/usr.sbin/vmctl/vmctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.h,v 1.8 2016/09/03 20:49:05 deraadt Exp $ */
+/* $OpenBSD: vmctl.h,v 1.9 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -27,6 +27,7 @@ enum actions {
CMD_CREATE,
CMD_LOAD,
CMD_RELOAD,
+ CMD_RESET,
CMD_START,
CMD_STATUS,
CMD_STOP,
@@ -44,6 +45,7 @@ struct parse_result {
size_t ndisks;
char **disks;
int disable;
+ unsigned int mode;
struct ctl_command *ctl;
};
diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c
index 2dc01389bda..d370254f8e8 100644
--- a/usr.sbin/vmd/control.c
+++ b/usr.sbin/vmd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.8 2016/09/29 22:42:04 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.9 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org>
@@ -367,6 +367,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
break;
case IMSG_VMDOP_LOAD:
case IMSG_VMDOP_RELOAD:
+ case IMSG_CTL_RESET:
proc_forward_imsg(ps, &imsg, PROC_PARENT, -1);
break;
default:
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index cab5400a32d..056b8dec336 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.33 2016/10/06 18:48:41 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.34 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -63,7 +63,8 @@ int
vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
{
struct privsep *ps = p->p_ps;
- int res = 0, cmd = 0, v = 0;
+ int res = 0, cmd = 0;
+ unsigned int v = 0;
struct vmop_create_params vmc;
struct vmop_id vid;
struct vm_terminate_params vtp;
@@ -103,15 +104,19 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_VMDOP_GET_INFO_VM_REQUEST:
proc_forward_imsg(ps, imsg, PROC_VMM, -1);
break;
- case IMSG_VMDOP_RELOAD:
- v = 1;
case IMSG_VMDOP_LOAD:
- if (IMSG_DATA_SIZE(imsg) > 0)
- str = get_string((uint8_t *)imsg->data,
- IMSG_DATA_SIZE(imsg));
- vmd_reload(v, str);
+ IMSG_SIZE_CHECK(imsg, str); /* at least one byte for path */
+ str = get_string((uint8_t *)imsg->data,
+ IMSG_DATA_SIZE(imsg));
+ case IMSG_VMDOP_RELOAD:
+ vmd_reload(0, str);
free(str);
break;
+ case IMSG_CTL_RESET:
+ IMSG_SIZE_CHECK(imsg, &v);
+ memcpy(&v, imsg->data, sizeof(v));
+ vmd_reload(v, str);
+ break;
default:
return (-1);
}
@@ -245,7 +250,7 @@ vmd_sighdlr(int sig, short event, void *arg)
* This is safe because libevent uses async signal handlers
* that run in the event loop and not in signal context.
*/
- vmd_reload(1, NULL);
+ vmd_reload(0, NULL);
break;
case SIGPIPE:
log_info("%s: ignoring SIGPIPE", __func__);
@@ -441,7 +446,7 @@ vmd_configure(void)
}
void
-vmd_reload(int reset, const char *filename)
+vmd_reload(unsigned int reset, const char *filename)
{
/* Switch back to the default config file */
if (filename == NULL || *filename == '\0')
@@ -449,12 +454,16 @@ vmd_reload(int reset, const char *filename)
log_debug("%s: level %d config file %s", __func__, reset, filename);
- if (reset)
- config_setreset(env, CONFIG_ALL);
-
- if (parse_config(filename) == -1) {
- log_debug("%s: failed to load config file %s",
- __func__, filename);
+ if (reset) {
+ /* Purge the configuration */
+ config_purge(env, reset);
+ config_setreset(env, reset);
+ } else {
+ /* Reload the configuration */
+ if (parse_config(filename) == -1) {
+ log_debug("%s: failed to load config file %s",
+ __func__, filename);
+ }
}
}
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 04e7e359a9a..5235189ee11 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.28 2016/10/06 18:48:41 reyk Exp $ */
+/* $OpenBSD: vmd.h,v 1.29 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -152,7 +152,7 @@ struct vmd {
};
/* vmd.c */
-void vmd_reload(int, const char *);
+void vmd_reload(unsigned int, const char *);
struct vmd_vm *vm_getbyvmid(uint32_t);
struct vmd_vm *vm_getbyid(uint32_t);
struct vmd_vm *vm_getbyname(const char *);
diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c
index bd874cdb75d..aae985dec83 100644
--- a/usr.sbin/vmd/vmm.c
+++ b/usr.sbin/vmd/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.50 2016/10/12 06:56:54 mlarkin Exp $ */
+/* $OpenBSD: vmm.c,v 1.51 2016/10/12 19:10:03 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -179,6 +179,7 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
struct vmop_result vmr;
uint32_t id = 0;
struct vmd_vm *vm;
+ unsigned int mode;
switch (imsg->hdr.type) {
case IMSG_VMDOP_START_VM_REQUEST:
@@ -225,6 +226,15 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
cmd = IMSG_VMDOP_GET_INFO_VM_END_DATA;
break;
case IMSG_CTL_RESET:
+ IMSG_SIZE_CHECK(imsg, &mode);
+ memcpy(&mode, imsg->data, sizeof(mode));
+
+ if (mode & CONFIG_VMS) {
+ /* Terminate and remove all VMs */
+ vmm_shutdown();
+ mode &= ~CONFIG_VMS;
+ }
+
config_getreset(env, imsg);
break;
default:
@@ -326,7 +336,8 @@ vmm_shutdown(void)
vtp.vtp_vm_id = vm->vm_params.vcp_id;
/* XXX suspend or request graceful shutdown */
- terminate_vm(&vtp);
+ if (terminate_vm(&vtp) == ENOENT)
+ vm_remove(vm);
}
}