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

Cyrill Gorcunov gorcunov at virtuozzo.com
Mon Jun 6 09:26:57 PDT 2016


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.
+		 */
+		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:


More information about the Devel mailing list