[CRIU] [PATCH 1/2] locks: Add ofd locks c/r

Eugene Batalov eabatalov89 at gmail.com
Thu Jan 12 01:29:44 PST 2017


Thank you Andrei.
Also this unchecked fcntl call already exists for another lock type so
we'll send a patch to fix both of them.

2017-01-05 4:47 GMT+03:00 Andrei Vagin <avagin at virtuozzo.com>:

> On Tue, Dec 20, 2016 at 01:24:38PM +0300, Pavel Begunkov wrote:
> > From: Begunkov Pavel <asml.silence at gmail.com>
> >
> > OFD locks logic reuses existing locks c/r functionality.
> >
> > Signed-off-by: Begunkov Pavel <asml.silence at gmail.com>
> > Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
> > ---
> >  criu/file-lock.c         | 80 ++++++++++++++++++++++++++++++
> ++++++++++++++++--
> >  criu/include/file-lock.h |  8 +++++
> >  criu/proc_parse.c        |  2 ++
> >  3 files changed, 87 insertions(+), 3 deletions(-)
> >
> > diff --git a/criu/file-lock.c b/criu/file-lock.c
> > index 1ab1e58..fbb963b 100644
> > --- a/criu/file-lock.c
> > +++ b/criu/file-lock.c
> > @@ -204,6 +204,57 @@ static int lock_check_fd(int lfd, struct file_lock
> *fl)
> >       return 1;
> >  }
> >
> > +static int lock_ofd_check_fd(int lfd, struct file_lock *fl)
> > +{
> > +     int ret;
> > +
> > +     struct flock lck = {
> > +             .l_whence = SEEK_SET,
> > +             .l_type   = F_WRLCK,
> > +             .l_start  = fl->start
> > +     };
> > +     if (strcmp(fl->end, "EOF")) {
> > +             unsigned long end;
> > +
> > +             ret = sscanf(fl->end, "%lu", &end);
> > +             if (ret <= 0) {
> > +                     pr_err("Invalid lock entry\n");
> > +                     return -1;
> > +             }
> > +             lck.l_len = end - fl->start + 1;
> > +     } else {
> > +             lck.l_len = 0;
> > +     }
> > +
> > +     ret = fcntl(lfd, F_OFD_SETLK, &lck);
> > +     pr_debug("   `- %d/%d\n", ret, errno);
> > +     if (ret != 0) {
> > +             if (errno != EAGAIN) {
> > +                     pr_err("Bogus lock test result %d\n", ret);
> > +                     return -1;
> > +             }
> > +
> > +             return 0;
> > +     } else {
> > +             /*
> > +              * The ret == 0 means, that new lock doesn't conflict
> > +              * with any others on the file. But since we do know,
> > +              * that there should be some other one (file is found
> > +              * in /proc/locks), it means that the lock is already
> > +              * on file pointed by fd.
> > +              */
> > +             pr_debug("   `- downgrading lock back\n");
> > +             if (fl->fl_ltype & LOCK_WRITE)
> > +                     lck.l_type = F_WRLCK;
> > +             else
> > +                     lck.l_type = F_RDLCK;
> > +
> > +             fcntl(lfd, F_OFD_SETLK, &lck);
>
>
> CID 173734 (#1 of 1): Unchecked return value from library (CHECKED_RETURN)
> 7. check_return: Calling fcntl(lfd, 37, &lck) without checking return
> value. This library function may fail and return an error code.
>
> > +     }
> > +
> > +     return 1;
> > +}
> > +
> >  int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
> >  {
> >       struct file_lock *fl;
> > @@ -232,11 +283,11 @@ int note_file_lock(struct pid *pid, int fd, int
> lfd, struct fd_parms *p)
> >                        */
> >                       if (fl->fl_owner != pid->real)
> >                               continue;
> > -             } else /* fl->fl_kind == FL_FLOCK */ {
> > +             } else /* fl->fl_kind == FL_FLOCK || fl->fl_kind == FL_OFD
> */ {
> >                       int ret;
> >
> >                       /*
> > -                      * FLOCKs can be inherited across fork,
> > +                      * OFD locks & FLOCKs can be inherited across fork,
> >                        * thus we can have any task as lock
> >                        * owner. But the creator is preferred
> >                        * anyway.
> > @@ -247,7 +298,11 @@ int note_file_lock(struct pid *pid, int fd, int
> lfd, struct fd_parms *p)
> >                               continue;
> >
> >                       pr_debug("Checking lock holder %d:%d\n",
> pid->real, fd);
> > -                     ret = lock_check_fd(lfd, fl);
> > +                     if (fl->fl_kind == FL_FLOCK)
> > +                             ret = lock_check_fd(lfd, fl);
> > +                     else
> > +                             ret = lock_ofd_check_fd(lfd, fl);
> > +
> >                       if (ret < 0)
> >                               return ret;
> >                       if (ret == 0)
> > @@ -312,6 +367,25 @@ static int restore_file_lock(FileLockEntry *fle)
> >                       pr_err("Can not set posix lock!\n");
> >                       goto err;
> >               }
> > +     } else if (fle->flag & FL_OFD) {
> > +             struct flock flk = {
> > +                     .l_whence = SEEK_SET,
> > +                     .l_start  = fle->start,
> > +                     .l_len    = fle->len,
> > +                     .l_pid    = 0,
> > +                     .l_type   = fle->type
> > +             };
> > +
> > +             pr_info("(ofd)flag: %d, type: %d, pid: %d, fd: %d, "
> > +                             "start: %8"PRIx64", len: %8"PRIx64"\n",
> > +                             fle->flag, fle->type, fle->pid, fle->fd,
> > +                             fle->start, fle->len);
> > +
> > +             ret = fcntl(fle->fd, F_OFD_SETLK, &flk);
> > +             if (ret < 0) {
> > +                     pr_err("Can not set ofd lock!\n");
> > +                     goto err;
> > +             }
> >       } else {
> >               pr_err("Unknown file lock style!\n");
> >               goto err;
> > diff --git a/criu/include/file-lock.h b/criu/include/file-lock.h
> > index 5c1bb5b..c3f2dab 100644
> > --- a/criu/include/file-lock.h
> > +++ b/criu/include/file-lock.h
> > @@ -9,6 +9,7 @@
> >  #define FL_UNKNOWN   -1
> >  #define FL_POSIX     1
> >  #define FL_FLOCK     2
> > +#define FL_OFD               4
> >
> >  /* for posix fcntl() and lockf() */
> >  #ifndef F_RDLCK
> > @@ -17,6 +18,13 @@
> >  #define F_UNLCK              2
> >  #endif
> >
> > +/* for OFD locks fcntl() */
> > +#ifndef F_OFD_GETLK
> > +#define F_OFD_GETLK  36
> > +#define F_OFD_SETLK  37
> > +#define F_OFD_SETLKW 38
> > +#endif
> > +
> >  /* operations for bsd flock(), also used by the kernel implementation */
> >  #define LOCK_SH              1       /* shared lock */
> >  #define LOCK_EX              2       /* exclusive lock */
> > diff --git a/criu/proc_parse.c b/criu/proc_parse.c
> > index 7c48b33..1f0bff8 100644
> > --- a/criu/proc_parse.c
> > +++ b/criu/proc_parse.c
> > @@ -1973,6 +1973,8 @@ static int parse_file_lock_buf(char *buf, struct
> file_lock *fl,
> >               fl->fl_kind = FL_POSIX;
> >       else if (!strcmp(fl_flag, "FLOCK"))
> >               fl->fl_kind = FL_FLOCK;
> > +     else if (!strcmp(fl_flag, "OFDLCK"))
> > +             fl->fl_kind = FL_OFD;
> >       else
> >               fl->fl_kind = FL_UNKNOWN;
> >
> > --
> > 2.10.0
> >
> > _______________________________________________
> > CRIU mailing list
> > CRIU at openvz.org
> > https://lists.openvz.org/mailman/listinfo/criu
>



-- 
Best regards,
Eugene Batalov.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvz.org/pipermail/criu/attachments/20170112/af57aaba/attachment-0001.html>


More information about the CRIU mailing list