summaryrefslogtreecommitdiffstats
path: root/usr.sbin/vmctl
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2018-12-04 08:17:17 +0000
committerclaudio <claudio@openbsd.org>2018-12-04 08:17:17 +0000
commit583f66182c3cfd5d7b117d30d54faadc736ebc2f (patch)
tree3692199239b4c7233e1f0583d1bc4d41c5d54c7a /usr.sbin/vmctl
parentIntroduce IMSG_VMDOP_WAIT_VM_REQUEST a control message that registers a (diff)
downloadwireguard-openbsd-583f66182c3cfd5d7b117d30d54faadc736ebc2f.tar.xz
wireguard-openbsd-583f66182c3cfd5d7b117d30d54faadc736ebc2f.zip
Add 'vmctl wait <VM>' a command that waits until the specified VM is
stopped/terminates. Useful in scripts when waiting until a vm has finished its work. Ok ccardenas@, reyk@
Diffstat (limited to 'usr.sbin/vmctl')
-rw-r--r--usr.sbin/vmctl/main.c29
-rw-r--r--usr.sbin/vmctl/vmctl.86
-rw-r--r--usr.sbin/vmctl/vmctl.c33
-rw-r--r--usr.sbin/vmctl/vmctl.h4
4 files changed, 65 insertions, 7 deletions
diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c
index d0efcaf3c8c..7a7f5d874d7 100644
--- a/usr.sbin/vmctl/main.c
+++ b/usr.sbin/vmctl/main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: main.c,v 1.48 2018/11/26 10:39:30 reyk Exp $ */
+/* $OpenBSD: main.c,v 1.49 2018/12/04 08:17:17 claudio Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -63,6 +63,7 @@ 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 *[]);
+int ctl_waitfor(struct parse_result *, int, char *[]);
int ctl_pause(struct parse_result *, int, char *[]);
int ctl_unpause(struct parse_result *, int, char *[]);
int ctl_send(struct parse_result *, int, char *[]);
@@ -82,6 +83,7 @@ struct ctl_command ctl_commands[] = {
"\t\t[-n switch] [-i count] [-d disk]* [-t name]" },
{ "status", CMD_STATUS, ctl_status, "[id]" },
{ "stop", CMD_STOP, ctl_stop, "[id|-a] [-fw]" },
+ { "wait", CMD_WAITFOR, ctl_waitfor, "id" },
{ "pause", CMD_PAUSE, ctl_pause, "id" },
{ "unpause", CMD_UNPAUSE, ctl_unpause, "id" },
{ "send", CMD_SEND, ctl_send, "id", 1},
@@ -178,7 +180,7 @@ parse(int argc, char *argv[])
err(1, "pledge");
}
if (ctl->main(&res, argc, argv) != 0)
- err(1, "failed");
+ exit(1);
if (ctl_sock != -1) {
close(ibuf->fd);
@@ -251,6 +253,9 @@ vmmaction(struct parse_result *res)
imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1,
&res->mode, sizeof(res->mode));
break;
+ case CMD_WAITFOR:
+ waitfor_vm(res->id, res->name);
+ break;
case CMD_PAUSE:
pause_vm(res->id, res->name);
break;
@@ -310,6 +315,9 @@ vmmaction(struct parse_result *res)
done = vm_start_complete(&imsg, &ret,
tty_autoconnect);
break;
+ case CMD_WAITFOR:
+ flags = VMOP_WAIT;
+ /* FALLTHROUGH */
case CMD_STOP:
done = terminate_vm_complete(&imsg, &ret,
flags);
@@ -337,7 +345,10 @@ vmmaction(struct parse_result *res)
}
}
- return (0);
+ if (ret)
+ return (1);
+ else
+ return (0);
}
void
@@ -952,6 +963,18 @@ ctl_console(struct parse_result *res, int argc, char *argv[])
}
int
+ctl_waitfor(struct parse_result *res, int argc, char *argv[])
+{
+ if (argc == 2) {
+ if (parse_vmid(res, argv[1], 0) == -1)
+ errx(1, "invalid id: %s", argv[1]);
+ } else if (argc != 2)
+ ctl_usage(res->ctl);
+
+ return (vmmaction(res));
+}
+
+int
ctl_pause(struct parse_result *res, int argc, char *argv[])
{
if (argc == 2) {
diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8
index 7ccee17cb7a..9ff53217599 100644
--- a/usr.sbin/vmctl/vmctl.8
+++ b/usr.sbin/vmctl/vmctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vmctl.8,v 1.54 2018/11/20 12:48:16 otto Exp $
+.\" $OpenBSD: vmctl.8,v 1.55 2018/12/04 08:17:17 claudio Exp $
.\"
.\" Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: November 20 2018 $
+.Dd $Mdocdate: December 4 2018 $
.Dt VMCTL 8
.Os
.Sh NAME
@@ -234,6 +234,8 @@ Stop all running VMs.
.It Cm unpause Ar id
Unpause (resume from a paused state) a VM with the specified
.Ar id .
+.It Cm wait Ar id
+Wait until the specified VM has stopped.
.El
.Pp
If the
diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c
index 66200a6ab28..334f43968c8 100644
--- a/usr.sbin/vmctl/vmctl.c
+++ b/usr.sbin/vmctl/vmctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.c,v 1.63 2018/11/26 10:39:30 reyk Exp $ */
+/* $OpenBSD: vmctl.c,v 1.64 2018/12/04 08:17:17 claudio Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
@@ -496,6 +496,10 @@ terminate_vm_complete(struct imsg *imsg, int *ret, unsigned int flags)
fprintf(stderr, "vm not found\n");
*ret = EIO;
break;
+ case EINTR:
+ fprintf(stderr, "interrupted call\n");
+ *ret = EIO;
+ break;
default:
errno = res;
fprintf(stderr, "failed: %s\n",
@@ -560,6 +564,33 @@ terminate_all(struct vmop_info_result *list, size_t ct, unsigned int flags)
}
/*
+ * waitfor_vm
+ *
+ * Wait until vmd stopped the indicated VM
+ *
+ * Parameters:
+ * terminate_id: ID of the vm to be terminated
+ * name: optional name of the VM to be terminated
+ */
+void
+waitfor_vm(uint32_t terminate_id, const char *name)
+{
+ struct vmop_id vid;
+
+ memset(&vid, 0, sizeof(vid));
+ vid.vid_id = terminate_id;
+ if (name != NULL) {
+ (void)strlcpy(vid.vid_name, name, sizeof(vid.vid_name));
+ fprintf(stderr, "waiting for vm %s: ", name);
+ } else {
+ fprintf(stderr, "waiting for vm: ");
+ }
+
+ imsg_compose(ibuf, IMSG_VMDOP_WAIT_VM_REQUEST,
+ 0, 0, -1, &vid, sizeof(vid));
+}
+
+/*
* get_info_vm
*
* Return the list of all running VMs or find a specific VM by ID or name.
diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h
index 37aeac34ce2..420dc0c00fb 100644
--- a/usr.sbin/vmctl/vmctl.h
+++ b/usr.sbin/vmctl/vmctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmctl.h,v 1.28 2018/11/26 10:39:30 reyk Exp $ */
+/* $OpenBSD: vmctl.h,v 1.29 2018/12/04 08:17:17 claudio Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -33,6 +33,7 @@ enum actions {
CMD_STATUS,
CMD_STOP,
CMD_STOPALL,
+ CMD_WAITFOR,
CMD_PAUSE,
CMD_UNPAUSE,
CMD_SEND,
@@ -96,6 +97,7 @@ int vm_start(uint32_t, const char *, int, int, char **, int,
int vm_start_complete(struct imsg *, int *, int);
void terminate_vm(uint32_t, const char *, unsigned int);
int terminate_vm_complete(struct imsg *, int *, unsigned int);
+void waitfor_vm(uint32_t, const char *);
void pause_vm(uint32_t, const char *);
int pause_vm_complete(struct imsg *, int *);
void unpause_vm(uint32_t, const char *);