summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2015-12-03 23:32:32 +0000
committerreyk <reyk@openbsd.org>2015-12-03 23:32:32 +0000
commit008065a53607d1f3681d98779b8a20ecc2d2abbc (patch)
tree1335601138b851ca0fbc06de2d2bfb4eac89f1e4
parentsync (diff)
downloadwireguard-openbsd-008065a53607d1f3681d98779b8a20ecc2d2abbc.tar.xz
wireguard-openbsd-008065a53607d1f3681d98779b8a20ecc2d2abbc.zip
Re-add the "load" and "reload" commands to vmctl: Instead of parsing
the configuration in vmctl directly, it now sends a (re)load request to vmd. The reload also resets the existing configuration status - this doesn't do much difference yet but a future change will compare if a specified VM is already running. "load" will allow to add configuration, while "reload" resets the state before loading.
-rw-r--r--usr.sbin/vmctl/main.c25
-rw-r--r--usr.sbin/vmctl/vmctl.88
-rw-r--r--usr.sbin/vmctl/vmctl.h3
-rw-r--r--usr.sbin/vmd/config.c11
-rw-r--r--usr.sbin/vmd/control.c15
-rw-r--r--usr.sbin/vmd/vmd.c53
-rw-r--r--usr.sbin/vmd/vmd.h8
-rw-r--r--usr.sbin/vmd/vmm.c5
8 files changed, 100 insertions, 28 deletions
diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c
index baa14eee475..ccb083529ed 100644
--- a/usr.sbin/vmctl/main.c
+++ b/usr.sbin/vmctl/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.1 2015/12/03 21:45:45 reyk Exp $ */
+/* $OpenBSD: main.c,v 1.2 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -39,7 +39,6 @@
#include "vmctl.h"
static const char *socket_name = SOCKET_NAME;
-static const char *config_file = VMD_CONF;
static int ctl_sock = -1;
__dead void usage(void);
@@ -56,6 +55,7 @@ int ctl_stop(struct parse_result *, int, char *[]);
struct ctl_command ctl_commands[] = {
{ "create", CMD_CREATE, ctl_create, "\"name\" -s size", 1 },
{ "load", CMD_LOAD, ctl_load, "[path]" },
+ { "reload", CMD_RELOAD, ctl_load, "[path]" },
{ "start", CMD_START, ctl_start,
"\"name\" -k kernel -m memory [-i interfaces] [[-d disk] ...]" },
{ "status", CMD_STATUS, ctl_status, "[id]" },
@@ -214,8 +214,17 @@ vmmaction(struct parse_result *res)
case CMD_STATUS:
get_info_vm(res->id);
break;
- case CMD_CREATE:
+ case CMD_RELOAD:
+ imsg_compose(ibuf, IMSG_VMDOP_RELOAD, 0, 0, -1,
+ res->path, res->path == NULL ? 0 : strlen(res->path) + 1);
+ 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);
+ done = 1;
+ break;
+ case CMD_CREATE:
case NONE:
break;
}
@@ -422,14 +431,18 @@ 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)
ctl_usage(res->ctl);
- /* XXX send message to vmd(8) to load the configuration */
- errno = ENOSYS;
- return (-1);
+ if (config_file != NULL &&
+ (res->path = strdup(config_file)) == NULL)
+ err(1, "strdup");
+
+ return (vmmaction(res));
}
int
diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8
index 35d85819928..dc53287615b 100644
--- a/usr.sbin/vmctl/vmctl.8
+++ b/usr.sbin/vmctl/vmctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vmctl.8,v 1.1 2015/12/03 21:45:45 reyk Exp $
+.\" $OpenBSD: vmctl.8,v 1.2 2015/12/03 23:32:32 reyk Exp $
.\"
.\" Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
.\"
@@ -46,7 +46,11 @@ The options are as follows:
.It Cm create Ar path Fl s Ar bytes
Creates a VM disk image file with the specified pathname and size,
rounded to megabytes.
-.It Xo Cm start Ar name
+.It Cm load Op Ar filename
+Load the configuration from the specified file.
+.It Cm reload Op Ar filename
+Reload the configuration from the default configuration file.
+.It Xo Cm start Op Ar name
.Fl k Ar path
.Fl m Ar bytes
.Op Fl d Ar path
diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h
index 4fdec6ea62c..03f96e43965 100644
--- a/usr.sbin/vmctl/vmctl.h
+++ b/usr.sbin/vmctl/vmctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.h,v 1.1 2015/12/03 21:45:45 reyk Exp $ */
+/* $OpenBSD: vmctl.h,v 1.2 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -26,6 +26,7 @@ enum actions {
NONE,
CMD_CREATE,
CMD_LOAD,
+ CMD_RELOAD,
CMD_START,
CMD_STATUS,
CMD_STOP,
diff --git a/usr.sbin/vmd/config.c b/usr.sbin/vmd/config.c
index d835ed88f6d..b5cf51786ab 100644
--- a/usr.sbin/vmd/config.c
+++ b/usr.sbin/vmd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.3 2015/12/03 16:11:32 reyk Exp $ */
+/* $OpenBSD: config.c,v 1.4 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -38,7 +38,7 @@ int
config_init(struct vmd *env)
{
struct privsep *ps = &env->vmd_ps;
- u_int what;
+ unsigned int what;
/* Global configuration */
if (privsep_process == PROC_PARENT) {
@@ -58,14 +58,13 @@ config_init(struct vmd *env)
}
void
-config_purge(struct vmd *env, u_int reset)
+config_purge(struct vmd *env, unsigned int reset)
{
struct privsep *ps = &env->vmd_ps;
struct vmd_vm *vm;
- u_int what;
+ unsigned int what;
what = ps->ps_what[privsep_process] & reset;
-
if (what & CONFIG_VMS && env->vmd_vms != NULL) {
while ((vm = TAILQ_FIRST(env->vmd_vms)) != NULL)
vm_remove(vm);
@@ -74,7 +73,7 @@ config_purge(struct vmd *env, u_int reset)
}
int
-config_setreset(struct vmd *env, u_int reset)
+config_setreset(struct vmd *env, unsigned int reset)
{
struct privsep *ps = &env->vmd_ps;
unsigned int id;
diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c
index 4bba8935023..e16c0849598 100644
--- a/usr.sbin/vmd/control.c
+++ b/usr.sbin/vmd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.3 2015/12/03 13:08:44 reyk Exp $ */
+/* $OpenBSD: control.c,v 1.4 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org>
@@ -317,10 +317,9 @@ control_dispatch_imsg(int fd, short event, void *arg)
break;
switch (imsg.hdr.type) {
- case IMSG_CTL_NOTIFY:
- case IMSG_CTL_VERBOSE:
- case IMSG_VMDOP_START_VM_REQUEST:
- case IMSG_VMDOP_TERMINATE_VM_REQUEST:
+ case IMSG_VMDOP_GET_INFO_VM_REQUEST:
+ break;
+ default:
if (c->peercred.uid != 0) {
log_warnx("denied request %d from uid %d",
imsg.hdr.type, c->peercred.uid);
@@ -328,8 +327,6 @@ control_dispatch_imsg(int fd, short event, void *arg)
goto fail;
}
break;
- case IMSG_VMDOP_GET_INFO_VM_REQUEST:
- default:
break;
}
@@ -366,6 +363,10 @@ control_dispatch_imsg(int fd, short event, void *arg)
return;
}
break;
+ case IMSG_VMDOP_LOAD:
+ case IMSG_VMDOP_RELOAD:
+ proc_forward_imsg(ps, &imsg, PROC_PARENT, -1);
+ break;
default:
log_debug("%s: error handling imsg %d",
__func__, imsg.hdr.type);
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index cbf65513c1d..674848628a2 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.15 2015/12/03 16:18:13 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.16 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -31,6 +31,7 @@
#include <signal.h>
#include <syslog.h>
#include <unistd.h>
+#include <ctype.h>
#include "proc.h"
#include "vmd.h"
@@ -56,8 +57,9 @@ 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, cmd = 0, v = 0;
struct vm_create_params vcp;
+ char *str = NULL;
switch (imsg->hdr.type) {
case IMSG_VMDOP_START_VM_REQUEST:
@@ -73,6 +75,15 @@ 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);
+ free(str);
+ break;
default:
return (-1);
}
@@ -152,7 +163,13 @@ vmd_sighdlr(int sig, short event, void *arg)
switch (sig) {
case SIGHUP:
- log_info("%s: ignoring SIGHUP", __func__);
+ log_info("%s: reload requested with SIGHUP", __func__);
+
+ /*
+ * This is safe because libevent uses async signal handlers
+ * that run in the event loop and not in signal context.
+ */
+ vmd_reload(1, NULL);
break;
case SIGPIPE:
log_info("%s: ignoring SIGPIPE", __func__);
@@ -358,6 +375,24 @@ vmd_configure(void)
}
void
+vmd_reload(int reset, const char *filename)
+{
+ /* Switch back to the default config file */
+ if (filename == NULL || *filename == '\0')
+ filename = env->vmd_conffile;
+
+ 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);
+ }
+}
+
+void
vmd_shutdown(void)
{
proc_kill(&env->vmd_ps);
@@ -405,3 +440,15 @@ vm_remove(struct vmd_vm *vm)
free(vm);
}
+
+char *
+get_string(uint8_t *ptr, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ if (!isprint(ptr[i]))
+ break;
+
+ return strndup(ptr, i);
+}
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 77c18902596..098f251dc51 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.9 2015/12/03 16:11:32 reyk Exp $ */
+/* $OpenBSD: vmd.h,v 1.10 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -59,7 +59,9 @@ enum imsg_type {
IMSG_VMDOP_TERMINATE_VM_RESPONSE,
IMSG_VMDOP_GET_INFO_VM_REQUEST,
IMSG_VMDOP_GET_INFO_VM_DATA,
- IMSG_VMDOP_GET_INFO_VM_END_DATA
+ IMSG_VMDOP_GET_INFO_VM_END_DATA,
+ IMSG_VMDOP_LOAD,
+ IMSG_VMDOP_RELOAD
};
struct vmop_start_result {
@@ -96,8 +98,10 @@ struct vmd {
};
/* vmd.c */
+void vmd_reload(int, const char *);
struct vmd_vm *vm_getbyvmid(uint32_t);
void vm_remove(struct vmd_vm *);
+char *get_string(uint8_t *, size_t);
/* vmm.c */
pid_t vmm(struct privsep *, struct privsep_proc *);
diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c
index d2315e39b47..27cf7b341bb 100644
--- a/usr.sbin/vmd/vmm.c
+++ b/usr.sbin/vmd/vmm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm.c,v 1.6 2015/12/03 13:27:14 reyk Exp $ */
+/* $OpenBSD: vmm.c,v 1.7 2015/12/03 23:32:32 reyk Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -202,6 +202,9 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
res = get_info_vm(ps, imsg);
cmd = IMSG_VMDOP_GET_INFO_VM_END_DATA;
break;
+ case IMSG_CTL_RESET:
+ config_getreset(env, imsg);
+ break;
default:
return (-1);
}