On Mon, Feb 27, 2017 at 10:55:31AM +0100, Reyk Floeter wrote:
> The following diff is not really needed without just yet, but:
> - openening /dev/ptm in advance might allow better pledge in the future
> - customizing "openpty" will allow to do what we need next
> Since openpty(4) is libutil and not libc, it should be fine not using it.
> 
> OK?
> 
>     Replace openpty(3) with local function that uses pre-opened /dev/ptm fd
>     
>     This allows more flexibility for upcoming changes and better pledge.
>     We also didn't use half of the features of libutil's openpty function.
>     Additionally, make sure that the ttys are closed correctly on shutdown.
> 

ok gilles@


> diff --git usr.sbin/vmd/config.c usr.sbin/vmd/config.c
> index f35a3b3..a16c143 100644
> --- usr.sbin/vmd/config.c
> +++ usr.sbin/vmd/config.c
> @@ -126,10 +126,9 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, 
> uint32_t peerid)
>       struct vmop_create_params *vmc = &vm->vm_params;
>       struct vm_create_params *vcp = &vmc->vmc_params;
>       unsigned int             i;
> -     int                      fd = -1, ttys_fd;
> +     int                      fd = -1;
>       int                      kernfd = -1, *diskfds = NULL, *tapfds = NULL;
>       int                      saved_errno = 0;
> -     char                     ptyname[VM_TTYNAME_MAX];
>       char                     ifname[IF_NAMESIZE], *s;
>       char                     path[PATH_MAX];
>       unsigned int             unit;
> @@ -241,12 +240,11 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, 
> uint32_t peerid)
>  
>       /* Open TTY */
>       if (vm->vm_ttyname == NULL) {
> -             if (openpty(&vm->vm_tty, &ttys_fd, ptyname, NULL, NULL) == -1 ||
> -                 (vm->vm_ttyname = strdup(ptyname)) == NULL) {
> -                     log_warn("%s: can't open tty %s", __func__, ptyname);
> +             if (vm_opentty(vm) == -1) {
> +                     log_warn("%s: can't open tty %s", __func__,
> +                         vm->vm_ttyname == NULL ? "" : vm->vm_ttyname);
>                       goto fail;
>               }
> -             close(ttys_fd);
>       }
>       if ((fd = dup(vm->vm_tty)) == -1) {
>               log_warn("%s: can't re-open tty %s", __func__, vm->vm_ttyname);
> diff --git usr.sbin/vmd/vmd.c usr.sbin/vmd/vmd.c
> index a01e40f..ed678ee 100644
> --- usr.sbin/vmd/vmd.c
> +++ usr.sbin/vmd/vmd.c
> @@ -20,6 +20,8 @@
>  #include <sys/queue.h>
>  #include <sys/wait.h>
>  #include <sys/cdefs.h>
> +#include <sys/tty.h>
> +#include <sys/ioctl.h>
>  
>  #include <stdio.h>
>  #include <stdlib.h>
> @@ -33,7 +35,6 @@
>  #include <syslog.h>
>  #include <unistd.h>
>  #include <ctype.h>
> -#include <util.h>
>  
>  #include "proc.h"
>  #include "vmd.h"
> @@ -484,6 +485,9 @@ vmd_configure(void)
>       struct vmd_vm           *vm;
>       struct vmd_switch       *vsw;
>  
> +     if ((env->vmd_ptmfd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC)) == -1)
> +             fatal("open %s", PATH_PTMDEV);
> +
>       /*
>        * pledge in the parent process:
>        * stdio - for malloc and basic I/O including events.
> @@ -605,6 +609,12 @@ vmd_reload(unsigned int reset, const char *filename)
>  void
>  vmd_shutdown(void)
>  {
> +     struct vmd_vm *vm, *vm_next;
> +
> +     TAILQ_FOREACH_SAFE(vm, env->vmd_vms, vm_entry, vm_next) {
> +             vm_remove(vm);
> +     }
> +
>       proc_kill(&env->vmd_ps);
>       free(env);
>  
> @@ -702,16 +712,8 @@ vm_stop(struct vmd_vm *vm, int keeptty)
>               close(vm->vm_kernel);
>               vm->vm_kernel = -1;
>       }
> -
> -     if (keeptty)
> -             return;
> -
> -     if (vm->vm_tty != -1) {
> -             close(vm->vm_tty);
> -             vm->vm_tty = -1;
> -     }
> -     free(vm->vm_ttyname);
> -     vm->vm_ttyname = NULL;
> +     if (!keeptty)
> +             vm_closetty(vm);
>  }
>  
>  void
> @@ -769,6 +771,7 @@ vm_register(struct privsep *ps, struct vmop_create_params 
> *vmc,
>  
>       memcpy(&vm->vm_params, vmc, sizeof(vm->vm_params));
>       vm->vm_pid = -1;
> +     vm->vm_tty = -1;
>  
>       for (i = 0; i < vcp->vcp_ndisks; i++)
>               vm->vm_disks[i] = -1;
> @@ -787,12 +790,45 @@ vm_register(struct privsep *ps, struct 
> vmop_create_params *vmc,
>  
>       *ret_vm = vm;
>       return (0);
> -fail:
> + fail:
>       if (errno == 0)
>               errno = EINVAL;
>       return (-1);
>  }
>  
> +int
> +vm_opentty(struct vmd_vm *vm)
> +{
> +     struct ptmget            ptm;
> +
> +     /*
> +      * Open tty with pre-opened PTM fd
> +      */
> +     if ((ioctl(env->vmd_ptmfd, PTMGET, &ptm) == -1))
> +             return (-1);
> +
> +     vm->vm_tty = ptm.cfd;
> +     close(ptm.sfd);
> +     if ((vm->vm_ttyname = strdup(ptm.sn)) == NULL)
> +             goto fail;
> +
> +     return (0);
> + fail:
> +     vm_closetty(vm);
> +     return (-1);
> +}
> +
> +void
> +vm_closetty(struct vmd_vm *vm)
> +{
> +     if (vm->vm_tty != -1) {
> +             close(vm->vm_tty);
> +             vm->vm_tty = -1;
> +     }
> +     free(vm->vm_ttyname);
> +     vm->vm_ttyname = NULL;
> +}
> +
>  void
>  switch_remove(struct vmd_switch *vsw)
>  {
> diff --git usr.sbin/vmd/vmd.h usr.sbin/vmd/vmd.h
> index e371112..26d345c 100644
> --- usr.sbin/vmd/vmd.h
> +++ usr.sbin/vmd/vmd.h
> @@ -185,6 +185,7 @@ struct vmd {
>       struct switchlist       *vmd_switches;
>  
>       int                      vmd_fd;
> +     int                      vmd_ptmfd;
>  };
>  
>  /* vmd.c */
> @@ -197,6 +198,8 @@ void       vm_stop(struct vmd_vm *, int);
>  void  vm_remove(struct vmd_vm *);
>  int   vm_register(struct privsep *, struct vmop_create_params *,
>           struct vmd_vm **, uint32_t);
> +int   vm_opentty(struct vmd_vm *);
> +void  vm_closetty(struct vmd_vm *);
>  void  switch_remove(struct vmd_switch *);
>  struct vmd_switch *switch_getbyname(const char *);
>  char *get_string(uint8_t *, size_t);
> 

-- 
Gilles Chehade

https://www.poolp.org                                          @poolpOrg

Reply via email to