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