2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

criu-ns: make --pidfile option show pid in caller pidns

Using the fact that we know criu_pid and criu is a parent of restored
process we can create pidfile with pid on caller pidns level.

We need to move mount namespace creation to child so that criu-ns can
see caller pidns proc.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov
2023-04-25 12:40:12 +08:00
committed by Andrei Vagin
parent 50e17a1cf3
commit cc607f8103

View File

@@ -6,6 +6,7 @@ import sys
import os
import fcntl
import termios
import time
# <sched.h> constants for unshare
CLONE_NEWNS = 0x00020000
@@ -110,8 +111,8 @@ def wrap_restore():
if '--restore-sibling' in restore_args:
raise OSError(errno.EINVAL, "--restore-sibling is not supported")
# Unshare pid and mount namespaces
if _unshare(CLONE_NEWNS | CLONE_NEWPID) != 0:
# Unshare pid namespace
if _unshare(CLONE_NEWPID) != 0:
_errno = ctypes.get_errno()
raise OSError(_errno, errno.errorcode[_errno])
@@ -123,8 +124,32 @@ def wrap_restore():
restore_detached = True
restore_args.remove('--restore-detached')
restore_pidfile = None
if '--pidfile' in restore_args:
try:
opt_index = restore_args.index('--pidfile')
restore_pidfile = restore_args[opt_index + 1]
del restore_args[opt_index:opt_index + 2]
except (ValueError, IndexError, FileNotFoundError):
raise OSError(errno.ENOENT, "--pidfile missing argument")
if not restore_pidfile.startswith('/'):
for base_dir_opt in ['--work-dir', '-W', '--images-dir', '-D']:
if base_dir_opt in restore_args:
try:
opt_index = restore_args.index(base_dir_opt)
restore_pidfile = os.path.join(restore_args[opt_index + 1], restore_pidfile)
break
except (ValueError, IndexError, FileNotFoundError):
raise OSError(errno.ENOENT, base_dir_opt + " missing argument")
criu_pid = os.fork()
if criu_pid == 0:
# Unshare mount namespace
if _unshare(CLONE_NEWNS) != 0:
_errno = ctypes.get_errno()
raise OSError(_errno, errno.errorcode[_errno])
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
@@ -139,6 +164,25 @@ def wrap_restore():
_mount_new_proc()
run_criu(restore_args)
if restore_pidfile:
restored_pid = None
retry = 5
while not restored_pid and retry:
with open('/proc/%d/task/%d/children' % (criu_pid, criu_pid)) as f:
line = f.readline().strip()
if len(line):
restored_pid = line
break
retry -= 1
time.sleep(1)
if restored_pid:
with open(restore_pidfile, 'w+') as f:
f.write(restored_pid)
else:
print("Warn: Search of restored pid for --pidfile option timeouted")
if restore_detached:
return 0