[ACT][PATCH] UBUNTU: SAUCE: ubuntu_ltp_syscalls: fix fanotify09 for kernels older than 4.15
Stefan Bader
stefan.bader at canonical.com
Thu Sep 26 08:54:50 UTC 2019
On 23.09.19 11:44, Kleber Sacilotto de Souza wrote:
> BugLink: https://bugs.launchpad.net/bugs/1804594
>
> Test case #2 was added to fanotify09 as a regression test for the
> following upstream commit:
>
> b469e7e47c8a fanotify: fix handling of events on child sub-directory
>
> which has been applied to v4.20 and backported to linux-4.19.y upstream
> stable. We backported these changes from 4.19.y to 4.15 but they are not
> trivial for backporting to older kernels, so the best option to fix the
> test case failures with 4.4 and older kernels is to apply a patch to
> revert the changes for this test case.
>
> While at it, fix a indentation issue found in testcase_blacklist().
For me its hard to say where this intended for (kernel or testcases). But
generally, is there a way to just make the test skip if the kernel is too old?
-Stefan
>
> Signed-off-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> ---
> ...t-changes-for-fanotify09-test-case-2.patch | 269 ++++++++++++++++++
> ubuntu_ltp_syscalls/ubuntu_ltp_syscalls.py | 26 +-
> 2 files changed, 288 insertions(+), 7 deletions(-)
> create mode 100644 ubuntu_ltp_syscalls/0001-Revert-changes-for-fanotify09-test-case-2.patch
>
> diff --git a/ubuntu_ltp_syscalls/0001-Revert-changes-for-fanotify09-test-case-2.patch b/ubuntu_ltp_syscalls/0001-Revert-changes-for-fanotify09-test-case-2.patch
> new file mode 100644
> index 00000000..5f40a331
> --- /dev/null
> +++ b/ubuntu_ltp_syscalls/0001-Revert-changes-for-fanotify09-test-case-2.patch
> @@ -0,0 +1,269 @@
> +From 10bb70e6dbaf76758b1a1746c7d936b16e2cef34 Mon Sep 17 00:00:00 2001
> +From: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> +Date: Fri, 20 Sep 2019 13:51:15 +0200
> +Subject: [PATCH] Revert changes for fanotify09 test case #2
> +
> +BugLink: https://bugs.launchpad.net/bugs/1804594
> +
> +Test case #2 was added to fanotify09 as a regression test for the
> +following upstream commit:
> +
> +b469e7e47c8a fanotify: fix handling of events on child sub-directory
> +
> +which has been applied to v4.20 and backported to linux-4.19.y upstream
> +stable.
> +
> +Revert the following changes to this test case so fanotify09 can be
> +tested with older kernels:
> +
> +e89d8e25d syscalls/fanotify09.c: Fix wrong group number
> +457e13c31 fanotify09: check merging of events on child subdir
> +
> +Signed-off-by: Kleber Sacilotto de Souza <kleber.souza at canonical.com>
> +---
> + .../kernel/syscalls/fanotify/fanotify09.c | 125 +++++-------------
> + 1 file changed, 34 insertions(+), 91 deletions(-)
> +
> +diff --git a/testcases/kernel/syscalls/fanotify/fanotify09.c b/testcases/kernel/syscalls/fanotify/fanotify09.c
> +index 0f926c49b..511ccc0e0 100644
> +--- a/testcases/kernel/syscalls/fanotify/fanotify09.c
> ++++ b/testcases/kernel/syscalls/fanotify/fanotify09.c
> +@@ -11,10 +11,6 @@
> + * This is a regression test for commit 54a307ba8d3c:
> + *
> + * fanotify: fix logic of events on child
> +- *
> +- * Test case #2 is a regression test for commit b469e7e47c8a:
> +- *
> +- * fanotify: fix handling of events on child sub-directory
> + */
> + #define _GNU_SOURCE
> + #include "config.h"
> +@@ -27,7 +23,6 @@
> + #include <string.h>
> + #include <sys/mount.h>
> + #include <sys/syscall.h>
> +-#include <stdint.h>
> + #include "tst_test.h"
> + #include "fanotify.h"
> +
> +@@ -44,34 +39,14 @@
> +
> + #define BUF_SIZE 256
> + static char fname[BUF_SIZE];
> +-static char symlnk[BUF_SIZE];
> +-static char fdpath[BUF_SIZE];
> + static int fd_notify[NUM_GROUPS];
> +
> + static char event_buf[EVENT_BUF_LEN];
> +
> + #define MOUNT_NAME "mntpoint"
> +-#define DIR_NAME "testdir"
> + static int mount_created;
> +
> +-static struct tcase {
> +- const char *tname;
> +- unsigned int ondir;
> +- int nevents;
> +-} tcases[] = {
> +- {
> +- "Events on children with both inode and mount marks",
> +- 0,
> +- 1,
> +- },
> +- {
> +- "Events on children and subdirs with both inode and mount marks",
> +- FAN_ONDIR,
> +- 2,
> +- },
> +-};
> +-
> +-static void create_fanotify_groups(unsigned int ondir)
> ++static void create_fanotify_groups(void)
> + {
> + unsigned int i, onchild;
> + int ret;
> +@@ -82,17 +57,15 @@ static void create_fanotify_groups(unsigned int ondir)
> + O_RDONLY);
> +
> + /* Add mount mark for each group without MODIFY event */
> +- onchild = (i == 0) ? FAN_EVENT_ON_CHILD | ondir : 0;
> + ret = fanotify_mark(fd_notify[i],
> + FAN_MARK_ADD | FAN_MARK_MOUNT,
> +- FAN_CLOSE_NOWRITE | onchild,
> ++ FAN_CLOSE_NOWRITE,
> + AT_FDCWD, ".");
> + if (ret < 0) {
> + tst_brk(TBROK | TERRNO,
> + "fanotify_mark(%d, FAN_MARK_ADD | "
> +- "FAN_MARK_MOUNT, FAN_MODIFY%s, AT_FDCWD,"
> +- " '.') failed", fd_notify[i],
> +- ondir ? " | FAN_ONDIR" : "");
> ++ "FAN_MARK_MOUNT, FAN_MODIFY, AT_FDCWD,"
> ++ " '.') failed", fd_notify[i]);
> + }
> + /*
> + * Add inode mark on parent for each group with MODIFY
> +@@ -101,15 +74,15 @@ static void create_fanotify_groups(unsigned int ondir)
> + * setting the DCACHE_FSNOTIFY_PARENT_WATCHED dentry
> + * flag.
> + */
> +- ret = fanotify_mark(fd_notify[i], FAN_MARK_ADD,
> +- FAN_MODIFY | ondir | onchild,
> +- AT_FDCWD, ".");
> ++ onchild = (i == 0) ? FAN_EVENT_ON_CHILD : 0;
> ++ ret = fanotify_mark(fd_notify[i],
> ++ FAN_MARK_ADD,
> ++ FAN_MODIFY | onchild, AT_FDCWD, ".");
> + if (ret < 0) {
> + tst_brk(TBROK | TERRNO,
> + "fanotify_mark(%d, FAN_MARK_ADD, "
> +- "FAN_MODIFY%s%s, AT_FDCWD, '.') failed",
> ++ "FAN_MODIFY%s, AT_FDCWD, '.') failed",
> + fd_notify[i],
> +- ondir ? " | FAN_ONDIR" : "",
> + onchild ? " | FAN_EVENT_ON_CHILD" : "");
> + }
> + }
> +@@ -125,13 +98,12 @@ static void cleanup_fanotify_groups(void)
> + }
> + }
> +
> +-static void verify_event(int group, struct fanotify_event_metadata *event,
> +- uint32_t expect)
> ++static void verify_event(int group, struct fanotify_event_metadata *event)
> + {
> +- if (event->mask != expect) {
> ++ if (event->mask != FAN_MODIFY) {
> + tst_res(TFAIL, "group %d got event: mask %llx (expected %llx) "
> + "pid=%u fd=%d", group, (unsigned long long)event->mask,
> +- (unsigned long long)expect,
> ++ (unsigned long long)FAN_MODIFY,
> + (unsigned)event->pid, event->fd);
> + } else if (event->pid != getpid()) {
> + tst_res(TFAIL, "group %d got event: mask %llx pid=%u "
> +@@ -139,44 +111,26 @@ static void verify_event(int group, struct fanotify_event_metadata *event,
> + (unsigned long long)event->mask, (unsigned)event->pid,
> + (unsigned)getpid(), event->fd);
> + } else {
> +- int len;
> +- sprintf(symlnk, "/proc/self/fd/%d", event->fd);
> +- len = readlink(symlnk, fdpath, sizeof(fdpath));
> +- if (len < 0)
> +- len = 0;
> +- fdpath[len] = 0;
> +- tst_res(TPASS, "group %d got event: mask %llx pid=%u fd=%d path=%s",
> ++ tst_res(TPASS, "group %d got event: mask %llx pid=%u fd=%d",
> + group, (unsigned long long)event->mask,
> +- (unsigned)event->pid, event->fd, fdpath);
> ++ (unsigned)event->pid, event->fd);
> + }
> + }
> +
> +-static void test_fanotify(unsigned int n)
> ++void test01(void)
> + {
> +- int ret, dirfd;
> ++ int ret;
> + unsigned int i;
> +- struct fanotify_event_metadata *event, *ev;
> +- struct tcase *tc = &tcases[n];
> +-
> +- tst_res(TINFO, "Test #%d: %s", n, tc->tname);
> ++ struct fanotify_event_metadata *event;
> +
> +- create_fanotify_groups(tc->ondir);
> ++ create_fanotify_groups();
> +
> + /*
> + * generate MODIFY event and no FAN_CLOSE_NOWRITE event.
> + */
> + SAFE_FILE_PRINTF(fname, "1");
> +- /*
> +- * generate FAN_CLOSE_NOWRITE event on a child subdir.
> +- */
> +- dirfd = SAFE_OPEN(DIR_NAME, O_RDONLY);
> +- if (dirfd >= 0)
> +- SAFE_CLOSE(dirfd);
> +
> +- /*
> +- * First verify the first group got the file MODIFY event and got just
> +- * one FAN_CLOSE_NOWRITE event.
> +- */
> ++ /* First verify the first group got the MODIFY event */
> + ret = read(fd_notify[0], event_buf, EVENT_BUF_LEN);
> + if (ret < 0) {
> + if (errno == EAGAIN) {
> +@@ -186,37 +140,28 @@ static void test_fanotify(unsigned int n)
> + "reading fanotify events failed");
> + }
> + }
> +- if (ret < tc->nevents * (int)FAN_EVENT_METADATA_LEN) {
> ++ if (ret < (int)FAN_EVENT_METADATA_LEN) {
> + tst_brk(TBROK,
> +- "short read when reading fanotify events (%d < %d)",
> +- ret, tc->nevents * (int)FAN_EVENT_METADATA_LEN);
> ++ "short read when reading fanotify "
> ++ "events (%d < %d)", ret,
> ++ (int)EVENT_BUF_LEN);
> + }
> + event = (struct fanotify_event_metadata *)event_buf;
> +- verify_event(0, event, FAN_MODIFY);
> +- if (tc->ondir)
> +- verify_event(0, event + 1, FAN_CLOSE_NOWRITE);
> +- if (ret > tc->nevents * (int)FAN_EVENT_METADATA_LEN) {
> +- tst_res(TFAIL,
> +- "first group got more than %d events (%d > %d)",
> +- tc->nevents, ret,
> +- tc->nevents * (int)FAN_EVENT_METADATA_LEN);
> +- }
> +- /* Close all file descriptors of read events */
> +- for (ev = event; ret >= (int)FAN_EVENT_METADATA_LEN; ev++) {
> +- if (ev->fd != FAN_NOFD)
> +- SAFE_CLOSE(ev->fd);
> +- ret -= (int)FAN_EVENT_METADATA_LEN;
> ++ if (ret > (int)event->event_len) {
> ++ tst_res(TFAIL, "first group got more than one "
> ++ "event (%d > %d)", ret,
> ++ event->event_len);
> ++ } else {
> ++ verify_event(0, event);
> + }
> ++ if (event->fd != FAN_NOFD)
> ++ SAFE_CLOSE(event->fd);
> +
> +- /*
> +- * Then verify the rest of the groups did not get the MODIFY event and
> +- * did not get the FAN_CLOSE_NOWRITE event on subdir.
> +- */
> ++ /* Then verify the rest of the groups did not get the MODIFY event */
> + for (i = 1; i < NUM_GROUPS; i++) {
> +- ret = read(fd_notify[i], event_buf, FAN_EVENT_METADATA_LEN);
> ++ ret = read(fd_notify[i], event_buf, EVENT_BUF_LEN);
> + if (ret > 0) {
> + tst_res(TFAIL, "group %d got event", i);
> +- verify_event(i, event, FAN_CLOSE_NOWRITE);
> + if (event->fd != FAN_NOFD)
> + SAFE_CLOSE(event->fd);
> + continue;
> +@@ -242,7 +187,6 @@ static void setup(void)
> + SAFE_MOUNT(MOUNT_NAME, MOUNT_NAME, "none", MS_BIND, NULL);
> + mount_created = 1;
> + SAFE_CHDIR(MOUNT_NAME);
> +- SAFE_MKDIR(DIR_NAME, 0755);
> +
> + sprintf(fname, "tfile_%d", getpid());
> + SAFE_FILE_PRINTF(fname, "1");
> +@@ -259,8 +203,7 @@ static void cleanup(void)
> + }
> +
> + static struct tst_test test = {
> +- .test = test_fanotify,
> +- .tcnt = ARRAY_SIZE(tcases),
> ++ .test_all = test01,
> + .setup = setup,
> + .cleanup = cleanup,
> + .needs_tmpdir = 1,
> +--
> +2.17.1
> +
> diff --git a/ubuntu_ltp_syscalls/ubuntu_ltp_syscalls.py b/ubuntu_ltp_syscalls/ubuntu_ltp_syscalls.py
> index bee157e7..469214de 100644
> --- a/ubuntu_ltp_syscalls/ubuntu_ltp_syscalls.py
> +++ b/ubuntu_ltp_syscalls/ubuntu_ltp_syscalls.py
> @@ -8,6 +8,12 @@ import yaml
> from autotest.client import test, utils
> from autotest.client.shared import error
>
> +try:
> + from packaging.version import parse
> +except ImportError:
> + # Compatibility fix for release < xenial
> + from distutils.version import StrictVersion
> +
> class ubuntu_ltp_syscalls(test.test):
> version = 1
>
> @@ -70,6 +76,17 @@ class ubuntu_ltp_syscalls(test.test):
> os.chdir(os.path.join(self.srcdir, 'ltp'))
> print("Patching utimensat_tests for Xenial...")
> utils.system('patch -N -p1 < %s/0001-utimensat_tests-fix-for-xenial.patch' % self.bindir)
> + # Disable fanotify09 test case #2 for kernels older than 4.15
> + apply_patch = False
> + try:
> + if parse(self.kernel) < parse("4.15.0"):
> + apply_patch = True
> + except NameError:
> + if StrictVersion(self.kernel) < StrictVersion("4.15.0"):
> + apply_patch = True
> + if apply_patch:
> + print("Patching fanotify09 for kernels older than 4.15...")
> + utils.system('patch -N -p1 < %s/0001-Revert-changes-for-fanotify09-test-case-2.patch' % self.bindir)
> utils.make('autotools')
> utils.configure()
> try:
> @@ -80,19 +97,14 @@ class ubuntu_ltp_syscalls(test.test):
> utils.make('install')
>
> def testcase_blacklist(self):
> - try:
> - from packaging.version import parse
> - except ImportError:
> - # Compatibility fix for release < xenial
> - from distutils.version import StrictVersion
> _blacklist = []
> fn = os.path.join(self.bindir, 'testcase-blacklist.yaml')
> with open(fn, 'r') as f:
> db = yaml.load(f)
> if self.flavour in db['flavour']:
> - _blacklist += list(db['flavour'][self.flavour].keys())
> + _blacklist += list(db['flavour'][self.flavour].keys())
> if self.flavour + '-' + self.series in db['flavour-series']:
> - _blacklist += list(db['flavour-series'][self.flavour + '-' + self.series].keys())
> + _blacklist += list(db['flavour-series'][self.flavour + '-' + self.series].keys())
> try:
> current_version = parse(self.kernel)
> for _kernel in db['kernel']:
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20190926/161998eb/attachment-0001.sig>
More information about the kernel-team
mailing list