1 /* 2 * Copyright (c) 2014 SUSE Linux. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * Started by Jan Kara <jack@suse.cz> 20 * 21 * DESCRIPTION 22 * Check that fanotify overflow event is properly generated 23 * 24 * ALGORITHM 25 * Generate enough events without reading them and check that overflow 26 * event is generated. 27 */ 28 #include "config.h" 29 30 #include <stdio.h> 31 #include <sys/stat.h> 32 #include <sys/types.h> 33 #include <fcntl.h> 34 #include <errno.h> 35 #include <string.h> 36 #include <sys/syscall.h> 37 #include "tst_test.h" 38 #include "fanotify.h" 39 40 #if defined(HAVE_SYS_FANOTIFY_H) 41 #include <sys/fanotify.h> 42 43 /* Currently this is fixed in kernel... */ 44 #define MAX_EVENTS 16384 45 46 #define BUF_SIZE 256 47 static char fname[BUF_SIZE]; 48 static int fd, fd_notify; 49 50 struct fanotify_event_metadata event; 51 52 void test01(void) 53 { 54 int i; 55 int len; 56 57 /* 58 * generate events 59 */ 60 for (i = 0; i < MAX_EVENTS + 1; i++) { 61 sprintf(fname, "fname_%d", i); 62 fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0644); 63 SAFE_CLOSE(fd); 64 } 65 66 while (1) { 67 /* 68 * get list on events 69 */ 70 len = read(fd_notify, &event, sizeof(event)); 71 if (len < 0) { 72 if (errno == -EAGAIN) { 73 tst_res(TFAIL, "Overflow event not " 74 "generated!\n"); 75 break; 76 } 77 tst_brk(TBROK | TERRNO, 78 "read of notification event failed"); 79 break; 80 } 81 if (event.fd != FAN_NOFD) 82 close(event.fd); 83 84 /* 85 * check events 86 */ 87 if (event.mask != FAN_OPEN && 88 event.mask != FAN_Q_OVERFLOW) { 89 tst_res(TFAIL, 90 "get event: mask=%llx (expected %llx)" 91 "pid=%u fd=%d", 92 (unsigned long long)event.mask, 93 (unsigned long long)FAN_OPEN, 94 (unsigned)event.pid, event.fd); 95 break; 96 } 97 if (event.mask == FAN_Q_OVERFLOW) { 98 if (event.fd != FAN_NOFD) { 99 tst_res(TFAIL, 100 "invalid overflow event: " 101 "mask=%llx pid=%u fd=%d", 102 (unsigned long long)event.mask, 103 (unsigned)event.pid, 104 event.fd); 105 break; 106 } 107 tst_res(TPASS, 108 "get event: mask=%llx pid=%u fd=%d", 109 (unsigned long long)event.mask, 110 (unsigned)event.pid, event.fd); 111 break; 112 } 113 } 114 } 115 116 static void setup(void) 117 { 118 fd_notify = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF | FAN_NONBLOCK, 119 O_RDONLY); 120 121 if (fanotify_mark(fd_notify, FAN_MARK_MOUNT | FAN_MARK_ADD, FAN_OPEN, 122 AT_FDCWD, ".") < 0) { 123 tst_brk(TBROK | TERRNO, 124 "fanotify_mark (%d, FAN_MARK_MOUNT | FAN_MARK_ADD, " 125 "FAN_OPEN, AT_FDCWD, \".\") failed", 126 fd_notify); 127 } 128 } 129 130 static void cleanup(void) 131 { 132 if (fd_notify > 0) 133 SAFE_CLOSE(fd_notify); 134 } 135 136 static struct tst_test test = { 137 .test_all = test01, 138 .setup = setup, 139 .cleanup = cleanup, 140 .needs_root = 1, 141 .needs_tmpdir = 1, 142 }; 143 #else 144 TST_TEST_TCONF("system doesn't have required fanotify support"); 145 #endif 146