@@ -57,7 +57,7 @@ static struct test_case_t {
57
57
{
58
58
"return invalid pidfd for event created by terminated child" ,
59
59
1 ,
60
- FAN_NOPIDFD ,
60
+ 1 ,
61
61
0 ,
62
62
},
63
63
{
@@ -72,6 +72,8 @@ static int fanotify_fd;
72
72
static char event_buf [BUF_SZ ];
73
73
static struct pidfd_fdinfo_t * self_pidfd_fdinfo ;
74
74
75
+ static int fd_error_unsupported ;
76
+
75
77
static struct pidfd_fdinfo_t * read_pidfd_fdinfo (int pidfd )
76
78
{
77
79
char * fdinfo_path ;
@@ -121,6 +123,15 @@ static void do_fork(void)
121
123
static void do_setup (void )
122
124
{
123
125
int pidfd ;
126
+ int init_flags = FAN_REPORT_PIDFD ;
127
+
128
+ if (tst_variant ) {
129
+ fanotify_fd = -1 ;
130
+ fd_error_unsupported = fanotify_init_flags_supported_on_fs (FAN_REPORT_FD_ERROR , "." );
131
+ if (fd_error_unsupported )
132
+ return ;
133
+ init_flags |= FAN_REPORT_FD_ERROR ;
134
+ }
124
135
125
136
SAFE_TOUCH (TEST_FILE , 0666 , NULL );
126
137
@@ -132,7 +143,7 @@ static void do_setup(void)
132
143
REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS (FAN_REPORT_PIDFD ,
133
144
TEST_FILE );
134
145
135
- fanotify_fd = SAFE_FANOTIFY_INIT (FAN_REPORT_PIDFD , O_RDWR );
146
+ fanotify_fd = SAFE_FANOTIFY_INIT (init_flags , O_RDWR );
136
147
SAFE_FANOTIFY_MARK (fanotify_fd , FAN_MARK_ADD , FAN_OPEN , AT_FDCWD ,
137
148
TEST_FILE );
138
149
@@ -150,8 +161,17 @@ static void do_test(unsigned int num)
150
161
{
151
162
int i = 0 , len ;
152
163
struct test_case_t * tc = & test_cases [num ];
164
+ int nopidfd_err = tc -> want_pidfd_err ?
165
+ (tst_variant ? - ESRCH : FAN_NOPIDFD ) : 0 ;
166
+ int fd_err = (tc -> remount_ro && tst_variant ) ? - EROFS : 0 ;
153
167
154
- tst_res (TINFO , "Test #%d: %s" , num , tc -> name );
168
+ tst_res (TINFO , "Test #%d.%d: %s %s" , num , tst_variant , tc -> name ,
169
+ tst_variant ? "(FAN_REPORT_FD_ERROR)" : "" );
170
+
171
+ if (fd_error_unsupported && tst_variant ) {
172
+ FANOTIFY_INIT_FLAGS_ERR_MSG (FAN_REPORT_FD_ERROR , fd_error_unsupported );
173
+ return ;
174
+ }
155
175
156
176
if (tc -> remount_ro ) {
157
177
/* SAFE_MOUNT fails to remount FUSE */
@@ -179,12 +199,12 @@ static void do_test(unsigned int num)
179
199
*/
180
200
len = read (fanotify_fd , event_buf , sizeof (event_buf ));
181
201
if (len < 0 ) {
182
- if (tc -> remount_ro && errno == EROFS ) {
202
+ if (tc -> remount_ro && ! fd_err && errno == EROFS ) {
183
203
tst_res (TPASS , "cannot read event with rw fd from a ro fs" );
184
204
return ;
185
205
}
186
206
tst_brk (TBROK | TERRNO , "reading fanotify events failed" );
187
- } else if (tc -> remount_ro ) {
207
+ } else if (tc -> remount_ro && ! fd_err ) {
188
208
tst_res (TFAIL , "got unexpected event with rw fd from a ro fs" );
189
209
}
190
210
while (i < len ) {
@@ -218,6 +238,28 @@ static void do_test(unsigned int num)
218
238
goto next_event ;
219
239
}
220
240
241
+ /*
242
+ * Check if event->fd reported any errors during
243
+ * creation and whether they're expected.
244
+ */
245
+ if (!fd_err && event -> fd >= 0 ) {
246
+ tst_res (TPASS ,
247
+ "event->fd %d is valid as expected" ,
248
+ event -> fd );
249
+ } else if (fd_err && event -> fd == fd_err ) {
250
+ tst_res (TPASS ,
251
+ "event->fd is error %d as expected" ,
252
+ event -> fd );
253
+ } else if (fd_err ) {
254
+ tst_res (TFAIL ,
255
+ "event->fd is %d, but expected error %d" ,
256
+ event -> fd , fd_err );
257
+ } else {
258
+ tst_res (TFAIL ,
259
+ "event->fd creation failed with error %d" ,
260
+ event -> fd );
261
+ }
262
+
221
263
/*
222
264
* Check if pidfd information object reported any errors during
223
265
* creation and whether they're expected.
@@ -229,20 +271,18 @@ static void do_test(unsigned int num)
229
271
(unsigned int )event -> pid ,
230
272
info -> pidfd );
231
273
goto next_event ;
232
- } else if (tc -> want_pidfd_err &&
233
- info -> pidfd != tc -> want_pidfd_err ) {
274
+ } else if (tc -> want_pidfd_err && info -> pidfd != nopidfd_err ) {
234
275
tst_res (TFAIL ,
235
276
"pidfd set to an unexpected error: %d for pid: %u" ,
236
277
info -> pidfd ,
237
278
(unsigned int )event -> pid );
238
279
goto next_event ;
239
- } else if (tc -> want_pidfd_err &&
240
- info -> pidfd == tc -> want_pidfd_err ) {
280
+ } else if (tc -> want_pidfd_err && info -> pidfd == nopidfd_err ) {
241
281
tst_res (TPASS ,
242
282
"pid: %u terminated before pidfd was created, "
243
283
"pidfd set to the value of: %d, as expected" ,
244
284
(unsigned int )event -> pid ,
245
- FAN_NOPIDFD );
285
+ nopidfd_err );
246
286
goto next_event ;
247
287
}
248
288
@@ -323,6 +363,7 @@ static struct tst_test test = {
323
363
.setup = do_setup ,
324
364
.test = do_test ,
325
365
.tcnt = ARRAY_SIZE (test_cases ),
366
+ .test_variants = 2 ,
326
367
.cleanup = do_cleanup ,
327
368
.all_filesystems = 1 ,
328
369
.needs_root = 1 ,
0 commit comments