From: reyk Date: Thu, 12 Jul 2018 12:04:49 +0000 (+0000) Subject: Allow to use configured/running VMs as templates for other VM instances. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6429e63326439075d6cce608bf8dee72a55247e0;p=openbsd Allow to use configured/running VMs as templates for other VM instances. This introduces new grammar and the -t optional in vmctl start. (For now, only root can create VM instances; but it is planned to allow users to create their own VMs based on permissions and quota.) OK ccardenas@ mlarkin@ jmc@ --- diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c index 7b288d5255c..2ab74c8bee1 100644 --- a/usr.sbin/vmctl/main.c +++ b/usr.sbin/vmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.37 2018/07/11 13:19:47 reyk Exp $ */ +/* $OpenBSD: main.c,v 1.38 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -71,7 +71,7 @@ struct ctl_command ctl_commands[] = { { "show", CMD_STATUS, ctl_status, "[id]" }, { "start", CMD_START, ctl_start, "\"name\"" " [-Lc] [-b image] [-r image] [-m size]\n" - "\t\t[-n switch] [-i count] [-d disk]*" }, + "\t\t[-n switch] [-i count] [-d disk]* [-I name]" }, { "status", CMD_STATUS, ctl_status, "[id]" }, { "stop", CMD_STOP, ctl_stop, "id [-fw]" }, { "pause", CMD_PAUSE, ctl_pause, "id" }, @@ -206,7 +206,7 @@ vmmaction(struct parse_result *res) case CMD_START: ret = vm_start(res->id, res->name, res->size, res->nifs, res->nets, res->ndisks, res->disks, res->path, - res->isopath); + res->isopath, res->instance); if (ret) { errno = ret; err(1, "start VM operation failed"); @@ -330,6 +330,7 @@ parse_free(struct parse_result *res) free(res->name); free(res->path); free(res->isopath); + free(res->instance); for (i = 0; i < res->ndisks; i++) free(res->disks[i]); free(res->disks); @@ -451,6 +452,20 @@ parse_vmid(struct parse_result *res, char *word, int needname) return (0); } +int +parse_instance(struct parse_result *res, char *word) +{ + if (strlen(word) >= VMM_MAX_NAME_LEN) { + warnx("instance vm name too long"); + return (-1); + } + res->id = 0; + if ((res->instance = strdup(word)) == NULL) + errx(1, "strdup"); + + return (0); +} + int ctl_create(struct parse_result *res, int argc, char *argv[]) { @@ -577,7 +592,7 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) argc--; argv++; - while ((ch = getopt(argc, argv, "b:r:cLm:n:d:i:")) != -1) { + while ((ch = getopt(argc, argv, "b:r:cLm:n:d:I:i:")) != -1) { switch (ch) { case 'b': if (res->path) @@ -618,6 +633,10 @@ ctl_start(struct parse_result *res, int argc, char *argv[]) if (parse_disk(res, path) != 0) errx(1, "invalid disk: %s", optarg); break; + case 'I': + if (parse_instance(res, optarg) == -1) + errx(1, "invalid name: %s", optarg); + break; case 'i': if (res->nifs != -1) errx(1, "interfaces specified multiple times"); diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8 index 8c1eb11bc76..81b54c13283 100644 --- a/usr.sbin/vmctl/vmctl.8 +++ b/usr.sbin/vmctl/vmctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vmctl.8,v 1.42 2018/07/11 17:21:57 jmc Exp $ +.\" $OpenBSD: vmctl.8,v 1.43 2018/07/12 12:04:49 reyk Exp $ .\" .\" Copyright (c) 2015 Mike Larkin .\" @@ -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: July 11 2018 $ +.Dd $Mdocdate: July 12 2018 $ .Dt VMCTL 8 .Os .Sh NAME @@ -94,10 +94,11 @@ command. .Op Fl n Ar switch .Bk -words .Op Fl r Ar path +.Op Fl t Ar name .Ek .Xc Starts a VM defined by the specified name and parameters: -.Bl -tag -width "-i count" +.Bl -tag -width "-I parent" .It Fl b Ar path Boot the VM with the specified kernel or BIOS image. If not specified, the default is to boot using the BIOS image in @@ -139,6 +140,13 @@ This image file will be available in the selected VM as a SCSI CD-ROM device attached to a virtio SCSI adapter (e.g.\& .Xr vioscsi 4 ) . +.It Fl t Ar name +Use an existing VM with the specified +.Ar name +as a template to create a new VM instance. +The instance will inherit settings from the parent VM, +except for exclusive options such as disk, interface lladdr, or +interface names. .El .Pp Note that the VM name supplied to the 'start' command can only consist of @@ -287,6 +295,12 @@ Create a new VM with 1GB memory, one network interface, one disk image # vmctl start "myvm" -m 1G -i 1 -b /bsd -d disk.img .Ed .Pp +Start a new VM instance with the name 'myvm' from a pre-configured +VM 'openbsd.4G': +.Bd -literal -offset indent +# vmctl start "myvm" -t "openbsd.4G" -d mydisk.img +.Ed +.Pp .Xr vmd 8 will create a new .Xr tap 4 diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c index c6dec18616a..7ab9a9bc60c 100644 --- a/usr.sbin/vmctl/vmctl.c +++ b/usr.sbin/vmctl/vmctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.c,v 1.53 2018/07/11 21:29:05 reyk Exp $ */ +/* $OpenBSD: vmctl.c,v 1.54 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2014 Mike Larkin @@ -62,6 +62,7 @@ int info_console; * disks: disk image file names * kernel: kernel image to load * iso: iso image file + * instance: create instance from vm * * Return: * 0 if the request to start the VM was sent successfully. @@ -69,7 +70,8 @@ int info_console; */ int vm_start(uint32_t start_id, const char *name, int memsize, int nnics, - char **nics, int ndisks, char **disks, char *kernel, char *iso) + char **nics, int ndisks, char **disks, char *kernel, char *iso, + char *instance) { struct vmop_create_params *vmc; struct vm_create_params *vcp; @@ -87,7 +89,9 @@ vm_start(uint32_t start_id, const char *name, int memsize, int nnics, flags |= VMOP_CREATE_KERNEL; if (iso) flags |= VMOP_CREATE_CDROM; - if (flags != 0) { + if (instance) + flags |= VMOP_CREATE_INSTANCE; + else if (flags != 0) { if (memsize < 1) memsize = VM_DEFAULT_MEMORY; if (ndisks > VMM_MAX_DISKS_PER_VM) @@ -172,6 +176,10 @@ vm_start(uint32_t start_id, const char *name, int memsize, int nnics, if (strlcpy(vcp->vcp_cdrom, iso, sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) errx(1, "cdrom name too long"); + if (instance != NULL) + if (strlcpy(vmc->vmc_instance, instance, + sizeof(vmc->vmc_instance)) >= sizeof(vmc->vmc_instance)) + errx(1, "instance vm name too long"); imsg_compose(ibuf, IMSG_VMDOP_START_VM_REQUEST, 0, 0, -1, vmc, sizeof(struct vmop_create_params)); @@ -219,7 +227,7 @@ vm_start_complete(struct imsg *imsg, int *ret, int autoconnect) *ret = ENOENT; break; case VMD_DISK_MISSING: - warnx("could not open specified disk image(s)"); + warnx("could not open disk image(s)"); *ret = ENOENT; break; case VMD_DISK_INVALID: diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h index 7fc8af8cbeb..91ade10b7d8 100644 --- a/usr.sbin/vmctl/vmctl.h +++ b/usr.sbin/vmctl/vmctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.h,v 1.20 2018/07/11 13:19:47 reyk Exp $ */ +/* $OpenBSD: vmctl.h,v 1.21 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -53,6 +53,7 @@ struct parse_result { size_t ndisks; char **disks; int verbose; + char *instance; unsigned int flags; unsigned int mode; struct ctl_command *ctl; @@ -75,6 +76,7 @@ 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 *, int); +int parse_instance(struct parse_result *, char *); void parse_free(struct parse_result *); int parse(int, char *[]); __dead void @@ -83,7 +85,7 @@ __dead void /* vmctl.c */ int create_imagefile(const char *, long); int vm_start(uint32_t, const char *, int, int, char **, int, - char **, char *, char *); + char **, char *, char *, char *); 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); diff --git a/usr.sbin/vmd/parse.y b/usr.sbin/vmd/parse.y index 305a6030875..a17079c4358 100644 --- a/usr.sbin/vmd/parse.y +++ b/usr.sbin/vmd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.40 2018/07/11 16:43:24 reyk Exp $ */ +/* $OpenBSD: parse.y,v 1.41 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2007-2016 Reyk Floeter @@ -93,7 +93,6 @@ int parse_disk(char *); static struct vmop_create_params vmc; static struct vm_create_params *vcp; static struct vmd_switch *vsw; -static struct vmd_vm *vm; static char vsw_type[IF_NAMESIZE]; static int vcp_disable; static size_t vcp_nnics; @@ -118,7 +117,7 @@ typedef struct { %token INCLUDE ERROR -%token ADD BOOT CDROM DISABLE DISK DOWN ENABLE GROUP INTERFACE LLADDR +%token ADD BOOT CDROM DISABLE DISK DOWN ENABLE GROUP INSTANCE INTERFACE LLADDR %token LOCAL LOCKED MEMORY NIFS OWNER PATH PREFIX RDOMAIN SIZE SOCKET SWITCH %token UP VM VMID %token NUMBER @@ -131,6 +130,7 @@ typedef struct { %type owner_id %type optstring %type string +%type vm_instance %% @@ -279,22 +279,42 @@ switch_opts : disable { } ; -vm : VM string { +vm : VM string vm_instance { unsigned int i; + char *name; memset(&vmc, 0, sizeof(vmc)); vcp = &vmc.vmc_params; vcp_disable = 0; vcp_nnics = 0; + if ($3 != NULL) { + /* This is an instance of a pre-configured VM */ + if (strlcpy(vmc.vmc_instance, $2, + sizeof(vmc.vmc_instance)) >= + sizeof(vmc.vmc_instance)) { + yyerror("vm %s name too long", $2); + free($2); + free($3); + YYERROR; + } + + free($2); + name = $3; + vmc.vmc_flags |= VMOP_CREATE_INSTANCE; + } else + name = $2; + for (i = 0; i < VMM_MAX_NICS_PER_VM; i++) { /* Set the interface to UP by default */ vmc.vmc_ifflags[i] |= IFF_UP; } - if (strlcpy(vcp->vcp_name, $2, sizeof(vcp->vcp_name)) >= - sizeof(vcp->vcp_name)) { + if (strlcpy(vcp->vcp_name, name, + sizeof(vcp->vcp_name)) >= sizeof(vcp->vcp_name)) { yyerror("vm name too long"); + free($2); + free($3); YYERROR; } @@ -302,7 +322,8 @@ vm : VM string { vmc.vmc_uid = 0; vmc.vmc_gid = -1; } '{' optnl vm_opts_l '}' { - int ret; + struct vmd_vm *vm; + int ret; /* configured interfaces vs. number of interfaces */ if (vcp_nnics > vcp->vcp_nnics) @@ -318,9 +339,8 @@ vm : VM string { vcp->vcp_name, vm->vm_running ? "running" : "already exists"); } else if (ret == -1) { - log_warn("%s:%d: vm \"%s\" failed", - file->name, yylval.lineno, - vcp->vcp_name); + yyerror("vm \"%s\" failed: %s", + vcp->vcp_name, strerror(errno)); YYERROR; } else { if (vcp_disable) @@ -337,6 +357,10 @@ vm : VM string { } ; +vm_instance : /* empty */ { $$ = NULL; } + | INSTANCE string { $$ = $2; } + ; + vm_opts_l : vm_opts_l vm_opts nl | vm_opts optnl ; @@ -673,6 +697,7 @@ lookup(char *s) { "group", GROUP }, { "id", VMID }, { "include", INCLUDE }, + { "instance", INSTANCE }, { "interface", INTERFACE }, { "interfaces", NIFS }, { "lladdr", LLADDR }, @@ -1163,12 +1188,19 @@ parse_size(char *word, int64_t val) int parse_disk(char *word) { + char path[PATH_MAX]; + if (vcp->vcp_ndisks >= VMM_MAX_DISKS_PER_VM) { log_warnx("too many disks"); return (-1); } - if (strlcpy(vcp->vcp_disks[vcp->vcp_ndisks], word, + if (realpath(word, path) == NULL) { + log_warn("disk %s", word); + return (-1); + } + + if (strlcpy(vcp->vcp_disks[vcp->vcp_ndisks], path, VMM_MAX_PATH_DISK) >= VMM_MAX_PATH_DISK) { log_warnx("disk path too long"); return (-1); diff --git a/usr.sbin/vmd/vm.conf.5 b/usr.sbin/vmd/vm.conf.5 index a73a561d0ad..b16bda1a3df 100644 --- a/usr.sbin/vmd/vm.conf.5 +++ b/usr.sbin/vmd/vm.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vm.conf.5,v 1.31 2018/06/26 11:34:25 jmc Exp $ +.\" $OpenBSD: vm.conf.5,v 1.32 2018/07/12 12:04:49 reyk Exp $ .\" .\" Copyright (c) 2015 Mike Larkin .\" Copyright (c) 2015 Reyk Floeter @@ -15,7 +15,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: June 26 2018 $ +.Dd $Mdocdate: July 12 2018 $ .Dt VM.CONF 5 .Os .Sh NAME @@ -121,6 +121,16 @@ section starts with a declaration of the virtual machine The name can be any alphanumeric string along with '.', '-', and '_' characters. However, it cannot start with '.', '-', or '_'. Typically the name is a hostname. +.It Ic vm Ar parent Ic instance Ar name Brq ... +A virtual machine can be created as an instance of any other +configured VM. +The new instance will inherit settings from the VM +.Ar parent , +except for exclusive options such as +.Ic disk , +.Ic interface lladdr , +or +.Ic interface name . .El .Pp Followed by a block of parameters that is enclosed in curly brackets: @@ -317,6 +327,14 @@ vm "vm2.example.com" { } .Ed .Pp +Create a new VM as an instance from +.Sq vm2.example.com : +.Bd -literal -offset indent +vm "vm2.example.com" instance "vm3.example.com" { + disk "/home/joe/vm3-disk.img" +} +.Ed +.Pp Create the switch "uplink" with an additional physical network interface: .Bd -literal -offset indent switch "uplink" { diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index db1d05e4302..7fcef0d4a1e 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.94 2018/07/11 16:37:31 reyk Exp $ */ +/* $OpenBSD: vmd.c,v 1.95 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -58,6 +58,9 @@ int vmd_dispatch_control(int, struct privsep_proc *, struct imsg *); int vmd_dispatch_vmm(int, struct privsep_proc *, struct imsg *); int vmd_check_vmh(struct vm_dump_header *); +int vm_instance(struct privsep *, struct vmd_vm **, + struct vmop_create_params *, uid_t); + struct vmd *env; static struct privsep_proc procs[] = { @@ -70,6 +73,7 @@ static struct privsep_proc procs[] = { /* For the privileged process */ static struct privsep_proc *proc_priv = &procs[0]; static struct passwd proc_privpw; +static const uint8_t zero_mac[ETHER_ADDR_LEN]; int vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) @@ -1140,14 +1144,17 @@ int vm_register(struct privsep *ps, struct vmop_create_params *vmc, struct vmd_vm **ret_vm, uint32_t id, uid_t uid) { - struct vmd_vm *vm = NULL; + struct vmd_vm *vm = NULL, *vm_parent = NULL; struct vm_create_params *vcp = &vmc->vmc_params; - static const uint8_t zero_mac[ETHER_ADDR_LEN]; uint32_t rng; unsigned int i; struct vmd_switch *sw; char *s; + /* Check if this is an instance of another VM */ + if (vm_instance(ps, &vm_parent, vmc, uid) == -1) + return (-1); + errno = 0; *ret_vm = NULL; @@ -1162,16 +1169,14 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, goto fail; } - /* - * non-root users can only start existing VMs - * XXX there could be a mechanism to allow overriding some options - */ - if (vm_checkperm(NULL, uid) != 0) { + /* non-root users can only start existing VMs or instances */ + if (vm_checkperm(vm_parent, uid) != 0) { errno = EPERM; goto fail; } if (vmc->vmc_flags == 0) { - errno = ENOENT; + log_warnx("invalid configuration, no devices"); + errno = VMD_DISK_MISSING; goto fail; } if (vcp->vcp_ncpus == 0) @@ -1267,6 +1272,153 @@ vm_register(struct privsep *ps, struct vmop_create_params *vmc, return (-1); } +int +vm_instance(struct privsep *ps, struct vmd_vm **vm_parent, + struct vmop_create_params *vmc, uid_t uid) +{ + char *name; + struct vm_create_params *vcp = &vmc->vmc_params; + struct vmop_create_params *vmcp; + struct vm_create_params *vcpp; + struct vmd_vm *vm = NULL; + unsigned int i, j; + uint32_t id; + + /* return without error if the parent is NULL (nothing to inherit) */ + if ((vmc->vmc_flags & VMOP_CREATE_INSTANCE) == 0 || + (*vm_parent = vm_getbyname(vmc->vmc_instance)) == NULL) + return (0); + + errno = 0; + vmcp = &(*vm_parent)->vm_params; + vcpp = &vmcp->vmc_params; + + /* + * Are we allowed to create an instance from this VM? + * + * XXX This is currently allowed for root but will check *vm_parent + * XXX once we defined instance permissions and quota. + */ + if (vm_checkperm(NULL, uid) != 0) { + log_warnx("vm \"%s\" no permission to create vm instance", + vcpp->vcp_name); + errno = ENAMETOOLONG; + return (-1); + } + + id = vcp->vcp_id; + name = vcp->vcp_name; + + if ((vm = vm_getbyname(vcp->vcp_name)) != NULL || + (vm = vm_getbyvmid(vcp->vcp_id)) != NULL) { + errno = EPROCLIM; + return (-1); + } + + /* machine options */ + if (vcp->vcp_ncpus == 0) + vcp->vcp_ncpus = vcpp->vcp_ncpus; + if (vcp->vcp_memranges[0].vmr_size == 0) + vcp->vcp_memranges[0].vmr_size = + vcpp->vcp_memranges[0].vmr_size; + + /* disks cannot be inherited */ + for (i = 0; i < vcp->vcp_ndisks; i++) { + /* Check if this disk is already used in the parent */ + for (j = 0; j < vcpp->vcp_ndisks; j++) { + if (strcmp(vcp->vcp_disks[i], + vcpp->vcp_disks[j]) == 0) { + log_warnx("vm \"%s\" disk %s cannot be reused", + name, vcp->vcp_disks[i]); + errno = EBUSY; + return (-1); + } + } + } + + /* interfaces */ + for (i = 0; i < vcpp->vcp_nnics; i++) { + /* Interface got overwritten */ + if (i < vcp->vcp_nnics) + continue; + + /* Copy interface from parent */ + vmc->vmc_ifflags[i] = vmcp->vmc_ifflags[i]; + (void)strlcpy(vmc->vmc_ifnames[i], vmcp->vmc_ifnames[i], + sizeof(vmc->vmc_ifnames[i])); + (void)strlcpy(vmc->vmc_ifswitch[i], vmcp->vmc_ifswitch[i], + sizeof(vmc->vmc_ifswitch[i])); + (void)strlcpy(vmc->vmc_ifgroup[i], vmcp->vmc_ifgroup[i], + sizeof(vmc->vmc_ifgroup[i])); + memcpy(vcp->vcp_macs[i], vcpp->vcp_macs[i], + sizeof(vcp->vcp_macs[i])); + vmc->vmc_ifrdomain[i] = vmcp->vmc_ifrdomain[i]; + vcp->vcp_nnics++; + } + for (i = 0; i < vcp->vcp_nnics; i++) { + for (j = 0; j < vcpp->vcp_nnics; j++) { + if (memcmp(zero_mac, vcp->vcp_macs[i], + sizeof(vcp->vcp_macs[i])) != 0 && + memcmp(vcpp->vcp_macs[i], vcp->vcp_macs[i], + sizeof(vcp->vcp_macs[i])) != 0) { + log_warnx("vm \"%s\" lladdr cannot be reused", + name); + errno = EBUSY; + return (-1); + } + if (strlen(vmc->vmc_ifnames[i]) && + strcmp(vmc->vmc_ifnames[i], + vmcp->vmc_ifnames[j]) == 0) { + log_warnx("vm \"%s\" %s cannot be reused", + vmc->vmc_ifnames[i], name); + errno = EBUSY; + return (-1); + } + } + } + + /* kernel */ + if (strlen(vcp->vcp_kernel) == 0 && + strlcpy(vcp->vcp_kernel, vcpp->vcp_kernel, + sizeof(vcp->vcp_kernel)) >= sizeof(vcp->vcp_kernel)) { + log_warnx("vm \"%s\" kernel name too long", name); + errno = EINVAL; + return (-1); + } + + /* cdrom */ + if (strlen(vcp->vcp_cdrom) == 0 && + strlcpy(vcp->vcp_cdrom, vcpp->vcp_cdrom, + sizeof(vcp->vcp_cdrom)) >= sizeof(vcp->vcp_cdrom)) { + log_warnx("vm \"%s\" cdrom name too long", name); + errno = EINVAL; + return (-1); + } + + /* user */ + if (vmc->vmc_uid == 0) + vmc->vmc_uid = vmcp->vmc_uid; + else if (vmc->vmc_uid != vmcp->vmc_uid) { + log_warnx("vm \"%s\" user mismatch", name); + errno = EPERM; + return (-1); + } + + /* group */ + if (vmc->vmc_gid == 0) + vmc->vmc_gid = vmcp->vmc_gid; + else if (vmc->vmc_gid != vmcp->vmc_gid) { + log_warnx("vm \"%s\" group mismatch", name); + errno = EPERM; + return (-1); + } + + /* finished, remove instance flags */ + vmc->vmc_flags &= ~VMOP_CREATE_INSTANCE; + + return (0); +} + /* * vm_checkperm * diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h index c25f9642147..036557413fa 100644 --- a/usr.sbin/vmd/vmd.h +++ b/usr.sbin/vmd/vmd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.h,v 1.74 2018/07/11 13:19:47 reyk Exp $ */ +/* $OpenBSD: vmd.h,v 1.75 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -141,6 +141,7 @@ struct vmop_create_params { #define VMOP_CREATE_NETWORK 0x04 #define VMOP_CREATE_DISK 0x08 #define VMOP_CREATE_CDROM 0x10 +#define VMOP_CREATE_INSTANCE 0x20 /* userland-only part of the create params */ unsigned int vmc_ifflags[VMM_MAX_NICS_PER_VM]; @@ -153,6 +154,7 @@ struct vmop_create_params { char vmc_ifswitch[VMM_MAX_NICS_PER_VM][VM_NAME_MAX]; char vmc_ifgroup[VMM_MAX_NICS_PER_VM][IF_NAMESIZE]; unsigned int vmc_ifrdomain[VMM_MAX_NICS_PER_VM]; + char vmc_instance[VMM_MAX_NAME_LEN]; uid_t vmc_uid; int64_t vmc_gid; }; diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c index 9beed72df96..12ce8cc991f 100644 --- a/usr.sbin/vmd/vmm.c +++ b/usr.sbin/vmd/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.86 2018/07/11 13:19:47 reyk Exp $ */ +/* $OpenBSD: vmm.c,v 1.87 2018/07/12 12:04:49 reyk Exp $ */ /* * Copyright (c) 2015 Mike Larkin @@ -284,7 +284,8 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) case IMSG_VMDOP_RECEIVE_VM_REQUEST: IMSG_SIZE_CHECK(imsg, &vmc); memcpy(&vmc, imsg->data, sizeof(vmc)); - ret = vm_register(ps, &vmc, &vm, imsg->hdr.peerid, vmc.vmc_uid); + ret = vm_register(ps, &vmc, &vm, + imsg->hdr.peerid, vmc.vmc_uid); vm->vm_tty = imsg->fd; vm->vm_received = 1; break;