1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2013 SUSE. All Rights Reserved. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Started by Jan Kara <jack@suse.cz> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * Check that fanotify work for a file. 11f08c3bdfSopenharmony_ci */ 12f08c3bdfSopenharmony_ci 13f08c3bdfSopenharmony_ci#define _GNU_SOURCE 14f08c3bdfSopenharmony_ci#include "config.h" 15f08c3bdfSopenharmony_ci 16f08c3bdfSopenharmony_ci#include <stdio.h> 17f08c3bdfSopenharmony_ci#include <sys/stat.h> 18f08c3bdfSopenharmony_ci#include <sys/types.h> 19f08c3bdfSopenharmony_ci#include <errno.h> 20f08c3bdfSopenharmony_ci#include <string.h> 21f08c3bdfSopenharmony_ci#include <sys/syscall.h> 22f08c3bdfSopenharmony_ci#include "tst_test.h" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_FANOTIFY_H 25f08c3bdfSopenharmony_ci#include "fanotify.h" 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_ci#define EVENT_MAX 1024 28f08c3bdfSopenharmony_ci/* size of the event structure, not counting name */ 29f08c3bdfSopenharmony_ci#define EVENT_SIZE (sizeof(struct fanotify_event_metadata)) 30f08c3bdfSopenharmony_ci/* reasonable guess as to size of 1024 events */ 31f08c3bdfSopenharmony_ci#define EVENT_BUF_LEN (EVENT_MAX * EVENT_SIZE) 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#define BUF_SIZE 256 34f08c3bdfSopenharmony_ci#define TST_TOTAL 12 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#define MOUNT_PATH "fs_mnt" 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cistatic struct tcase { 39f08c3bdfSopenharmony_ci const char *tname; 40f08c3bdfSopenharmony_ci struct fanotify_mark_type mark; 41f08c3bdfSopenharmony_ci unsigned int init_flags; 42f08c3bdfSopenharmony_ci} tcases[] = { 43f08c3bdfSopenharmony_ci { 44f08c3bdfSopenharmony_ci "inode mark events", 45f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(INODE), 46f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF 47f08c3bdfSopenharmony_ci }, 48f08c3bdfSopenharmony_ci { 49f08c3bdfSopenharmony_ci "mount mark events", 50f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(MOUNT), 51f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF 52f08c3bdfSopenharmony_ci }, 53f08c3bdfSopenharmony_ci { 54f08c3bdfSopenharmony_ci "filesystem mark events", 55f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), 56f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF 57f08c3bdfSopenharmony_ci }, 58f08c3bdfSopenharmony_ci { 59f08c3bdfSopenharmony_ci "inode mark events (FAN_REPORT_FID)", 60f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(INODE), 61f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF|FAN_REPORT_FID 62f08c3bdfSopenharmony_ci }, 63f08c3bdfSopenharmony_ci { 64f08c3bdfSopenharmony_ci "mount mark events (FAN_REPORT_FID)", 65f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(MOUNT), 66f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF|FAN_REPORT_FID 67f08c3bdfSopenharmony_ci }, 68f08c3bdfSopenharmony_ci { 69f08c3bdfSopenharmony_ci "filesystem mark events (FAN_REPORT_FID)", 70f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), 71f08c3bdfSopenharmony_ci FAN_CLASS_NOTIF|FAN_REPORT_FID 72f08c3bdfSopenharmony_ci }, 73f08c3bdfSopenharmony_ci}; 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_cistatic char fname[BUF_SIZE]; 76f08c3bdfSopenharmony_cistatic char buf[BUF_SIZE]; 77f08c3bdfSopenharmony_cistatic int fd_notify; 78f08c3bdfSopenharmony_cistatic int fan_report_fid_unsupported; 79f08c3bdfSopenharmony_cistatic int filesystem_mark_unsupported; 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_cistatic unsigned long long event_set[EVENT_MAX]; 82f08c3bdfSopenharmony_ci 83f08c3bdfSopenharmony_cistatic char event_buf[EVENT_BUF_LEN]; 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_cistatic void test_fanotify(unsigned int n) 86f08c3bdfSopenharmony_ci{ 87f08c3bdfSopenharmony_ci struct tcase *tc = &tcases[n]; 88f08c3bdfSopenharmony_ci struct fanotify_mark_type *mark = &tc->mark; 89f08c3bdfSopenharmony_ci int fd, ret, len, i = 0, test_num = 0; 90f08c3bdfSopenharmony_ci int tst_count = 0; 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci tst_res(TINFO, "Test #%d: %s", n, tc->tname); 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci if (fan_report_fid_unsupported && (tc->init_flags & FAN_REPORT_FID)) { 95f08c3bdfSopenharmony_ci FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_FID, fan_report_fid_unsupported); 96f08c3bdfSopenharmony_ci return; 97f08c3bdfSopenharmony_ci } 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci if (filesystem_mark_unsupported && mark->flag == FAN_MARK_FILESYSTEM) { 100f08c3bdfSopenharmony_ci tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?"); 101f08c3bdfSopenharmony_ci return; 102f08c3bdfSopenharmony_ci } 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci fd_notify = SAFE_FANOTIFY_INIT(tc->init_flags, O_RDONLY); 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD | mark->flag, 107f08c3bdfSopenharmony_ci FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN, AT_FDCWD, fname); 108f08c3bdfSopenharmony_ci 109f08c3bdfSopenharmony_ci /* 110f08c3bdfSopenharmony_ci * generate sequence of events 111f08c3bdfSopenharmony_ci */ 112f08c3bdfSopenharmony_ci fd = SAFE_OPEN(fname, O_RDONLY); 113f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_OPEN; 114f08c3bdfSopenharmony_ci tst_count++; 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci SAFE_READ(0, fd, buf, BUF_SIZE); 117f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_ACCESS; 118f08c3bdfSopenharmony_ci tst_count++; 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 121f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_CLOSE_NOWRITE; 122f08c3bdfSopenharmony_ci tst_count++; 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci /* 125f08c3bdfSopenharmony_ci * Get list of events so far. We get events here to avoid 126f08c3bdfSopenharmony_ci * merging of following events with the previous ones. 127f08c3bdfSopenharmony_ci */ 128f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf, EVENT_BUF_LEN); 129f08c3bdfSopenharmony_ci len = ret; 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700); 132f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_OPEN; 133f08c3bdfSopenharmony_ci tst_count++; 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, fname, strlen(fname)); 136f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_MODIFY; 137f08c3bdfSopenharmony_ci tst_count++; 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 140f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_CLOSE_WRITE; 141f08c3bdfSopenharmony_ci tst_count++; 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci /* 144f08c3bdfSopenharmony_ci * get another list of events 145f08c3bdfSopenharmony_ci */ 146f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf + len, 147f08c3bdfSopenharmony_ci EVENT_BUF_LEN - len); 148f08c3bdfSopenharmony_ci len += ret; 149f08c3bdfSopenharmony_ci 150f08c3bdfSopenharmony_ci /* 151f08c3bdfSopenharmony_ci * Ignore mask testing 152f08c3bdfSopenharmony_ci */ 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_ci /* Ignore access events */ 155f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd_notify, 156f08c3bdfSopenharmony_ci FAN_MARK_ADD | mark->flag | FAN_MARK_IGNORED_MASK, 157f08c3bdfSopenharmony_ci FAN_ACCESS, AT_FDCWD, fname); 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci fd = SAFE_OPEN(fname, O_RDWR); 160f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_OPEN; 161f08c3bdfSopenharmony_ci tst_count++; 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci /* This event should be ignored */ 164f08c3bdfSopenharmony_ci SAFE_READ(0, fd, buf, BUF_SIZE); 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci /* 167f08c3bdfSopenharmony_ci * get another list of events to verify the last one got ignored 168f08c3bdfSopenharmony_ci */ 169f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf + len, 170f08c3bdfSopenharmony_ci EVENT_BUF_LEN - len); 171f08c3bdfSopenharmony_ci len += ret; 172f08c3bdfSopenharmony_ci 173f08c3bdfSopenharmony_ci SAFE_LSEEK(fd, 0, SEEK_SET); 174f08c3bdfSopenharmony_ci /* Generate modify event to clear ignore mask */ 175f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, fname, 1); 176f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_MODIFY; 177f08c3bdfSopenharmony_ci tst_count++; 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ci /* 180f08c3bdfSopenharmony_ci * This event shouldn't be ignored because previous modification 181f08c3bdfSopenharmony_ci * should have removed the ignore mask 182f08c3bdfSopenharmony_ci */ 183f08c3bdfSopenharmony_ci SAFE_READ(0, fd, buf, BUF_SIZE); 184f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_ACCESS; 185f08c3bdfSopenharmony_ci tst_count++; 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 188f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_CLOSE_WRITE; 189f08c3bdfSopenharmony_ci tst_count++; 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci /* Read events to verify previous access was properly generated */ 192f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf + len, 193f08c3bdfSopenharmony_ci EVENT_BUF_LEN - len); 194f08c3bdfSopenharmony_ci len += ret; 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci /* 197f08c3bdfSopenharmony_ci * Now ignore open & close events regardless of file 198f08c3bdfSopenharmony_ci * modifications 199f08c3bdfSopenharmony_ci */ 200f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD | mark->flag | 201f08c3bdfSopenharmony_ci FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY, 202f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname); 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci /* This event should be ignored */ 205f08c3bdfSopenharmony_ci fd = SAFE_OPEN(fname, O_RDWR); 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fd, fname, 1); 208f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_MODIFY; 209f08c3bdfSopenharmony_ci tst_count++; 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci /* This event should be still ignored */ 212f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci /* This event should still be ignored */ 215f08c3bdfSopenharmony_ci fd = SAFE_OPEN(fname, O_RDWR); 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci /* Read events to verify open & close were ignored */ 218f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf + len, 219f08c3bdfSopenharmony_ci EVENT_BUF_LEN - len); 220f08c3bdfSopenharmony_ci len += ret; 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci /* Now remove open and close from ignored mask */ 223f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd_notify, 224f08c3bdfSopenharmony_ci FAN_MARK_REMOVE | mark->flag | FAN_MARK_IGNORED_MASK, 225f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE, AT_FDCWD, fname); 226f08c3bdfSopenharmony_ci 227f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 228f08c3bdfSopenharmony_ci event_set[tst_count] = FAN_CLOSE_WRITE; 229f08c3bdfSopenharmony_ci tst_count++; 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_ci /* Read events to verify close was generated */ 232f08c3bdfSopenharmony_ci ret = SAFE_READ(0, fd_notify, event_buf + len, 233f08c3bdfSopenharmony_ci EVENT_BUF_LEN - len); 234f08c3bdfSopenharmony_ci len += ret; 235f08c3bdfSopenharmony_ci 236f08c3bdfSopenharmony_ci if (TST_TOTAL != tst_count) { 237f08c3bdfSopenharmony_ci tst_brk(TBROK, 238f08c3bdfSopenharmony_ci "TST_TOTAL (%d) and tst_count (%d) are not " 239f08c3bdfSopenharmony_ci "equal", TST_TOTAL, tst_count); 240f08c3bdfSopenharmony_ci } 241f08c3bdfSopenharmony_ci tst_count = 0; 242f08c3bdfSopenharmony_ci 243f08c3bdfSopenharmony_ci /* 244f08c3bdfSopenharmony_ci * check events 245f08c3bdfSopenharmony_ci */ 246f08c3bdfSopenharmony_ci while (i < len) { 247f08c3bdfSopenharmony_ci struct fanotify_event_metadata *event; 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci event = (struct fanotify_event_metadata *)&event_buf[i]; 250f08c3bdfSopenharmony_ci if (test_num >= TST_TOTAL) { 251f08c3bdfSopenharmony_ci tst_res(TFAIL, 252f08c3bdfSopenharmony_ci "got unnecessary event: mask=%llx " 253f08c3bdfSopenharmony_ci "pid=%u fd=%d", 254f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 255f08c3bdfSopenharmony_ci (unsigned int)event->pid, event->fd); 256f08c3bdfSopenharmony_ci } else if (!(event->mask & event_set[test_num])) { 257f08c3bdfSopenharmony_ci tst_res(TFAIL, 258f08c3bdfSopenharmony_ci "got event: mask=%llx (expected %llx) " 259f08c3bdfSopenharmony_ci "pid=%u fd=%d", 260f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 261f08c3bdfSopenharmony_ci event_set[test_num], 262f08c3bdfSopenharmony_ci (unsigned int)event->pid, event->fd); 263f08c3bdfSopenharmony_ci } else if (event->pid != getpid()) { 264f08c3bdfSopenharmony_ci tst_res(TFAIL, 265f08c3bdfSopenharmony_ci "got event: mask=%llx pid=%u " 266f08c3bdfSopenharmony_ci "(expected %u) fd=%d", 267f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 268f08c3bdfSopenharmony_ci (unsigned int)event->pid, 269f08c3bdfSopenharmony_ci (unsigned int)getpid(), 270f08c3bdfSopenharmony_ci event->fd); 271f08c3bdfSopenharmony_ci } else { 272f08c3bdfSopenharmony_ci if (event->fd == -2 || (event->fd == FAN_NOFD && 273f08c3bdfSopenharmony_ci (tc->init_flags & FAN_REPORT_FID))) 274f08c3bdfSopenharmony_ci goto pass; 275f08c3bdfSopenharmony_ci ret = read(event->fd, buf, BUF_SIZE); 276f08c3bdfSopenharmony_ci if (ret != (int)strlen(fname)) { 277f08c3bdfSopenharmony_ci tst_res(TFAIL, 278f08c3bdfSopenharmony_ci "cannot read from returned fd " 279f08c3bdfSopenharmony_ci "of event: mask=%llx pid=%u " 280f08c3bdfSopenharmony_ci "fd=%d ret=%d (errno=%d)", 281f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 282f08c3bdfSopenharmony_ci (unsigned int)event->pid, 283f08c3bdfSopenharmony_ci event->fd, ret, errno); 284f08c3bdfSopenharmony_ci } else if (memcmp(buf, fname, strlen(fname))) { 285f08c3bdfSopenharmony_ci tst_res(TFAIL, 286f08c3bdfSopenharmony_ci "wrong data read from returned fd " 287f08c3bdfSopenharmony_ci "of event: mask=%llx pid=%u " 288f08c3bdfSopenharmony_ci "fd=%d", 289f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 290f08c3bdfSopenharmony_ci (unsigned int)event->pid, 291f08c3bdfSopenharmony_ci event->fd); 292f08c3bdfSopenharmony_ci } else { 293f08c3bdfSopenharmony_cipass: 294f08c3bdfSopenharmony_ci tst_res(TPASS, 295f08c3bdfSopenharmony_ci "got event: mask=%llx pid=%u fd=%d", 296f08c3bdfSopenharmony_ci (unsigned long long)event->mask, 297f08c3bdfSopenharmony_ci (unsigned int)event->pid, event->fd); 298f08c3bdfSopenharmony_ci } 299f08c3bdfSopenharmony_ci } 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci /* 302f08c3bdfSopenharmony_ci * We have verified the data now so close fd and 303f08c3bdfSopenharmony_ci * invalidate it so that we don't check it again 304f08c3bdfSopenharmony_ci * unnecessarily 305f08c3bdfSopenharmony_ci */ 306f08c3bdfSopenharmony_ci if (event->fd >= 0) 307f08c3bdfSopenharmony_ci SAFE_CLOSE(event->fd); 308f08c3bdfSopenharmony_ci event->fd = -2; 309f08c3bdfSopenharmony_ci event->mask &= ~event_set[test_num]; 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci /* No events left in current mask? Go for next event */ 312f08c3bdfSopenharmony_ci if (event->mask == 0) 313f08c3bdfSopenharmony_ci i += event->event_len; 314f08c3bdfSopenharmony_ci 315f08c3bdfSopenharmony_ci test_num++; 316f08c3bdfSopenharmony_ci } 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci for (; test_num < TST_TOTAL; test_num++) { 319f08c3bdfSopenharmony_ci tst_res(TFAIL, "didn't get event: mask=%llx", 320f08c3bdfSopenharmony_ci event_set[test_num]); 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_ci } 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ci /* Remove mark to clear FAN_MARK_IGNORED_SURV_MODIFY */ 325f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_REMOVE | mark->flag, 326f08c3bdfSopenharmony_ci FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN, 327f08c3bdfSopenharmony_ci AT_FDCWD, fname); 328f08c3bdfSopenharmony_ci 329f08c3bdfSopenharmony_ci SAFE_CLOSE(fd_notify); 330f08c3bdfSopenharmony_ci} 331f08c3bdfSopenharmony_ci 332f08c3bdfSopenharmony_cistatic void setup(void) 333f08c3bdfSopenharmony_ci{ 334f08c3bdfSopenharmony_ci int fd; 335f08c3bdfSopenharmony_ci 336f08c3bdfSopenharmony_ci /* Check for kernel fanotify support */ 337f08c3bdfSopenharmony_ci fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); 338f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 339f08c3bdfSopenharmony_ci 340f08c3bdfSopenharmony_ci sprintf(fname, MOUNT_PATH"/tfile_%d", getpid()); 341f08c3bdfSopenharmony_ci SAFE_FILE_PRINTF(fname, "1"); 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ci fan_report_fid_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_FID, fname); 344f08c3bdfSopenharmony_ci filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM); 345f08c3bdfSopenharmony_ci} 346f08c3bdfSopenharmony_ci 347f08c3bdfSopenharmony_cistatic void cleanup(void) 348f08c3bdfSopenharmony_ci{ 349f08c3bdfSopenharmony_ci if (fd_notify > 0) 350f08c3bdfSopenharmony_ci SAFE_CLOSE(fd_notify); 351f08c3bdfSopenharmony_ci} 352f08c3bdfSopenharmony_ci 353f08c3bdfSopenharmony_cistatic struct tst_test test = { 354f08c3bdfSopenharmony_ci .test = test_fanotify, 355f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 356f08c3bdfSopenharmony_ci .setup = setup, 357f08c3bdfSopenharmony_ci .cleanup = cleanup, 358f08c3bdfSopenharmony_ci .needs_root = 1, 359f08c3bdfSopenharmony_ci .mount_device = 1, 360f08c3bdfSopenharmony_ci .mntpoint = MOUNT_PATH, 361f08c3bdfSopenharmony_ci}; 362f08c3bdfSopenharmony_ci 363f08c3bdfSopenharmony_ci#else 364f08c3bdfSopenharmony_ci TST_TEST_TCONF("system doesn't have required fanotify support"); 365f08c3bdfSopenharmony_ci#endif 366