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

2016-06-06 Thread Cyrill Gorcunov
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 
CC: Vladimir Davydov 
CC: Konstantin Khorenko 
CC: Igor Sukhih 
CC: Pavel Emelyanov 
---
 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.
+*/
+   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;
+   }
 
switch(key) {
case VE_CONFIGURE_OS_RELEASE:
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


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

2016-06-09 Thread Vladimir Davydov
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 
> CC: Vladimir Davydov 
> CC: Konstantin Khorenko 
> CC: Igor Sukhih 
> CC: Pavel Emelyanov 
> ---
>  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...

> + 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.

>  
>   switch(key) {
>   case VE_CONFIGURE_OS_RELEASE:
___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


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

2016-06-09 Thread Cyrill Gorcunov
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 
> > CC: Vladimir Davydov 
> > CC: Konstantin Khorenko 
> > CC: Igor Sukhih 
> > CC: Pavel Emelyanov 
> > ---
> >  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