On Thu, Jun 09, 2016 at 01:34:31PM +0300, Vladimir Davydov wrote:
> On Mon, Jun 06, 2016 at 07:26:57PM +0300, Cyrill Gorcunov wrote:
> > After tty code redesing we've been requiring container to start
> > first before be able to connect into it via vzctl console command.
> > Here we rather allow userspace tool to wait until container brought
> > to life and proceed connecting into console.
> > 
> > https://jira.sw.ru/browse/PSBM-39463
> > 
> > Signed-off-by: Cyrill Gorcunov <gorcu...@virtuozzo.com>
> > CC: Vladimir Davydov <vdavy...@virtuozzo.com>
> > CC: Konstantin Khorenko <khore...@virtuozzo.com>
> > CC: Igor Sukhih <i...@virtuozzo.com>
> > CC: Pavel Emelyanov <xe...@virtuozzo.com>
> > ---
> >  include/linux/ve.h  |    2 ++
> >  kernel/ve/ve.c      |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  kernel/ve/vecalls.c |   23 +++++++++++++++++++++--
> >  3 files changed, 71 insertions(+), 2 deletions(-)
> > 
> > Index: linux-pcs7.git/include/linux/ve.h
> > ===================================================================
> > --- linux-pcs7.git.orig/include/linux/ve.h
> > +++ linux-pcs7.git/include/linux/ve.h
> > @@ -215,6 +215,8 @@ void ve_stop_ns(struct pid_namespace *ns
> >  void ve_exit_ns(struct pid_namespace *ns);
> >  int ve_start_container(struct ve_struct *ve);
> >  
> > +int ve_console_wait(envid_t veid);
> > +
> >  extern bool current_user_ns_initial(void);
> >  struct user_namespace *ve_init_user_ns(void);
> >  
> > Index: linux-pcs7.git/kernel/ve/ve.c
> > ===================================================================
> > --- linux-pcs7.git.orig/kernel/ve/ve.c
> > +++ linux-pcs7.git/kernel/ve/ve.c
> > @@ -260,6 +260,49 @@ struct user_namespace *ve_init_user_ns(v
> >  }
> >  EXPORT_SYMBOL(ve_init_user_ns);
> >  
> > +static DEFINE_IDR(ve_idr_console);
> > +static DECLARE_RWSEM(ve_console_sem);
> > +
> > +int ve_console_wait(envid_t veid)
> > +{
> > +   DECLARE_COMPLETION_ONSTACK(console_work);
> > +   int ret;
> > +
> > +   down_write(&ve_console_sem);
> > +   if (idr_find(&ve_idr_console, veid)) {
> > +           up_write(&ve_console_sem);
> > +           return -EEXIST;
> > +   }
> > +
> > +   ret = idr_alloc(&ve_idr_console, &console_work, veid, veid + 1, 
> > GFP_KERNEL);
> > +   if (ret < 0) {
> > +           if (ret == -ENOSPC)
> > +                   ret = -EEXIST;
> > +   } else
> > +           ret = 0;
> > +   downgrade_write(&ve_console_sem);
> > +
> > +   if (!ret) {
> > +           ret = wait_for_completion_interruptible(&console_work);
> > +           idr_remove(&ve_idr_console, veid);
> > +   }
> > +
> > +   up_read(&ve_console_sem);
> > +   return ret;
> > +}
> > +EXPORT_SYMBOL(ve_console_wait);
> > +
> > +static void ve_console_notify(struct ve_struct *ve)
> > +{
> > +   struct completion *console_work;
> > +
> > +   down_read(&ve_console_sem);
> > +   console_work = idr_find(&ve_idr_console, ve->veid);
> > +   if (console_work)
> > +           complete(console_work);
> > +   up_read(&ve_console_sem);
> > +}
> > +
> >  int nr_threads_ve(struct ve_struct *ve)
> >  {
> >     return cgroup_task_count(ve->css.cgroup);
> > @@ -494,6 +537,11 @@ int ve_start_container(struct ve_struct
> >  
> >     get_ve(ve); /* for ve_exit_ns() */
> >  
> > +   /*
> > +    * Console waiter are to be notified at the very
> > +    * end when everything else is ready.
> > +    */
> > +   ve_console_notify(ve);
> >     return 0;
> >  
> >  err_iterate:
> > Index: linux-pcs7.git/kernel/ve/vecalls.c
> > ===================================================================
> > --- linux-pcs7.git.orig/kernel/ve/vecalls.c
> > +++ linux-pcs7.git/kernel/ve/vecalls.c
> > @@ -991,8 +991,27 @@ static int ve_configure(envid_t veid, un
> >     int err = -ENOKEY;
> >  
> >     ve = get_ve_by_id(veid);
> > -   if (!ve)
> > -           return -EINVAL;
> > +   if (!ve) {
> > +
> > +           if (key != VE_CONFIGURE_OPEN_TTY)
> > +                   return -EINVAL;
> > +           /*
> > +            * Offline console management:
> > +            * wait until ve is up and proceed.
> > +            */
> 
> What if a VE is created right here, before we call ve_console_wait()?
> Looks like the caller will hang forever...

Yeah, could be a race. Thanks!

> > +           err = ve_console_wait(veid);
> > +           if (err)
> > +                   return err;
> > +
> > +           /*
> > +            * A container should not exit immediately once
> > +            * started but if it does, for any reason, simply
> > +            * exit out gracefully.
> > +            */
> > +           ve = get_ve_by_id(veid);
> > +           if (!ve)
> > +                   return -ENOENT;
> > +   }
> 
> Can't we fold this into vtty_open_master()? The latter doesn't need ve
> object, it only needs veid, which is known here.

Will do.
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to