[CRIU] [PATCH] cr-super: Initial commit
Pavel Emelyanov
xemul at parallels.com
Wed Sep 16 07:20:25 PDT 2015
On 09/16/2015 04:43 PM, Cyrill Gorcunov wrote:
> On Wed, Sep 16, 2015 at 02:55:09PM +0300, Andrew Vagin wrote:
>>
>> In addition, we need to check that we are able to attache to a process
>> by ptrace.
>>
>> I think for that we need to drop CAP_SYS_PTRACE from the effective set,
>> try to call PTRACE_SEIZE and if this operation was success, we can read
>> map_files.
>
> What for? It's already checked by criu itself. Seizing process is not
> that cheap operation, which actually changes internal state of a task
> we're poking while this wrapper is supposed to be very fast and
> "client" filtering should be based on groups (say group criu)
> or any other auth mechanism. Moreover, in the kernel there
> is a check for PTRACE_MODE_READ not for PTRACE_MODE_ATTACH
> (as happens for ptrace-seizing) so it's not 1:1 map of
> what map-files reading does. Am I missing something obvious?
>
>>> +++ b/super/cr-super.h
>>> @@ -0,0 +1,59 @@
>>> +#ifndef __CR_SUPER_H__
>>> +#define __CR_SUPER_H__
>>> +
>>> +#include <limits.h>
>>> +
>>> +enum {
>>> + SUPER_RSP_OK = 1,
>>> + SUPER_RSP_ERR = 2,
>>> +
>>> + SUPER_REQ_EXIT = 3,
>>> +
>>> + SUPER_REQ_MFD_OPEN_DIR = 4,
>>
>> Why do we need to have a separate command to open a directory?
>>
>> We can cache a directory desriptor and open a directory only
>> if prev_pid isn't equal to req->pid.
>>
>>> + SUPER_REQ_MFD_FILL_STAT = 5,
>>> + SUPER_REQ_MFD_FILL_LINK = 6,
>>> + SUPER_REQ_MFD_FILL_MNT_ID = 7,
>>
>> Why we can't have one only one command?
>
> Look, there is one problem -- aufs, it might ask for
Let's forget the aufs case for non-root usage. It was invented
for Docker to workaround the fs's problem. Now aufs is not used
by it, it's replaced with overlayfs.
> reading link, so we have to pass the complete PATH_MAX
> size via net. But I wanted to minimize net usage impact
> so the packets are small in size (ie there usually gonna
> be the following sequence
>
> -> open-dir
> <- ok
> -> get-stat
> <- ok
>
> and that's all. Probably merging open-dir with get-stat
> is a good idea. Thanks for the note.
>
> Same time for auif it might endup in
>
> -> opendir
> <- ok
> -> get-stat
> <- ok
> -> read-link (huge size)
> <- ok
> -> parse mnt-id
> <- ok
>
>>> +
>>> +#define __check_opened(__r) \
>>> + do { \
>>> + if (mfd_dir_fd < 0) { \
>>> + pr_err("dir is not yet opened\n"); \
>>> + __RSP_ERR(__r, -EINVAL); \
>>> + return -EINVAL; \
>>> + } \
>>> + } while (0)
>>
>> I don't like macroses which calls "return"
>
> ok, i'll make it inline
>
>>> +
>>> + pr_debug("Listening\n");
>>> + for (;;) {
>>> + recv_size = recv(socket_fd, NULL, 0, MSG_TRUNC | MSG_PEEK);
>>> + if (recv_size < sizeof(super_req_hdr_t)) {
>>> + pr_perror("Can't read request");
>>> + goto out;
>>> + }
>>> +
>>> + reqcv_buf = xmalloc(recv_size);
>>> + if (!reqcv_buf)
>>> + goto out;
>>> +
>>> + recv_size = recv(socket_fd, reqcv_buf, recv_size, MSG_TRUNC);
>>> + if (recv_size < 0) {
>>> + pr_perror("Can't read request");
>>> + goto out;
>>> + } else if (recv_size == 0)
>>> + goto out;
>>> +
>>> + __TRACE_RCV_PKT(reqcv_buf);
>>> +
>>> + ret = handle_request(socket_fd, &ids, reqcv_buf, recv_size);
>>> + if (ret < 0)
>>> + goto out;
>>> +
>>> + __TRACE_SND_PKT(reqcv_buf);
>>> +
>>> + send_size = send(socket_fd, reqcv_buf, recv_size, 0);
>>> + if (send_size < recv_size) {
>>> + pr_perror("Can't send request");
>>
>> Don't mix ret and the function exit code.
>> Here ret is zero, so you return zero code for the error case
>
> yes, thanks, need to setup @ret here, missed.
>
>>> +
>>> +usage:
>>> + printf("%s: --fd <num>\n", argv[0][1]);
>>
>> This should be printed on stderr
>
> ok
> .
>
More information about the CRIU
mailing list