Skip to content

Commit

Permalink
mount: create a slave pty if it has to be bind-mounted to somewhere
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
avagin committed Feb 7, 2017
1 parent d4b2177 commit 7c0c074
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 6 deletions.
29 changes: 23 additions & 6 deletions criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions criu/filesystems.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -698,6 +699,7 @@ static struct fstype fstypes[] = {
.name = "devpts",
.parse = devpts_parse,
.code = FSTYPE__DEVPTS,
.restore = devpts_restore,
}, {
.name = "simfs",
.code = FSTYPE__SIMFS,
Expand Down
3 changes: 3 additions & 0 deletions criu/include/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
80 changes: 80 additions & 0 deletions criu/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "namespaces.h"
#include "external.h"
#include "action-scripts.h"
#include "mount.h"

#include "protobuf.h"
#include "util.h"
Expand All @@ -38,6 +39,7 @@
#include "parasite.h"

#include "pstree.h"
#include "fdstore.h"
#include "tty.h"

/*
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}

0 comments on commit 7c0c074

Please sign in to comment.