[CRIU] [PATCH 3/5] mount: create a slave pty if it has to be bind-mounted to somewhere
Andrei Vagin
avagin at openvz.org
Tue Feb 7 00:43:29 PST 2017
From: Andrei Vagin <avagin at virtuozzo.com>
Now we create pty pairs when file descriptors are restored.
The problem is that a slave tty can be bind-mounted to somewhere
and in this case we have to create this pair and hold a master file
descritore before related file descriptors will not be restored.
In this patch, a unix socket is used to hold file descriptros.
And we use SK_PEEK_OFF and MSG_PEEK to get any of them.
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
criu/cr-restore.c | 29 ++++++++++++++++----
criu/filesystems.c | 2 ++
criu/include/tty.h | 3 ++
criu/tty.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 108 insertions(+), 6 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 9fa9bc3..911d7af 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -77,6 +77,7 @@
#include "fault-injection.h"
#include "sk-queue.h"
#include "sigframe.h"
+#include "fdstore.h"
#include "parasite-syscall.h"
#include "files-reg.h"
@@ -174,9 +175,6 @@ static struct collect_image_info *cinfos[] = {
&inotify_mark_cinfo,
&fanotify_cinfo,
&fanotify_mark_cinfo,
- &tty_info_cinfo,
- &tty_cinfo,
- &tty_cdata,
&tunfile_cinfo,
&ext_file_cinfo,
&timerfd_cinfo,
@@ -186,6 +184,13 @@ static struct collect_image_info *cinfos[] = {
&sk_queues_cinfo,
};
+/* These images are requered to restore namespaces */
+static struct collect_image_info *before_ns_cinfos[] = {
+ &tty_info_cinfo, /* Restore devpts content */
+ &tty_cinfo,
+ &tty_cdata,
+};
+
struct post_prepare_cb {
struct list_head list;
int (*actor)(void *data);
@@ -226,9 +231,6 @@ static int root_prepare_shared(void)
pr_info("Preparing info about shared resources\n");
- if (prepare_shared_tty())
- return -1;
-
if (prepare_shared_reg_files())
return -1;
@@ -1399,6 +1401,13 @@ static int restore_task_with_children(void *_arg)
/* Restore root task */
if (current->parent == NULL) {
+ int i;
+
+ if (prepare_shared_tty())
+ goto err;
+
+ if (fdstore_init())
+ goto err;
if (join_namespaces()) {
pr_perror("Join namespaces failed");
goto err;
@@ -1415,6 +1424,13 @@ static int restore_task_with_children(void *_arg)
if (mount_proc())
goto err;
+ for (i = 0; i < ARRAY_SIZE(before_ns_cinfos); i++) {
+ ret = collect_image(before_ns_cinfos[i]);
+ if (ret)
+ return -1;
+ }
+
+
if (prepare_namespace(current, ca->clone_flags))
goto err;
@@ -3197,6 +3213,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
close_proc();
close_service_fd(ROOT_FD_OFF);
close_service_fd(USERNSD_SK);
+ close_service_fd(FDSTORE_SK_OFF);
close_service_fd(RPC_SK_OFF);
__gcov_flush();
diff --git a/criu/filesystems.c b/criu/filesystems.c
index 7fc4c26..4688d1f 100644
--- a/criu/filesystems.c
+++ b/criu/filesystems.c
@@ -18,6 +18,7 @@
#include "autofs.h"
#include "util.h"
#include "fs-magic.h"
+#include "tty.h"
#include "images/mnt.pb-c.h"
#include "images/binfmt-misc.pb-c.h"
@@ -698,6 +699,7 @@ static struct fstype fstypes[] = {
.name = "devpts",
.parse = devpts_parse,
.code = FSTYPE__DEVPTS,
+ .restore = devpts_restore,
}, {
.name = "simfs",
.code = FSTYPE__SIMFS,
diff --git a/criu/include/tty.h b/criu/include/tty.h
index 6fa00db..4656038 100644
--- a/criu/include/tty.h
+++ b/criu/include/tty.h
@@ -29,6 +29,9 @@ extern struct collect_image_info tty_cinfo;
extern struct collect_image_info tty_cdata;
extern int prepare_shared_tty(void);
+struct mount_info;
+extern int devpts_restore(struct mount_info *pm);
+
extern int tty_prep_fds(void);
extern void tty_fini_fds(void);
diff --git a/criu/tty.c b/criu/tty.c
index 5bfce44..c1bb95c 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -29,6 +29,7 @@
#include "namespaces.h"
#include "external.h"
#include "action-scripts.h"
+#include "mount.h"
#include "protobuf.h"
#include "util.h"
@@ -38,6 +39,7 @@
#include "parasite.h"
#include "pstree.h"
+#include "fdstore.h"
#include "tty.h"
/*
@@ -102,6 +104,8 @@ struct tty_info {
struct tty_info *ctl_tty;
struct tty_info *link;
struct tty_data_entry *tty_data;
+
+ int fdstore_id;
};
struct tty_dump_info {
@@ -616,6 +620,9 @@ static int __pty_open_ptmx_index(int index, int flags,
static int pty_open_ptmx_index(struct file_desc *d, struct tty_info *info, int flags)
{
+ if (info->fdstore_id >= 0)
+ return fdstore_get(info->fdstore_id);
+
return __pty_open_ptmx_index(info->tie->pty->index, flags,
open_tty_reg, d, path_from_reg(d));
}
@@ -1632,6 +1639,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
return -1;
}
+ info->fdstore_id = -1;
list_add(&info->list, &all_ttys);
return file_desc_add(&info->d, info->tfe->id, &tty_desc_ops);
}
@@ -2143,3 +2151,75 @@ void tty_fini_fds(void)
{
close_service_fd(SELF_STDIN_OFF);
}
+
+static int open_pty(void *arg, int flags)
+{
+ int dfd = (unsigned long) arg;
+ /*
+ * Never set as a control terminal automatically, all
+ * ctty magic happens only in tty_set_sid().
+ */
+ flags |= O_NOCTTY;
+ return openat(dfd, "ptmx", flags);
+}
+
+/* Create a pty pair and save a master descriptor in fdstore */
+static int pty_create_ptmx_index(int dfd, int index, int flags)
+{
+ struct tty_info *info;
+ int fd, id;
+
+ fd = __pty_open_ptmx_index(index, flags, open_pty, (void *)(unsigned long) dfd, "ptmx");
+ if (fd < 0)
+ return -1;
+
+ id = fdstore_add(fd);
+ if (id < 0)
+ return -1;
+ close(fd);
+
+ list_for_each_entry(info, &all_ttys, list) {
+ if (!is_pty(info->driver))
+ continue;
+
+ if (info->tie->pty->index == index) {
+ info->fdstore_id = id;
+ }
+ }
+
+ return 0;
+}
+
+/* Restore slave pty-s which have to be bind-mounted to somewhere */
+int devpts_restore(struct mount_info *pm)
+{
+ struct mount_info *bm;
+ int dfd, exit_code = -1;
+
+ dfd = open(pm->mountpoint, O_RDONLY);
+ if (dfd < 0) {
+ pr_perror("Unable to open %s", pm->mountpoint);
+ return -1;
+ }
+
+
+ list_for_each_entry(bm, &pm->mnt_bind, mnt_bind) {
+ int idx;
+ struct stat st;
+
+ if (sscanf(bm->root, "/%d", &idx) < 1)
+ continue;
+
+ if (fstatat(dfd, bm->root + 1, &st, 0) == 0)
+ continue;
+
+ pr_debug("Create a slave tty %d\n", idx);
+ if (pty_create_ptmx_index(dfd, idx, O_RDWR))
+ goto err;
+ }
+
+ exit_code = 0;
+err:
+ close(dfd);
+ return exit_code;
+}
--
2.7.4
More information about the CRIU
mailing list