diff options
-rw-r--r-- | usr.sbin/vmctl/main.c | 46 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.8 | 12 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.c | 14 | ||||
-rw-r--r-- | usr.sbin/vmctl/vmctl.h | 7 |
4 files changed, 65 insertions, 14 deletions
diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c index 44db2347a6d..740e9cd5f77 100644 --- a/usr.sbin/vmctl/main.c +++ b/usr.sbin/vmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.18 2016/10/12 19:10:03 reyk Exp $ */ +/* $OpenBSD: main.c,v 1.19 2016/11/26 18:37:32 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -63,7 +63,8 @@ struct ctl_command ctl_commands[] = { { "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]*" }, + " [-c] [-k kernel] [-m size]\n" + "\t\t[-n switch] [-i count] [-d disk]*" }, { "status", CMD_STATUS, ctl_status, "[id]" }, { "stop", CMD_STOP, ctl_stop, "id" }, { NULL } @@ -191,7 +192,7 @@ vmmaction(struct parse_result *res) switch (res->action) { case CMD_START: - ret = start_vm(res->name, res->size, res->nifs, + ret = start_vm(res->name, res->size, res->nifs, res->nets, res->ndisks, res->disks, res->path); if (ret) { errno = ret; @@ -308,6 +309,29 @@ parse_ifs(struct parse_result *res, char *word, int val) } } res->nifs = val; + + return (0); +} + +int +parse_network(struct parse_result *res, char *word) +{ + char **nets; + char *s; + + if ((nets = reallocarray(res->nets, res->nnets + 1, + sizeof(char *))) == NULL) { + warn("reallocarray"); + return (-1); + } + if ((s = strdup(word)) == NULL) { + warn("strdup"); + return (-1); + } + nets[res->nnets] = s; + res->nets = nets; + res->nnets++; + return (0); } @@ -480,7 +504,7 @@ ctl_reset(struct parse_result *res, int argc, char *argv[]) int ctl_start(struct parse_result *res, int argc, char *argv[]) { - int ch; + int ch, i; char path[PATH_MAX]; if (argc < 2) @@ -491,7 +515,7 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) argc--; argv++; - while ((ch = getopt(argc, argv, "ck:m:d:i:")) != -1) { + while ((ch = getopt(argc, argv, "ck:m:n:d:i:")) != -1) { switch (ch) { case 'c': tty_autoconnect = 1; @@ -510,6 +534,10 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) if (parse_size(res, optarg, 0) != 0) errx(1, "invalid memory size: %s", optarg); break; + case 'n': + if (parse_network(res, optarg) != 0) + errx(1, "invalid network: %s", optarg); + break; case 'd': if (realpath(optarg, path) == NULL) err(1, "invalid disk path"); @@ -528,6 +556,14 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) } } + for (i = res->nnets; i < res->nifs; i++) { + /* Add interface that is not attached to a switch */ + if (parse_network(res, "") == -1) + return (-1); + } + if (res->nnets > res->nifs) + res->nifs = res->nnets; + return (vmmaction(res)); } diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8 index 4dd26b12f62..821cdb2b3e2 100644 --- a/usr.sbin/vmctl/vmctl.8 +++ b/usr.sbin/vmctl/vmctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vmctl.8,v 1.17 2016/10/13 19:43:44 martijn Exp $ +.\" $OpenBSD: vmctl.8,v 1.18 2016/11/26 18:37:32 reyk 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: October 13 2016 $ +.Dd $Mdocdate: November 26 2016 $ .Dt VMCTL 8 .Os .Sh NAME @@ -87,6 +87,14 @@ Kernel to load when booting the VM. Memory .Ar size of the VM, rounded to megabytes. +.It Fl n Ar switch +Add a network interface that is attached to the specified virtual +.Ar switch . +See +.Sx SWITCH CONFIGURATION +in +.Xr vm.conf 5 +for more information. .El .It Cm status Op Ar id Lists VMs running on the host, optionally listing just the selected VM diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c index 3f69c4b6bcf..79eadc2ff73 100644 --- a/usr.sbin/vmctl/vmctl.c +++ b/usr.sbin/vmctl/vmctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.c,v 1.18 2016/11/24 07:58:55 reyk Exp $ */ +/* $OpenBSD: vmctl.c,v 1.19 2016/11/26 18:37:32 reyk Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> @@ -52,6 +52,7 @@ int info_console; * name: optional name of the VM * memsize: memory size (MB) of the VM to create * nnics: number of vionet network interfaces to create + * nics: switch names of the network interfaces to create * ndisks: number of disk images * disks: disk image file names * kernel: kernel image to load @@ -61,8 +62,8 @@ int info_console; * ENOMEM if a memory allocation failure occurred. */ int -start_vm(const char *name, int memsize, int nnics, int ndisks, char **disks, - char *kernel) +start_vm(const char *name, int memsize, int nnics, char **nics, + int ndisks, char **disks, char *kernel) { struct vmop_create_params *vmc; struct vm_create_params *vcp; @@ -78,6 +79,8 @@ start_vm(const char *name, int memsize, int nnics, int ndisks, char **disks, errx(1, "no kernel or disk specified"); if (nnics == -1) nnics = 0; + if (nnics > VMM_MAX_NICS_PER_VM) + errx(1, "too many network interfaces"); if (nnics == 0) warnx("starting without network interfaces"); @@ -97,15 +100,16 @@ start_vm(const char *name, int memsize, int nnics, int ndisks, char **disks, vcp->vcp_ncpus = 1; vcp->vcp_ndisks = ndisks; + vcp->vcp_nnics = nnics; for (i = 0 ; i < ndisks; i++) strlcpy(vcp->vcp_disks[i], disks[i], VMM_MAX_PATH_DISK); - + for (i = 0 ; i < nnics; i++) + strlcpy(vmc->vmc_ifswitch[i], nics[i], IF_NAMESIZE); if (name != NULL) strlcpy(vcp->vcp_name, name, VMM_MAX_NAME_LEN); if (kernel != NULL) strlcpy(vcp->vcp_kernel, kernel, VMM_MAX_KERNEL_PATH); - vcp->vcp_nnics = nnics; imsg_compose(ibuf, IMSG_VMDOP_START_VM_REQUEST, 0, 0, -1, vmc, sizeof(struct vmop_create_params)); diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h index 68d70233c73..953f3e7ec67 100644 --- a/usr.sbin/vmctl/vmctl.h +++ b/usr.sbin/vmctl/vmctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.h,v 1.9 2016/10/12 19:10:03 reyk Exp $ */ +/* $OpenBSD: vmctl.h,v 1.10 2016/11/26 18:37:32 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -42,6 +42,8 @@ struct parse_result { char *path; long long size; int nifs; + char **nets; + int nnets; size_t ndisks; char **disks; int disable; @@ -62,6 +64,7 @@ struct imsgbuf *ibuf; /* main.c */ int vmmaction(struct parse_result *); int parse_ifs(struct parse_result *, char *, int); +int parse_network(struct parse_result *, char *); int parse_size(struct parse_result *, char *, long long); int parse_disk(struct parse_result *, char *); int parse_vmid(struct parse_result *, char *); @@ -72,7 +75,7 @@ __dead void /* vmctl.c */ int create_imagefile(const char *, long); -int start_vm(const char *, int, int, int, char **, char *); +int start_vm(const char *, int, int, char **, int, char **, char *); int start_vm_complete(struct imsg *, int *, int); void terminate_vm(uint32_t, const char *); int terminate_vm_complete(struct imsg *, int *); |