[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