[CRIU] [PATCH] cr-super: Initial commit
Andrew Vagin
avagin at odin.com
Wed Sep 16 07:22:07 PDT 2015
On Wed, Sep 16, 2015 at 04:43:21PM +0300, 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?
Someout else (except criu) can use this tool. Pavel suggested a good
solution for this case.
>
> > > +++ 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
> 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
It may be very slow to request informatiosn about each mappings
separatly. Maybe we can open /proc/PID/map_files/XXXX and send the file
descriptor back?
>
> > > +
> > > +#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.
Could you use additional variables to avoid such bugs? We do this in
other places.
>
> > > +
> > > +usage:
> > > + printf("%s: --fd <num>\n", argv[0][1]);
> >
> > This should be printed on stderr
>
> ok
More information about the CRIU
mailing list