[Devel] [PATCH RHEL7 COMMIT] ve/tty: vzcon -- Add container dummy console support

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jun 18 06:16:15 PDT 2015


The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.14
------>
commit 84364c191199c50f1bc6fbf7d5f121750c5a1f66
Author: Cyrill Gorcunov <gorcunov at virtuozzo.com>
Date:   Thu Jun 18 17:16:15 2015 +0400

    ve/tty: vzcon -- Add container dummy console support
    
    In PCS6 we have a console emulation via virtual tty code
    (VTTY option in config file). The code of vtty is very
    close to standart pty (unix98 terminals) but on new kernels
    the pty code has been heavily modified due to changes in
    tty layer itself.
    
    That said this vz console is rather a simple stub for future
    enhancements which zaps messages written to it by the kernel
    but allows systemd based conatiners (such as Fedora 21)
    to successfully hook agetty service on the conatiner's console.
    
    https://jira.sw.ru/browse/PSBM-32686
    
    Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
    
    CC: Andrey Vagin <avagin at virtuozzo.com>
    CC: Vladimir Davydov <vdavydov at virtuozzo.com>
    CC: Konstantin Khorenko <khorenko at virtuozzo.com>
    CC: Pavel Emelyanov <xemul at virtuozzo.com>
---
 drivers/tty/tty_io.c |   6 ++-
 kernel/ve/Makefile   |   2 +-
 kernel/ve/console.c  | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 5996ba1..8fac760 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1941,10 +1941,12 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
 #endif
 	case MKDEV(TTYAUX_MAJOR, 1): {
 		struct tty_driver *console_driver = console_device(index);
+#ifdef CONFIG_VE
 		if (!ve_is_super(get_exec_env())) {
-			printk_once("Support of virtual console is not yet implemented in VE\n");
-			return ERR_PTR(-ENODEV);
+			extern struct tty_driver *vz_console_device(int *index);
+			console_driver = vz_console_device(index);
 		}
+#endif
 		if (console_driver) {
 			driver = tty_driver_kref_get(console_driver);
 			if (driver) {
diff --git a/kernel/ve/Makefile b/kernel/ve/Makefile
index a8371d5..512ccf0 100644
--- a/kernel/ve/Makefile
+++ b/kernel/ve/Makefile
@@ -4,7 +4,7 @@
 # Copyright (c) 2000-2015 Parallels IP Holdings GmbH
 #
 
-obj-$(CONFIG_VE) = ve.o veowner.o hooks.o vzstat_core.o ve-kobject.o
+obj-$(CONFIG_VE) = ve.o veowner.o hooks.o vzstat_core.o ve-kobject.o console.o
 obj-$(CONFIG_VZ_WDOG) += vzwdog.o
 obj-$(CONFIG_VE_CALLS) += vzmon.o
 
diff --git a/kernel/ve/console.c b/kernel/ve/console.c
new file mode 100644
index 0000000..9924922
--- /dev/null
+++ b/kernel/ve/console.c
@@ -0,0 +1,146 @@
+#define pr_fmt(fmt) "vz con: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/console.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/tty.h>
+#include <linux/ve.h>
+
+static struct tty_driver *vz_con_driver;
+
+struct vz_tty_priv {
+	struct tty_port		port;
+	struct ve_struct	*owner_ve;
+};
+
+static int vz_tty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+	static const struct tty_port_operations vz_tty_port_ops;
+	struct vz_tty_priv *priv;
+	int ret;
+
+	BUG_ON(tty->index != 0);
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->owner_ve = get_exec_env();
+	tty_port_init(&priv->port);
+	priv->port.ops = &vz_tty_port_ops;
+	tty->driver_data = priv;
+
+	ret = tty_port_install(&priv->port, driver, tty);
+	if (ret) {
+		pr_err("Can't install tty port: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	tty_port_destroy(&priv->port);
+	kfree(priv);
+	return ret;
+}
+
+static int vz_tty_open(struct tty_struct *tty, struct file *filp)
+{
+	struct vz_tty_priv *priv = tty->driver_data;
+	return tty_port_open(&priv->port, tty, filp);
+}
+
+static void vz_tty_close(struct tty_struct *tty, struct file *filp)
+{
+	struct vz_tty_priv *priv = tty->driver_data;
+	tty_port_close(&priv->port, tty, filp);
+}
+
+static void vz_tty_cleanup(struct tty_struct *tty)
+{
+	struct vz_tty_priv *priv = tty->driver_data;
+
+	tty->driver_data = NULL;
+	priv->owner_ve = NULL;
+	tty_port_destroy(&priv->port);
+	kfree(priv);
+}
+
+static int vz_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	return count;
+}
+
+static int vz_tty_write_room(struct tty_struct *tty)
+{
+	return 4096;
+}
+
+static void vz_tty_hangup(struct tty_struct *tty)
+{
+	struct vz_tty_priv *priv = tty->driver_data;
+	tty_port_hangup(&priv->port);
+}
+
+static const struct tty_operations vz_tty_fops = {
+	.install	= vz_tty_install,
+	.open		= vz_tty_open,
+	.close		= vz_tty_close,
+	.cleanup	= vz_tty_cleanup,
+	.write		= vz_tty_write,
+	.write_room	= vz_tty_write_room,
+	.hangup		= vz_tty_hangup,
+};
+
+static void __exit vz_exit(void)
+{
+	put_tty_driver(vz_con_driver);
+}
+module_exit(vz_exit)
+
+static int __init init(void)
+{
+	int ret = 0;
+
+	vz_con_driver = tty_alloc_driver(1,
+					 TTY_DRIVER_REAL_RAW		|
+					 TTY_DRIVER_RESET_TERMIOS	|
+					 TTY_DRIVER_CONTAINERIZED);
+	if (IS_ERR(vz_con_driver)) {
+		pr_err("Couldn't allocate vzcon driver\n");
+		return PTR_ERR(vz_con_driver);
+	}
+
+	vz_con_driver->driver_name	= "vzcon driver";
+	vz_con_driver->name		= "vzcon";
+	vz_con_driver->name_base	= 1;
+	vz_con_driver->major		= 0;
+	vz_con_driver->minor_start	= 1;
+	vz_con_driver->type		= TTY_DRIVER_TYPE_CONSOLE;
+	vz_con_driver->init_termios	= tty_std_termios;
+	vz_con_driver->ve		= get_ve0();
+	tty_set_operations(vz_con_driver, &vz_tty_fops);
+
+	ret = tty_register_driver(vz_con_driver);
+	if (ret) {
+		pr_err("Couldn't register vzcon driver\n");
+		put_tty_driver(vz_con_driver);
+		return ret;
+	}
+
+	return 0;
+}
+module_init(init);
+
+struct tty_driver *vz_console_device(int *index)
+{
+	*index = 0;
+	return vz_con_driver;
+}
+EXPORT_SYMBOL(vz_console_device);
+
+MODULE_DESCRIPTION("Virtuozzo Container console");
+MODULE_LICENSE("GPL v2");



More information about the Devel mailing list