blob: 735f03ac027ce0d7e42d9c0be7caa1164ce7be58 [file] [log] [blame]
Jan Kara8b01a2a2014-02-24 16:15:11 +01001/*
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 <sys/fcntl.h>
34#include <errno.h>
35#include <string.h>
36#include <sys/syscall.h>
37#include "test.h"
Jan Kara8b01a2a2014-02-24 16:15:11 +010038#include "linux_syscall_numbers.h"
39#include "fanotify.h"
40#include "safe_macros.h"
41
42char *TCID = "fanotify05";
43int TST_TOTAL = 1;
44
45#if defined(HAVE_SYS_FANOTIFY_H)
46#include <sys/fanotify.h>
47
48/* Currently this is fixed in kernel... */
49#define MAX_EVENTS 16384
50
51static void setup(void);
52static void cleanup(void);
53
54#define BUF_SIZE 256
55static char fname[BUF_SIZE];
56static int fd, fd_notify;
57
58struct fanotify_event_metadata event;
59
60int main(int ac, char **av)
61{
62 int lc, i;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020063 const char *msg;
Jan Kara8b01a2a2014-02-24 16:15:11 +010064 int len;
65
66 msg = parse_opts(ac, av, NULL, NULL);
67 if (msg != NULL)
68 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
69
70 setup();
71
72 for (lc = 0; TEST_LOOPING(lc); lc++) {
73 /*
74 * generate events
75 */
76 for (i = 0; i < MAX_EVENTS + 1; i++) {
77 sprintf(fname, "fname_%d", i);
78 fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0644);
79 SAFE_CLOSE(cleanup, fd);
80 }
81
82 while (1) {
83 /*
84 * get list on events
85 */
86 len = read(fd_notify, &event, sizeof(event));
87 if (len < 0) {
88 if (errno == -EAGAIN) {
89 tst_resm(TFAIL, "Overflow event not "
90 "generated!\n");
91 break;
92 }
93 tst_brkm(TBROK | TERRNO, cleanup,
94 "read of notification event failed");
95 break;
96 }
97 if (event.fd != FAN_NOFD)
98 close(event.fd);
99
100 /*
101 * check events
102 */
103 if (event.mask != FAN_OPEN &&
104 event.mask != FAN_Q_OVERFLOW) {
105 tst_resm(TFAIL,
106 "get event: mask=%llx (expected %llx)"
107 "pid=%u fd=%d",
108 (unsigned long long)event.mask,
109 (unsigned long long)FAN_OPEN,
110 (unsigned)event.pid, event.fd);
111 break;
112 }
113 if (event.mask == FAN_Q_OVERFLOW) {
114 if (event.fd != FAN_NOFD) {
115 tst_resm(TFAIL,
116 "invalid overflow event: "
117 "mask=%llx pid=%u fd=%d",
118 (unsigned long long)event.mask,
119 (unsigned)event.pid,
120 event.fd);
121 break;
122 }
123 tst_resm(TPASS,
124 "get event: mask=%llx pid=%u fd=%d",
125 (unsigned long long)event.mask,
126 (unsigned)event.pid, event.fd);
127 break;
128 }
129 }
130 }
131
132 cleanup();
133 tst_exit();
134}
135
136static void setup(void)
137{
138 tst_sig(NOFORK, DEF_HANDLER, cleanup);
139
140 TEST_PAUSE;
141
142 tst_tmpdir();
143
Helge Dellerff964762014-07-29 18:10:40 +0200144 fd_notify = fanotify_init(FAN_CLASS_NOTIF | FAN_NONBLOCK, O_RDONLY);
Jan Kara8b01a2a2014-02-24 16:15:11 +0100145 if (fd_notify < 0) {
146 if (errno == ENOSYS) {
147 tst_brkm(TCONF, cleanup,
148 "fanotify is not configured in this kernel.");
149 } else {
150 tst_brkm(TBROK | TERRNO, cleanup,
151 "fanotify_init failed");
152 }
153 }
154
Helge Dellerff964762014-07-29 18:10:40 +0200155 if (fanotify_mark(fd_notify, FAN_MARK_MOUNT | FAN_MARK_ADD, FAN_OPEN,
Jan Kara8b01a2a2014-02-24 16:15:11 +0100156 AT_FDCWD, ".") < 0) {
157 tst_brkm(TBROK | TERRNO, cleanup,
158 "fanotify_mark (%d, FAN_MARK_MOUNT | FAN_MARK_ADD, "
159 "FAN_OPEN, AT_FDCWD, \".\") failed",
160 fd_notify);
161 }
162}
163
164static void cleanup(void)
165{
166 if (fd_notify > 0 && close(fd_notify) == -1)
167 tst_resm(TWARN, "close(%d) failed", fd_notify);
168
Jan Kara8b01a2a2014-02-24 16:15:11 +0100169 tst_rmdir();
170}
171
172#else
173
174int main(void)
175{
176 tst_brkm(TCONF, NULL, "system doesn't have required fanotify support");
177}
178
179#endif