@@ -48,8 +48,16 @@ static uint64_t get_mnt_id(struct __test_metadata *const _metadata,
4848
4949static const char root_mntpoint_templ [] = "/tmp/mount-notify_test_root.XXXXXX" ;
5050
51+ static const int mark_cmds [] = {
52+ FAN_MARK_ADD ,
53+ FAN_MARK_REMOVE ,
54+ FAN_MARK_FLUSH
55+ };
56+
57+ #define NUM_FAN_FDS ARRAY_SIZE(mark_cmds)
58+
5159FIXTURE (fanotify ) {
52- int fan_fd ;
60+ int fan_fd [ NUM_FAN_FDS ] ;
5361 char buf [256 ];
5462 unsigned int rem ;
5563 void * next ;
@@ -61,7 +69,7 @@ FIXTURE(fanotify) {
6169
6270FIXTURE_SETUP (fanotify )
6371{
64- int ret ;
72+ int i , ret ;
6573
6674 ASSERT_EQ (unshare (CLONE_NEWNS ), 0 );
6775
@@ -89,20 +97,34 @@ FIXTURE_SETUP(fanotify)
8997 self -> root_id = get_mnt_id (_metadata , "/" );
9098 ASSERT_NE (self -> root_id , 0 );
9199
92- self -> fan_fd = fanotify_init (FAN_REPORT_MNT , 0 );
93- ASSERT_GE (self -> fan_fd , 0 );
94-
95- ret = fanotify_mark (self -> fan_fd , FAN_MARK_ADD | FAN_MARK_MNTNS ,
96- FAN_MNT_ATTACH | FAN_MNT_DETACH , self -> ns_fd , NULL );
97- ASSERT_EQ (ret , 0 );
100+ for (i = 0 ; i < NUM_FAN_FDS ; i ++ ) {
101+ self -> fan_fd [i ] = fanotify_init (FAN_REPORT_MNT | FAN_NONBLOCK ,
102+ 0 );
103+ ASSERT_GE (self -> fan_fd [i ], 0 );
104+ ret = fanotify_mark (self -> fan_fd [i ], FAN_MARK_ADD |
105+ FAN_MARK_MNTNS ,
106+ FAN_MNT_ATTACH | FAN_MNT_DETACH ,
107+ self -> ns_fd , NULL );
108+ ASSERT_EQ (ret , 0 );
109+ // On fd[0] we do an extra ADD that changes nothing.
110+ // On fd[1]/fd[2] we REMOVE/FLUSH which removes the mark.
111+ ret = fanotify_mark (self -> fan_fd [i ], mark_cmds [i ] |
112+ FAN_MARK_MNTNS ,
113+ FAN_MNT_ATTACH | FAN_MNT_DETACH ,
114+ self -> ns_fd , NULL );
115+ ASSERT_EQ (ret , 0 );
116+ }
98117
99118 self -> rem = 0 ;
100119}
101120
102121FIXTURE_TEARDOWN (fanotify )
103122{
123+ int i ;
124+
104125 ASSERT_EQ (self -> rem , 0 );
105- close (self -> fan_fd );
126+ for (i = 0 ; i < NUM_FAN_FDS ; i ++ )
127+ close (self -> fan_fd [i ]);
106128
107129 ASSERT_EQ (fchdir (self -> orig_root ), 0 );
108130
@@ -123,8 +145,21 @@ static uint64_t expect_notify(struct __test_metadata *const _metadata,
123145 unsigned int thislen ;
124146
125147 if (!self -> rem ) {
126- ssize_t len = read (self -> fan_fd , self -> buf , sizeof (self -> buf ));
127- ASSERT_GT (len , 0 );
148+ ssize_t len ;
149+ int i ;
150+
151+ for (i = NUM_FAN_FDS - 1 ; i >= 0 ; i -- ) {
152+ len = read (self -> fan_fd [i ], self -> buf ,
153+ sizeof (self -> buf ));
154+ if (i > 0 ) {
155+ // Groups 1,2 should get EAGAIN
156+ ASSERT_EQ (len , -1 );
157+ ASSERT_EQ (errno , EAGAIN );
158+ } else {
159+ // Group 0 should get events
160+ ASSERT_GT (len , 0 );
161+ }
162+ }
128163
129164 self -> rem = len ;
130165 self -> next = (void * ) self -> buf ;
0 commit comments