197
unlink(cookie_pathname.buf);
198
199
/*
200
- * Technically, this is an infinite wait (well, unless another
201
- * thread sends us an abort). I'd like to change this to
202
- * use `pthread_cond_timedwait()` and return an error/timeout
203
- * and let the caller do the trivial response thing, but we
204
- * don't have that routine in our thread-utils.
205
- *
206
- * After extensive beta testing I'm not really worried about
207
- * this. Also note that the above open() and unlink() calls
208
- * will cause at least two FS events on that path, so the odds
209
- * of getting stuck are pretty slim.
200
+ * Wait for the listener thread to observe the cookie file.
201
+ * Time out after a short interval so that the client
202
+ * does not hang forever if the filesystem does not deliver
203
+ * events (e.g., on certain container/overlay filesystems
204
+ * where inotify watches succeed but events never arrive).
205
*/
211
- while (cookie->result == FCIR_INIT)
212
- pthread_cond_wait(&state->cookies_cond,
213
- &state->main_lock);
206
+ {
207
+ struct timeval now;
208
+ struct timespec ts;
209
+ int err = 0;
210
+
211
+ gettimeofday(&now, NULL);
212
+ ts.tv_sec = now.tv_sec + 1;
213
+ ts.tv_nsec = now.tv_usec * 1000;
214
+
215
+ while (cookie->result == FCIR_INIT && !err)
216
+ err = pthread_cond_timedwait(&state->cookies_cond,
217
+ &state->main_lock,
218
+ &ts);
219
+ if (err == ETIMEDOUT && cookie->result == FCIR_INIT) {
220
+ trace_printf_key(&trace_fsmonitor,
221
+ "cookie_wait timed out");
222
+ cookie->result = FCIR_ERROR;
223
+ }
224
+ }
225
226
done:
227
hashmap_remove(&state->cookies, &cookie->entry, NULL);