[Devel] [PATCH rh7] vtty: Allow to wait until container's console appear
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
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
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