summaryrefslogtreecommitdiff
path: root/usr.sbin/vmctl/vmctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/vmctl/vmctl.c')
-rw-r--r--usr.sbin/vmctl/vmctl.c89
1 files changed, 73 insertions, 16 deletions
diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c
index 4fffa110469..355bd4d0900 100644
--- a/usr.sbin/vmctl/vmctl.c
+++ b/usr.sbin/vmctl/vmctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.c,v 1.58 2018/09/16 02:43:11 millert Exp $ */
+/* $OpenBSD: vmctl.c,v 1.59 2018/09/27 17:15:36 reyk Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
@@ -45,7 +45,8 @@
extern char *__progname;
uint32_t info_id;
char info_name[VMM_MAX_NAME_LEN];
-int info_console;
+enum actions info_action;
+unsigned int info_flags;
/*
* vm_start
@@ -440,8 +441,12 @@ terminate_vm(uint32_t terminate_id, const char *name, unsigned int flags)
memset(&vid, 0, sizeof(vid));
vid.vid_id = terminate_id;
- if (name != NULL)
+ if (name != NULL) {
(void)strlcpy(vid.vid_name, name, sizeof(vid.vid_name));
+ fprintf(stderr, "stopping vm %s: ", name);
+ } else {
+ fprintf(stderr, "stopping vm: ");
+ }
vid.vid_flags = flags & (VMOP_FORCE|VMOP_WAIT);
@@ -482,28 +487,32 @@ terminate_vm_complete(struct imsg *imsg, int *ret, unsigned int flags)
if (res) {
switch (res) {
case VMD_VM_STOP_INVALID:
- warnx("cannot stop vm that is not running");
+ fprintf(stderr,
+ "cannot stop vm that is not running\n");
*ret = EINVAL;
break;
case ENOENT:
- warnx("vm not found");
+ fprintf(stderr, "vm not found\n");
*ret = EIO;
break;
default:
errno = res;
- warn("terminate vm command failed");
+ fprintf(stderr, "failed: %s\n",
+ strerror(res));
*ret = EIO;
}
} else if (flags & VMOP_WAIT) {
- warnx("terminated vm %d", vmr->vmr_id);
+ fprintf(stderr, "terminated vm %d\n", vmr->vmr_id);
} else if (flags & VMOP_FORCE) {
- warnx("requested to terminate vm %d", vmr->vmr_id);
+ fprintf(stderr, "forced to terminate vm %d\n",
+ vmr->vmr_id);
} else {
- warnx("requested to shutdown vm %d", vmr->vmr_id);
+ fprintf(stderr, "requested to shutdown vm %d\n",
+ vmr->vmr_id);
*ret = 0;
}
} else {
- warnx("unexpected response received from vmd");
+ fprintf(stderr, "unexpected response received from vmd\n");
*ret = EINVAL;
}
errno = *ret;
@@ -512,6 +521,44 @@ terminate_vm_complete(struct imsg *imsg, int *ret, unsigned int flags)
}
/*
+ * terminate_all
+ *
+ * Request to stop all VMs gracefully
+ *
+ * Parameters
+ * list: the vm information (consolidated) returned from vmd via imsg
+ * ct : the size (number of elements in 'list') of the result
+ * flags: VMOP_FORCE or VMOP_WAIT flags
+ */
+void
+terminate_all(struct vmop_info_result *list, size_t ct, unsigned int flags)
+{
+ struct vm_info_result *vir;
+ struct vmop_info_result *vmi;
+ struct parse_result res;
+ size_t i;
+
+ for (i = 0; i < ct; i++) {
+ vmi = &list[i];
+ vir = &vmi->vir_info;
+
+ /* The VM is already stopped */
+ if (vir->vir_creator_pid == 0 || vir->vir_id == 0)
+ continue;
+
+ memset(&res, 0, sizeof(res));
+ res.action = CMD_STOP;
+ res.id = 0;
+ res.flags = info_flags;
+
+ if ((res.name = strdup(vir->vir_name)) == NULL)
+ errx(1, "strdup");
+
+ vmmaction(&res);
+ }
+}
+
+/*
* get_info_vm
*
* Return the list of all running VMs or find a specific VM by ID or name.
@@ -519,17 +566,20 @@ terminate_vm_complete(struct imsg *imsg, int *ret, unsigned int flags)
* Parameters:
* id: optional ID of a VM to list
* name: optional name of a VM to list
- * console: if true, open the console of the selected VM (by name or ID)
+ * action: if CMD_CONSOLE or CMD_STOP open a console or terminate the VM.
+ * flags: optional flags used by the CMD_STOP action.
*
* Request a list of running VMs from vmd
*/
void
-get_info_vm(uint32_t id, const char *name, int console)
+get_info_vm(uint32_t id, const char *name, enum actions action,
+ unsigned int flags)
{
info_id = id;
if (name != NULL)
(void)strlcpy(info_name, name, sizeof(info_name));
- info_console = console;
+ info_action = action;
+ info_flags = flags;
imsg_compose(ibuf, IMSG_VMDOP_GET_INFO_VM_REQUEST, 0, 0, -1, NULL, 0);
}
@@ -574,7 +624,7 @@ check_info_id(const char *name, uint32_t id)
* to the "list vm" data. The caller should check the value of
* 'ret' to determine which case occurred.
*
- * This function does not return if a VM is found and info_console is set.
+ * This function does not return if a VM is found and info_action is CMD_CONSOLE
*
* The function also sets 'ret' to the error code as follows:
* 0 : Message successfully processed
@@ -599,10 +649,17 @@ add_info(struct imsg *imsg, int *ret)
*ret = 0;
return (0);
} else if (imsg->hdr.type == IMSG_VMDOP_GET_INFO_VM_END_DATA) {
- if (info_console)
+ switch (info_action) {
+ case CMD_CONSOLE:
vm_console(vir, ct);
- else
+ break;
+ case CMD_STOPALL:
+ terminate_all(vir, ct, info_flags);
+ break;
+ default:
print_vm_info(vir, ct);
+ break;
+ }
free(vir);
*ret = 0;
return (1);