[Devel] [PATCH rh7] vtty: Allow to wait until container's console appear
Vladimir Davydov
vdavydov at virtuozzo.com
Thu Jun 9 03:34:31 PDT 2016
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...
> + 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:
More information about the Devel
mailing list