@@ -48,8 +48,16 @@ static uint64_t get_mnt_id(struct __test_metadata *const _metadata,
48
48
49
49
static const char root_mntpoint_templ [] = "/tmp/mount-notify_test_root.XXXXXX" ;
50
50
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
+
51
59
FIXTURE (fanotify ) {
52
- int fan_fd ;
60
+ int fan_fd [ NUM_FAN_FDS ] ;
53
61
char buf [256 ];
54
62
unsigned int rem ;
55
63
void * next ;
@@ -61,7 +69,7 @@ FIXTURE(fanotify) {
61
69
62
70
FIXTURE_SETUP (fanotify )
63
71
{
64
- int ret ;
72
+ int i , ret ;
65
73
66
74
ASSERT_EQ (unshare (CLONE_NEWNS ), 0 );
67
75
@@ -89,20 +97,34 @@ FIXTURE_SETUP(fanotify)
89
97
self -> root_id = get_mnt_id (_metadata , "/" );
90
98
ASSERT_NE (self -> root_id , 0 );
91
99
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
+ }
98
117
99
118
self -> rem = 0 ;
100
119
}
101
120
102
121
FIXTURE_TEARDOWN (fanotify )
103
122
{
123
+ int i ;
124
+
104
125
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 ]);
106
128
107
129
ASSERT_EQ (fchdir (self -> orig_root ), 0 );
108
130
@@ -123,8 +145,21 @@ static uint64_t expect_notify(struct __test_metadata *const _metadata,
123
145
unsigned int thislen ;
124
146
125
147
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
+ }
128
163
129
164
self -> rem = len ;
130
165
self -> next = (void * ) self -> buf ;
0 commit comments