Skip to content

Commit

Permalink
tty: allow to dump and restore external terminals (v2)
Browse files Browse the repository at this point in the history
Now we can use the --inherit-fd option to mark external terminals on dump
and to tell which file desdriptors should be used to restore these terminals.

Here is an example how it works:
$ setsid sleep 1000

$ ipython
In [1]: import os
In [2]: st = os.stat("/proc/self/fd/0")
In [3]: print "tty[%x:%x]" % (st.st_rdev, st.st_dev)
tty:[8800:d]

$ps -C sleep
  PID TTY          TIME CMD
 4109 ?        00:00:00 sleep

$ ./criu dump --external 'tty[8800:d]' -D imgs -v4 -t 4109
$ ./criu restore --inherit-fd 'fd[1]:tty[8800:d]' -D imgs -v4

v2: add missed break
    remove @non_file from tty_driver

Signed-off-by: Andrew Vagin <[email protected]>
Signed-off-by: Pavel Emelyanov <[email protected]>
  • Loading branch information
avagin authored and xemul committed Dec 29, 2015
1 parent 6280625 commit 4bab48f
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
4 changes: 3 additions & 1 deletion crtools.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,9 @@ int main(int argc, char *argv[], char *envp[])
" --enable-fs FSNAMES a comma separated list of filesystem names or \"all\".\n"
" force criu to (try to) dump/restore these filesystem's\n"
" mountpoints even if fs is not supported.\n"
" --external RES dump objects from this list as external resources\n"
" --external RES dump objects from this list as external resources:\n"
" Formats of RES:\n"
" tty[rdev:dev]\n"
"\n"
"* Logging:\n"
" -o|--log-file FILE log file name\n"
Expand Down
2 changes: 1 addition & 1 deletion files.c
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ void inherit_fd_log(void)
/*
* Look up the inherit fd list by a file identifier.
*/
static int inherit_fd_lookup_id(char *id)
int inherit_fd_lookup_id(char *id)
{
int ret;
struct inherit_fd *inh;
Expand Down
1 change: 1 addition & 0 deletions include/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ extern int inherit_fd_resolve_clash(int fd);
extern int inherit_fd_fini(void);

extern bool external_lookup_id(char *id);
extern int inherit_fd_lookup_id(char *id);

extern bool inherited_fd(struct file_desc *, int *fdp);

Expand Down
1 change: 1 addition & 0 deletions protobuf/tty.proto
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum TtyType {
CONSOLE = 2;
VT = 3;
CTTY = 4;
EXT_TTY = 5;
}

message tty_info_entry {
Expand Down
60 changes: 56 additions & 4 deletions tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ static struct tty_driver vt_driver = {
.open = open_simple_tty,
};

static int open_ext_tty(struct tty_info *info);
static struct tty_driver ext_driver = {
.type = TTY_TYPE__EXT_TTY,
.name = "ext",
.open = open_ext_tty,
};

static int pts_fd_get_index(int fd, const struct fd_parms *p)
{
int index;
Expand Down Expand Up @@ -235,6 +242,11 @@ static struct tty_driver pts_driver = {
struct tty_driver *get_tty_driver(dev_t rdev, dev_t dev)
{
int major, minor;
char id[42];

snprintf(id, sizeof(id), "tty[%lx:%lx]", rdev, dev);
if (external_lookup_id(id) || inherit_fd_lookup_id(id) >= 0)
return &ext_driver;

major = major(rdev);
minor = minor(rdev);
Expand Down Expand Up @@ -606,6 +618,12 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
if (!is_service_fd(fd, CTL_TTY_OFF))
return 0;

if (driver->type == TTY_TYPE__EXT_TTY) {
slave = -1;
if (!inherited_fd(&info->d, &slave) && slave < 0)
return -1;
goto out;
}
if (driver->img_get_index)
index = driver->img_get_index(info);
else
Expand All @@ -626,6 +644,7 @@ static int tty_restore_ctl_terminal(struct file_desc *d, int fd)
goto err;
}

out:
pr_info("Restore session %d by %d tty (index %d)\n",
info->tie->sid, (int)getpid(), index);

Expand All @@ -652,6 +671,9 @@ static bool tty_is_master(struct tty_info *info)
case TTY_TYPE__VT:
if (!opts.shell_job)
return true;
break;
case TTY_TYPE__EXT_TTY:
return true;
}

return false;
Expand Down Expand Up @@ -970,6 +992,21 @@ static int open_simple_tty(struct tty_info *info)
return -1;
}

static int open_ext_tty(struct tty_info *info)
{
int fd = -1;

if (!inherited_fd(&info->d, &fd) && fd < 0)
return -1;

if (restore_tty_params(fd, info)) {
close(fd);
return -1;
}

return fd;
}

static int tty_open(struct file_desc *d)
{
struct tty_info *info = container_of(d, struct tty_info, d);
Expand Down Expand Up @@ -1013,12 +1050,22 @@ static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
list_add_tail(&fle->ps_list, tgt);
}

static char *tty_d_name(struct file_desc *d, char *buf, size_t s)
{
struct tty_info *info = container_of(d, struct tty_info, d);

snprintf(buf, s, "tty[%x:%x]", info->tie->rdev, info->tie->dev);

return buf;
}

static struct file_desc_ops tty_desc_ops = {
.type = FD_TYPES__TTY,
.open = tty_open,
.post_open = tty_restore_ctl_terminal,
.want_transport = tty_transport,
.collect_fd = tty_collect_fd,
.name = tty_d_name,
};

static struct pstree_item *find_first_sid(int sid)
Expand Down Expand Up @@ -1322,6 +1369,7 @@ static int collect_one_tty_info_entry(void *obj, ProtobufCMessage *msg)
case TTY_TYPE__CTTY:
case TTY_TYPE__CONSOLE:
case TTY_TYPE__VT:
case TTY_TYPE__EXT_TTY:
if (info->tie->pty) {
pr_err("PTY data found (id %x), corrupted image?\n",
info->tie->id);
Expand Down Expand Up @@ -1362,6 +1410,10 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)

INIT_LIST_HEAD(&info->sibling);
info->driver = get_tty_driver(info->tie->rdev, info->tie->dev);
if (info->driver == NULL) {
pr_err("Unable to find a tty driver\n");
return -1;
}
info->create = tty_is_master(info);
info->inherit = false;
info->ctl_tty = NULL;
Expand All @@ -1383,7 +1435,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg)
info->tfe->id);
return -1;
}
} else {
} if (info->driver->type != TTY_TYPE__EXT_TTY) {
pr_err("No reg_d descriptor for id %#x\n", info->tfe->id);
return -1;
}
Expand Down Expand Up @@ -1585,9 +1637,6 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)

pr_info("Dumping tty %d with id %#x\n", lfd, id);

if (dump_one_reg_file(lfd, id, p))
return -1;

driver = get_tty_driver(p->stat.st_rdev, p->stat.st_dev);
if (driver->fd_get_index)
index = driver->fd_get_index(lfd, p);
Expand All @@ -1599,6 +1648,9 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
return -1;
}

if (driver->type != TTY_TYPE__EXT_TTY && dump_one_reg_file(lfd, id, p))
return -1;

e.id = id;
e.tty_info_id = tty_gen_id(driver, index);
e.flags = p->flags;
Expand Down

0 comments on commit 4bab48f

Please sign in to comment.