[CRIU] [RFC PATCH 4/5] autofs: restore procedure introduced
Pavel Emelyanov
xemul at parallels.com
Wed Nov 25 04:21:22 PST 2015
On 11/24/2015 03:54 PM, Stanislav Kinsburskiy wrote:
>
>
> 24.11.2015 13:24, Pavel Emelyanov пишет:
>> On 11/24/2015 02:20 PM, Stanislav Kinsburskiy wrote:
>>>
>>> 24.11.2015 11:58, Pavel Emelyanov пишет:
>>>>>>> +struct autofs_info_s {
>>>>>>> + int pipe_fd;
>>>>>>> + const char *mnt_path;
>>>>>>> + struct autofs_info_s *next;
>>>>>>> +};
>>>>>>> +
>>>>>>> +struct autofs_service_s {
>>>>>>> + int pgrp;
>>>>>>> + struct autofs_info_s *mnt_info;
>>>>>>> + struct autofs_service_s *next;
>>>>>>> +} *automount;
>>>>>>> +
>>>>>>> +int autofs_fixup_owner(struct autofs_info_s *info)
>>>>>>> +{
>>>>>>> + int autofs_fd, mnt_fd, err = -1;
>>>>>>> + struct autofs_dev_ioctl param;
>>>>>>> +
>>>>>>> + autofs_fd = open("/dev/autofs", O_RDONLY);
>>>>>>> + if (autofs_fd == -1) {
>>>>>>> + pr_perror("failed to open /dev/autofs");
>>>>>>> + return -1;
>>>>>>> + }
>>>>>>> +
>>>>>>> + mnt_fd = open(info->mnt_path, O_RDONLY | O_DIRECTORY);
>>>>>>> + if (mnt_fd == -1) {
>>>>>>> + pr_perror("failed to open %s", info->mnt_path);
>>>>>>> + goto close_fd;
>>>>>>> + }
>>>>>>> +
>>>>>>> + init_autofs_dev_ioctl(¶m);
>>>>>>> + err = ioctl(mnt_fd, AUTOFS_IOC_CATATONIC, 0);
>>>>>>> + if (err == -1) {
>>>>>>> + pr_perror("failed to set mount point catatonic");
>>>>>>> + goto close_mnt_fd;
>>>>>>> +
>>>>>>> + }
>>>>>>> +
>>>>>>> + init_autofs_dev_ioctl(¶m);
>>>>>>> + param.ioctlfd = mnt_fd;
>>>>>>> + param.setpipefd.pipefd = info->pipe_fd;
>>>>>> The info->pipe_fd is set by autofs_mount() and the fd value is purely
>>>>>> parsed from options. Who and when creates this very fd?
>>>>> The pipe itself belongs to automount process and restored as any other fd.
>>>>> Yes, we are probably lucky, that automount doesn't close write end of
>>>>> the pipe, which is sent to the kernel.
>>>> I still don't get it. CRIU would close pipe's write end once ->open is
>>>> called, so in ->post_open the kernel part of the pipe should not be
>>>> available.
>>>>
>>>> Can you write the sequence of steps that lead to this particular place
>>>> in the code and show _where_ the write end of the pipe is (was) created?
>>>>
>>> It's very simple: user space process (automount) contains _both_ ends of
>>> the pipe. One of this ends is also used by the kernel.
>>> IOW, pipe is reopened, as any other, and write end is not closed.
>>> That's a pure luck, that automount process doesn't close write end.
>> OK, but then you should add a check for the write-end being in the process.
>
> That's easy. But, probably, it doesn't make much sense.
It does. If you're going to restore a task _without_ that end, you'll end
up with some fake or (which is worse) wrong fd passed into autofs.
> 1) Nice fd_has_data() helper works only on read end.
> 2) We have to find read end anyway.
>
> Is there any way to find another end of pipe without reading image file?
On dump or on restore?
>>> In case of systemd, this end is closed. And this case have to be covered
>>> as well. There should be some way, how to find the _read_ end of kernel
>>> pipe. If you know one, hint will be highly appreciated.
>> No way to get this info, kernel should be patched to at least report
>> pipe inode number.
>
> Yes, I was also thinking about it. I'll do so for now.
>
>>> But I suggest to fix this stuff on top of the series. While the series
>>> requires a check, that process contains both ends (like automount does).
>>>
>>> Does it suits you?
>> Yes. But I wonder how you will _safely_ distinguish which process is
>> attached to autofs mount. Doing this by pgrp only doesn't look OK.
>
> Agreed. But if we introduce pipe inode report from autofs, then we can
> check, that process with specified pgrp has a pipe with the same inode,
> as kernel's control pipe.
Yup.
> In this case it should be safe from my pow.
Yes, that's the way to go. So we need a kernel patch for autofs support.
-- Pavel
More information about the CRIU
mailing list