<div dir="ltr">Thank you, Pavel.</div><div class="gmail_extra"><br><div class="gmail_quote">2016-12-30 13:47 GMT+03:00 Pavel Emelyanov <span dir="ltr">&lt;<a href="mailto:xemul@virtuozzo.com" target="_blank">xemul@virtuozzo.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 12/30/2016 12:17 PM, Pavel Emelyanov wrote:<br>
&gt; On 12/20/2016 01:24 PM, Pavel Begunkov wrote:<br>
&gt;&gt; From: Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; There are 3 tests that cover the following cases:<br>
&gt;&gt;<br>
&gt;&gt; 1. single OFD lock<br>
&gt;&gt; 2. overlapped OFD locks<br>
&gt;&gt; 3. inhertited OFD locks<br>
&gt;&gt;<br>
&gt;&gt; Tests logic is similar to logic of tests for other lock types.<br>
&gt;&gt;<br>
&gt;&gt; OFD lock specific header-only library was added to avoid code<br>
&gt;&gt; duplication in the tests.<br>
&gt;&gt;<br>
&gt;&gt; Signed-off-by: Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;<br>
&gt;&gt; Signed-off-by: Eugene Batalov &lt;<a href="mailto:eabatalov89@gmail.com">eabatalov89@gmail.com</a>&gt;<br>
&gt;&gt; ---<br>
&gt;&gt;  test/zdtm/static/Makefile          |   3 +<br>
&gt;&gt;  test/zdtm/static/file_locks06.<wbr>c    |  67 ++++++++++++++++<br>
&gt;&gt;  test/zdtm/static/file_locks06.<wbr>desc |   1 +<br>
&gt;&gt;  test/zdtm/static/file_locks07.<wbr>c    | 101 ++++++++++++++++++++++++<br>
&gt;&gt;  test/zdtm/static/file_locks07.<wbr>desc |   1 +<br>
&gt;&gt;  test/zdtm/static/file_locks08.<wbr>c    |  86 +++++++++++++++++++++<br>
&gt;<br>
&gt; Guys, this test fails:<br>
<br>
</span>I&#39;ve fixed it with 7d38db56a67d5f0d9f6e3fb499197b<wbr>4d081108b2<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; # ./zdtm.py run -t zdtm/static/file_locks08<br>
&gt; cc -D_GNU_SOURCE    umount2.c   -o umount2<br>
&gt; cc -D_GNU_SOURCE    zdtm_ct.c   -o zdtm_ct<br>
&gt; === Run 1/1 ================ zdtm/static/file_locks08<br>
&gt;<br>
&gt; ====================== Run zdtm/static/file_locks08 in h =======================<br>
&gt; cc -g -O2 -Wall -Werror -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0  -iquote ../lib/arch/x86/include -I../lib   file_locks08.c ../lib/libzdtmtst.a ../lib/libzdtmtst.a -o file_locks08<br>
&gt; Start test<br>
&gt; ./file_locks08 --pidfile=file_locks08.pid --outfile=file_locks08.out --filename=file_locks08.test<br>
&gt; Run criu dump<br>
&gt; Run criu restore<br>
&gt; Send the 15 signal to  39<br>
&gt; Wait for zdtm/static/file_locks08(39) to die for 0.100000<br>
&gt; Removing dump/zdtm/static/file_locks08/<wbr>39<br>
&gt; ====================== Test zdtm/static/file_locks08 PASS ======================<br>
&gt;<br>
&gt; ====================== Run zdtm/static/file_locks08 in ns ======================<br>
&gt; Construct root for zdtm/static/file_locks08<br>
&gt; Start test<br>
&gt; ./file_locks08 --pidfile=file_locks08.pid --outfile=file_locks08.out --filename=file_locks08.test<br>
&gt; Run criu dump<br>
&gt; Run criu restore<br>
&gt; 5: Old files lost: set([&#39;1&#39;, &#39;0&#39;, &#39;3&#39;, &#39;2&#39;, &#39;4&#39;])<br>
&gt; 5: New files appeared: set([])<br>
&gt; ############## Test zdtm/static/file_locks08 FAIL at fds compare ###############<br>
&gt; Send the 9 signal to  100<br>
&gt; ##############################<wbr>####### FAIL ##############################<wbr>#######<br>
&gt;<br>
&gt; -- Pavel<br>
&gt;<br>
&gt;&gt;  test/zdtm/static/file_locks08.<wbr>desc |   1 +<br>
&gt;&gt;  test/zdtm/static/ofd_file_<wbr>locks.h  | 153 ++++++++++++++++++++++++++++++<wbr>+++++++<br>
&gt;&gt;  8 files changed, 413 insertions(+)<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks06.<wbr>c<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks06.<wbr>desc<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks07.<wbr>c<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks07.<wbr>desc<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks08.<wbr>c<br>
&gt;&gt;  create mode 100644 test/zdtm/static/file_locks08.<wbr>desc<br>
&gt;&gt;  create mode 100644 test/zdtm/static/ofd_file_<wbr>locks.h<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile<br>
&gt;&gt; index c932093..f270f9f 100644<br>
&gt;&gt; --- a/test/zdtm/static/Makefile<br>
&gt;&gt; +++ b/test/zdtm/static/Makefile<br>
&gt;&gt; @@ -221,6 +221,9 @@ TST_FILE =                               \<br>
&gt;&gt;              file_locks03                    \<br>
&gt;&gt;              file_locks04                    \<br>
&gt;&gt;              file_locks05                    \<br>
&gt;&gt; +            file_locks06                    \<br>
&gt;&gt; +            file_locks07                    \<br>
&gt;&gt; +            file_locks08                    \<br>
&gt;&gt;              netns-nf                        \<br>
&gt;&gt;              maps_file_prot                  \<br>
&gt;&gt;              socket_close_data01             \<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks06.c b/test/zdtm/static/file_<wbr>locks06.c<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..2e1ba43<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks06.c<br>
&gt;&gt; @@ -0,0 +1,67 @@<br>
&gt;&gt; +#define _GNU_SOURCE<br>
&gt;&gt; +<br>
&gt;&gt; +#include &lt;sys/file.h&gt;<br>
&gt;&gt; +#include &lt;unistd.h&gt;<br>
&gt;&gt; +#include &lt;fcntl.h&gt;<br>
&gt;&gt; +<br>
&gt;&gt; +#include &quot;ofd_file_locks.h&quot;<br>
&gt;&gt; +#include &quot;zdtmtst.h&quot;<br>
&gt;&gt; +<br>
&gt;&gt; +const char *test_doc    = &quot;Check that OFD lock for the whole file is restored&quot;;<br>
&gt;&gt; +const char *test_author = &quot;Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;&quot;;<br>
&gt;&gt; +<br>
&gt;&gt; +char *filename;<br>
&gt;&gt; +TEST_OPTION(filename, string, &quot;file name&quot;, 1);<br>
&gt;&gt; +<br>
&gt;&gt; +<br>
&gt;&gt; +int init_lock(int *fd, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    *fd = open(filename, O_RDWR | O_CREAT, 0666);<br>
&gt;&gt; +    if (*fd &lt; 0) {<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t open file&quot;);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    lck-&gt;l_type = F_WRLCK;<br>
&gt;&gt; +    lck-&gt;l_whence = SEEK_SET;<br>
&gt;&gt; +    lck-&gt;l_start = 0;<br>
&gt;&gt; +    lck-&gt;l_len = 0;<br>
&gt;&gt; +    lck-&gt;l_pid = 0;<br>
&gt;&gt; +<br>
&gt;&gt; +    if (fcntl(*fd, F_OFD_SETLK, lck) &lt; 0) {<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t set ofd lock&quot;);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +void cleanup(int *fd)<br>
&gt;&gt; +{<br>
&gt;&gt; +    if (close(*fd))<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t close fd\n&quot;);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (unlink(filename))<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t unlink file\n&quot;);<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +int main(int argc, char **argv)<br>
&gt;&gt; +{<br>
&gt;&gt; +    int fd;<br>
&gt;&gt; +    struct flock lck;<br>
&gt;&gt; +<br>
&gt;&gt; +    test_init(argc, argv);<br>
&gt;&gt; +    if (init_lock(&amp;fd, &amp;lck))<br>
&gt;&gt; +            return 1;<br>
&gt;&gt; +<br>
&gt;&gt; +    test_daemon();<br>
&gt;&gt; +    test_waitsig();<br>
&gt;&gt; +<br>
&gt;&gt; +    if (check_file_lock_restored(<wbr>getpid(), fd, &amp;lck) ||<br>
&gt;&gt; +            check_lock_exists(filename, &amp;lck) &lt; 0)<br>
&gt;&gt; +            fail(&quot;OFD file locks check failed\n&quot;);<br>
&gt;&gt; +    else<br>
&gt;&gt; +            pass();<br>
&gt;&gt; +<br>
&gt;&gt; +    cleanup(&amp;fd);<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks06.desc b/test/zdtm/static/file_<wbr>locks06.desc<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..80cd04e<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks06.desc<br>
&gt;&gt; @@ -0,0 +1 @@<br>
&gt;&gt; +{&#39;flags&#39;: &#39;excl&#39;, &#39;opts&#39;: &#39;--file-locks&#39;}<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks07.c b/test/zdtm/static/file_<wbr>locks07.c<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..1f94625<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks07.c<br>
&gt;&gt; @@ -0,0 +1,101 @@<br>
&gt;&gt; +#define _GNU_SOURCE<br>
&gt;&gt; +<br>
&gt;&gt; +#include &lt;sys/file.h&gt;<br>
&gt;&gt; +#include &lt;unistd.h&gt;<br>
&gt;&gt; +#include &lt;fcntl.h&gt;<br>
&gt;&gt; +<br>
&gt;&gt; +#include &quot;ofd_file_locks.h&quot;<br>
&gt;&gt; +#include &quot;zdtmtst.h&quot;<br>
&gt;&gt; +<br>
&gt;&gt; +const char *test_doc    = &quot;Check that &#39;overlapping&#39; OFD read locks work&quot;;<br>
&gt;&gt; +const char *test_author = &quot;Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;&quot;;<br>
&gt;&gt; +<br>
&gt;&gt; +char *filename;<br>
&gt;&gt; +TEST_OPTION(filename, string, &quot;file name&quot;, 1);<br>
&gt;&gt; +<br>
&gt;&gt; +<br>
&gt;&gt; +#define FILE_NUM 4<br>
&gt;&gt; +static int fds[FILE_NUM];<br>
&gt;&gt; +static struct flock lcks[FILE_NUM];<br>
&gt;&gt; +static short types[] = {F_RDLCK, F_RDLCK, F_RDLCK, F_RDLCK};<br>
&gt;&gt; +static off_t starts[] = {0, 10, 0, 70};<br>
&gt;&gt; +static off_t lens[]  = {20, 30, 100, 200};<br>
&gt;&gt; +<br>
&gt;&gt; +void fill_lock(struct flock *lock, off_t start, off_t len, short int type)<br>
&gt;&gt; +{<br>
&gt;&gt; +    lock-&gt;l_start = start;<br>
&gt;&gt; +    lock-&gt;l_len = len;<br>
&gt;&gt; +    lock-&gt;l_type = type;<br>
&gt;&gt; +    lock-&gt;l_whence = SEEK_SET;<br>
&gt;&gt; +    lock-&gt;l_pid = 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +int init_file_locks(void)<br>
&gt;&gt; +{<br>
&gt;&gt; +    size_t i;<br>
&gt;&gt; +<br>
&gt;&gt; +    for (i = 0; i &lt; FILE_NUM; ++i)<br>
&gt;&gt; +            fill_lock(&amp;lcks[i], starts[i], lens[i], types[i]);<br>
&gt;&gt; +<br>
&gt;&gt; +    for (i = 0; i &lt; FILE_NUM; ++i) {<br>
&gt;&gt; +            fds[i] = open(filename, O_RDWR | O_CREAT, 0666);<br>
&gt;&gt; +<br>
&gt;&gt; +            if (fds[i] &lt; 0) {<br>
&gt;&gt; +                    pr_perror(&quot;Can&#39;t open file&quot;);<br>
&gt;&gt; +                    return -1;<br>
&gt;&gt; +            }<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    for (i = 0; i &lt; FILE_NUM; ++i)<br>
&gt;&gt; +            if (fcntl(fds[i], F_OFD_SETLKW, &amp;lcks[i]) &lt; 0) {<br>
&gt;&gt; +                    pr_perror(&quot;Can&#39;t set ofd lock&quot;);<br>
&gt;&gt; +                    return -1;<br>
&gt;&gt; +            }<br>
&gt;&gt; +<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +void cleanup(void)<br>
&gt;&gt; +{<br>
&gt;&gt; +    size_t i;<br>
&gt;&gt; +<br>
&gt;&gt; +    for (i = 0; i &lt; FILE_NUM; ++i)<br>
&gt;&gt; +            if (close(fds[i]))<br>
&gt;&gt; +                    pr_perror(&quot;Can&#39;t close fd\n&quot;);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (unlink(filename))<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t unlink file failed\n&quot;);<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +int check_file_locks_restored(<wbr>void)<br>
&gt;&gt; +{<br>
&gt;&gt; +    size_t i;<br>
&gt;&gt; +    int pid = getpid();<br>
&gt;&gt; +<br>
&gt;&gt; +    for (i = 0; i &lt; FILE_NUM; ++i) {<br>
&gt;&gt; +            if (check_file_lock_restored(pid, fds[i], &amp;lcks[i]))<br>
&gt;&gt; +                    return -1;<br>
&gt;&gt; +            if (check_lock_exists(filename, &amp;lcks[i]) &lt; 0)<br>
&gt;&gt; +                    return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +int main(int argc, char **argv)<br>
&gt;&gt; +{<br>
&gt;&gt; +    test_init(argc, argv);<br>
&gt;&gt; +    if (init_file_locks())<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +<br>
&gt;&gt; +    test_daemon();<br>
&gt;&gt; +    test_waitsig();<br>
&gt;&gt; +<br>
&gt;&gt; +    if (check_file_locks_restored())<br>
&gt;&gt; +            fail(&quot;OFD file locks check failed\n&quot;);<br>
&gt;&gt; +    else<br>
&gt;&gt; +            pass();<br>
&gt;&gt; +<br>
&gt;&gt; +    cleanup();<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks07.desc b/test/zdtm/static/file_<wbr>locks07.desc<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..80cd04e<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks07.desc<br>
&gt;&gt; @@ -0,0 +1 @@<br>
&gt;&gt; +{&#39;flags&#39;: &#39;excl&#39;, &#39;opts&#39;: &#39;--file-locks&#39;}<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks08.c b/test/zdtm/static/file_<wbr>locks08.c<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..a0d93dd<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks08.c<br>
&gt;&gt; @@ -0,0 +1,86 @@<br>
&gt;&gt; +#define _GNU_SOURCE<br>
&gt;&gt; +<br>
&gt;&gt; +#include &lt;sys/wait.h&gt;<br>
&gt;&gt; +#include &lt;sys/file.h&gt;<br>
&gt;&gt; +#include &lt;unistd.h&gt;<br>
&gt;&gt; +#include &lt;fcntl.h&gt;<br>
&gt;&gt; +#include &lt;stdlib.h&gt;<br>
&gt;&gt; +<br>
&gt;&gt; +#include &quot;ofd_file_locks.h&quot;<br>
&gt;&gt; +#include &quot;zdtmtst.h&quot;<br>
&gt;&gt; +<br>
&gt;&gt; +const char *test_doc    = &quot;Check that inherited OFD locks work&quot;;<br>
&gt;&gt; +const char *test_author = &quot;Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;&quot;;<br>
&gt;&gt; +<br>
&gt;&gt; +char *filename;<br>
&gt;&gt; +TEST_OPTION(filename, string, &quot;file name&quot;, 1);<br>
&gt;&gt; +<br>
&gt;&gt; +<br>
&gt;&gt; +int init_file_lock(int *fd, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    *fd = open(filename, O_RDWR | O_CREAT, 0666);<br>
&gt;&gt; +    if (*fd &lt; 0) {<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t open file&quot;);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    lck-&gt;l_type = F_WRLCK;<br>
&gt;&gt; +    lck-&gt;l_whence = SEEK_SET;<br>
&gt;&gt; +    lck-&gt;l_start = 0;<br>
&gt;&gt; +    lck-&gt;l_len = 0; /* lock whole file */<br>
&gt;&gt; +    lck-&gt;l_pid = 0; /* should be 0 for ofd lock */<br>
&gt;&gt; +<br>
&gt;&gt; +    if (fcntl(*fd, F_OFD_SETLKW, lck) &lt; 0) {<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t set ofd lock&quot;);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +void cleanup(int *fd)<br>
&gt;&gt; +{<br>
&gt;&gt; +    if (close(*fd))<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t close fd\n&quot;);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (unlink(filename))<br>
&gt;&gt; +            pr_perror(&quot;Can&#39;t unlink file\n&quot;);<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +int main(int argc, char **argv)<br>
&gt;&gt; +{<br>
&gt;&gt; +    int fd;<br>
&gt;&gt; +    int pid;<br>
&gt;&gt; +    int status;<br>
&gt;&gt; +    int ret = 0;<br>
&gt;&gt; +    struct flock lck;<br>
&gt;&gt; +<br>
&gt;&gt; +    test_init(argc, argv);<br>
&gt;&gt; +    if (init_file_lock(&amp;fd, &amp;lck))<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +<br>
&gt;&gt; +    pid = fork();<br>
&gt;&gt; +    if (pid == 0) {<br>
&gt;&gt; +            if (check_file_lock_restored(<wbr>getpid(), fd, &amp;lck) ||<br>
&gt;&gt; +                    check_lock_exists(filename, &amp;lck) &lt; 0)<br>
&gt;&gt; +                    ret = -1;<br>
&gt;&gt; +            exit(ret);<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    test_daemon();<br>
&gt;&gt; +    test_waitsig();<br>
&gt;&gt; +<br>
&gt;&gt; +    if (check_file_lock_restored(<wbr>getpid(), fd, &amp;lck) ||<br>
&gt;&gt; +            check_lock_exists(filename, &amp;lck) &lt; 0)<br>
&gt;&gt; +            fail(&quot;OFD file locks check failed\n&quot;);<br>
&gt;&gt; +<br>
&gt;&gt; +    kill(pid, SIGTERM);<br>
&gt;&gt; +    ret = waitpid(pid, &amp;status, 0);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (ret &lt; 0 || !WIFEXITED(status) || WEXITSTATUS(status))<br>
&gt;&gt; +            fail(&quot;OFD file locks check failed\n&quot;);<br>
&gt;&gt; +    else<br>
&gt;&gt; +            pass();<br>
&gt;&gt; +<br>
&gt;&gt; +    cleanup(&amp;fd);<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; diff --git a/test/zdtm/static/file_<wbr>locks08.desc b/test/zdtm/static/file_<wbr>locks08.desc<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..80cd04e<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/file_<wbr>locks08.desc<br>
&gt;&gt; @@ -0,0 +1 @@<br>
&gt;&gt; +{&#39;flags&#39;: &#39;excl&#39;, &#39;opts&#39;: &#39;--file-locks&#39;}<br>
&gt;&gt; diff --git a/test/zdtm/static/ofd_file_<wbr>locks.h b/test/zdtm/static/ofd_file_<wbr>locks.h<br>
&gt;&gt; new file mode 100644<br>
&gt;&gt; index 0000000..049401a<br>
&gt;&gt; --- /dev/null<br>
&gt;&gt; +++ b/test/zdtm/static/ofd_file_<wbr>locks.h<br>
&gt;&gt; @@ -0,0 +1,153 @@<br>
&gt;&gt; +#ifndef ZDTM_OFD_FILE_LOCKS_H_<br>
&gt;&gt; +#define ZDTM_OFD_FILE_LOCKS_H_<br>
&gt;&gt; +<br>
&gt;&gt; +#include &lt;sys/file.h&gt;<br>
&gt;&gt; +#include &lt;unistd.h&gt;<br>
&gt;&gt; +#include &lt;fcntl.h&gt;<br>
&gt;&gt; +#include &lt;string.h&gt;<br>
&gt;&gt; +<br>
&gt;&gt; +#include &quot;zdtmtst.h&quot;<br>
&gt;&gt; +#include &quot;fs.h&quot;<br>
&gt;&gt; +<br>
&gt;&gt; +#ifndef F_OFD_GETLK<br>
&gt;&gt; +#define F_OFD_GETLK 36<br>
&gt;&gt; +#define F_OFD_SETLK 37<br>
&gt;&gt; +#define F_OFD_SETLKW        38<br>
&gt;&gt; +#endif<br>
&gt;&gt; +<br>
&gt;&gt; +/*<br>
&gt;&gt; + * Header library for parsing of OFD locks<br>
&gt;&gt; + * from procfs and checking them after restoring.<br>
&gt;&gt; + */<br>
&gt;&gt; +<br>
&gt;&gt; +static int parse_ofd_lock(char *buf, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    char fl_flag[10], fl_type[15], fl_option[10], fl_end[32];<br>
&gt;&gt; +    long long start;<br>
&gt;&gt; +    int num;<br>
&gt;&gt; +<br>
&gt;&gt; +    if (strncmp(buf, &quot;lock:\t&quot;, 6) != 0)<br>
&gt;&gt; +            return 1; /* isn&#39;t lock, skip record */<br>
&gt;&gt; +<br>
&gt;&gt; +    num = sscanf(buf,<br>
&gt;&gt; +            &quot;%*s %*d: %s %s %s %*d %*x:%*x:%*d %lld %s&quot;,<br>
&gt;&gt; +            fl_flag, fl_type, fl_option, &amp;start, fl_end);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (num &lt; 4) {<br>
&gt;&gt; +            pr_err(&quot;Invalid lock info %s\n&quot;, buf);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    if (strcmp(fl_flag, &quot;OFDLCK&quot;))<br>
&gt;&gt; +            return 1;<br>
&gt;&gt; +<br>
&gt;&gt; +    lck-&gt;l_start = start;<br>
&gt;&gt; +<br>
&gt;&gt; +    if (strcmp(fl_end, &quot;EOF&quot;)) {<br>
&gt;&gt; +            unsigned long end;<br>
&gt;&gt; +<br>
&gt;&gt; +            if (sscanf(fl_end, &quot;%lu&quot;, &amp;end) &lt;= 0) {<br>
&gt;&gt; +                    pr_err(&quot;Invalid lock entry\n&quot;);<br>
&gt;&gt; +                    return -1;<br>
&gt;&gt; +            }<br>
&gt;&gt; +            lck-&gt;l_len = end - lck-&gt;l_start + 1;<br>
&gt;&gt; +    } else {<br>
&gt;&gt; +            lck-&gt;l_len = 0;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    if (strcmp(fl_option, &quot;WRITE&quot;) == 0)<br>
&gt;&gt; +            lck-&gt;l_type = F_WRLCK;<br>
&gt;&gt; +    else<br>
&gt;&gt; +            lck-&gt;l_type = F_RDLCK;<br>
&gt;&gt; +<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +static int read_fd_ofd_lock(int pid, int fd, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    char path[PATH_MAX];<br>
&gt;&gt; +    char buf[100];<br>
&gt;&gt; +    int num;<br>
&gt;&gt; +    FILE *proc_file = NULL;<br>
&gt;&gt; +<br>
&gt;&gt; +    sprintf(path, &quot;/proc/%i/fdinfo/%i&quot;, pid, fd);<br>
&gt;&gt; +    proc_file = fopen(path, &quot;r&quot;);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (!proc_file) {<br>
&gt;&gt; +            pr_err(&quot;Can&#39;t open %s\n&quot;, path);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    num = -1;<br>
&gt;&gt; +    while (fgets(buf, sizeof(buf), proc_file)) {<br>
&gt;&gt; +            num = parse_ofd_lock(buf, lck);<br>
&gt;&gt; +            if (num &lt;= 0)<br>
&gt;&gt; +                    break;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    if (fclose(proc_file)) {<br>
&gt;&gt; +            pr_err(&quot;Can&#39;t close %s\n&quot;, path);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    return num;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +static int check_lock_exists(const char *filename, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    int ret = -1;<br>
&gt;&gt; +    int fd;<br>
&gt;&gt; +<br>
&gt;&gt; +    fd = open(filename, O_RDWR, 0666);<br>
&gt;&gt; +<br>
&gt;&gt; +    if (lck-&gt;l_type == F_RDLCK) {<br>
&gt;&gt; +            /* check, that there is no write lock */<br>
&gt;&gt; +            ret = fcntl(fd, F_OFD_GETLK, lck);<br>
&gt;&gt; +            if (ret) {<br>
&gt;&gt; +                    pr_err(&quot;fcntl failed (%i)\n&quot;, ret);<br>
&gt;&gt; +                    goto out;<br>
&gt;&gt; +            }<br>
&gt;&gt; +            if (lck-&gt;l_type != F_UNLCK) {<br>
&gt;&gt; +                    pr_err(&quot;OFD lock type do not match\n&quot;);<br>
&gt;&gt; +                    goto out;<br>
&gt;&gt; +            }<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    /* check, that lock is set */<br>
&gt;&gt; +    lck-&gt;l_type = F_WRLCK;<br>
&gt;&gt; +    ret = fcntl(fd, F_OFD_GETLK, lck);<br>
&gt;&gt; +    if (ret) {<br>
&gt;&gt; +            pr_err(&quot;fcntl failed (%i)\n&quot;, ret);<br>
&gt;&gt; +            goto out;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    if (lck-&gt;l_type == F_UNLCK) {<br>
&gt;&gt; +            pr_err(&quot;Lock not found\n&quot;);<br>
&gt;&gt; +            goto out;<br>
&gt;&gt; +    }<br>
&gt;&gt; +<br>
&gt;&gt; +    ret = 0;<br>
&gt;&gt; +out:<br>
&gt;&gt; +    if (close(fd))<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    return ret;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +static int check_file_locks_match(struct flock *orig_lck, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    return orig_lck-&gt;l_start == lck-&gt;l_start &amp;&amp;<br>
&gt;&gt; +            orig_lck-&gt;l_len == lck-&gt;l_len &amp;&amp;<br>
&gt;&gt; +            orig_lck-&gt;l_type == lck-&gt;l_type;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +static int check_file_lock_restored(int pid, int fd, struct flock *lck)<br>
&gt;&gt; +{<br>
&gt;&gt; +    struct flock lck_restored;<br>
&gt;&gt; +<br>
&gt;&gt; +    if (read_fd_ofd_lock(pid, fd, &amp;lck_restored))<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +<br>
&gt;&gt; +    if (!check_file_locks_match(lck, &amp;lck_restored)) {<br>
&gt;&gt; +            pr_err(&quot;Can&#39;t restore file lock (fd: %i)\n&quot;, fd);<br>
&gt;&gt; +            return -1;<br>
&gt;&gt; +    }<br>
&gt;&gt; +    return 0;<br>
&gt;&gt; +}<br>
&gt;&gt; +<br>
&gt;&gt; +#endif /* ZDTM_OFD_FILE_LOCKS_H_ */<br>
&gt;&gt;<br>
&gt;<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Best regards,<br>Eugene Batalov.</div>
</div>