[CRIU] [PATCH v2] Add inherit fd support

Saied Kazemi saied at google.com
Wed Dec 10 09:39:15 PST 2014


On Wed, Dec 10, 2014 at 1:52 AM, Pavel Emelyanov <xemul at parallels.com> wrote:
> On 12/09/2014 11:20 PM, Saied Kazemi wrote:
>> There are cases where a process's 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.  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.
>>
>> As a debugging aid, if the argument has the format debug[%d]:%s, it tells
>> criu to write out the string after colon to the file descriptor %d.  This
>> can be used, for example, as an easy way to leave a "restore marker"
>> in the output stream of the process.
>>
>> It's important to note that inherit fd support breaks applications
>> that depend on the state of the file descriptor being inherited.  So,
>> consider inherit fd only for specific use cases that you know for sure
>> won't break the application.
>>
>> For examples please visit http://criu.org/Category:HOWTO.
>>
>> Signed-off-by: Saied Kazemi <saied at google.com>
>
> Patch applied, thanks a lot! I have only one question, would you clarify
> it please:
>
>
>> +int inherit_fd_fini()
>> +{
>> +     int reused;
>> +     struct inherit_fd *inh;
>> +
>> +     list_for_each_entry(inh, &opts.inherit_fds, inh_list) {
>> +             if (inh->inh_fd < 0) {
>> +                     pr_err("File %s in inherit fd list has invalid fd %d\n",
>> +                             inh->inh_id, inh->inh_fd);
>> +                     return -1;
>> +             }
>> +
>> +             reused = inherit_fd_reused(inh);
>
> How can the fd become reused? I've found no places where the fd sitting
> in the inh object may become such.

Sorry that it's not obvious, Andrew had the same question.  Please let
me know if we should add a comment to explain.

Some parts of the file restore engine can close an inherit fd
explicitly by close() or implicitly by dup2() to reuse that
descriptor.  For example, here is a code snippet from
send_fd_to_self():

        if (move_img_fd(sock, dfd))
                return -1;

        if (dup2(fd, dfd) != dfd) {
                pr_perror("Can't dup local fd %d -> %d", fd, dfd);
                return -1;
        }

dfd may be an inherit fd.  In the specific case of send_fd_to_self(),
we check for clashes at the beginning of the function and, therefore,
this function will not reuse an inherit fd.  However, to avoid adding
a ton of clash detect and resolve code everywhere we close() and/or
dup2(), we just make sure that when we're dup()ing or close()ing our
inherit fd we're still dealing with the same fd that we inherited.

I hope it's more clear now.

>> +             if (reused < 0)
>> +                     return -1;
>> +
>> +             if (!reused) {
>> +                     pr_debug("Closing inherit fd %d -> %s\n", inh->inh_fd,
>> +                             inh->inh_id);
>> +                     if (close_safe(&inh->inh_fd) < 0)
>> +                             return -1;
>> +             }
>> +     }
>> +     return 0;
>> +}
>

Thank you for applying this patch.

--Saied


More information about the CRIU mailing list