[Devel] [PATCH rh7] vtty: Allow to wait until container's console appear

Cyrill Gorcunov gorcunov at virtuozzo.com
Thu Jun 9 03:41:11 PDT 2016


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 <gorcunov at virtuozzo.com>
> > CC: Vladimir Davydov <vdavydov at virtuozzo.com>
> > CC: Konstantin Khorenko <khorenko at virtuozzo.com>
> > CC: Igor Sukhih <igor at virtuozzo.com>
> > CC: Pavel Emelyanov <xemul at 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.


More information about the Devel mailing list