[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