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 <[email protected]>
> CC: Vladimir Davydov <[email protected]>
> CC: Konstantin Khorenko <[email protected]>
> CC: Igor Sukhih <[email protected]>
> CC: Pavel Emelyanov <[email protected]>
> ---
>  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
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to