Contents

There are cases where a process' file descriptor cannot be restored
from the checkpoint images. For example, a pipe file descriptor with one
end in the checkpointed process and the other end in a separate process
(that was not part of the checkpointed process tree) cannot be restored
because after checkpoint the pipe will be broken.

There are also cases where the user wants to use a new file during
restore instead of the original file at checkpoint time. For example,
the user wants to change the log file of a process from /path/to/oldlog
to /path/to/newlog.

In these cases, criu's caller should set up a new file descriptor to be
inherited by the restored process and specify the file descriptor with
the --inherit-fd command line option.

Please note that inherit fd support breaks applications that depend
on the state of the file descriptor being inherited. For example, an
application that depends on the seek offset within a file at checkpoint
time will fail after restore if the file is replaced with another file
at a different seek offset.

You should consider using this feature only for specific use cases that you know
for sure won't break the application. In other words, use it at your
own risk.

The argument of --inherit-fd has the format fd[%d]:%s,
where %d tells criu which of its own file descriptors to use
for restoring the file identified by %s. Note that the file descriptor
number should be enclosed in literal square brackets (and as square brackets are
handled specially by the command line shell, they might need to be properly escaped).

As a debugging aid, if the argument has the format debug[%d]:%s, criu
will just write out the string after colon to the file descriptor %d.
This can be used to leave a "restore marker" in the output stream of
the process.

Let's redirect the output of test.sh from the simple loop example
to /tmp/old, checkpoint it, and restore it to use /tmp/new as its
output file.

As you see below, we have used criu's file descriptor 7 (just as an
arbitrary descriptor) with the --inherit-fd option. Note that the file path
in the argument of --inherit-fd is relative to the root of the process
(i.e., tmp/old).

To replace an external pipe that was connected to an external process
is more involved because unnamed pipes are typically created between
a parent and a child process. Therefore, the external process has to
invoke criu as its child and set up a new pipe between itself and criu
to be inherited by the restored process.

To demonstrate how this is done, consider a parent process that spawns
a child which will write messages to its parent through a pipe. When a
couple of messages has been received by parent, it invokes criu to
checkpoint the child. As a result of checkpoint, the child exits and
the pipe will be broken. Then, the parent sets up a new pipe between
itself and criu and invokes it to restore the child using the new pipe
(instead of the old one).

Note that unlike restoring, checkpointing the child doesn't have to be
done by the parent (i.e., can be done manually by the user). But for
simplicity, we're having the parent checkpoint the child.

The source code for pipe.c can be found in criu source tree under
test/pipes. Each output line is preceded by the process that has
generated it. Notice pipe:[472728] is replaced with pipe:[474324]
passed through criu's fd[3].

"criu dump" tries to resolve paths for each files, so the first example works only for files which can be resolved from dumped mount namespaces. If we have a file from another namespace, we call it as "external" and criu isn't able to restore it without external help. We need to enumerate all external files on dump and set inherit file descriptors on restore. This descriptors will be used only to open a file via /proc/self/fd, so it doesn't matter with which flags an inherited descriptor has been opened. The format of file id is file[mnt_id:inode].