1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Started by Matthew Bobrowski <mbobrowski@mbobrowski.org> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * Validate that the values returned within an event when FAN_REPORT_FID is 11f08c3bdfSopenharmony_ci * specified matches those that are obtained via explicit invocation to system 12f08c3bdfSopenharmony_ci * calls statfs(2) and name_to_handle_at(2). 13f08c3bdfSopenharmony_ci */ 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci/* 16f08c3bdfSopenharmony_ci * This is also regression test for: 17f08c3bdfSopenharmony_ci * c285a2f01d69 ("fanotify: update connector fsid cache on add mark") 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#define _GNU_SOURCE 21f08c3bdfSopenharmony_ci#include "config.h" 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci#include <stdio.h> 24f08c3bdfSopenharmony_ci#include <string.h> 25f08c3bdfSopenharmony_ci#include <sys/statfs.h> 26f08c3bdfSopenharmony_ci#include <sys/types.h> 27f08c3bdfSopenharmony_ci#include <sys/stat.h> 28f08c3bdfSopenharmony_ci#include <sys/mount.h> 29f08c3bdfSopenharmony_ci#include <errno.h> 30f08c3bdfSopenharmony_ci#include <unistd.h> 31f08c3bdfSopenharmony_ci#include "tst_test.h" 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#ifdef HAVE_SYS_FANOTIFY_H 34f08c3bdfSopenharmony_ci#include "fanotify.h" 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#define PATH_LEN 128 37f08c3bdfSopenharmony_ci#define BUF_SIZE 256 38f08c3bdfSopenharmony_ci#define DIR_ONE "dir_one" 39f08c3bdfSopenharmony_ci#define FILE_ONE "file_one" 40f08c3bdfSopenharmony_ci#define FILE_TWO "file_two" 41f08c3bdfSopenharmony_ci#define MOUNT_PATH "tstmnt" 42f08c3bdfSopenharmony_ci#define EVENT_MAX ARRAY_SIZE(objects) 43f08c3bdfSopenharmony_ci#define DIR_PATH_ONE MOUNT_PATH"/"DIR_ONE 44f08c3bdfSopenharmony_ci#define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE 45f08c3bdfSopenharmony_ci#define FILE_PATH_TWO MOUNT_PATH"/"FILE_TWO 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ci#if defined(HAVE_NAME_TO_HANDLE_AT) 48f08c3bdfSopenharmony_cistruct event_t { 49f08c3bdfSopenharmony_ci unsigned long long expected_mask; 50f08c3bdfSopenharmony_ci}; 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_cistatic struct object_t { 53f08c3bdfSopenharmony_ci const char *path; 54f08c3bdfSopenharmony_ci int is_dir; 55f08c3bdfSopenharmony_ci struct fanotify_fid_t fid; 56f08c3bdfSopenharmony_ci} objects[] = { 57f08c3bdfSopenharmony_ci {FILE_PATH_ONE, 0, {}}, 58f08c3bdfSopenharmony_ci {FILE_PATH_TWO, 0, {}}, 59f08c3bdfSopenharmony_ci {DIR_PATH_ONE, 1, {}} 60f08c3bdfSopenharmony_ci}; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic struct test_case_t { 63f08c3bdfSopenharmony_ci struct fanotify_mark_type mark; 64f08c3bdfSopenharmony_ci unsigned long long mask; 65f08c3bdfSopenharmony_ci} test_cases[] = { 66f08c3bdfSopenharmony_ci { 67f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(INODE), 68f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE 69f08c3bdfSopenharmony_ci }, 70f08c3bdfSopenharmony_ci { 71f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(INODE), 72f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR 73f08c3bdfSopenharmony_ci }, 74f08c3bdfSopenharmony_ci { 75f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(MOUNT), 76f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE 77f08c3bdfSopenharmony_ci }, 78f08c3bdfSopenharmony_ci { 79f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(MOUNT), 80f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR 81f08c3bdfSopenharmony_ci }, 82f08c3bdfSopenharmony_ci { 83f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), 84f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE 85f08c3bdfSopenharmony_ci }, 86f08c3bdfSopenharmony_ci { 87f08c3bdfSopenharmony_ci INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), 88f08c3bdfSopenharmony_ci FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci}; 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_cistatic int ovl_mounted; 93f08c3bdfSopenharmony_cistatic int bind_mounted; 94f08c3bdfSopenharmony_cistatic int nofid_fd; 95f08c3bdfSopenharmony_cistatic int fanotify_fd; 96f08c3bdfSopenharmony_cistatic int filesystem_mark_unsupported; 97f08c3bdfSopenharmony_cistatic char events_buf[BUF_SIZE]; 98f08c3bdfSopenharmony_cistatic struct event_t event_set[EVENT_MAX]; 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_cistatic void create_objects(void) 101f08c3bdfSopenharmony_ci{ 102f08c3bdfSopenharmony_ci unsigned int i; 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(objects); i++) { 105f08c3bdfSopenharmony_ci if (objects[i].is_dir) 106f08c3bdfSopenharmony_ci SAFE_MKDIR(objects[i].path, 0755); 107f08c3bdfSopenharmony_ci else 108f08c3bdfSopenharmony_ci SAFE_FILE_PRINTF(objects[i].path, "0"); 109f08c3bdfSopenharmony_ci } 110f08c3bdfSopenharmony_ci} 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_cistatic void get_object_stats(void) 113f08c3bdfSopenharmony_ci{ 114f08c3bdfSopenharmony_ci unsigned int i; 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(objects); i++) 117f08c3bdfSopenharmony_ci fanotify_save_fid(objects[i].path, &objects[i].fid); 118f08c3bdfSopenharmony_ci} 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_cistatic int setup_marks(unsigned int fd, struct test_case_t *tc) 121f08c3bdfSopenharmony_ci{ 122f08c3bdfSopenharmony_ci unsigned int i; 123f08c3bdfSopenharmony_ci struct fanotify_mark_type *mark = &tc->mark; 124f08c3bdfSopenharmony_ci 125f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(objects); i++) { 126f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(fd, FAN_MARK_ADD | mark->flag, tc->mask, 127f08c3bdfSopenharmony_ci AT_FDCWD, objects[i].path); 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci /* Setup the expected mask for each generated event */ 130f08c3bdfSopenharmony_ci event_set[i].expected_mask = tc->mask; 131f08c3bdfSopenharmony_ci if (!objects[i].is_dir) 132f08c3bdfSopenharmony_ci event_set[i].expected_mask &= ~FAN_ONDIR; 133f08c3bdfSopenharmony_ci } 134f08c3bdfSopenharmony_ci return 0; 135f08c3bdfSopenharmony_ci} 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_cistatic void do_test(unsigned int number) 138f08c3bdfSopenharmony_ci{ 139f08c3bdfSopenharmony_ci unsigned int i; 140f08c3bdfSopenharmony_ci int len, fds[ARRAY_SIZE(objects)]; 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci struct file_handle *event_file_handle; 143f08c3bdfSopenharmony_ci struct fanotify_event_metadata *metadata; 144f08c3bdfSopenharmony_ci struct fanotify_event_info_fid *event_fid; 145f08c3bdfSopenharmony_ci struct test_case_t *tc = &test_cases[number]; 146f08c3bdfSopenharmony_ci struct fanotify_mark_type *mark = &tc->mark; 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci tst_res(TINFO, 149f08c3bdfSopenharmony_ci "Test #%d.%d: FAN_REPORT_FID with mark flag: %s", 150f08c3bdfSopenharmony_ci number, tst_variant, mark->name); 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ci if (tst_variant && !ovl_mounted) { 153f08c3bdfSopenharmony_ci tst_res(TCONF, "overlayfs not supported on %s", tst_device->fs_type); 154f08c3bdfSopenharmony_ci return; 155f08c3bdfSopenharmony_ci } 156f08c3bdfSopenharmony_ci 157f08c3bdfSopenharmony_ci if (filesystem_mark_unsupported && mark->flag & FAN_MARK_FILESYSTEM) { 158f08c3bdfSopenharmony_ci tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?"); 159f08c3bdfSopenharmony_ci return; 160f08c3bdfSopenharmony_ci } 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci fanotify_fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY); 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci /* 165f08c3bdfSopenharmony_ci * Place marks on a set of objects and setup the expected masks 166f08c3bdfSopenharmony_ci * for each event that is expected to be generated. 167f08c3bdfSopenharmony_ci */ 168f08c3bdfSopenharmony_ci if (setup_marks(fanotify_fd, tc) != 0) 169f08c3bdfSopenharmony_ci goto out; 170f08c3bdfSopenharmony_ci 171f08c3bdfSopenharmony_ci /* Variant #1: watching upper fs - open files on overlayfs */ 172f08c3bdfSopenharmony_ci if (tst_variant == 1) { 173f08c3bdfSopenharmony_ci if (mark->flag & FAN_MARK_MOUNT) { 174f08c3bdfSopenharmony_ci tst_res(TCONF, "overlayfs upper fs cannot be watched with mount mark"); 175f08c3bdfSopenharmony_ci goto out; 176f08c3bdfSopenharmony_ci } 177f08c3bdfSopenharmony_ci SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL); 178f08c3bdfSopenharmony_ci } 179f08c3bdfSopenharmony_ci 180f08c3bdfSopenharmony_ci /* Generate sequence of FAN_OPEN events on objects */ 181f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(objects); i++) 182f08c3bdfSopenharmony_ci fds[i] = SAFE_OPEN(objects[i].path, O_RDONLY); 183f08c3bdfSopenharmony_ci 184f08c3bdfSopenharmony_ci /* 185f08c3bdfSopenharmony_ci * Generate sequence of FAN_CLOSE_NOWRITE events on objects. Each 186f08c3bdfSopenharmony_ci * FAN_CLOSE_NOWRITE event is expected to be merged with its 187f08c3bdfSopenharmony_ci * respective FAN_OPEN event that was performed on the same object. 188f08c3bdfSopenharmony_ci */ 189f08c3bdfSopenharmony_ci for (i = 0; i < ARRAY_SIZE(objects); i++) { 190f08c3bdfSopenharmony_ci if (fds[i] > 0) 191f08c3bdfSopenharmony_ci SAFE_CLOSE(fds[i]); 192f08c3bdfSopenharmony_ci } 193f08c3bdfSopenharmony_ci 194f08c3bdfSopenharmony_ci if (tst_variant == 1) 195f08c3bdfSopenharmony_ci SAFE_UMOUNT(MOUNT_PATH); 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ci /* Read events from event queue */ 198f08c3bdfSopenharmony_ci len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE); 199f08c3bdfSopenharmony_ci 200f08c3bdfSopenharmony_ci /* Iterate over event queue */ 201f08c3bdfSopenharmony_ci for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf; 202f08c3bdfSopenharmony_ci FAN_EVENT_OK(metadata, len); 203f08c3bdfSopenharmony_ci metadata = FAN_EVENT_NEXT(metadata, len), i++) { 204f08c3bdfSopenharmony_ci struct fanotify_fid_t *expected_fid = &objects[i].fid; 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci event_fid = (struct fanotify_event_info_fid *) (metadata + 1); 207f08c3bdfSopenharmony_ci event_file_handle = (struct file_handle *) event_fid->handle; 208f08c3bdfSopenharmony_ci 209f08c3bdfSopenharmony_ci /* File descriptor is redundant with FAN_REPORT_FID */ 210f08c3bdfSopenharmony_ci if (metadata->fd != FAN_NOFD) 211f08c3bdfSopenharmony_ci tst_res(TFAIL, 212f08c3bdfSopenharmony_ci "Unexpectedly received file descriptor %d in " 213f08c3bdfSopenharmony_ci "event. Expected to get FAN_NOFD(%d)", 214f08c3bdfSopenharmony_ci metadata->fd, FAN_NOFD); 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci /* Ensure that the correct mask has been reported in event */ 217f08c3bdfSopenharmony_ci if (metadata->mask != event_set[i].expected_mask) 218f08c3bdfSopenharmony_ci tst_res(TFAIL, 219f08c3bdfSopenharmony_ci "Unexpected mask received: %llx (expected: " 220f08c3bdfSopenharmony_ci "%llx) in event", 221f08c3bdfSopenharmony_ci metadata->mask, 222f08c3bdfSopenharmony_ci event_set[i].expected_mask); 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_ci /* Verify handle_bytes returned in event */ 225f08c3bdfSopenharmony_ci if (event_file_handle->handle_bytes != 226f08c3bdfSopenharmony_ci expected_fid->handle.handle_bytes) { 227f08c3bdfSopenharmony_ci tst_res(TFAIL, 228f08c3bdfSopenharmony_ci "handle_bytes (%x) returned in event does not " 229f08c3bdfSopenharmony_ci "equal to handle_bytes (%x) returned in " 230f08c3bdfSopenharmony_ci "name_to_handle_at(2)", 231f08c3bdfSopenharmony_ci event_file_handle->handle_bytes, 232f08c3bdfSopenharmony_ci expected_fid->handle.handle_bytes); 233f08c3bdfSopenharmony_ci continue; 234f08c3bdfSopenharmony_ci } 235f08c3bdfSopenharmony_ci 236f08c3bdfSopenharmony_ci /* Verify handle_type returned in event */ 237f08c3bdfSopenharmony_ci if (event_file_handle->handle_type != 238f08c3bdfSopenharmony_ci expected_fid->handle.handle_type) { 239f08c3bdfSopenharmony_ci tst_res(TFAIL, 240f08c3bdfSopenharmony_ci "handle_type (%x) returned in event does not " 241f08c3bdfSopenharmony_ci "equal to handle_type (%x) returned in " 242f08c3bdfSopenharmony_ci "name_to_handle_at(2)", 243f08c3bdfSopenharmony_ci event_file_handle->handle_type, 244f08c3bdfSopenharmony_ci expected_fid->handle.handle_type); 245f08c3bdfSopenharmony_ci continue; 246f08c3bdfSopenharmony_ci } 247f08c3bdfSopenharmony_ci 248f08c3bdfSopenharmony_ci /* Verify file identifier f_handle returned in event */ 249f08c3bdfSopenharmony_ci if (memcmp(event_file_handle->f_handle, 250f08c3bdfSopenharmony_ci expected_fid->handle.f_handle, 251f08c3bdfSopenharmony_ci expected_fid->handle.handle_bytes) != 0) { 252f08c3bdfSopenharmony_ci tst_res(TFAIL, 253f08c3bdfSopenharmony_ci "file_handle returned in event does not match " 254f08c3bdfSopenharmony_ci "the file_handle returned in " 255f08c3bdfSopenharmony_ci "name_to_handle_at(2)"); 256f08c3bdfSopenharmony_ci continue; 257f08c3bdfSopenharmony_ci } 258f08c3bdfSopenharmony_ci 259f08c3bdfSopenharmony_ci /* Verify filesystem ID fsid returned in event */ 260f08c3bdfSopenharmony_ci if (memcmp(&event_fid->fsid, &expected_fid->fsid, 261f08c3bdfSopenharmony_ci sizeof(expected_fid->fsid)) != 0) { 262f08c3bdfSopenharmony_ci tst_res(TFAIL, 263f08c3bdfSopenharmony_ci "event_fid.fsid != stat.f_fsid that was " 264f08c3bdfSopenharmony_ci "obtained via statfs(2)"); 265f08c3bdfSopenharmony_ci continue; 266f08c3bdfSopenharmony_ci } 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci tst_res(TPASS, 269f08c3bdfSopenharmony_ci "got event: mask=%llx, pid=%d, fid=%x.%x.%lx values " 270f08c3bdfSopenharmony_ci "returned in event match those returned in statfs(2) " 271f08c3bdfSopenharmony_ci "and name_to_handle_at(2)", 272f08c3bdfSopenharmony_ci metadata->mask, 273f08c3bdfSopenharmony_ci getpid(), 274f08c3bdfSopenharmony_ci FSID_VAL_MEMBER(event_fid->fsid, 0), 275f08c3bdfSopenharmony_ci FSID_VAL_MEMBER(event_fid->fsid, 1), 276f08c3bdfSopenharmony_ci *(unsigned long *) event_file_handle->f_handle); 277f08c3bdfSopenharmony_ci } 278f08c3bdfSopenharmony_ciout: 279f08c3bdfSopenharmony_ci SAFE_CLOSE(fanotify_fd); 280f08c3bdfSopenharmony_ci} 281f08c3bdfSopenharmony_ci 282f08c3bdfSopenharmony_cistatic void do_setup(void) 283f08c3bdfSopenharmony_ci{ 284f08c3bdfSopenharmony_ci const char *mnt; 285f08c3bdfSopenharmony_ci 286f08c3bdfSopenharmony_ci /* 287f08c3bdfSopenharmony_ci * Bind mount to either base fs or to overlayfs over base fs: 288f08c3bdfSopenharmony_ci * Variant #0: watch base fs - open files on base fs 289f08c3bdfSopenharmony_ci * Variant #1: watch upper fs - open files on overlayfs 290f08c3bdfSopenharmony_ci * 291f08c3bdfSopenharmony_ci * Variant #1 tests a bug whose fix bc2473c90fca ("ovl: enable fsnotify 292f08c3bdfSopenharmony_ci * events on underlying real files") in kernel 6.5 is not likely to be 293f08c3bdfSopenharmony_ci * backported to older kernels. 294f08c3bdfSopenharmony_ci * To avoid waiting for events that won't arrive when testing old kernels, 295f08c3bdfSopenharmony_ci * require that kernel supports encoding fid with new flag AT_HADNLE_FID, 296f08c3bdfSopenharmony_ci * also merged to 6.5 and not likely to be backported to older kernels. 297f08c3bdfSopenharmony_ci */ 298f08c3bdfSopenharmony_ci if (tst_variant) { 299f08c3bdfSopenharmony_ci REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(AT_HANDLE_FID); 300f08c3bdfSopenharmony_ci ovl_mounted = TST_MOUNT_OVERLAY(); 301f08c3bdfSopenharmony_ci mnt = OVL_UPPER; 302f08c3bdfSopenharmony_ci } else { 303f08c3bdfSopenharmony_ci mnt = OVL_BASE_MNTPOINT; 304f08c3bdfSopenharmony_ci 305f08c3bdfSopenharmony_ci } 306f08c3bdfSopenharmony_ci REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, mnt); 307f08c3bdfSopenharmony_ci SAFE_MKDIR(MOUNT_PATH, 0755); 308f08c3bdfSopenharmony_ci SAFE_MOUNT(mnt, MOUNT_PATH, "none", MS_BIND, NULL); 309f08c3bdfSopenharmony_ci bind_mounted = 1; 310f08c3bdfSopenharmony_ci 311f08c3bdfSopenharmony_ci filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM); 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ci nofid_fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); 314f08c3bdfSopenharmony_ci 315f08c3bdfSopenharmony_ci /* Create file and directory objects for testing */ 316f08c3bdfSopenharmony_ci create_objects(); 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci /* 319f08c3bdfSopenharmony_ci * Create a mark on first inode without FAN_REPORT_FID, to test 320f08c3bdfSopenharmony_ci * uninitialized connector->fsid cache. This mark remains for all test 321f08c3bdfSopenharmony_ci * cases and is not expected to get any events (no writes in this test). 322f08c3bdfSopenharmony_ci */ 323f08c3bdfSopenharmony_ci SAFE_FANOTIFY_MARK(nofid_fd, FAN_MARK_ADD, FAN_CLOSE_WRITE, AT_FDCWD, 324f08c3bdfSopenharmony_ci FILE_PATH_ONE); 325f08c3bdfSopenharmony_ci 326f08c3bdfSopenharmony_ci /* Get the filesystem fsid and file handle for each created object */ 327f08c3bdfSopenharmony_ci get_object_stats(); 328f08c3bdfSopenharmony_ci} 329f08c3bdfSopenharmony_ci 330f08c3bdfSopenharmony_cistatic void do_cleanup(void) 331f08c3bdfSopenharmony_ci{ 332f08c3bdfSopenharmony_ci SAFE_CLOSE(nofid_fd); 333f08c3bdfSopenharmony_ci if (fanotify_fd > 0) 334f08c3bdfSopenharmony_ci SAFE_CLOSE(fanotify_fd); 335f08c3bdfSopenharmony_ci if (bind_mounted) { 336f08c3bdfSopenharmony_ci SAFE_UMOUNT(MOUNT_PATH); 337f08c3bdfSopenharmony_ci SAFE_RMDIR(MOUNT_PATH); 338f08c3bdfSopenharmony_ci } 339f08c3bdfSopenharmony_ci if (ovl_mounted) 340f08c3bdfSopenharmony_ci SAFE_UMOUNT(OVL_MNT); 341f08c3bdfSopenharmony_ci} 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_cistatic struct tst_test test = { 344f08c3bdfSopenharmony_ci .test = do_test, 345f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(test_cases), 346f08c3bdfSopenharmony_ci .test_variants = 2, 347f08c3bdfSopenharmony_ci .setup = do_setup, 348f08c3bdfSopenharmony_ci .cleanup = do_cleanup, 349f08c3bdfSopenharmony_ci .needs_root = 1, 350f08c3bdfSopenharmony_ci .mount_device = 1, 351f08c3bdfSopenharmony_ci .mntpoint = OVL_BASE_MNTPOINT, 352f08c3bdfSopenharmony_ci .all_filesystems = 1, 353f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 354f08c3bdfSopenharmony_ci {"linux-git", "c285a2f01d69"}, 355f08c3bdfSopenharmony_ci {"linux-git", "bc2473c90fca"}, 356f08c3bdfSopenharmony_ci {} 357f08c3bdfSopenharmony_ci } 358f08c3bdfSopenharmony_ci}; 359f08c3bdfSopenharmony_ci 360f08c3bdfSopenharmony_ci#else 361f08c3bdfSopenharmony_ci TST_TEST_TCONF("System does not have required name_to_handle_at() support"); 362f08c3bdfSopenharmony_ci#endif 363f08c3bdfSopenharmony_ci#else 364f08c3bdfSopenharmony_ci TST_TEST_TCONF("System does not have required fanotify support"); 365f08c3bdfSopenharmony_ci#endif 366