Hi, vmctl reload is currently broken, the attached diff fixes it and re-introduces the semantics that originally came from iked:
- load/reload just reloads the configuration without clearing any running configuration. This way you can start vmd with a few configured vms, terminate one vm, and reload the configuration which will restart the terminated vm but keep the running ones. - reset clears the configuration (and possibly terminates vms) without reloading the configuration. "vmctl reset" thus terminates all vms. # vmctl load /etc/my-personal-vm.conf # vmctl reload # vmctl reset OK? Reyk Index: usr.sbin/vmd/control.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/control.c,v retrieving revision 1.8 diff -u -p -u -p -r1.8 control.c --- usr.sbin/vmd/control.c 29 Sep 2016 22:42:04 -0000 1.8 +++ usr.sbin/vmd/control.c 12 Oct 2016 11:37:21 -0000 @@ -367,6 +367,7 @@ control_dispatch_imsg(int fd, short even break; case IMSG_VMDOP_LOAD: case IMSG_VMDOP_RELOAD: + case IMSG_CTL_RESET: proc_forward_imsg(ps, &imsg, PROC_PARENT, -1); break; default: Index: usr.sbin/vmd/vmd.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/vmd.c,v retrieving revision 1.33 diff -u -p -u -p -r1.33 vmd.c --- usr.sbin/vmd/vmd.c 6 Oct 2016 18:48:41 -0000 1.33 +++ usr.sbin/vmd/vmd.c 12 Oct 2016 11:37:21 -0000 @@ -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 priv 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); } @@ -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 *filena 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); + } } } Index: usr.sbin/vmd/vmd.h =================================================================== RCS file: /cvs/src/usr.sbin/vmd/vmd.h,v retrieving revision 1.28 diff -u -p -u -p -r1.28 vmd.h --- usr.sbin/vmd/vmd.h 6 Oct 2016 18:48:41 -0000 1.28 +++ usr.sbin/vmd/vmd.h 12 Oct 2016 11:37:21 -0000 @@ -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 *); Index: usr.sbin/vmd/vmm.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/vmm.c,v retrieving revision 1.50 diff -u -p -u -p -r1.50 vmm.c --- usr.sbin/vmd/vmm.c 12 Oct 2016 06:56:54 -0000 1.50 +++ usr.sbin/vmd/vmm.c 12 Oct 2016 11:37:21 -0000 @@ -179,6 +179,7 @@ vmm_dispatch_parent(int fd, struct privs 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 privs 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); } } Index: usr.sbin/vmctl/main.c =================================================================== RCS file: /cvs/src/usr.sbin/vmctl/main.c,v retrieving revision 1.17 diff -u -p -u -p -r1.17 main.c --- usr.sbin/vmctl/main.c 10 May 2016 11:00:54 -0000 1.17 +++ usr.sbin/vmctl/main.c 12 Oct 2016 11:37:21 -0000 @@ -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 *, in 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,16 +438,41 @@ ctl_status(struct parse_result *res, int 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)); } Index: usr.sbin/vmctl/vmctl.8 =================================================================== RCS file: /cvs/src/usr.sbin/vmctl/vmctl.8,v retrieving revision 1.15 diff -u -p -u -p -r1.15 vmctl.8 --- usr.sbin/vmctl/vmctl.8 4 Oct 2016 17:25:52 -0000 1.15 +++ usr.sbin/vmctl/vmctl.8 12 Oct 2016 11:37:21 -0000 @@ -56,10 +56,16 @@ Creates a VM disk image file with the sp 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 Index: usr.sbin/vmctl/vmctl.h =================================================================== RCS file: /cvs/src/usr.sbin/vmctl/vmctl.h,v retrieving revision 1.8 diff -u -p -u -p -r1.8 vmctl.h --- usr.sbin/vmctl/vmctl.h 3 Sep 2016 20:49:05 -0000 1.8 +++ usr.sbin/vmctl/vmctl.h 12 Oct 2016 11:37:21 -0000 @@ -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; };