1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2018 Huawei. All Rights Reserved. 4 * 5 * Started by nixiaoming <nixiaoming@huawei.com> 6 */ 7 8/*\ 9 * [Description] 10 * After fanotify_init adds flags FAN_REPORT_TID, 11 * check whether the program can accurately identify which thread id 12 * in the multithreaded program triggered the event. 13 */ 14 15#define _GNU_SOURCE 16#include "config.h" 17 18#include <stdio.h> 19#include <stdlib.h> 20 21#include <sys/stat.h> 22#include <sys/types.h> 23#include <errno.h> 24#include <string.h> 25#include <unistd.h> 26#include <sys/syscall.h> 27#include <pthread.h> 28#include <sys/stat.h> 29#include <linux/limits.h> 30#include "tst_test.h" 31#include "tst_safe_pthread.h" 32 33#ifdef HAVE_SYS_FANOTIFY_H 34#include "fanotify.h" 35 36#define gettid() syscall(SYS_gettid) 37static int tid; 38 39static int fan_report_tid_unsupported; 40 41static void *thread_create_file(void *arg LTP_ATTRIBUTE_UNUSED) 42{ 43 char tid_file[64] = {0}; 44 45 tid = gettid(); 46 snprintf(tid_file, sizeof(tid_file), "test_tid_%d", tid); 47 SAFE_FILE_PRINTF(tid_file, "1"); 48 49 pthread_exit(0); 50} 51 52static unsigned int tcases[] = { 53 FAN_CLASS_NOTIF, 54 FAN_CLASS_NOTIF | FAN_REPORT_TID 55}; 56 57static void test01(unsigned int i) 58{ 59 pthread_t p_id; 60 struct fanotify_event_metadata event; 61 int fd_notify; 62 int tgid = getpid(); 63 64 tst_res(TINFO, "Test #%u: %s FAN_REPORT_TID: tgid=%d, tid=%d, event.pid=%d", 65 i, (tcases[i] & FAN_REPORT_TID) ? "with" : "without", 66 tgid, tid, event.pid); 67 68 if (fan_report_tid_unsupported && (tcases[i] & FAN_REPORT_TID)) { 69 FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_TID, fan_report_tid_unsupported); 70 return; 71 } 72 73 fd_notify = SAFE_FANOTIFY_INIT(tcases[i], 0); 74 75 SAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD, 76 FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD, AT_FDCWD, "."); 77 78 SAFE_PTHREAD_CREATE(&p_id, NULL, thread_create_file, NULL); 79 80 SAFE_READ(0, fd_notify, &event, sizeof(struct fanotify_event_metadata)); 81 82 if ((tcases[i] & FAN_REPORT_TID) && event.pid == tid) 83 tst_res(TPASS, "event.pid == tid"); 84 else if (!(tcases[i] & FAN_REPORT_TID) && event.pid == tgid) 85 tst_res(TPASS, "event.pid == tgid"); 86 else 87 tst_res(TFAIL, "unexpected event.pid value"); 88 89 if (event.fd != FAN_NOFD) 90 SAFE_CLOSE(event.fd); 91 SAFE_CLOSE(fd_notify); 92 SAFE_PTHREAD_JOIN(p_id, NULL); 93} 94 95static void setup(void) 96{ 97 fan_report_tid_unsupported = fanotify_init_flags_supported_by_kernel(FAN_REPORT_TID); 98} 99 100static struct tst_test test = { 101 .setup = setup, 102 .test = test01, 103 .tcnt = ARRAY_SIZE(tcases), 104 .needs_tmpdir = 1, 105 .needs_root = 1, 106}; 107 108#else 109 TST_TEST_TCONF("system doesn't have required fanotify support"); 110#endif 111