diff mbox series

[ACT] UBUNTU: SAUCE: ubuntu_ltp_syscalls: fix fanotify09 for kernels older than 4.15

Message ID 20190923094458.10293-1-kleber.souza@canonical.com
State New
Headers show
Series [ACT] UBUNTU: SAUCE: ubuntu_ltp_syscalls: fix fanotify09 for kernels older than 4.15 | expand

Commit Message

Kleber Sacilotto de Souza Sept. 23, 2019, 9:44 a.m. UTC
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().

Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@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

Comments

Stefan Bader Sept. 26, 2019, 8:54 a.m. UTC | #1
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@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@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@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']:
>
Kleber Sacilotto de Souza Sept. 26, 2019, 3:15 p.m. UTC | #2
On 26.09.19 10:54, Stefan Bader wrote:
> 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?

The '[ACT]' tag I used as a indicator that it's for the autotest-client tests
repo.

This solution to revert the test case patch is kind of ugly. I'll investigate
further to see if we can make the test itself skip that test case.


Thanks,
Kleber

> 
> -Stefan
> 
>>
>> Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@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@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@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']:
>>
> 
>
Po-Hsu Lin Oct. 9, 2019, 11:25 a.m. UTC | #3
A newer version of the patch from Kleber has been applied to
autotest-client-test:
    https://kernel.ubuntu.com/git/ubuntu/autotest-client-tests.git/commit/?id=4d83ea486a463a89e726715c55e037b479205f0d

Thus I'm NAKing this thread.

Thanks!
Sam
diff mbox series

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@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@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']: