1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2014 SUSE. All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2018 CTERA Networks. All Rights Reserved.
5*49cdfc7eSAndroid Build Coastguard Worker *
6*49cdfc7eSAndroid Build Coastguard Worker * Started by Jan Kara <[email protected]>
7*49cdfc7eSAndroid Build Coastguard Worker * Forked from fanotify06.c by Amir Goldstein <[email protected]>
8*49cdfc7eSAndroid Build Coastguard Worker */
9*49cdfc7eSAndroid Build Coastguard Worker
10*49cdfc7eSAndroid Build Coastguard Worker /*\
11*49cdfc7eSAndroid Build Coastguard Worker * [Description]
12*49cdfc7eSAndroid Build Coastguard Worker * Check that fanotify properly merges ignore mask of a mount mark
13*49cdfc7eSAndroid Build Coastguard Worker * with a mask of an inode mark on the same group. Unlike the
14*49cdfc7eSAndroid Build Coastguard Worker * prototype test fanotify06, do not use FAN_MODIFY event for the
15*49cdfc7eSAndroid Build Coastguard Worker * test mask, because it hides the bug.
16*49cdfc7eSAndroid Build Coastguard Worker */
17*49cdfc7eSAndroid Build Coastguard Worker
18*49cdfc7eSAndroid Build Coastguard Worker /*
19*49cdfc7eSAndroid Build Coastguard Worker * This is a regression test for commit:
20*49cdfc7eSAndroid Build Coastguard Worker *
21*49cdfc7eSAndroid Build Coastguard Worker * 9bdda4e9cf2d fsnotify: fix ignore mask logic in fsnotify()
22*49cdfc7eSAndroid Build Coastguard Worker *
23*49cdfc7eSAndroid Build Coastguard Worker * Test case #16 is a regression test for commit:
24*49cdfc7eSAndroid Build Coastguard Worker *
25*49cdfc7eSAndroid Build Coastguard Worker * 2f02fd3fa13e fanotify: fix ignore mask logic for events on child...
26*49cdfc7eSAndroid Build Coastguard Worker *
27*49cdfc7eSAndroid Build Coastguard Worker * Test cases with 'ignored_onchild' are regression tests for commit
28*49cdfc7eSAndroid Build Coastguard Worker * (from v5.9, unlikely to be backported thus not in .tags):
29*49cdfc7eSAndroid Build Coastguard Worker *
30*49cdfc7eSAndroid Build Coastguard Worker * 497b0c5a7c06 fsnotify: send event to parent and child with single...
31*49cdfc7eSAndroid Build Coastguard Worker */
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
34*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
35*49cdfc7eSAndroid Build Coastguard Worker
36*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
37*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
38*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
39*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
40*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
43*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
44*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
45*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
46*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_stdio.h"
47*49cdfc7eSAndroid Build Coastguard Worker
48*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_SYS_FANOTIFY_H
49*49cdfc7eSAndroid Build Coastguard Worker #include "fanotify.h"
50*49cdfc7eSAndroid Build Coastguard Worker
51*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_MAX 1024
52*49cdfc7eSAndroid Build Coastguard Worker /* size of the event structure, not counting name */
53*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_SIZE (sizeof(struct fanotify_event_metadata))
54*49cdfc7eSAndroid Build Coastguard Worker /* reasonable guess as to size of 1024 events */
55*49cdfc7eSAndroid Build Coastguard Worker #define EVENT_BUF_LEN (EVENT_MAX * EVENT_SIZE)
56*49cdfc7eSAndroid Build Coastguard Worker
57*49cdfc7eSAndroid Build Coastguard Worker static unsigned int fanotify_class[] = {
58*49cdfc7eSAndroid Build Coastguard Worker FAN_CLASS_PRE_CONTENT,
59*49cdfc7eSAndroid Build Coastguard Worker FAN_CLASS_CONTENT,
60*49cdfc7eSAndroid Build Coastguard Worker FAN_CLASS_NOTIF,
61*49cdfc7eSAndroid Build Coastguard Worker /* Reporting dfid+name+fid merges events similar to reporting fd */
62*49cdfc7eSAndroid Build Coastguard Worker FAN_REPORT_DFID_NAME_FID,
63*49cdfc7eSAndroid Build Coastguard Worker };
64*49cdfc7eSAndroid Build Coastguard Worker #define NUM_CLASSES ARRAY_SIZE(fanotify_class)
65*49cdfc7eSAndroid Build Coastguard Worker #define NUM_PRIORITIES 3
66*49cdfc7eSAndroid Build Coastguard Worker
67*49cdfc7eSAndroid Build Coastguard Worker #define GROUPS_PER_PRIO 3
68*49cdfc7eSAndroid Build Coastguard Worker
69*49cdfc7eSAndroid Build Coastguard Worker static int fd_notify[NUM_CLASSES][GROUPS_PER_PRIO];
70*49cdfc7eSAndroid Build Coastguard Worker static int fd_syncfs;
71*49cdfc7eSAndroid Build Coastguard Worker
72*49cdfc7eSAndroid Build Coastguard Worker static char event_buf[EVENT_BUF_LEN];
73*49cdfc7eSAndroid Build Coastguard Worker static int event_buf_pos, event_buf_len;
74*49cdfc7eSAndroid Build Coastguard Worker static int exec_events_unsupported;
75*49cdfc7eSAndroid Build Coastguard Worker static int fan_report_dfid_unsupported;
76*49cdfc7eSAndroid Build Coastguard Worker static int filesystem_mark_unsupported;
77*49cdfc7eSAndroid Build Coastguard Worker static int evictable_mark_unsupported;
78*49cdfc7eSAndroid Build Coastguard Worker static int ignore_mark_unsupported;
79*49cdfc7eSAndroid Build Coastguard Worker
80*49cdfc7eSAndroid Build Coastguard Worker #define MOUNT_PATH "fs_mnt"
81*49cdfc7eSAndroid Build Coastguard Worker #define MNT2_PATH "mntpoint"
82*49cdfc7eSAndroid Build Coastguard Worker #define DIR_NAME "testdir"
83*49cdfc7eSAndroid Build Coastguard Worker #define FILE_NAME "testfile"
84*49cdfc7eSAndroid Build Coastguard Worker #define FILE2_NAME "testfile2"
85*49cdfc7eSAndroid Build Coastguard Worker #define SUBDIR_NAME "testdir2"
86*49cdfc7eSAndroid Build Coastguard Worker #define TEST_APP "fanotify_child"
87*49cdfc7eSAndroid Build Coastguard Worker #define TEST_APP2 "fanotify_child2"
88*49cdfc7eSAndroid Build Coastguard Worker #define DIR_PATH MOUNT_PATH"/"DIR_NAME
89*49cdfc7eSAndroid Build Coastguard Worker #define DIR_PATH_MULTI DIR_PATH"%d"
90*49cdfc7eSAndroid Build Coastguard Worker #define FILE_PATH DIR_PATH"/"FILE_NAME
91*49cdfc7eSAndroid Build Coastguard Worker #define FILE_PATH_MULTI FILE_PATH"%d"
92*49cdfc7eSAndroid Build Coastguard Worker #define FILE_PATH_MULTIDIR DIR_PATH_MULTI"/"FILE_NAME
93*49cdfc7eSAndroid Build Coastguard Worker #define FILE2_PATH DIR_PATH"/"FILE2_NAME
94*49cdfc7eSAndroid Build Coastguard Worker #define SUBDIR_PATH DIR_PATH"/"SUBDIR_NAME
95*49cdfc7eSAndroid Build Coastguard Worker #define FILE_EXEC_PATH MOUNT_PATH"/"TEST_APP
96*49cdfc7eSAndroid Build Coastguard Worker #define FILE2_EXEC_PATH MOUNT_PATH"/"TEST_APP2
97*49cdfc7eSAndroid Build Coastguard Worker #define DIR_MNT2 MNT2_PATH"/"DIR_NAME
98*49cdfc7eSAndroid Build Coastguard Worker #define FILE_MNT2 DIR_MNT2"/"FILE_NAME
99*49cdfc7eSAndroid Build Coastguard Worker #define FILE2_MNT2 DIR_MNT2"/"FILE2_NAME
100*49cdfc7eSAndroid Build Coastguard Worker #define FILE_EXEC_PATH2 MNT2_PATH"/"TEST_APP
101*49cdfc7eSAndroid Build Coastguard Worker #define FILE2_EXEC_PATH2 MNT2_PATH"/"TEST_APP2
102*49cdfc7eSAndroid Build Coastguard Worker
103*49cdfc7eSAndroid Build Coastguard Worker #define DROP_CACHES_FILE "/proc/sys/vm/drop_caches"
104*49cdfc7eSAndroid Build Coastguard Worker #define CACHE_PRESSURE_FILE "/proc/sys/vm/vfs_cache_pressure"
105*49cdfc7eSAndroid Build Coastguard Worker
106*49cdfc7eSAndroid Build Coastguard Worker static int old_cache_pressure;
107*49cdfc7eSAndroid Build Coastguard Worker static pid_t child_pid;
108*49cdfc7eSAndroid Build Coastguard Worker static int bind_mount_created;
109*49cdfc7eSAndroid Build Coastguard Worker static unsigned int num_classes = NUM_CLASSES;
110*49cdfc7eSAndroid Build Coastguard Worker static int max_file_multi;
111*49cdfc7eSAndroid Build Coastguard Worker
112*49cdfc7eSAndroid Build Coastguard Worker enum {
113*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_INODE,
114*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_PARENT,
115*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_SUBDIR,
116*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_MOUNT,
117*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_FILESYSTEM,
118*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_EVICTABLE,
119*49cdfc7eSAndroid Build Coastguard Worker };
120*49cdfc7eSAndroid Build Coastguard Worker
121*49cdfc7eSAndroid Build Coastguard Worker static struct fanotify_mark_type fanotify_mark_types[] = {
122*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(INODE),
123*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(PARENT),
124*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(SUBDIR),
125*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(MOUNT),
126*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(FILESYSTEM),
127*49cdfc7eSAndroid Build Coastguard Worker INIT_FANOTIFY_MARK_TYPE(EVICTABLE),
128*49cdfc7eSAndroid Build Coastguard Worker };
129*49cdfc7eSAndroid Build Coastguard Worker
130*49cdfc7eSAndroid Build Coastguard Worker static struct tcase {
131*49cdfc7eSAndroid Build Coastguard Worker const char *tname;
132*49cdfc7eSAndroid Build Coastguard Worker int mark_path_cnt;
133*49cdfc7eSAndroid Build Coastguard Worker const char *mark_path_fmt;
134*49cdfc7eSAndroid Build Coastguard Worker int mark_type;
135*49cdfc7eSAndroid Build Coastguard Worker int ignore_path_cnt;
136*49cdfc7eSAndroid Build Coastguard Worker const char *ignore_path_fmt;
137*49cdfc7eSAndroid Build Coastguard Worker int ignore_mark_type;
138*49cdfc7eSAndroid Build Coastguard Worker unsigned int ignored_flags;
139*49cdfc7eSAndroid Build Coastguard Worker int event_path_cnt;
140*49cdfc7eSAndroid Build Coastguard Worker const char *event_path_fmt;
141*49cdfc7eSAndroid Build Coastguard Worker unsigned long long expected_mask_with_ignore;
142*49cdfc7eSAndroid Build Coastguard Worker unsigned long long expected_mask_without_ignore;
143*49cdfc7eSAndroid Build Coastguard Worker } tcases[] = {
144*49cdfc7eSAndroid Build Coastguard Worker {
145*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore mount events created on a specific file",
146*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
147*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
148*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_MNT2,
149*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
150*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
151*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
152*49cdfc7eSAndroid Build Coastguard Worker },
153*49cdfc7eSAndroid Build Coastguard Worker {
154*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore exec mount events created on a specific file",
155*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
156*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
157*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_EXEC_PATH2,
158*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
159*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH,
160*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN_EXEC,
161*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
162*49cdfc7eSAndroid Build Coastguard Worker },
163*49cdfc7eSAndroid Build Coastguard Worker {
164*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore mount events created on another file",
165*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
166*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
167*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_PATH,
168*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
169*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE2_PATH,
170*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
171*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
172*49cdfc7eSAndroid Build Coastguard Worker },
173*49cdfc7eSAndroid Build Coastguard Worker {
174*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore exec mount events created on another file",
175*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
176*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
177*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_EXEC_PATH,
178*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
179*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE2_EXEC_PATH,
180*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_OPEN_EXEC,
181*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
182*49cdfc7eSAndroid Build Coastguard Worker },
183*49cdfc7eSAndroid Build Coastguard Worker {
184*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore inode events created on a specific mount point",
185*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
186*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
187*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
188*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
189*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_MNT2,
190*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
191*49cdfc7eSAndroid Build Coastguard Worker },
192*49cdfc7eSAndroid Build Coastguard Worker {
193*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore exec inode events created on a specific mount point",
194*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_EXEC_PATH,
195*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
196*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
197*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
198*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH2,
199*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN_EXEC,
200*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
201*49cdfc7eSAndroid Build Coastguard Worker },
202*49cdfc7eSAndroid Build Coastguard Worker {
203*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore inode events created on another mount point",
204*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_MNT2,
205*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
206*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
207*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
208*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
209*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
210*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
211*49cdfc7eSAndroid Build Coastguard Worker },
212*49cdfc7eSAndroid Build Coastguard Worker {
213*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore exec inode events created on another mount point",
214*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_EXEC_PATH2,
215*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
216*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
217*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
218*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH,
219*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_OPEN_EXEC,
220*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
221*49cdfc7eSAndroid Build Coastguard Worker },
222*49cdfc7eSAndroid Build Coastguard Worker {
223*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore fs events created on a specific file",
224*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
225*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
226*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_PATH,
227*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
228*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
229*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
230*49cdfc7eSAndroid Build Coastguard Worker },
231*49cdfc7eSAndroid Build Coastguard Worker {
232*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore exec fs events created on a specific file",
233*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
234*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
235*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_EXEC_PATH,
236*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
237*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH,
238*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN_EXEC,
239*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
240*49cdfc7eSAndroid Build Coastguard Worker },
241*49cdfc7eSAndroid Build Coastguard Worker {
242*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore mount events created on another file",
243*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
244*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
245*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_PATH,
246*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
247*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE2_PATH,
248*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
249*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
250*49cdfc7eSAndroid Build Coastguard Worker },
251*49cdfc7eSAndroid Build Coastguard Worker {
252*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore exec mount events created on another file",
253*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
254*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
255*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_EXEC_PATH,
256*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_INODE,
257*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE2_EXEC_PATH,
258*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_OPEN_EXEC,
259*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
260*49cdfc7eSAndroid Build Coastguard Worker },
261*49cdfc7eSAndroid Build Coastguard Worker {
262*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore fs events created on a specific mount point",
263*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
264*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
265*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
266*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
267*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_MNT2,
268*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
269*49cdfc7eSAndroid Build Coastguard Worker },
270*49cdfc7eSAndroid Build Coastguard Worker {
271*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore exec fs events created on a specific mount point",
272*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
273*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
274*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
275*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
276*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH2,
277*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN_EXEC,
278*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
279*49cdfc7eSAndroid Build Coastguard Worker },
280*49cdfc7eSAndroid Build Coastguard Worker {
281*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore fs events created on another mount point",
282*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
283*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
284*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
285*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
286*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
287*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
288*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
289*49cdfc7eSAndroid Build Coastguard Worker },
290*49cdfc7eSAndroid Build Coastguard Worker {
291*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore exec fs events created on another mount point",
292*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
293*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
294*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MNT2_PATH,
295*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
296*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH,
297*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_OPEN_EXEC,
298*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
299*49cdfc7eSAndroid Build Coastguard Worker },
300*49cdfc7eSAndroid Build Coastguard Worker {
301*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore child exec events created on a specific mount point",
302*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
303*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_PARENT,
304*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = MOUNT_PATH,
305*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_MOUNT,
306*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_EXEC_PATH,
307*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN_EXEC,
308*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_OPEN_EXEC
309*49cdfc7eSAndroid Build Coastguard Worker },
310*49cdfc7eSAndroid Build Coastguard Worker {
311*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore events on children of directory created on a specific file",
312*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = DIR_PATH,
313*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_PARENT,
314*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
315*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
316*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
317*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
318*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
319*49cdfc7eSAndroid Build Coastguard Worker },
320*49cdfc7eSAndroid Build Coastguard Worker {
321*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore events on file created inside a parent watching children",
322*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
323*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
324*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
325*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
326*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
327*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
328*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
329*49cdfc7eSAndroid Build Coastguard Worker },
330*49cdfc7eSAndroid Build Coastguard Worker {
331*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore events on file created inside a parent not watching children",
332*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
333*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_INODE,
334*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
335*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
336*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
337*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
338*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
339*49cdfc7eSAndroid Build Coastguard Worker },
340*49cdfc7eSAndroid Build Coastguard Worker {
341*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore mount events created inside a parent watching children",
342*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
343*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
344*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
345*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
346*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
347*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
348*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
349*49cdfc7eSAndroid Build Coastguard Worker },
350*49cdfc7eSAndroid Build Coastguard Worker {
351*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore mount events created inside a parent not watching children",
352*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
353*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
354*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
355*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
356*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
357*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
358*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
359*49cdfc7eSAndroid Build Coastguard Worker },
360*49cdfc7eSAndroid Build Coastguard Worker {
361*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore fs events created inside a parent watching children",
362*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
363*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
364*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
365*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
366*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
367*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
368*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
369*49cdfc7eSAndroid Build Coastguard Worker },
370*49cdfc7eSAndroid Build Coastguard Worker {
371*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore fs events created inside a parent not watching children",
372*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = FILE_PATH,
373*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
374*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
375*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
376*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH,
377*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
378*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
379*49cdfc7eSAndroid Build Coastguard Worker },
380*49cdfc7eSAndroid Build Coastguard Worker /* Evictable ignore mark test cases */
381*49cdfc7eSAndroid Build Coastguard Worker {
382*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore mount events created on file with evicted ignore mark",
383*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
384*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
385*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_cnt = 16,
386*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_PATH_MULTI,
387*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_EVICTABLE,
388*49cdfc7eSAndroid Build Coastguard Worker .event_path_cnt = 16,
389*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH_MULTI,
390*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
391*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
392*49cdfc7eSAndroid Build Coastguard Worker },
393*49cdfc7eSAndroid Build Coastguard Worker {
394*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore fs events created on a file with evicted ignore mark",
395*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
396*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
397*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_cnt = 16,
398*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = FILE_PATH_MULTI,
399*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_EVICTABLE,
400*49cdfc7eSAndroid Build Coastguard Worker .event_path_cnt = 16,
401*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH_MULTI,
402*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
403*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
404*49cdfc7eSAndroid Build Coastguard Worker },
405*49cdfc7eSAndroid Build Coastguard Worker {
406*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore mount events created inside a parent with evicted ignore mark",
407*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
408*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_MOUNT,
409*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_cnt = 16,
410*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH_MULTI,
411*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_EVICTABLE,
412*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
413*49cdfc7eSAndroid Build Coastguard Worker .event_path_cnt = 16,
414*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH_MULTIDIR,
415*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
416*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
417*49cdfc7eSAndroid Build Coastguard Worker },
418*49cdfc7eSAndroid Build Coastguard Worker {
419*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore fs events created inside a parent with evicted ignore mark",
420*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = MOUNT_PATH,
421*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_FILESYSTEM,
422*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_cnt = 16,
423*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH_MULTI,
424*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_EVICTABLE,
425*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
426*49cdfc7eSAndroid Build Coastguard Worker .event_path_cnt = 16,
427*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = FILE_PATH_MULTIDIR,
428*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN,
429*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN
430*49cdfc7eSAndroid Build Coastguard Worker },
431*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE specific test cases */
432*49cdfc7eSAndroid Build Coastguard Worker {
433*49cdfc7eSAndroid Build Coastguard Worker .tname = "ignore events on subdir inside a parent watching subdirs",
434*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = SUBDIR_PATH,
435*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_SUBDIR,
436*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
437*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
438*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD | FAN_ONDIR,
439*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = SUBDIR_PATH,
440*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = 0,
441*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_ONDIR
442*49cdfc7eSAndroid Build Coastguard Worker },
443*49cdfc7eSAndroid Build Coastguard Worker {
444*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore events on subdir inside a parent not watching children",
445*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = SUBDIR_PATH,
446*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_SUBDIR,
447*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
448*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
449*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_ONDIR,
450*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = SUBDIR_PATH,
451*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_ONDIR,
452*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_ONDIR
453*49cdfc7eSAndroid Build Coastguard Worker },
454*49cdfc7eSAndroid Build Coastguard Worker {
455*49cdfc7eSAndroid Build Coastguard Worker .tname = "don't ignore events on subdir inside a parent watching non-dir children",
456*49cdfc7eSAndroid Build Coastguard Worker .mark_path_fmt = SUBDIR_PATH,
457*49cdfc7eSAndroid Build Coastguard Worker .mark_type = FANOTIFY_SUBDIR,
458*49cdfc7eSAndroid Build Coastguard Worker .ignore_path_fmt = DIR_PATH,
459*49cdfc7eSAndroid Build Coastguard Worker .ignore_mark_type = FANOTIFY_PARENT,
460*49cdfc7eSAndroid Build Coastguard Worker .ignored_flags = FAN_EVENT_ON_CHILD,
461*49cdfc7eSAndroid Build Coastguard Worker .event_path_fmt = SUBDIR_PATH,
462*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_with_ignore = FAN_OPEN | FAN_ONDIR,
463*49cdfc7eSAndroid Build Coastguard Worker .expected_mask_without_ignore = FAN_OPEN | FAN_ONDIR
464*49cdfc7eSAndroid Build Coastguard Worker },
465*49cdfc7eSAndroid Build Coastguard Worker };
466*49cdfc7eSAndroid Build Coastguard Worker
format_path_check(char * buf,const char * fmt,int count,int i)467*49cdfc7eSAndroid Build Coastguard Worker static int format_path_check(char *buf, const char *fmt, int count, int i)
468*49cdfc7eSAndroid Build Coastguard Worker {
469*49cdfc7eSAndroid Build Coastguard Worker int limit = count ? : 1;
470*49cdfc7eSAndroid Build Coastguard Worker
471*49cdfc7eSAndroid Build Coastguard Worker if (i >= limit)
472*49cdfc7eSAndroid Build Coastguard Worker return 0;
473*49cdfc7eSAndroid Build Coastguard Worker
474*49cdfc7eSAndroid Build Coastguard Worker if (count)
475*49cdfc7eSAndroid Build Coastguard Worker sprintf(buf, fmt, i);
476*49cdfc7eSAndroid Build Coastguard Worker else
477*49cdfc7eSAndroid Build Coastguard Worker strcpy(buf, fmt);
478*49cdfc7eSAndroid Build Coastguard Worker return 1;
479*49cdfc7eSAndroid Build Coastguard Worker }
480*49cdfc7eSAndroid Build Coastguard Worker
481*49cdfc7eSAndroid Build Coastguard Worker #define foreach_path(tc, buf, pname) \
482*49cdfc7eSAndroid Build Coastguard Worker for (int piter = 0; format_path_check((buf), (tc)->pname##_fmt, \
483*49cdfc7eSAndroid Build Coastguard Worker (tc)->pname##_cnt, piter); piter++)
484*49cdfc7eSAndroid Build Coastguard Worker
show_fanotify_ignore_marks(int fd,int min,int max)485*49cdfc7eSAndroid Build Coastguard Worker static void show_fanotify_ignore_marks(int fd, int min, int max)
486*49cdfc7eSAndroid Build Coastguard Worker {
487*49cdfc7eSAndroid Build Coastguard Worker unsigned int mflags, mask, ignored_mask;
488*49cdfc7eSAndroid Build Coastguard Worker char procfdinfo[100];
489*49cdfc7eSAndroid Build Coastguard Worker char line[BUFSIZ];
490*49cdfc7eSAndroid Build Coastguard Worker int marks = 0;
491*49cdfc7eSAndroid Build Coastguard Worker FILE *f;
492*49cdfc7eSAndroid Build Coastguard Worker
493*49cdfc7eSAndroid Build Coastguard Worker sprintf(procfdinfo, "/proc/%d/fdinfo/%d", (int)getpid(), fd);
494*49cdfc7eSAndroid Build Coastguard Worker f = SAFE_FOPEN(procfdinfo, "r");
495*49cdfc7eSAndroid Build Coastguard Worker while (fgets(line, BUFSIZ, f)) {
496*49cdfc7eSAndroid Build Coastguard Worker if (sscanf(line, "fanotify ino:%*x sdev:%*x mflags: %x mask:%x ignored_mask:%x",
497*49cdfc7eSAndroid Build Coastguard Worker &mflags, &mask, &ignored_mask) == 3) {
498*49cdfc7eSAndroid Build Coastguard Worker if (ignored_mask != 0)
499*49cdfc7eSAndroid Build Coastguard Worker marks++;
500*49cdfc7eSAndroid Build Coastguard Worker }
501*49cdfc7eSAndroid Build Coastguard Worker }
502*49cdfc7eSAndroid Build Coastguard Worker if (marks < min) {
503*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Found %d ignore marks but at least %d expected", marks, min);
504*49cdfc7eSAndroid Build Coastguard Worker return;
505*49cdfc7eSAndroid Build Coastguard Worker }
506*49cdfc7eSAndroid Build Coastguard Worker if (marks > max) {
507*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "Found %d ignore marks but at most %d expected", marks, max);
508*49cdfc7eSAndroid Build Coastguard Worker return;
509*49cdfc7eSAndroid Build Coastguard Worker }
510*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "Found %d ignore marks which is in expected range %d-%d", marks, min, max);
511*49cdfc7eSAndroid Build Coastguard Worker }
512*49cdfc7eSAndroid Build Coastguard Worker
drop_caches(void)513*49cdfc7eSAndroid Build Coastguard Worker static void drop_caches(void)
514*49cdfc7eSAndroid Build Coastguard Worker {
515*49cdfc7eSAndroid Build Coastguard Worker if (syncfs(fd_syncfs) < 0)
516*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "Unexpected error when syncing filesystem");
517*49cdfc7eSAndroid Build Coastguard Worker
518*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(DROP_CACHES_FILE, "3");
519*49cdfc7eSAndroid Build Coastguard Worker }
520*49cdfc7eSAndroid Build Coastguard Worker
create_fanotify_groups(unsigned int n)521*49cdfc7eSAndroid Build Coastguard Worker static int create_fanotify_groups(unsigned int n)
522*49cdfc7eSAndroid Build Coastguard Worker {
523*49cdfc7eSAndroid Build Coastguard Worker struct tcase *tc = &tcases[n];
524*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_mark_type *mark, *ignore_mark;
525*49cdfc7eSAndroid Build Coastguard Worker unsigned int mark_ignored, mask;
526*49cdfc7eSAndroid Build Coastguard Worker unsigned int p, i;
527*49cdfc7eSAndroid Build Coastguard Worker int evictable_ignored = (tc->ignore_mark_type == FANOTIFY_EVICTABLE);
528*49cdfc7eSAndroid Build Coastguard Worker int ignore_mark_type;
529*49cdfc7eSAndroid Build Coastguard Worker int ignored_onchild = tc->ignored_flags & FAN_EVENT_ON_CHILD;
530*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
531*49cdfc7eSAndroid Build Coastguard Worker
532*49cdfc7eSAndroid Build Coastguard Worker mark = &fanotify_mark_types[tc->mark_type];
533*49cdfc7eSAndroid Build Coastguard Worker ignore_mark = &fanotify_mark_types[tc->ignore_mark_type];
534*49cdfc7eSAndroid Build Coastguard Worker ignore_mark_type = ignore_mark->flag & FAN_MARK_TYPES;
535*49cdfc7eSAndroid Build Coastguard Worker
536*49cdfc7eSAndroid Build Coastguard Worker /* Open fd for syncfs before creating groups to avoid the FAN_OPEN event */
537*49cdfc7eSAndroid Build Coastguard Worker fd_syncfs = SAFE_OPEN(MOUNT_PATH, O_RDONLY);
538*49cdfc7eSAndroid Build Coastguard Worker
539*49cdfc7eSAndroid Build Coastguard Worker for (p = 0; p < num_classes; p++) {
540*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < GROUPS_PER_PRIO; i++) {
541*49cdfc7eSAndroid Build Coastguard Worker fd_notify[p][i] = SAFE_FANOTIFY_INIT(fanotify_class[p] |
542*49cdfc7eSAndroid Build Coastguard Worker FAN_NONBLOCK, O_RDONLY);
543*49cdfc7eSAndroid Build Coastguard Worker
544*49cdfc7eSAndroid Build Coastguard Worker /*
545*49cdfc7eSAndroid Build Coastguard Worker * Add mark for each group.
546*49cdfc7eSAndroid Build Coastguard Worker *
547*49cdfc7eSAndroid Build Coastguard Worker * FAN_EVENT_ON_CHILD has no effect on filesystem/mount
548*49cdfc7eSAndroid Build Coastguard Worker * or inode mark on non-directory.
549*49cdfc7eSAndroid Build Coastguard Worker */
550*49cdfc7eSAndroid Build Coastguard Worker foreach_path(tc, path, mark_path)
551*49cdfc7eSAndroid Build Coastguard Worker SAFE_FANOTIFY_MARK(fd_notify[p][i],
552*49cdfc7eSAndroid Build Coastguard Worker FAN_MARK_ADD | mark->flag,
553*49cdfc7eSAndroid Build Coastguard Worker tc->expected_mask_without_ignore |
554*49cdfc7eSAndroid Build Coastguard Worker FAN_EVENT_ON_CHILD | FAN_ONDIR,
555*49cdfc7eSAndroid Build Coastguard Worker AT_FDCWD, path);
556*49cdfc7eSAndroid Build Coastguard Worker
557*49cdfc7eSAndroid Build Coastguard Worker /* Do not add ignore mark for first priority groups */
558*49cdfc7eSAndroid Build Coastguard Worker if (p == 0)
559*49cdfc7eSAndroid Build Coastguard Worker continue;
560*49cdfc7eSAndroid Build Coastguard Worker
561*49cdfc7eSAndroid Build Coastguard Worker /*
562*49cdfc7eSAndroid Build Coastguard Worker * Run tests in two variants:
563*49cdfc7eSAndroid Build Coastguard Worker * 1. Legacy FAN_MARK_IGNORED_MASK
564*49cdfc7eSAndroid Build Coastguard Worker * 2. FAN_MARK_IGNORE
565*49cdfc7eSAndroid Build Coastguard Worker */
566*49cdfc7eSAndroid Build Coastguard Worker mark_ignored = tst_variant ? FAN_MARK_IGNORE_SURV : FAN_MARK_IGNORED_SURV;
567*49cdfc7eSAndroid Build Coastguard Worker mask = FAN_OPEN | tc->ignored_flags;
568*49cdfc7eSAndroid Build Coastguard Worker add_mark:
569*49cdfc7eSAndroid Build Coastguard Worker foreach_path(tc, path, ignore_path)
570*49cdfc7eSAndroid Build Coastguard Worker SAFE_FANOTIFY_MARK(fd_notify[p][i],
571*49cdfc7eSAndroid Build Coastguard Worker FAN_MARK_ADD | ignore_mark->flag | mark_ignored,
572*49cdfc7eSAndroid Build Coastguard Worker mask, AT_FDCWD, path);
573*49cdfc7eSAndroid Build Coastguard Worker
574*49cdfc7eSAndroid Build Coastguard Worker /*
575*49cdfc7eSAndroid Build Coastguard Worker * FAN_MARK_IGNORE respects FAN_EVENT_ON_CHILD flag, but legacy
576*49cdfc7eSAndroid Build Coastguard Worker * FAN_MARK_IGNORED_MASK does not. When using legacy ignore mask,
577*49cdfc7eSAndroid Build Coastguard Worker * if ignored mask is on a parent watching children, we need to
578*49cdfc7eSAndroid Build Coastguard Worker * also set the event and flag FAN_EVENT_ON_CHILD in mark mask.
579*49cdfc7eSAndroid Build Coastguard Worker * This is needed to indicate that parent ignored mask
580*49cdfc7eSAndroid Build Coastguard Worker * should be applied to events on children.
581*49cdfc7eSAndroid Build Coastguard Worker */
582*49cdfc7eSAndroid Build Coastguard Worker if (ignored_onchild && mark_ignored & FAN_MARK_IGNORED_MASK) {
583*49cdfc7eSAndroid Build Coastguard Worker mark_ignored = 0;
584*49cdfc7eSAndroid Build Coastguard Worker goto add_mark;
585*49cdfc7eSAndroid Build Coastguard Worker }
586*49cdfc7eSAndroid Build Coastguard Worker
587*49cdfc7eSAndroid Build Coastguard Worker /*
588*49cdfc7eSAndroid Build Coastguard Worker * When using FAN_MARK_IGNORE, verify that the FAN_EVENT_ON_CHILD
589*49cdfc7eSAndroid Build Coastguard Worker * flag in mark mask does not affect the ignore mask.
590*49cdfc7eSAndroid Build Coastguard Worker *
591*49cdfc7eSAndroid Build Coastguard Worker * If parent does not want to ignore FAN_OPEN events on children,
592*49cdfc7eSAndroid Build Coastguard Worker * set a mark mask to watch FAN_CLOSE_WRITE events on children
593*49cdfc7eSAndroid Build Coastguard Worker * to make sure we do not ignore FAN_OPEN events from children.
594*49cdfc7eSAndroid Build Coastguard Worker *
595*49cdfc7eSAndroid Build Coastguard Worker * If parent wants to ignore FAN_OPEN events on childern,
596*49cdfc7eSAndroid Build Coastguard Worker * set a mark mask to watch FAN_CLOSE events only on parent itself
597*49cdfc7eSAndroid Build Coastguard Worker * to make sure we do not get FAN_CLOSE events from children.
598*49cdfc7eSAndroid Build Coastguard Worker *
599*49cdfc7eSAndroid Build Coastguard Worker * If we had already set the FAN_EVENT_ON_CHILD in the parent
600*49cdfc7eSAndroid Build Coastguard Worker * mark mask (mark_type == FANOTIFY_PARENT), then FAN_CLOSE mask
601*49cdfc7eSAndroid Build Coastguard Worker * will apply also to childern, so we skip this verification.
602*49cdfc7eSAndroid Build Coastguard Worker */
603*49cdfc7eSAndroid Build Coastguard Worker if (mark_ignored & FAN_MARK_IGNORE &&
604*49cdfc7eSAndroid Build Coastguard Worker tc->ignore_mark_type == FANOTIFY_PARENT) {
605*49cdfc7eSAndroid Build Coastguard Worker if (!ignored_onchild)
606*49cdfc7eSAndroid Build Coastguard Worker mask = FAN_CLOSE_WRITE | FAN_EVENT_ON_CHILD | FAN_ONDIR;
607*49cdfc7eSAndroid Build Coastguard Worker else if (tc->mark_type == FANOTIFY_PARENT)
608*49cdfc7eSAndroid Build Coastguard Worker continue;
609*49cdfc7eSAndroid Build Coastguard Worker else if (tc->ignored_flags & FAN_ONDIR)
610*49cdfc7eSAndroid Build Coastguard Worker mask = FAN_CLOSE | ignored_onchild;
611*49cdfc7eSAndroid Build Coastguard Worker else
612*49cdfc7eSAndroid Build Coastguard Worker mask = FAN_CLOSE | FAN_ONDIR;
613*49cdfc7eSAndroid Build Coastguard Worker mark_ignored = 0;
614*49cdfc7eSAndroid Build Coastguard Worker goto add_mark;
615*49cdfc7eSAndroid Build Coastguard Worker }
616*49cdfc7eSAndroid Build Coastguard Worker }
617*49cdfc7eSAndroid Build Coastguard Worker }
618*49cdfc7eSAndroid Build Coastguard Worker
619*49cdfc7eSAndroid Build Coastguard Worker /*
620*49cdfc7eSAndroid Build Coastguard Worker * Verify that first priority groups have no ignore inode marks and that
621*49cdfc7eSAndroid Build Coastguard Worker * drop_caches evicted the evictable ignore marks of other groups.
622*49cdfc7eSAndroid Build Coastguard Worker */
623*49cdfc7eSAndroid Build Coastguard Worker if (evictable_ignored)
624*49cdfc7eSAndroid Build Coastguard Worker drop_caches();
625*49cdfc7eSAndroid Build Coastguard Worker
626*49cdfc7eSAndroid Build Coastguard Worker if (ignore_mark_type == FAN_MARK_INODE) {
627*49cdfc7eSAndroid Build Coastguard Worker for (p = 0; p < num_classes; p++) {
628*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < GROUPS_PER_PRIO; i++) {
629*49cdfc7eSAndroid Build Coastguard Worker if (fd_notify[p][i] > 0) {
630*49cdfc7eSAndroid Build Coastguard Worker int minexp, maxexp;
631*49cdfc7eSAndroid Build Coastguard Worker
632*49cdfc7eSAndroid Build Coastguard Worker if (p == 0) {
633*49cdfc7eSAndroid Build Coastguard Worker minexp = maxexp = 0;
634*49cdfc7eSAndroid Build Coastguard Worker } else if (evictable_ignored) {
635*49cdfc7eSAndroid Build Coastguard Worker minexp = 0;
636*49cdfc7eSAndroid Build Coastguard Worker /*
637*49cdfc7eSAndroid Build Coastguard Worker * Check at least half the
638*49cdfc7eSAndroid Build Coastguard Worker * marks get evicted by reclaim
639*49cdfc7eSAndroid Build Coastguard Worker */
640*49cdfc7eSAndroid Build Coastguard Worker maxexp = tc->ignore_path_cnt / 2;
641*49cdfc7eSAndroid Build Coastguard Worker } else {
642*49cdfc7eSAndroid Build Coastguard Worker minexp = maxexp = tc->ignore_path_cnt ? : 1;
643*49cdfc7eSAndroid Build Coastguard Worker }
644*49cdfc7eSAndroid Build Coastguard Worker show_fanotify_ignore_marks(fd_notify[p][i],
645*49cdfc7eSAndroid Build Coastguard Worker minexp, maxexp);
646*49cdfc7eSAndroid Build Coastguard Worker }
647*49cdfc7eSAndroid Build Coastguard Worker }
648*49cdfc7eSAndroid Build Coastguard Worker }
649*49cdfc7eSAndroid Build Coastguard Worker }
650*49cdfc7eSAndroid Build Coastguard Worker
651*49cdfc7eSAndroid Build Coastguard Worker return 0;
652*49cdfc7eSAndroid Build Coastguard Worker }
653*49cdfc7eSAndroid Build Coastguard Worker
cleanup_fanotify_groups(void)654*49cdfc7eSAndroid Build Coastguard Worker static void cleanup_fanotify_groups(void)
655*49cdfc7eSAndroid Build Coastguard Worker {
656*49cdfc7eSAndroid Build Coastguard Worker unsigned int i, p;
657*49cdfc7eSAndroid Build Coastguard Worker
658*49cdfc7eSAndroid Build Coastguard Worker for (p = 0; p < num_classes; p++) {
659*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < GROUPS_PER_PRIO; i++) {
660*49cdfc7eSAndroid Build Coastguard Worker if (fd_notify[p][i] > 0)
661*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd_notify[p][i]);
662*49cdfc7eSAndroid Build Coastguard Worker }
663*49cdfc7eSAndroid Build Coastguard Worker }
664*49cdfc7eSAndroid Build Coastguard Worker if (fd_syncfs > 0)
665*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd_syncfs);
666*49cdfc7eSAndroid Build Coastguard Worker }
667*49cdfc7eSAndroid Build Coastguard Worker
668*49cdfc7eSAndroid Build Coastguard Worker /* Flush out all pending dirty inodes and destructing marks */
mount_cycle(void)669*49cdfc7eSAndroid Build Coastguard Worker static void mount_cycle(void)
670*49cdfc7eSAndroid Build Coastguard Worker {
671*49cdfc7eSAndroid Build Coastguard Worker if (bind_mount_created)
672*49cdfc7eSAndroid Build Coastguard Worker SAFE_UMOUNT(MNT2_PATH);
673*49cdfc7eSAndroid Build Coastguard Worker SAFE_UMOUNT(MOUNT_PATH);
674*49cdfc7eSAndroid Build Coastguard Worker SAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);
675*49cdfc7eSAndroid Build Coastguard Worker SAFE_MOUNT(MOUNT_PATH, MNT2_PATH, "none", MS_BIND, NULL);
676*49cdfc7eSAndroid Build Coastguard Worker bind_mount_created = 1;
677*49cdfc7eSAndroid Build Coastguard Worker }
678*49cdfc7eSAndroid Build Coastguard Worker
verify_event(int p,int group,struct fanotify_event_metadata * event,unsigned long long expected_mask)679*49cdfc7eSAndroid Build Coastguard Worker static int verify_event(int p, int group, struct fanotify_event_metadata *event,
680*49cdfc7eSAndroid Build Coastguard Worker unsigned long long expected_mask)
681*49cdfc7eSAndroid Build Coastguard Worker {
682*49cdfc7eSAndroid Build Coastguard Worker /* Only FAN_REPORT_FID reports the FAN_ONDIR flag in events on dirs */
683*49cdfc7eSAndroid Build Coastguard Worker if (!(fanotify_class[p] & FAN_REPORT_FID))
684*49cdfc7eSAndroid Build Coastguard Worker expected_mask &= ~FAN_ONDIR;
685*49cdfc7eSAndroid Build Coastguard Worker
686*49cdfc7eSAndroid Build Coastguard Worker if (event->mask != expected_mask) {
687*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "group %d (%x) got event: mask %llx (expected %llx) "
688*49cdfc7eSAndroid Build Coastguard Worker "pid=%u fd=%u", group, fanotify_class[p],
689*49cdfc7eSAndroid Build Coastguard Worker (unsigned long long) event->mask,
690*49cdfc7eSAndroid Build Coastguard Worker (unsigned long long) expected_mask,
691*49cdfc7eSAndroid Build Coastguard Worker (unsigned int)event->pid, event->fd);
692*49cdfc7eSAndroid Build Coastguard Worker return 0;
693*49cdfc7eSAndroid Build Coastguard Worker } else if (event->pid != child_pid) {
694*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "group %d (%x) got event: mask %llx pid=%u "
695*49cdfc7eSAndroid Build Coastguard Worker "(expected %u) fd=%u", group, fanotify_class[p],
696*49cdfc7eSAndroid Build Coastguard Worker (unsigned long long)event->mask, (unsigned int)event->pid,
697*49cdfc7eSAndroid Build Coastguard Worker (unsigned int)child_pid, event->fd);
698*49cdfc7eSAndroid Build Coastguard Worker return 0;
699*49cdfc7eSAndroid Build Coastguard Worker }
700*49cdfc7eSAndroid Build Coastguard Worker return 1;
701*49cdfc7eSAndroid Build Coastguard Worker }
702*49cdfc7eSAndroid Build Coastguard Worker
generate_event(struct tcase * tc,unsigned long long expected_mask)703*49cdfc7eSAndroid Build Coastguard Worker static int generate_event(struct tcase *tc, unsigned long long expected_mask)
704*49cdfc7eSAndroid Build Coastguard Worker {
705*49cdfc7eSAndroid Build Coastguard Worker int fd, status;
706*49cdfc7eSAndroid Build Coastguard Worker
707*49cdfc7eSAndroid Build Coastguard Worker child_pid = SAFE_FORK();
708*49cdfc7eSAndroid Build Coastguard Worker
709*49cdfc7eSAndroid Build Coastguard Worker if (child_pid == 0) {
710*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
711*49cdfc7eSAndroid Build Coastguard Worker
712*49cdfc7eSAndroid Build Coastguard Worker foreach_path(tc, path, event_path) {
713*49cdfc7eSAndroid Build Coastguard Worker if (expected_mask & FAN_OPEN_EXEC) {
714*49cdfc7eSAndroid Build Coastguard Worker SAFE_EXECL(path, path, NULL);
715*49cdfc7eSAndroid Build Coastguard Worker } else {
716*49cdfc7eSAndroid Build Coastguard Worker fd = SAFE_OPEN(path, O_RDONLY);
717*49cdfc7eSAndroid Build Coastguard Worker
718*49cdfc7eSAndroid Build Coastguard Worker if (fd > 0)
719*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fd);
720*49cdfc7eSAndroid Build Coastguard Worker }
721*49cdfc7eSAndroid Build Coastguard Worker }
722*49cdfc7eSAndroid Build Coastguard Worker
723*49cdfc7eSAndroid Build Coastguard Worker exit(0);
724*49cdfc7eSAndroid Build Coastguard Worker }
725*49cdfc7eSAndroid Build Coastguard Worker
726*49cdfc7eSAndroid Build Coastguard Worker SAFE_WAITPID(child_pid, &status, 0);
727*49cdfc7eSAndroid Build Coastguard Worker
728*49cdfc7eSAndroid Build Coastguard Worker if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
729*49cdfc7eSAndroid Build Coastguard Worker return 1;
730*49cdfc7eSAndroid Build Coastguard Worker return 0;
731*49cdfc7eSAndroid Build Coastguard Worker }
732*49cdfc7eSAndroid Build Coastguard Worker
fetch_event(int fd,int * retp)733*49cdfc7eSAndroid Build Coastguard Worker static struct fanotify_event_metadata *fetch_event(int fd, int *retp)
734*49cdfc7eSAndroid Build Coastguard Worker {
735*49cdfc7eSAndroid Build Coastguard Worker int ret;
736*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_event_metadata *event;
737*49cdfc7eSAndroid Build Coastguard Worker
738*49cdfc7eSAndroid Build Coastguard Worker *retp = 0;
739*49cdfc7eSAndroid Build Coastguard Worker if (event_buf_pos >= event_buf_len) {
740*49cdfc7eSAndroid Build Coastguard Worker event_buf_pos = 0;
741*49cdfc7eSAndroid Build Coastguard Worker ret = read(fd, event_buf, EVENT_BUF_LEN);
742*49cdfc7eSAndroid Build Coastguard Worker if (ret < 0) {
743*49cdfc7eSAndroid Build Coastguard Worker if (errno == EAGAIN)
744*49cdfc7eSAndroid Build Coastguard Worker return NULL;
745*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "reading fanotify events failed");
746*49cdfc7eSAndroid Build Coastguard Worker }
747*49cdfc7eSAndroid Build Coastguard Worker event_buf_len = ret;
748*49cdfc7eSAndroid Build Coastguard Worker }
749*49cdfc7eSAndroid Build Coastguard Worker if (event_buf_len - event_buf_pos < (int)FAN_EVENT_METADATA_LEN) {
750*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK,
751*49cdfc7eSAndroid Build Coastguard Worker "too short event when reading fanotify events (%d < %d)",
752*49cdfc7eSAndroid Build Coastguard Worker event_buf_len - event_buf_pos,
753*49cdfc7eSAndroid Build Coastguard Worker (int)FAN_EVENT_METADATA_LEN);
754*49cdfc7eSAndroid Build Coastguard Worker }
755*49cdfc7eSAndroid Build Coastguard Worker event = (struct fanotify_event_metadata *)(event_buf + event_buf_pos);
756*49cdfc7eSAndroid Build Coastguard Worker event_buf_pos += event->event_len;
757*49cdfc7eSAndroid Build Coastguard Worker return event;
758*49cdfc7eSAndroid Build Coastguard Worker }
759*49cdfc7eSAndroid Build Coastguard Worker
test_fanotify(unsigned int n)760*49cdfc7eSAndroid Build Coastguard Worker static void test_fanotify(unsigned int n)
761*49cdfc7eSAndroid Build Coastguard Worker {
762*49cdfc7eSAndroid Build Coastguard Worker struct tcase *tc = &tcases[n];
763*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_mark_type *mark, *ignore_mark;
764*49cdfc7eSAndroid Build Coastguard Worker int ret;
765*49cdfc7eSAndroid Build Coastguard Worker unsigned int p, i;
766*49cdfc7eSAndroid Build Coastguard Worker struct fanotify_event_metadata *event;
767*49cdfc7eSAndroid Build Coastguard Worker int event_count;
768*49cdfc7eSAndroid Build Coastguard Worker
769*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "Test #%d: %s", n, tc->tname);
770*49cdfc7eSAndroid Build Coastguard Worker
771*49cdfc7eSAndroid Build Coastguard Worker if (exec_events_unsupported && tc->expected_mask_with_ignore & FAN_OPEN_EXEC) {
772*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "FAN_OPEN_EXEC not supported in kernel?");
773*49cdfc7eSAndroid Build Coastguard Worker return;
774*49cdfc7eSAndroid Build Coastguard Worker }
775*49cdfc7eSAndroid Build Coastguard Worker
776*49cdfc7eSAndroid Build Coastguard Worker if (filesystem_mark_unsupported && tc->mark_type == FANOTIFY_FILESYSTEM) {
777*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?");
778*49cdfc7eSAndroid Build Coastguard Worker return;
779*49cdfc7eSAndroid Build Coastguard Worker }
780*49cdfc7eSAndroid Build Coastguard Worker
781*49cdfc7eSAndroid Build Coastguard Worker if (evictable_mark_unsupported && tc->ignore_mark_type == FANOTIFY_EVICTABLE) {
782*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "FAN_MARK_EVICTABLE not supported in kernel?");
783*49cdfc7eSAndroid Build Coastguard Worker return;
784*49cdfc7eSAndroid Build Coastguard Worker }
785*49cdfc7eSAndroid Build Coastguard Worker
786*49cdfc7eSAndroid Build Coastguard Worker if (ignore_mark_unsupported && tst_variant) {
787*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "FAN_MARK_IGNORE not supported in kernel?");
788*49cdfc7eSAndroid Build Coastguard Worker return;
789*49cdfc7eSAndroid Build Coastguard Worker }
790*49cdfc7eSAndroid Build Coastguard Worker
791*49cdfc7eSAndroid Build Coastguard Worker if (tc->ignored_flags & FAN_EVENT_ON_CHILD && tst_kvercmp(5, 9, 0) < 0) {
792*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "ignored mask in combination with flag FAN_EVENT_ON_CHILD"
793*49cdfc7eSAndroid Build Coastguard Worker " has undefined behavior on kernel < 5.9");
794*49cdfc7eSAndroid Build Coastguard Worker return;
795*49cdfc7eSAndroid Build Coastguard Worker }
796*49cdfc7eSAndroid Build Coastguard Worker
797*49cdfc7eSAndroid Build Coastguard Worker if (tc->ignored_flags && tc->ignore_mark_type == FANOTIFY_PARENT &&
798*49cdfc7eSAndroid Build Coastguard Worker !tst_variant && tc->mark_type == FANOTIFY_SUBDIR) {
799*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "flags FAN_EVENT_ON_CHILD and FAN_ONDIR do not take effect"
800*49cdfc7eSAndroid Build Coastguard Worker " with legacy FAN_MARK_IGNORED_MASK");
801*49cdfc7eSAndroid Build Coastguard Worker return;
802*49cdfc7eSAndroid Build Coastguard Worker }
803*49cdfc7eSAndroid Build Coastguard Worker
804*49cdfc7eSAndroid Build Coastguard Worker if (create_fanotify_groups(n) != 0)
805*49cdfc7eSAndroid Build Coastguard Worker goto cleanup;
806*49cdfc7eSAndroid Build Coastguard Worker
807*49cdfc7eSAndroid Build Coastguard Worker mark = &fanotify_mark_types[tc->mark_type];
808*49cdfc7eSAndroid Build Coastguard Worker ignore_mark = &fanotify_mark_types[tc->ignore_mark_type];
809*49cdfc7eSAndroid Build Coastguard Worker
810*49cdfc7eSAndroid Build Coastguard Worker /* Generate event in child process */
811*49cdfc7eSAndroid Build Coastguard Worker if (!generate_event(tc, tc->expected_mask_with_ignore))
812*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "Child process terminated incorrectly");
813*49cdfc7eSAndroid Build Coastguard Worker
814*49cdfc7eSAndroid Build Coastguard Worker /* First verify all groups without matching ignore mask got the event */
815*49cdfc7eSAndroid Build Coastguard Worker for (p = 0; p < num_classes; p++) {
816*49cdfc7eSAndroid Build Coastguard Worker if (p > 0 && !tc->expected_mask_with_ignore)
817*49cdfc7eSAndroid Build Coastguard Worker break;
818*49cdfc7eSAndroid Build Coastguard Worker
819*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < GROUPS_PER_PRIO; i++) {
820*49cdfc7eSAndroid Build Coastguard Worker event_count = 0;
821*49cdfc7eSAndroid Build Coastguard Worker event_buf_pos = event_buf_len = 0;
822*49cdfc7eSAndroid Build Coastguard Worker while ((event = fetch_event(fd_notify[p][i], &ret))) {
823*49cdfc7eSAndroid Build Coastguard Worker event_count++;
824*49cdfc7eSAndroid Build Coastguard Worker if (!verify_event(p, i, event, p == 0 ?
825*49cdfc7eSAndroid Build Coastguard Worker tc->expected_mask_without_ignore :
826*49cdfc7eSAndroid Build Coastguard Worker tc->expected_mask_with_ignore))
827*49cdfc7eSAndroid Build Coastguard Worker break;
828*49cdfc7eSAndroid Build Coastguard Worker if (event->fd != FAN_NOFD)
829*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(event->fd);
830*49cdfc7eSAndroid Build Coastguard Worker }
831*49cdfc7eSAndroid Build Coastguard Worker if (ret < 0)
832*49cdfc7eSAndroid Build Coastguard Worker continue;
833*49cdfc7eSAndroid Build Coastguard Worker if (event_count != (tc->event_path_cnt ? : 1)) {
834*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "group %d (%x) with %s "
835*49cdfc7eSAndroid Build Coastguard Worker "got unexpected number of events (%d != %d)",
836*49cdfc7eSAndroid Build Coastguard Worker i, fanotify_class[p], mark->name,
837*49cdfc7eSAndroid Build Coastguard Worker event_count, tc->event_path_cnt);
838*49cdfc7eSAndroid Build Coastguard Worker } else {
839*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "group %d (%x) got %d events: mask %llx pid=%u",
840*49cdfc7eSAndroid Build Coastguard Worker i, fanotify_class[p], event_count,
841*49cdfc7eSAndroid Build Coastguard Worker (unsigned long long)(p == 0 ?
842*49cdfc7eSAndroid Build Coastguard Worker tc->expected_mask_without_ignore :
843*49cdfc7eSAndroid Build Coastguard Worker tc->expected_mask_with_ignore),
844*49cdfc7eSAndroid Build Coastguard Worker (unsigned int)child_pid);
845*49cdfc7eSAndroid Build Coastguard Worker }
846*49cdfc7eSAndroid Build Coastguard Worker }
847*49cdfc7eSAndroid Build Coastguard Worker }
848*49cdfc7eSAndroid Build Coastguard Worker /* Then verify all groups with matching ignore mask did got the event */
849*49cdfc7eSAndroid Build Coastguard Worker for (p = 1; p < num_classes && !tc->expected_mask_with_ignore; p++) {
850*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < GROUPS_PER_PRIO; i++) {
851*49cdfc7eSAndroid Build Coastguard Worker event_count = 0;
852*49cdfc7eSAndroid Build Coastguard Worker event_buf_pos = event_buf_len = 0;
853*49cdfc7eSAndroid Build Coastguard Worker while ((event = fetch_event(fd_notify[p][i], &ret))) {
854*49cdfc7eSAndroid Build Coastguard Worker event_count++;
855*49cdfc7eSAndroid Build Coastguard Worker if (event->fd != FAN_NOFD)
856*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(event->fd);
857*49cdfc7eSAndroid Build Coastguard Worker }
858*49cdfc7eSAndroid Build Coastguard Worker if (ret < 0)
859*49cdfc7eSAndroid Build Coastguard Worker continue;
860*49cdfc7eSAndroid Build Coastguard Worker if (event_count > tc->event_path_cnt / 2)
861*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "group %d (%x) with %s and "
862*49cdfc7eSAndroid Build Coastguard Worker "%s ignore mask got unexpectedly many events (%d > %d)",
863*49cdfc7eSAndroid Build Coastguard Worker i, fanotify_class[p], mark->name,
864*49cdfc7eSAndroid Build Coastguard Worker ignore_mark->name, event_count,
865*49cdfc7eSAndroid Build Coastguard Worker tc->event_path_cnt / 2);
866*49cdfc7eSAndroid Build Coastguard Worker }
867*49cdfc7eSAndroid Build Coastguard Worker }
868*49cdfc7eSAndroid Build Coastguard Worker cleanup:
869*49cdfc7eSAndroid Build Coastguard Worker cleanup_fanotify_groups();
870*49cdfc7eSAndroid Build Coastguard Worker mount_cycle();
871*49cdfc7eSAndroid Build Coastguard Worker }
872*49cdfc7eSAndroid Build Coastguard Worker
setup(void)873*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
874*49cdfc7eSAndroid Build Coastguard Worker {
875*49cdfc7eSAndroid Build Coastguard Worker int i;
876*49cdfc7eSAndroid Build Coastguard Worker
877*49cdfc7eSAndroid Build Coastguard Worker exec_events_unsupported = fanotify_flags_supported_on_fs(FAN_CLASS_CONTENT,
878*49cdfc7eSAndroid Build Coastguard Worker 0, FAN_OPEN_EXEC, MOUNT_PATH);
879*49cdfc7eSAndroid Build Coastguard Worker filesystem_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_FILESYSTEM,
880*49cdfc7eSAndroid Build Coastguard Worker MOUNT_PATH);
881*49cdfc7eSAndroid Build Coastguard Worker evictable_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_EVICTABLE,
882*49cdfc7eSAndroid Build Coastguard Worker MOUNT_PATH);
883*49cdfc7eSAndroid Build Coastguard Worker ignore_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_IGNORE_SURV,
884*49cdfc7eSAndroid Build Coastguard Worker MOUNT_PATH);
885*49cdfc7eSAndroid Build Coastguard Worker fan_report_dfid_unsupported = fanotify_flags_supported_on_fs(FAN_REPORT_DFID_NAME,
886*49cdfc7eSAndroid Build Coastguard Worker FAN_MARK_MOUNT,
887*49cdfc7eSAndroid Build Coastguard Worker FAN_OPEN, MOUNT_PATH);
888*49cdfc7eSAndroid Build Coastguard Worker if (fan_report_dfid_unsupported) {
889*49cdfc7eSAndroid Build Coastguard Worker FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_DFID_NAME, fan_report_dfid_unsupported);
890*49cdfc7eSAndroid Build Coastguard Worker /* Limit tests to legacy priority classes */
891*49cdfc7eSAndroid Build Coastguard Worker num_classes = NUM_PRIORITIES;
892*49cdfc7eSAndroid Build Coastguard Worker }
893*49cdfc7eSAndroid Build Coastguard Worker
894*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(DIR_PATH, 0755);
895*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(SUBDIR_PATH, 0755);
896*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(FILE_PATH, "1");
897*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < (int)ARRAY_SIZE(tcases); i++) {
898*49cdfc7eSAndroid Build Coastguard Worker if (tcases[i].mark_path_cnt > max_file_multi)
899*49cdfc7eSAndroid Build Coastguard Worker max_file_multi = tcases[i].mark_path_cnt;
900*49cdfc7eSAndroid Build Coastguard Worker if (tcases[i].ignore_path_cnt > max_file_multi)
901*49cdfc7eSAndroid Build Coastguard Worker max_file_multi = tcases[i].ignore_path_cnt;
902*49cdfc7eSAndroid Build Coastguard Worker if (tcases[i].event_path_cnt > max_file_multi)
903*49cdfc7eSAndroid Build Coastguard Worker max_file_multi = tcases[i].event_path_cnt;
904*49cdfc7eSAndroid Build Coastguard Worker }
905*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < max_file_multi; i++) {
906*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
907*49cdfc7eSAndroid Build Coastguard Worker
908*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, FILE_PATH_MULTI, i);
909*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(path, "1");
910*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, DIR_PATH_MULTI, i);
911*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(path, 0755);
912*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, FILE_PATH_MULTIDIR, i);
913*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(path, "1");
914*49cdfc7eSAndroid Build Coastguard Worker }
915*49cdfc7eSAndroid Build Coastguard Worker
916*49cdfc7eSAndroid Build Coastguard Worker SAFE_CP(TEST_APP, FILE_EXEC_PATH);
917*49cdfc7eSAndroid Build Coastguard Worker SAFE_CP(TEST_APP, FILE2_EXEC_PATH);
918*49cdfc7eSAndroid Build Coastguard Worker
919*49cdfc7eSAndroid Build Coastguard Worker /* Create another bind mount at another path for generating events */
920*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(MNT2_PATH, 0755);
921*49cdfc7eSAndroid Build Coastguard Worker mount_cycle();
922*49cdfc7eSAndroid Build Coastguard Worker
923*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_SCANF(CACHE_PRESSURE_FILE, "%d", &old_cache_pressure);
924*49cdfc7eSAndroid Build Coastguard Worker /* Set high priority for evicting inodes */
925*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(CACHE_PRESSURE_FILE, "500");
926*49cdfc7eSAndroid Build Coastguard Worker }
927*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)928*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
929*49cdfc7eSAndroid Build Coastguard Worker {
930*49cdfc7eSAndroid Build Coastguard Worker int i;
931*49cdfc7eSAndroid Build Coastguard Worker
932*49cdfc7eSAndroid Build Coastguard Worker cleanup_fanotify_groups();
933*49cdfc7eSAndroid Build Coastguard Worker
934*49cdfc7eSAndroid Build Coastguard Worker if (bind_mount_created)
935*49cdfc7eSAndroid Build Coastguard Worker SAFE_UMOUNT(MNT2_PATH);
936*49cdfc7eSAndroid Build Coastguard Worker
937*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(CACHE_PRESSURE_FILE, "%d", old_cache_pressure);
938*49cdfc7eSAndroid Build Coastguard Worker
939*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < max_file_multi; i++) {
940*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
941*49cdfc7eSAndroid Build Coastguard Worker
942*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, FILE_PATH_MULTIDIR, i);
943*49cdfc7eSAndroid Build Coastguard Worker SAFE_UNLINK(path);
944*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, DIR_PATH_MULTI, i);
945*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(path);
946*49cdfc7eSAndroid Build Coastguard Worker sprintf(path, FILE_PATH_MULTI, i);
947*49cdfc7eSAndroid Build Coastguard Worker SAFE_UNLINK(path);
948*49cdfc7eSAndroid Build Coastguard Worker }
949*49cdfc7eSAndroid Build Coastguard Worker SAFE_UNLINK(FILE_PATH);
950*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(SUBDIR_PATH);
951*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(DIR_PATH);
952*49cdfc7eSAndroid Build Coastguard Worker SAFE_RMDIR(MNT2_PATH);
953*49cdfc7eSAndroid Build Coastguard Worker }
954*49cdfc7eSAndroid Build Coastguard Worker
955*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
956*49cdfc7eSAndroid Build Coastguard Worker .test = test_fanotify,
957*49cdfc7eSAndroid Build Coastguard Worker .tcnt = ARRAY_SIZE(tcases),
958*49cdfc7eSAndroid Build Coastguard Worker .test_variants = 2,
959*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
960*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup,
961*49cdfc7eSAndroid Build Coastguard Worker .mount_device = 1,
962*49cdfc7eSAndroid Build Coastguard Worker .mntpoint = MOUNT_PATH,
963*49cdfc7eSAndroid Build Coastguard Worker .needs_root = 1,
964*49cdfc7eSAndroid Build Coastguard Worker .forks_child = 1,
965*49cdfc7eSAndroid Build Coastguard Worker .resource_files = (const char *const []) {
966*49cdfc7eSAndroid Build Coastguard Worker TEST_APP,
967*49cdfc7eSAndroid Build Coastguard Worker NULL
968*49cdfc7eSAndroid Build Coastguard Worker },
969*49cdfc7eSAndroid Build Coastguard Worker .tags = (const struct tst_tag[]) {
970*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "9bdda4e9cf2d"},
971*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "2f02fd3fa13e"},
972*49cdfc7eSAndroid Build Coastguard Worker {}
973*49cdfc7eSAndroid Build Coastguard Worker }
974*49cdfc7eSAndroid Build Coastguard Worker };
975*49cdfc7eSAndroid Build Coastguard Worker
976*49cdfc7eSAndroid Build Coastguard Worker #else
977*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF("system doesn't have required fanotify support");
978*49cdfc7eSAndroid Build Coastguard Worker #endif
979