diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-12-04 08:17:18 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-12-04 08:17:18 +0000 |
commit | 2975b01a5b89f23dc156323c95b38cbbbc45ffc0 (patch) | |
tree | 359190310acd0f90bdd323864fe9130efef69c70 | |
parent | ab8bb4c044896ca3664f97e974e6be02ee5e4803 (diff) |
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@
-rw-r--r-- | usr.sbin/vmctl/main.c | 29 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.8 | 6 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.c | 33 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.h | 4 |
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 *); |