diff options
author | 2015-12-03 23:32:32 +0000 | |
---|---|---|
committer | 2015-12-03 23:32:32 +0000 | |
commit | 008065a53607d1f3681d98779b8a20ecc2d2abbc (patch) | |
tree | 1335601138b851ca0fbc06de2d2bfb4eac89f1e4 | |
parent | sync (diff) | |
download | wireguard-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.c | 25 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.8 | 8 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.h | 3 | ||||
-rw-r--r-- | usr.sbin/vmd/config.c | 11 | ||||
-rw-r--r-- | usr.sbin/vmd/control.c | 15 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.c | 53 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.h | 8 | ||||
-rw-r--r-- | usr.sbin/vmd/vmm.c | 5 |
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); } |