On Wed, Oct 12, 2016 at 01:44:25PM +0200, Reyk Floeter wrote:
> 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?
> 

ajacoutot@ reminded me of SIGHUP:
change it to reload instead of reset on HUP.

Updated diff, OK?

Reyk

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 12:01:14 -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 12:01:14 -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 12:01:14 -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;
 };
 
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 12:01:14 -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 12:01:14 -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);
        }
@@ -245,7 +250,7 @@ vmd_sighdlr(int sig, short event, void *
                 * 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 *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 12:01:14 -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 12:01:14 -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);
        }
 }
 

Reply via email to