[CRIU] Re: [PATCH 5/6] tty: Restore orphan slavery peers
Cyrill Gorcunov
gorcunov at openvz.org
Fri Sep 14 07:48:36 EDT 2012
On Fri, Sep 14, 2012 at 03:12:56PM +0400, Pavel Emelyanov wrote:
> On 09/14/2012 02:38 PM, Cyrill Gorcunov wrote:
> >
> > In case if there is no master peer associated
> > with a slave peer we have two cases
> >
> > - the master peer was closed before slave
> > - we just have no master peer at all, but
> > only slave one
>
> Remove the 2nd case from patch. It should be implemented with
> Andrey's non-existing sids/pgids.
Here is just first problem only addressed.
-------------- next part --------------
>From 5bc338a21c66fd2c23ecf5db6f6d72ab25a2b202 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Thu, 13 Sep 2012 21:07:57 +0400
Subject: [PATCH] tty: Restore orphan slavery peers
In case if there is no master peer associated
with a slave peer we have two cases
- the master peer was closed before slave
- we just have no master peer at all, but
only slave one
This patch addresses only first case -- we open
fake master and hook slaves on it, then close it
immediately.
The second case will be addressed later.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
cr-restore.c | 4 ++
include/tty.h | 1 +
tty.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 96 insertions(+), 6 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 4ce2336..4f5089a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -144,6 +144,10 @@ static int prepare_shared(void)
goto err;
mark_pipe_master();
+ ret = tty_setup_orphan_slavery(&opts);
+ if (ret)
+ goto err;
+
ret = tty_prepare_shared();
if (ret)
diff --git a/include/tty.h b/include/tty.h
index 2a8f746..dbb1856 100644
--- a/include/tty.h
+++ b/include/tty.h
@@ -17,5 +17,6 @@ extern int dump_tty(struct fd_parms *p, int lfd, const struct cr_fdset *set);
extern int collect_tty(void);
extern int tty_is_master(struct fdinfo_list_entry *le);
extern int tty_prepare_shared(void);
+extern int tty_setup_orphan_slavery(const struct cr_options *opts);
#endif /* CR_TTY_H__ */
diff --git a/tty.c b/tty.c
index 9a13598..6961aa7 100644
--- a/tty.c
+++ b/tty.c
@@ -80,6 +80,9 @@ struct tty_info {
struct list_head sibling;
int major;
+
+ bool create;
+ bool noparams;
};
static LIST_HEAD(all_tty_info_entries);
@@ -520,6 +523,42 @@ static int receive_tty(struct tty_info *info)
return fd;
}
+static int pty_open_fake_ptmx(struct tty_info *slave)
+{
+ int master = -1, ret = -1, fd = -1;
+ char pts_name[64];
+
+ snprintf(pts_name, sizeof(pts_name), PTS_FMT, slave->tie->pty->index);
+
+ master = pty_open_ptmx_index(O_RDONLY, slave->tie->pty->index);
+ if (master < 0) {
+ pr_perror("Can't open fale %x (index %d)",
+ slave->tfe->id, slave->tie->pty->index);
+ return -1;
+ }
+
+ unlock_pty(master);
+
+ fd = open(pts_name, slave->tfe->flags);
+ if (fd < 0) {
+ pr_perror("Can't open slave %s", pts_name);
+ goto err;
+ }
+
+ if (restore_tty_params(fd, slave))
+ goto err;
+
+ if (pty_open_slaves(slave))
+ goto err;
+
+ ret = fd;
+ fd = -1;
+err:
+ close_safe(&master);
+ close_safe(&fd);
+ return ret;
+}
+
static int pty_open_ptmx(struct tty_info *info)
{
int master = -1;
@@ -567,9 +606,12 @@ static int tty_open(struct file_desc *d)
tty_show_pty_info("open", info);
- if (!pty_is_master(info))
+ if (!info->create)
return receive_tty(info);
+ if (!pty_is_master(info))
+ return pty_open_fake_ptmx(info);
+
return pty_open_ptmx(info);
}
@@ -577,7 +619,7 @@ static int tty_open(struct file_desc *d)
static int tty_transport(FdinfoEntry *fe, struct file_desc *d)
{
struct tty_info *info = container_of(d, struct tty_info, d);
- return pty_is_master(info) == false;
+ return !info->create;
}
static struct file_desc_ops tty_desc_ops = {
@@ -607,6 +649,45 @@ static int tty_find_restoring_task(struct tty_info *info)
return -1;
}
+int tty_setup_orphan_slavery(const struct cr_options *opts)
+{
+ struct tty_info *info, *peer, *m;
+
+ list_for_each_entry(info, &all_ttys, list) {
+ struct fdinfo_list_entry *a, *b;
+ bool has_leader = false;
+
+ if (pty_is_master(info))
+ continue;
+
+ a = file_master(&info->d);
+ m = info;
+
+ list_for_each_entry(peer, &info->sibling, sibling) {
+ if (pty_is_master(peer)) {
+ has_leader = true;
+ break;
+ }
+
+ b = file_master(&peer->d);
+ if (a->pid > b->pid ||
+ (a->pid == b->pid && a->fe->fd > b->fe->fd)) {
+ a = b;
+ m = peer;
+ }
+ }
+
+ /* Here is new one */
+ if (!has_leader) {
+ m->create = true;
+ pr_debug("Found orphan slave fake leader (%#x)\n",
+ m->tfe->id);
+ }
+ }
+
+ return 0;
+}
+
static int tty_setup_slavery(void)
{
struct tty_info *info, *peer, *m;
@@ -674,11 +755,13 @@ static int verify_info(struct tty_info *info)
pr_err("Corrupted slave peer %x\n", info->tfe->id);
return -1;
}
- }
- if (verify_termios(info->tfe->id, info->tie->termios_locked) ||
- verify_termios(info->tfe->id, info->tie->termios))
- return -1;
+ info->noparams = true;
+ } else {
+ if (verify_termios(info->tfe->id, info->tie->termios_locked) ||
+ verify_termios(info->tfe->id, info->tie->termios))
+ return -1;
+ }
if (!pty_is_master(info)) {
if (info->tie->sid || info->tie->pgrp)
@@ -740,6 +823,8 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
INIT_LIST_HEAD(&info->sibling);
info->major = major(info->tie->rdev);
+ info->create = (info->major == TTYAUX_MAJOR);
+ info->noparams = false;
if (verify_info(info))
return -1;
--
1.7.7.6
More information about the CRIU
mailing list