diff options
author | Pavel Tikhomirov <ptikhomirov@virtuozzo.com> | 2022-06-22 12:12:07 +0300 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2022-08-31 01:11:33 +0300 |
commit | 94bfff77edac467b69b787f7aaf0ba4fac1feb95 (patch) | |
tree | b94c9245f6602d68d3567ae43ad9010e11a0798e | |
parent | 517c0947050e63aac72f63a3bf373d76264723b9 (diff) |
criu-ns: capture controlling tty
When we are restoring in new pidns we specifically do setsid() from
criu-ns init so that sids of restored tasks are non-zero in this pidns
and on next dump CRIU would not have problems with zero sids, see [1].
But after this CRIU tries to inherit and setup a tty for the restored
process, and it fails to set it's process group via TIOCSPGRP to be a
foreground group for it's tty, because tty already is a controlling tty
for other session (which we had before setsid).
So to make it restore we need to reset tty to be a controlling tty of
criu-ns init via TIOCSCTTY before calling criu.
Else when restoring first time via criu-ns (from criu-ns dump) we get:
Error (criu/tty.c:689): tty: Failed to set group 40816 on 0: Inappropriate ioctl for device
https://github.com/checkpoint-restore/criu/issues/232 [1]
v2: add why and what comment in code, set controlling tty only for
--shell-job and fail if stdin is not a tty.
Fixes: #1893
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
-rwxr-xr-x | scripts/criu-ns | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/scripts/criu-ns b/scripts/criu-ns index 1217c3dcd..d51e7772c 100755 --- a/scripts/criu-ns +++ b/scripts/criu-ns @@ -4,6 +4,8 @@ import ctypes.util import errno import sys import os +import fcntl +import termios # <sched.h> constants for unshare CLONE_NEWNS = 0x00020000 @@ -124,6 +126,16 @@ def wrap_restore(): criu_pid = os.fork() if criu_pid == 0: os.setsid() + # Set stdin tty to be a controlling tty of our new session, this is + # required by --shell-job option, as for it CRIU would try to set a + # process group of restored root task to be a foreground group on the + # terminal. + if '--shell-job' in restore_args or '-j' in restore_args: + if os.isatty(sys.stdin.fileno()): + fcntl.ioctl(sys.stdin.fileno(), termios.TIOCSCTTY, 1) + else: + raise OSError(errno.EINVAL, 'The stdin is not a tty for a --shell-job') + _mount_new_proc() run_criu(restore_args) |