Skip to content

Commit

Permalink
criu-ns: capture controlling tty
Browse files Browse the repository at this point in the history
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

checkpoint-restore#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: checkpoint-restore#1893
Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
  • Loading branch information
Snorch authored and avagin committed Mar 13, 2023
1 parent a12173a commit a177dd4
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions scripts/criu-ns
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit a177dd4

Please sign in to comment.