xref: /openbsd-src/usr.sbin/vmctl/main.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$OpenBSD: main.c,v 1.55 2019/03/18 20:27:12 kn Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/queue.h>
22 #include <sys/un.h>
23 
24 #include <machine/vmmvar.h>
25 
26 #include <err.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdint.h>
31 #include <limits.h>
32 #include <string.h>
33 #include <syslog.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <util.h>
37 #include <imsg.h>
38 
39 #include "vmd.h"
40 #include "virtio.h"
41 #include "proc.h"
42 #include "vmctl.h"
43 
44 #define RAW_FMT		"raw"
45 #define QCOW2_FMT	"qcow2"
46 
47 static const char	*socket_name = SOCKET_NAME;
48 static int		 ctl_sock = -1;
49 static int		 tty_autoconnect = 0;
50 
51 __dead void	 usage(void);
52 __dead void	 ctl_usage(struct ctl_command *);
53 
54 int		 vmm_action(struct parse_result *);
55 
56 int		 ctl_console(struct parse_result *, int, char *[]);
57 int		 ctl_convert(const char *, const char *, int, size_t);
58 int		 ctl_create(struct parse_result *, int, char *[]);
59 int		 ctl_load(struct parse_result *, int, char *[]);
60 int		 ctl_log(struct parse_result *, int, char *[]);
61 int		 ctl_reload(struct parse_result *, int, char *[]);
62 int		 ctl_reset(struct parse_result *, int, char *[]);
63 int		 ctl_start(struct parse_result *, int, char *[]);
64 int		 ctl_status(struct parse_result *, int, char *[]);
65 int		 ctl_stop(struct parse_result *, int, char *[]);
66 int		 ctl_waitfor(struct parse_result *, int, char *[]);
67 int		 ctl_pause(struct parse_result *, int, char *[]);
68 int		 ctl_unpause(struct parse_result *, int, char *[]);
69 int		 ctl_send(struct parse_result *, int, char *[]);
70 int		 ctl_receive(struct parse_result *, int, char *[]);
71 
72 struct ctl_command ctl_commands[] = {
73 	{ "console",	CMD_CONSOLE,	ctl_console,	"id" },
74 	{ "create",	CMD_CREATE,	ctl_create,
75 		"disk [-b base | -i disk] [-s size]", 1 },
76 	{ "load",	CMD_LOAD,	ctl_load,	"filename" },
77 	{ "log",	CMD_LOG,	ctl_log,	"[brief | verbose]" },
78 	{ "pause",	CMD_PAUSE,	ctl_pause,	"id" },
79 	{ "receive",	CMD_RECEIVE,	ctl_receive,	"name" ,	1},
80 	{ "reload",	CMD_RELOAD,	ctl_reload,	"" },
81 	{ "reset",	CMD_RESET,	ctl_reset,	"[all | switches | vms]" },
82 	{ "send",	CMD_SEND,	ctl_send,	"id",	1},
83 	{ "show",	CMD_STATUS,	ctl_status,	"[id]" },
84 	{ "start",	CMD_START,	ctl_start,	"id | name"
85 	    " [-cL] [-B device] [-b path] [-d disk] [-i count]\n"
86 	    "\t\t[-m size] [-n switch] [-r path] [-t name]" },
87 	{ "status",	CMD_STATUS,	ctl_status,	"[id]" },
88 	{ "stop",	CMD_STOP,	ctl_stop,	"[id | -a] [-fw]" },
89 	{ "unpause",	CMD_UNPAUSE,	ctl_unpause,	"id" },
90 	{ "wait",	CMD_WAITFOR,	ctl_waitfor,	"id" },
91 	{ NULL }
92 };
93 
94 __dead void
95 usage(void)
96 {
97 	extern char	*__progname;
98 	int		 i;
99 
100 	fprintf(stderr, "usage:\t%s [-v] command [arg ...]\n",
101 	    __progname);
102 	for (i = 0; ctl_commands[i].name != NULL; i++) {
103 		fprintf(stderr, "\t%s %s %s\n", __progname,
104 		    ctl_commands[i].name, ctl_commands[i].usage);
105 	}
106 	exit(1);
107 }
108 
109 __dead void
110 ctl_usage(struct ctl_command *ctl)
111 {
112 	extern char	*__progname;
113 
114 	fprintf(stderr, "usage:\t%s [-v] %s %s\n", __progname,
115 	    ctl->name, ctl->usage);
116 	exit(1);
117 }
118 
119 int
120 main(int argc, char *argv[])
121 {
122 	int	 ch, verbose = 1;
123 
124 	while ((ch = getopt(argc, argv, "v")) != -1) {
125 		switch (ch) {
126 		case 'v':
127 			verbose = 2;
128 			break;
129 		default:
130 			usage();
131 			/* NOTREACHED */
132 		}
133 	}
134 	argc -= optind;
135 	argv += optind;
136 	optreset = 1;
137 	optind = 1;
138 
139 	if (argc < 1)
140 		usage();
141 
142 	log_init(verbose, LOG_DAEMON);
143 
144 	return (parse(argc, argv));
145 }
146 
147 int
148 parse(int argc, char *argv[])
149 {
150 	struct ctl_command	*ctl = NULL;
151 	struct parse_result	 res;
152 	int			 i;
153 
154 	memset(&res, 0, sizeof(res));
155 	res.nifs = -1;
156 
157 	for (i = 0; ctl_commands[i].name != NULL; i++) {
158 		if (strncmp(ctl_commands[i].name,
159 		    argv[0], strlen(argv[0])) == 0) {
160 			if (ctl != NULL) {
161 				fprintf(stderr,
162 				    "ambiguous argument: %s\n", argv[0]);
163 				usage();
164 			}
165 			ctl = &ctl_commands[i];
166 		}
167 	}
168 
169 	if (ctl == NULL) {
170 		fprintf(stderr, "unknown argument: %s\n", argv[0]);
171 		usage();
172 	}
173 
174 	res.action = ctl->action;
175 	res.ctl = ctl;
176 
177 	if (!ctl->has_pledge) {
178 		/* pledge(2) default if command doesn't have its own pledge */
179 		if (pledge("stdio rpath exec unix getpw unveil", NULL) == -1)
180 			err(1, "pledge");
181 	}
182 	if (ctl->main(&res, argc, argv) != 0)
183 		exit(1);
184 
185 	if (ctl_sock != -1) {
186 		close(ibuf->fd);
187 		free(ibuf);
188 	}
189 
190 	return (0);
191 }
192 
193 int
194 vmmaction(struct parse_result *res)
195 {
196 	struct sockaddr_un	 sun;
197 	struct imsg		 imsg;
198 	int			 done = 0;
199 	int			 n;
200 	int			 ret, action;
201 	unsigned int		 flags;
202 
203 	if (ctl_sock == -1) {
204 		if (unveil(SOCKET_NAME, "r") == -1)
205 			err(1, "unveil");
206 		if ((ctl_sock = socket(AF_UNIX,
207 		    SOCK_STREAM|SOCK_CLOEXEC, 0)) == -1)
208 			err(1, "socket");
209 
210 		memset(&sun, 0, sizeof(sun));
211 		sun.sun_family = AF_UNIX;
212 		strlcpy(sun.sun_path, socket_name, sizeof(sun.sun_path));
213 
214 		if (connect(ctl_sock,
215 		    (struct sockaddr *)&sun, sizeof(sun)) == -1)
216 			err(1, "connect: %s", socket_name);
217 
218 		if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
219 			err(1, "malloc");
220 		imsg_init(ibuf, ctl_sock);
221 	}
222 
223 	switch (res->action) {
224 	case CMD_START:
225 		ret = vm_start(res->id, res->name, res->size, res->nifs,
226 		    res->nets, res->ndisks, res->disks, res->disktypes,
227 		    res->path, res->isopath, res->instance, res->bootdevice);
228 		if (ret) {
229 			errno = ret;
230 			err(1, "start VM operation failed");
231 		}
232 		break;
233 	case CMD_STOP:
234 		terminate_vm(res->id, res->name, res->flags);
235 		break;
236 	case CMD_STATUS:
237 	case CMD_CONSOLE:
238 	case CMD_STOPALL:
239 		get_info_vm(res->id, res->name, res->action, res->flags);
240 		break;
241 	case CMD_LOAD:
242 		imsg_compose(ibuf, IMSG_VMDOP_LOAD, 0, 0, -1,
243 		    res->path, strlen(res->path) + 1);
244 		break;
245 	case CMD_LOG:
246 		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1,
247 		    &res->verbose, sizeof(res->verbose));
248 		break;
249 	case CMD_RELOAD:
250 		imsg_compose(ibuf, IMSG_VMDOP_RELOAD, 0, 0, -1, NULL, 0);
251 		break;
252 	case CMD_RESET:
253 		imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1,
254 		    &res->mode, sizeof(res->mode));
255 		break;
256 	case CMD_WAITFOR:
257 		waitfor_vm(res->id, res->name);
258 		break;
259 	case CMD_PAUSE:
260 		pause_vm(res->id, res->name);
261 		break;
262 	case CMD_UNPAUSE:
263 		unpause_vm(res->id, res->name);
264 		break;
265 	case CMD_SEND:
266 		send_vm(res->id, res->name);
267 		done = 1;
268 		break;
269 	case CMD_RECEIVE:
270 		vm_receive(res->id, res->name);
271 		break;
272 	case CMD_CREATE:
273 	case NONE:
274 		/* The action is not expected here */
275 		errx(1, "invalid action %u", res->action);
276 		break;
277 	}
278 
279 	action = res->action;
280 	flags = res->flags;
281 	parse_free(res);
282 
283 	while (ibuf->w.queued)
284 		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
285 			err(1, "write error");
286 
287 	while (!done) {
288 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
289 			errx(1, "imsg_read error");
290 		if (n == 0)
291 			errx(1, "pipe closed");
292 
293 		while (!done) {
294 			if ((n = imsg_get(ibuf, &imsg)) == -1)
295 				errx(1, "imsg_get error");
296 			if (n == 0)
297 				break;
298 
299 			if (imsg.hdr.type == IMSG_CTL_FAIL) {
300 				if (IMSG_DATA_SIZE(&imsg) == sizeof(ret))
301 					memcpy(&ret, imsg.data, sizeof(ret));
302 				else
303 					ret = 0;
304 				if (ret != 0) {
305 					memcpy(&ret, imsg.data, sizeof(ret));
306 					errno = ret;
307 					err(1, "command failed");
308 				} else
309 					errx(1, "command failed");
310 			}
311 
312 			ret = 0;
313 			switch (action) {
314 			case CMD_START:
315 				done = vm_start_complete(&imsg, &ret,
316 				    tty_autoconnect);
317 				break;
318 			case CMD_WAITFOR:
319 				flags = VMOP_WAIT;
320 				/* FALLTHROUGH */
321 			case CMD_STOP:
322 				done = terminate_vm_complete(&imsg, &ret,
323 				    flags);
324 				break;
325 			case CMD_CONSOLE:
326 			case CMD_STATUS:
327 			case CMD_STOPALL:
328 				done = add_info(&imsg, &ret);
329 				break;
330 			case CMD_PAUSE:
331 				done = pause_vm_complete(&imsg, &ret);
332 				break;
333 			case CMD_RECEIVE:
334 				done = vm_start_complete(&imsg, &ret, 0);
335 				break;
336 			case CMD_UNPAUSE:
337 				done = unpause_vm_complete(&imsg, &ret);
338 				break;
339 			default:
340 				done = 1;
341 				break;
342 			}
343 
344 			imsg_free(&imsg);
345 		}
346 	}
347 
348 	if (ret)
349 		return (1);
350 	else
351 		return (0);
352 }
353 
354 void
355 parse_free(struct parse_result *res)
356 {
357 	size_t	 i;
358 
359 	free(res->name);
360 	free(res->path);
361 	free(res->isopath);
362 	free(res->instance);
363 	for (i = 0; i < res->ndisks; i++)
364 		free(res->disks[i]);
365 	free(res->disks);
366 	free(res->disktypes);
367 	memset(res, 0, sizeof(*res));
368 }
369 
370 int
371 parse_ifs(struct parse_result *res, char *word, int val)
372 {
373 	const char	*error;
374 
375 	if (word != NULL) {
376 		val = strtonum(word, 0, INT_MAX, &error);
377 		if (error != NULL)  {
378 			warnx("invalid count \"%s\": %s", word, error);
379 			return (-1);
380 		}
381 	}
382 	res->nifs = val;
383 
384 	return (0);
385 }
386 
387 int
388 parse_network(struct parse_result *res, char *word)
389 {
390 	char		**nets;
391 	char		*s;
392 
393 	if ((nets = reallocarray(res->nets, res->nnets + 1,
394 	    sizeof(char *))) == NULL) {
395 		warn("reallocarray");
396 		return (-1);
397 	}
398 	if ((s = strdup(word)) == NULL) {
399 		warn("strdup");
400 		return (-1);
401 	}
402 	nets[res->nnets] = s;
403 	res->nets = nets;
404 	res->nnets++;
405 
406 	return (0);
407 }
408 
409 int
410 parse_size(struct parse_result *res, char *word, long long val)
411 {
412 	if (word != NULL) {
413 		if (scan_scaled(word, &val) != 0) {
414 			warn("invalid size: %s", word);
415 			return (-1);
416 		}
417 	}
418 
419 	if (val < (1024 * 1024)) {
420 		warnx("size must be at least one megabyte");
421 		return (-1);
422 	} else
423 		res->size = val / 1024 / 1024;
424 
425 	if ((res->size * 1024 * 1024) != val)
426 		warnx("size rounded to %lld megabytes", res->size);
427 
428 	return (0);
429 }
430 
431 int
432 parse_disktype(const char *s, const char **ret)
433 {
434 	char		 buf[BUFSIZ];
435 	const char	*ext;
436 	int		 fd;
437 	ssize_t		 len;
438 
439 	*ret = s;
440 
441 	/* Try to parse the explicit format (qcow2:disk.qc2) */
442 	if (strstr(s, RAW_FMT) == s && *(s + strlen(RAW_FMT)) == ':') {
443 		*ret = s + strlen(RAW_FMT) + 1;
444 		return (VMDF_RAW);
445 	}
446 	if (strstr(s, QCOW2_FMT) == s && *(s + strlen(QCOW2_FMT)) == ':') {
447 		*ret = s + strlen(QCOW2_FMT) + 1;
448 		return (VMDF_QCOW2);
449 	}
450 
451 	/* Or try to derive the format from the file signature */
452 	if ((fd = open(s, O_RDONLY)) != -1) {
453 		len = read(fd, buf, sizeof(buf));
454 		close(fd);
455 
456 		if (len >= (ssize_t)strlen(VM_MAGIC_QCOW) &&
457 		    strncmp(buf, VM_MAGIC_QCOW,
458 		    strlen(VM_MAGIC_QCOW)) == 0) {
459 			/* Return qcow2, the version will be checked later */
460 			return (VMDF_QCOW2);
461 		}
462 	}
463 
464 	/*
465 	 * Use the extension as a last option.  This is needed for
466 	 * 'vmctl create' as the file, and the signature, doesn't
467 	 * exist yet.
468 	 */
469 	if ((ext = strrchr(s, '.')) != NULL && *(++ext) != '\0') {
470 		if (strcasecmp(ext, RAW_FMT) == 0)
471 			return (VMDF_RAW);
472 		else if (strcasecmp(ext, QCOW2_FMT) == 0)
473 			return (VMDF_QCOW2);
474 	}
475 
476 	/* Fallback to raw */
477 	return (VMDF_RAW);
478 }
479 
480 int
481 parse_disk(struct parse_result *res, char *word, int type)
482 {
483 	char		**disks;
484 	int		*disktypes;
485 	char		*s;
486 
487 	if ((disks = reallocarray(res->disks, res->ndisks + 1,
488 	    sizeof(char *))) == NULL) {
489 		warn("reallocarray");
490 		return (-1);
491 	}
492 	if ((disktypes = reallocarray(res->disktypes, res->ndisks + 1,
493 	    sizeof(int))) == NULL) {
494 		warn("reallocarray");
495 		return -1;
496 	}
497 	if ((s = strdup(word)) == NULL) {
498 		warn("strdup");
499 		return (-1);
500 	}
501 	disks[res->ndisks] = s;
502 	disktypes[res->ndisks] = type;
503 	res->disks = disks;
504 	res->disktypes = disktypes;
505 	res->ndisks++;
506 
507 	return (0);
508 }
509 
510 int
511 parse_vmid(struct parse_result *res, char *word, int needname)
512 {
513 	const char	*error;
514 	uint32_t	 id;
515 
516 	if (word == NULL) {
517 		warnx("missing vmid argument");
518 		return (-1);
519 	}
520 	if (*word == '-') {
521 		/* don't print a warning to allow command line options */
522 		return (-1);
523 	}
524 	id = strtonum(word, 0, UINT32_MAX, &error);
525 	if (error == NULL) {
526 		if (needname) {
527 			warnx("invalid vm name");
528 			return (-1);
529 		} else {
530 			res->id = id;
531 			res->name = NULL;
532 		}
533 	} else {
534 		if (strlen(word) >= VMM_MAX_NAME_LEN) {
535 			warnx("name too long");
536 			return (-1);
537 		}
538 		res->id = 0;
539 		if ((res->name = strdup(word)) == NULL)
540 			errx(1, "strdup");
541 	}
542 
543 	return (0);
544 }
545 
546 int
547 parse_instance(struct parse_result *res, char *word)
548 {
549 	if (strlen(word) >= VMM_MAX_NAME_LEN) {
550 		warnx("instance vm name too long");
551 		return (-1);
552 	}
553 	res->id = 0;
554 	if ((res->instance = strdup(word)) == NULL)
555 		errx(1, "strdup");
556 
557 	return (0);
558 }
559 
560 int
561 ctl_create(struct parse_result *res, int argc, char *argv[])
562 {
563 	int		 ch, ret, type;
564 	const char	*disk, *format, *base, *input;
565 
566 	if (argc < 2)
567 		ctl_usage(res->ctl);
568 
569 	base = input = NULL;
570 	type = parse_disktype(argv[1], &disk);
571 
572 	if (pledge("stdio rpath wpath cpath unveil", NULL) == -1)
573 		err(1, "pledge");
574 	if (unveil(disk, "rwc") == -1)
575 		err(1, "unveil");
576 
577 	argc--;
578 	argv++;
579 
580 	while ((ch = getopt(argc, argv, "b:i:s:")) != -1) {
581 		switch (ch) {
582 		case 'b':
583 			base = optarg;
584 			if (unveil(base, "r") == -1)
585 				err(1, "unveil");
586 			break;
587 		case 'i':
588 			input = optarg;
589 			if (unveil(input, "r") == -1)
590 				err(1, "unveil");
591 			break;
592 		case 's':
593 			if (parse_size(res, optarg, 0) != 0)
594 				errx(1, "invalid size: %s", optarg);
595 			break;
596 		default:
597 			ctl_usage(res->ctl);
598 			/* NOTREACHED */
599 		}
600 	}
601 	argc -= optind;
602 	argv += optind;
603 
604 	if (argc > 0)
605 		ctl_usage(res->ctl);
606 
607 	if (input) {
608 		if (base && input)
609 			errx(1, "conflicting -b and -i arguments");
610 		return ctl_convert(input, disk, type, res->size);
611 	}
612 
613 	if (unveil(NULL, NULL))
614 		err(1, "unveil");
615 
616 	if (base && type != VMDF_QCOW2)
617 		errx(1, "base images require qcow2 disk format");
618 	if (res->size == 0 && !base) {
619 		fprintf(stderr, "could not create %s: missing size argument\n",
620 		    disk);
621 		ctl_usage(res->ctl);
622 	}
623 
624 	if ((ret = create_imagefile(type, disk, base, res->size, &format)) != 0) {
625 		errno = ret;
626 		err(1, "create imagefile operation failed");
627 	} else
628 		warnx("%s imagefile created", format);
629 
630 	return (0);
631 }
632 
633 int
634 ctl_convert(const char *srcfile, const char *dstfile, int dsttype, size_t dstsize)
635 {
636 	struct {
637 		int			 fd;
638 		int			 type;
639 		struct virtio_backing	 file;
640 		const char		*disk;
641 		off_t			 size;
642 	}	 src, dst;
643 	int		 ret;
644 	const char	*format, *errstr = NULL;
645 	uint8_t		*buf = NULL, *zerobuf = NULL;
646 	size_t		 buflen;
647 	ssize_t		 len, rlen;
648 	off_t		 off;
649 
650 	memset(&src, 0, sizeof(src));
651 	memset(&dst, 0, sizeof(dst));
652 
653 	src.type = parse_disktype(srcfile, &src.disk);
654 	dst.type = dsttype;
655 	dst.disk = dstfile;
656 
657 	if ((src.fd = open_imagefile(src.type, src.disk, O_RDONLY,
658 	    &src.file, &src.size)) == -1) {
659 		errstr = "failed to open source image file";
660 		goto done;
661 	}
662 
663 	/* We can only lock unveil after opening the disk and all base images */
664 	if (unveil(NULL, NULL))
665 		err(1, "unveil");
666 
667 	if (dstsize == 0)
668 		dstsize = src.size;
669 	else
670 		dstsize *= 1048576;
671 	if (dstsize < (size_t)src.size) {
672 		errstr = "size cannot be smaller than input disk size";
673 		goto done;
674 	}
675 
676 	/* align to megabytes */
677 	dst.size = ALIGNSZ(dstsize, 1048576);
678 
679 	if ((ret = create_imagefile(dst.type, dst.disk, NULL,
680 	   dst.size / 1048576, &format)) != 0) {
681 		errno = ret;
682 		errstr = "failed to create destination image file";
683 		goto done;
684 	}
685 
686 	if ((dst.fd = open_imagefile(dst.type, dst.disk, O_RDWR,
687 	    &dst.file, &dst.size)) == -1) {
688 		errstr = "failed to open destination image file";
689 		goto done;
690 	}
691 
692 	if (pledge("stdio", NULL) == -1)
693 		err(1, "pledge");
694 
695 	/*
696 	 * Use 64k buffers by default.  This could also be adjusted to
697 	 * the backend cluster size.
698 	 */
699 	buflen = 1 << 16;
700 	if ((buf = calloc(1, buflen)) == NULL ||
701 	    (zerobuf = calloc(1, buflen)) == NULL) {
702 		errstr = "failed to allocated buffers";
703 		goto done;
704 	}
705 
706 	for (off = 0; off < dst.size; off += len) {
707 		/* Read input from the source image */
708 		if (off < src.size) {
709 			len = MIN((off_t)buflen, src.size - off);
710 			if ((rlen = src.file.pread(src.file.p,
711 			    buf, (size_t)len, off)) != len) {
712 				errno = EIO;
713 				errstr = "failed to read from source";
714 				goto done;
715 			}
716 		} else
717 			len = 0;
718 
719 		/* and pad the remaining bytes */
720 		if (len < (ssize_t)buflen) {
721 			log_debug("%s: padding %zd zero bytes at offset %lld",
722 			    format, buflen - len, off + len);
723 			memset(buf + len, 0, buflen - len);
724 			len = buflen;
725 		}
726 
727 		/*
728 		 * No need to copy empty buffers.  This allows the backend,
729 		 * sparse files or QCOW2 images, to save space in the
730 		 * destination file.
731 		 */
732 		if (memcmp(buf, zerobuf, buflen) == 0)
733 			continue;
734 
735 		log_debug("%s: writing %zd of %lld bytes at offset %lld",
736 		    format, len, dst.size, off);
737 
738 		if ((rlen = dst.file.pwrite(dst.file.p,
739 		    buf, (size_t)len, off)) != len) {
740 			errno = EIO;
741 			errstr = "failed to write to destination";
742 			goto done;
743 		}
744 	}
745 
746 	if (dstsize < (size_t)dst.size)
747 		warnx("destination size rounded to %lld megabytes",
748 		    dst.size / 1048576);
749 
750  done:
751 	free(buf);
752 	free(zerobuf);
753 	if (src.file.p != NULL)
754 		src.file.close(src.file.p, 0);
755 	if (dst.file.p != NULL)
756 		dst.file.close(dst.file.p, 0);
757 	if (errstr != NULL)
758 		errx(1, "%s", errstr);
759 	else
760 		warnx("%s imagefile created", format);
761 
762 	return (0);
763 }
764 
765 int
766 ctl_status(struct parse_result *res, int argc, char *argv[])
767 {
768 	if (argc == 2) {
769 		if (parse_vmid(res, argv[1], 0) == -1)
770 			errx(1, "invalid id: %s", argv[1]);
771 	} else if (argc > 2)
772 		ctl_usage(res->ctl);
773 
774 	return (vmmaction(res));
775 }
776 
777 int
778 ctl_load(struct parse_result *res, int argc, char *argv[])
779 {
780 	if (argc != 2)
781 		ctl_usage(res->ctl);
782 
783 	if ((res->path = strdup(argv[1])) == NULL)
784 		err(1, "strdup");
785 
786 	return (vmmaction(res));
787 }
788 
789 int
790 ctl_log(struct parse_result *res, int argc, char *argv[])
791 {
792 	if (argc != 2)
793 		ctl_usage(res->ctl);
794 
795 	if (strncasecmp("brief", argv[1], strlen(argv[1])) == 0)
796 		res->verbose = 0;
797 	else if (strncasecmp("verbose", argv[1], strlen(argv[1])) == 0)
798 		res->verbose = 2;
799 	else
800 		ctl_usage(res->ctl);
801 
802 	return (vmmaction(res));
803 }
804 
805 int
806 ctl_reload(struct parse_result *res, int argc, char *argv[])
807 {
808 	if (argc != 1)
809 		ctl_usage(res->ctl);
810 
811 	return (vmmaction(res));
812 }
813 
814 int
815 ctl_reset(struct parse_result *res, int argc, char *argv[])
816 {
817 	if (argc == 2) {
818 		if (strcasecmp("all", argv[1]) == 0)
819 			res->mode = CONFIG_ALL;
820 		else if (strcasecmp("vms", argv[1]) == 0)
821 			res->mode = CONFIG_VMS;
822 		else if (strcasecmp("switches", argv[1]) == 0)
823 			res->mode = CONFIG_SWITCHES;
824 		else
825 			ctl_usage(res->ctl);
826 	} else if (argc > 2)
827 		ctl_usage(res->ctl);
828 
829 	if (res->mode == 0)
830 		res->mode = CONFIG_ALL;
831 
832 	return (vmmaction(res));
833 }
834 
835 int
836 ctl_start(struct parse_result *res, int argc, char *argv[])
837 {
838 	int		 ch, i, type;
839 	char		 path[PATH_MAX];
840 	const char	*s;
841 
842 	if (argc < 2)
843 		ctl_usage(res->ctl);
844 
845 	if (parse_vmid(res, argv[1], 0) == -1)
846 		errx(1, "invalid id: %s", argv[1]);
847 
848 	argc--;
849 	argv++;
850 
851 	while ((ch = getopt(argc, argv, "b:B:cd:i:Lm:n:r:t:")) != -1) {
852 		switch (ch) {
853 		case 'b':
854 			if (res->path)
855 				errx(1, "boot image specified multiple times");
856 			if (realpath(optarg, path) == NULL)
857 				err(1, "invalid boot image path");
858 			if ((res->path = strdup(path)) == NULL)
859 				errx(1, "strdup");
860 			break;
861 		case 'B':
862 			if (res->bootdevice)
863 				errx(1, "boot device specified multiple times");
864 			if (strcmp("disk", optarg) == 0)
865 				res->bootdevice = VMBOOTDEV_DISK;
866 			else if (strcmp("cdrom", optarg) == 0)
867 				res->bootdevice = VMBOOTDEV_CDROM;
868 			else if (strcmp("net", optarg) == 0)
869 				res->bootdevice = VMBOOTDEV_NET;
870 			else
871 				errx(1, "unknown boot device %s", optarg);
872 			break;
873 		case 'r':
874 			if (res->isopath)
875 				errx(1, "iso image specified multiple times");
876 			if (realpath(optarg, path) == NULL)
877 				err(1, "invalid iso image path");
878 			if ((res->isopath = strdup(path)) == NULL)
879 				errx(1, "strdup");
880 			break;
881 		case 'c':
882 			tty_autoconnect = 1;
883 			break;
884 		case 'L':
885 			if (parse_network(res, ".") != 0)
886 				errx(1, "invalid network: %s", optarg);
887 			break;
888 		case 'm':
889 			if (res->size)
890 				errx(1, "memory specified multiple times");
891 			if (parse_size(res, optarg, 0) != 0)
892 				errx(1, "invalid memory size: %s", optarg);
893 			break;
894 		case 'n':
895 			if (parse_network(res, optarg) != 0)
896 				errx(1, "invalid network: %s", optarg);
897 			break;
898 		case 'd':
899 			type = parse_disktype(optarg, &s);
900 			if (realpath(s, path) == NULL)
901 				err(1, "invalid disk path");
902 			if (parse_disk(res, path, type) != 0)
903 				errx(1, "invalid disk: %s", optarg);
904 			break;
905 		case 'i':
906 			if (res->nifs != -1)
907 				errx(1, "interfaces specified multiple times");
908 			if (parse_ifs(res, optarg, 0) != 0)
909 				errx(1, "invalid interface count: %s", optarg);
910 			break;
911 		case 't':
912 			if (parse_instance(res, optarg) == -1)
913 				errx(1, "invalid name: %s", optarg);
914 			break;
915 		default:
916 			ctl_usage(res->ctl);
917 			/* NOTREACHED */
918 		}
919 	}
920 	argc -= optind;
921 	argv += optind;
922 
923 	if (argc > 0)
924 		ctl_usage(res->ctl);
925 
926 	for (i = res->nnets; i < res->nifs; i++) {
927 		/* Add interface that is not attached to a switch */
928 		if (parse_network(res, "") == -1)
929 			return (-1);
930 	}
931 	if (res->nnets > res->nifs)
932 		res->nifs = res->nnets;
933 
934 	return (vmmaction(res));
935 }
936 
937 int
938 ctl_stop(struct parse_result *res, int argc, char *argv[])
939 {
940 	int		 ch, ret;
941 
942 	if (argc < 2)
943 		ctl_usage(res->ctl);
944 
945 	if ((ret = parse_vmid(res, argv[1], 0)) == 0) {
946 		argc--;
947 		argv++;
948 	}
949 
950 	while ((ch = getopt(argc, argv, "afw")) != -1) {
951 		switch (ch) {
952 		case 'f':
953 			res->flags |= VMOP_FORCE;
954 			break;
955 		case 'w':
956 			res->flags |= VMOP_WAIT;
957 			break;
958 		case 'a':
959 			res->action = CMD_STOPALL;
960 			break;
961 		default:
962 			ctl_usage(res->ctl);
963 			/* NOTREACHED */
964 		}
965 	}
966 	argc -= optind;
967 	argv += optind;
968 
969 	if (argc > 0)
970 		ctl_usage(res->ctl);
971 
972 	/* VM id is only expected without the -a flag */
973 	if ((res->action != CMD_STOPALL && ret == -1) ||
974 	    (res->action == CMD_STOPALL && ret != -1))
975 		errx(1, "invalid id: %s", argv[1]);
976 
977 	return (vmmaction(res));
978 }
979 
980 int
981 ctl_console(struct parse_result *res, int argc, char *argv[])
982 {
983 	if (argc == 2) {
984 		if (parse_vmid(res, argv[1], 0) == -1)
985 			errx(1, "invalid id: %s", argv[1]);
986 	} else if (argc != 2)
987 		ctl_usage(res->ctl);
988 
989 	return (vmmaction(res));
990 }
991 
992 int
993 ctl_waitfor(struct parse_result *res, int argc, char *argv[])
994 {
995 	if (argc == 2) {
996 		if (parse_vmid(res, argv[1], 0) == -1)
997 			errx(1, "invalid id: %s", argv[1]);
998 	} else if (argc != 2)
999 		ctl_usage(res->ctl);
1000 
1001 	return (vmmaction(res));
1002 }
1003 
1004 int
1005 ctl_pause(struct parse_result *res, int argc, char *argv[])
1006 {
1007 	if (argc == 2) {
1008 		if (parse_vmid(res, argv[1], 0) == -1)
1009 			errx(1, "invalid id: %s", argv[1]);
1010 	} else if (argc != 2)
1011 		ctl_usage(res->ctl);
1012 
1013 	return (vmmaction(res));
1014 }
1015 
1016 int
1017 ctl_unpause(struct parse_result *res, int argc, char *argv[])
1018 {
1019 	if (argc == 2) {
1020 		if (parse_vmid(res, argv[1], 0) == -1)
1021 			errx(1, "invalid id: %s", argv[1]);
1022 	} else if (argc != 2)
1023 		ctl_usage(res->ctl);
1024 
1025 	return (vmmaction(res));
1026 }
1027 
1028 int
1029 ctl_send(struct parse_result *res, int argc, char *argv[])
1030 {
1031 	if (pledge("stdio unix sendfd unveil", NULL) == -1)
1032 		err(1, "pledge");
1033 	if (argc == 2) {
1034 		if (parse_vmid(res, argv[1], 0) == -1)
1035 			errx(1, "invalid id: %s", argv[1]);
1036 	} else if (argc != 2)
1037 		ctl_usage(res->ctl);
1038 
1039 	return (vmmaction(res));
1040 }
1041 
1042 int
1043 ctl_receive(struct parse_result *res, int argc, char *argv[])
1044 {
1045 	if (pledge("stdio unix sendfd unveil", NULL) == -1)
1046 		err(1, "pledge");
1047 	if (argc == 2) {
1048 		if (parse_vmid(res, argv[1], 1) == -1)
1049 			errx(1, "invalid id: %s", argv[1]);
1050 	} else if (argc != 2)
1051 		ctl_usage(res->ctl);
1052 
1053 	return (vmmaction(res));
1054 }
1055 
1056 __dead void
1057 ctl_openconsole(const char *name)
1058 {
1059 	closefrom(STDERR_FILENO + 1);
1060 	if (unveil(VMCTL_CU, "x") == -1)
1061 		err(1, "unveil");
1062 	execl(VMCTL_CU, VMCTL_CU, "-l", name, "-s", "115200", (char *)NULL);
1063 	err(1, "failed to open the console");
1064 }
1065