summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/vmctl/main.c46
-rw-r--r--usr.sbin/vmctl/vmctl.812
-rw-r--r--usr.sbin/vmctl/vmctl.c14
-rw-r--r--usr.sbin/vmctl/vmctl.h7
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 *);