[Devel] [PATCH rh7]: ve: Provide interface for current tty inheritance
Andrey Vagin
avagin at virtuozzo.com
Fri Feb 16 01:18:27 MSK 2018
On Thu, Feb 15, 2018 at 09:54:39PM +0300, Cyrill Gorcunov wrote:
> When fork() is called the current controlling terminal is inherited
> by a child process. But in criu we fork all process first and then
> restore their files, thus if terminal is opened in some children
> its reference get lost. We refuse to checkpoint such configurations
> at the moment in criu itself.
>
> So to be able to restore this kind of container we need a way to
> propagate controlling terminal to children processes, and here
> is an interface "ve.ctty" entry on toplevel ve cgroup. One have
> to pass pid of the donor task in first position followed by a series
> of recipient pids.
Cyrill, you chose a very weird interface. I think we can add an ioctl to
set a current terminal for a task. And I think we have a good chance to
push it into the upstream kernle.
Thanks,
Andrei
>
> https://jira.sw.ru/browse/PSBM-76490
>
> CC: Andrey Vagin <avagin at virtuozzo.com>
> CC: Andrey Ryabinin <aryabinin at virtuozzo.com>
> CC: Konstantin Khorenko <khorenko at virtuozzo.com>
> CC: "Denis V. Lunev" <den at virtuozzo.com>
> Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
> ---
> Guys, take a look please. Note the patch on its own is useless
> because CRIU support needed as well. I already have a working
> version of patches for CRIU, but they are ~300 lines of code
> so I'm trying to shrink them because it's too much.
>
> kernel/ve/ve.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 96 insertions(+)
>
> Index: linux-pcs7.git/kernel/ve/ve.c
> ===================================================================
> --- linux-pcs7.git.orig/kernel/ve/ve.c
> +++ linux-pcs7.git/kernel/ve/ve.c
> @@ -37,6 +37,7 @@
> #include <linux/fs_struct.h>
> #include <linux/task_work.h>
> #include <linux/ctype.h>
> +#include <linux/tty.h>
>
> #include <uapi/linux/vzcalluser.h>
> #include <linux/vziptable_defs.h>
> @@ -1214,6 +1215,7 @@ enum {
> VE_CF_NETNS_NR,
> VE_CF_NETIF_MAX_NR,
> VE_CF_NETIF_NR,
> + VE_CF_CTTY,
> };
>
> static int ve_ts_read(struct cgroup *cg, struct cftype *cft, struct seq_file *m)
> @@ -1393,6 +1395,94 @@ static int ve_write_running_u64(struct c
> return _ve_write_u64(cg, cft, value, 1);
> }
>
> +static int ve_write_ctty(struct cgroup *cg, struct cftype *cft, const char *buffer)
> +{
> + struct task_struct *tsk_from, *tsk_to;
> + struct tty_struct *tty_from, *tty_to;
> + pid_t pid_from, pid_to;
> + unsigned long flags;
> + char *pids;
> + int ret;
> +
> + /*
> + * Buffer format is the following
> + *
> + * pid_from pid_to pid_to ...
> + *
> + * where pid_to are pids to propagate
> + * current terminal into.
> + */
> +
> + pids = skip_spaces(buffer);
> + if (sscanf(pids, "%d", &pid_from) != 1)
> + return -EINVAL;
> + pids = strchr(pids, ' ');
> + if (!pids)
> + return -EINVAL;
> + pids = skip_spaces(pids);
> +
> + rcu_read_lock();
> + tsk_from = find_task_by_vpid(pid_from);
> + if (tsk_from)
> + get_task_struct(tsk_from);
> + rcu_read_unlock();
> +
> + if (!tsk_from)
> + return -ESRCH;
> +
> + spin_lock_irqsave(&tsk_from->sighand->siglock, flags);
> + tty_from = tty_kref_get(tsk_from->signal->tty);
> + spin_unlock_irqrestore(&tsk_from->sighand->siglock, flags);
> +
> + if (!tty_from) {
> + ret = -ENOTTY;
> + goto out;
> + }
> +
> + ret = 0;
> + while (pids && *pids) {
> + if (sscanf(pids, "%d", &pid_to) != 1) {
> + ret = -EINVAL;
> + goto out;
> + }
> + pids = strchr(pids, ' ');
> + if (pids)
> + pids = skip_spaces(pids);
> +
> + rcu_read_lock();
> + tsk_to = find_task_by_vpid(pid_to);
> + if (tsk_to)
> + get_task_struct(tsk_to);
> + rcu_read_unlock();
> +
> + if (!tsk_to) {
> + ret = -ESRCH;
> + goto out;
> + }
> +
> + if (tsk_from->task_ve == tsk_to->task_ve) {
> + spin_lock_irqsave(&tsk_to->sighand->siglock, flags);
> + tty_to = tsk_to->signal->tty;
> + if (!tty_to)
> + tsk_to->signal->tty = tty_kref_get(tty_from);
> + else
> + ret = -EBUSY;
> + spin_unlock_irqrestore(&tsk_to->sighand->siglock, flags);
> + } else
> + ret = -EINVAL;
> +
> + put_task_struct(tsk_to);
> +
> + if (ret)
> + goto out;
> + }
> +
> +out:
> + tty_kref_put(tty_from);
> + put_task_struct(tsk_from);
> + return ret;
> +}
> +
> static struct cftype ve_cftypes[] = {
> {
> .name = "state",
> @@ -1496,6 +1586,12 @@ static struct cftype ve_cftypes[] = {
> .read_u64 = ve_read_u64,
> .private = VE_CF_NETIF_NR,
> },
> + {
> + .name = "ctty",
> + .flags = CFTYPE_ONLY_ON_ROOT,
> + .write_string = ve_write_ctty,
> + .private = VE_CF_CTTY,
> + },
> { }
> };
>
More information about the Devel
mailing list