1 /* Copyright 2012-present Facebook, Inc.
2  * Licensed under the Apache License, Version 2.0 */
3 
4 #include "watchman.h"
5 #ifdef __APPLE__
6 # include <sys/attr.h>
7 #endif
8 
9 static struct watchman_ops *watcher_ops = NULL;
10 static watchman_global_watcher_t watcher = NULL;
11 static w_ht_t *watched_roots = NULL;
12 static volatile long live_roots = 0;
13 static pthread_mutex_t root_lock = PTHREAD_MUTEX_INITIALIZER;
14 
15 // Each root gets a number that uniquely identifies it within the process. This
16 // helps avoid confusion if a root is removed and then added again.
17 static long next_root_number = 1;
18 
19 /* Some error conditions will put us into a non-recoverable state where we
20  * can't guarantee that we will be operating correctly.  Rather than suffering
21  * in silence and misleading our clients, we'll poison ourselves and advertise
22  * that we have done so and provide some advice on how the user can cure us. */
23 char *poisoned_reason = NULL;
24 
25 static void crawler(w_root_t *root, struct watchman_pending_collection *coll,
26     w_string_t *dir_name, struct timeval now, bool recursive);
27 
28 static void w_root_teardown(w_root_t *root);
29 
delete_trigger(w_ht_val_t val)30 static void delete_trigger(w_ht_val_t val)
31 {
32   struct watchman_trigger_command *cmd = w_ht_val_ptr(val);
33 
34   w_trigger_command_free(cmd);
35 }
36 
37 static const struct watchman_hash_funcs trigger_hash_funcs = {
38   w_ht_string_copy,
39   w_ht_string_del,
40   w_ht_string_equal,
41   w_ht_string_hash,
42   NULL,
43   delete_trigger
44 };
45 
delete_dir(w_ht_val_t val)46 static void delete_dir(w_ht_val_t val)
47 {
48   struct watchman_dir *dir = w_ht_val_ptr(val);
49 
50   w_log(W_LOG_DBG, "delete_dir(%.*s)\n", dir->path->len, dir->path->buf);
51 
52   w_string_delref(dir->path);
53   dir->path = NULL;
54 
55   if (dir->files) {
56     w_ht_free(dir->files);
57     dir->files = NULL;
58   }
59   if (dir->dirs) {
60     w_ht_free(dir->dirs);
61     dir->dirs = NULL;
62   }
63   free(dir);
64 }
65 
66 static const struct watchman_hash_funcs dirname_hash_funcs = {
67   w_ht_string_copy,
68   w_ht_string_del,
69   w_ht_string_equal,
70   w_ht_string_hash,
71   NULL,
72   delete_dir
73 };
74 
load_root_config(w_root_t * root,const char * path)75 static void load_root_config(w_root_t *root, const char *path)
76 {
77   char cfgfilename[WATCHMAN_NAME_MAX];
78   json_error_t err;
79 
80   snprintf(cfgfilename, sizeof(cfgfilename), "%s%c.watchmanconfig",
81       path, WATCHMAN_DIR_SEP);
82 
83   if (!w_path_exists(cfgfilename)) {
84     if (errno == ENOENT) {
85       return;
86     }
87     w_log(W_LOG_ERR, "%s is not accessible: %s\n",
88         cfgfilename, strerror(errno));
89     return;
90   }
91 
92   root->config_file = json_load_file(cfgfilename, 0, &err);
93   if (!root->config_file) {
94     w_log(W_LOG_ERR, "failed to parse json from %s: %s\n",
95         cfgfilename, err.text);
96   }
97 }
98 
99 static size_t root_init_offset = offsetof(w_root_t, _init_sentinel_);
100 
101 // internal initialization for root
w_root_init(w_root_t * root,char ** errmsg)102 static bool w_root_init(w_root_t *root, char **errmsg)
103 {
104   struct watchman_dir *dir;
105   struct watchman_dir_handle *osdir;
106 
107   memset((char *)root + root_init_offset, 0,
108          sizeof(w_root_t) - root_init_offset);
109 
110   osdir = w_dir_open(root->root_path->buf);
111   if (!osdir) {
112     ignore_result(asprintf(errmsg, "failed to opendir(%s): %s",
113           root->root_path->buf,
114           strerror(errno)));
115     return false;
116   }
117   w_dir_close(osdir);
118 
119   if (!watcher_ops->root_init(watcher, root, errmsg)) {
120     return false;
121   }
122 
123   root->number = __sync_fetch_and_add(&next_root_number, 1);
124 
125   root->cursors = w_ht_new(2, &w_ht_string_funcs);
126   root->suffixes = w_ht_new(2, &w_ht_string_funcs);
127 
128   root->dirname_to_dir = w_ht_new(HINT_NUM_DIRS, &dirname_hash_funcs);
129   root->ticks = 1;
130 
131   // "manually" populate the initial dir, as the dir resolver will
132   // try to find its parent and we don't want it to for the root
133   dir = calloc(1, sizeof(*dir));
134   dir->path = root->root_path;
135   w_string_addref(dir->path);
136   w_ht_set(root->dirname_to_dir, w_ht_ptr_val(dir->path), w_ht_ptr_val(dir));
137 
138   time(&root->last_cmd_timestamp);
139 
140   return root;
141 }
142 
config_get_ignore_vcs(w_root_t * root)143 static json_t *config_get_ignore_vcs(w_root_t *root)
144 {
145   json_t *ignores = cfg_get_json(root, "ignore_vcs");
146   if (ignores && !json_is_array(ignores)) {
147     return NULL;
148   }
149 
150   if (ignores) {
151     // incref so that the caller can simply decref whatever we return
152     json_incref(ignores);
153   } else {
154     // default to a well-known set of vcs's
155     ignores = json_pack("[sss]", ".git", ".svn", ".hg");
156   }
157   return ignores;
158 }
159 
apply_ignore_vcs_configuration(w_root_t * root,char ** errmsg)160 static bool apply_ignore_vcs_configuration(w_root_t *root, char **errmsg)
161 {
162   w_string_t *name;
163   w_string_t *fullname;
164   uint8_t i;
165   json_t *ignores;
166   char hostname[256];
167   struct stat st;
168 
169   ignores = config_get_ignore_vcs(root);
170   if (!ignores) {
171     ignore_result(asprintf(errmsg, "ignore_vcs must be an array of strings"));
172     return false;
173   }
174 
175   for (i = 0; i < json_array_size(ignores); i++) {
176     const char *ignore = json_string_value(json_array_get(ignores, i));
177 
178     if (!ignore) {
179       ignore_result(asprintf(errmsg,
180           "ignore_vcs must be an array of strings"));
181       json_decref(ignores);
182       return false;
183     }
184 
185     name = w_string_new(ignore);
186     fullname = w_string_path_cat(root->root_path, name);
187 
188     // if we are completely ignoring this dir, we have nothing more to
189     // do here
190     if (w_ht_get(root->ignore_dirs, w_ht_ptr_val(fullname))) {
191       w_string_delref(fullname);
192       w_string_delref(name);
193       continue;
194     }
195 
196     w_ht_set(root->ignore_vcs, w_ht_ptr_val(fullname),
197         w_ht_ptr_val(fullname));
198 
199     // While we're at it, see if we can find out where to put our
200     // query cookie information
201     if (root->query_cookie_dir == NULL &&
202         w_lstat(fullname->buf, &st, root->case_sensitive) == 0 &&
203         S_ISDIR(st.st_mode)) {
204       // root/{.hg,.git,.svn}
205       root->query_cookie_dir = w_string_path_cat(root->root_path, name);
206     }
207     w_string_delref(name);
208     w_string_delref(fullname);
209   }
210 
211   json_decref(ignores);
212 
213   if (root->query_cookie_dir == NULL) {
214     w_string_addref(root->root_path);
215     root->query_cookie_dir = root->root_path;
216   }
217   gethostname(hostname, sizeof(hostname));
218   hostname[sizeof(hostname) - 1] = '\0';
219 
220   root->query_cookie_prefix = w_string_make_printf(
221       "%.*s%c" WATCHMAN_COOKIE_PREFIX "%s-%d-", root->query_cookie_dir->len,
222       root->query_cookie_dir->buf, WATCHMAN_DIR_SEP, hostname, (int)getpid());
223   return true;
224 }
225 
apply_ignore_configuration(w_root_t * root)226 static void apply_ignore_configuration(w_root_t *root)
227 {
228   w_string_t *name;
229   w_string_t *fullname;
230   uint8_t i;
231   json_t *ignores;
232 
233   ignores = cfg_get_json(root, "ignore_dirs");
234   if (!ignores) {
235     return;
236   }
237   if (!json_is_array(ignores)) {
238     w_log(W_LOG_ERR, "ignore_dirs must be an array of strings\n");
239     return;
240   }
241 
242   for (i = 0; i < json_array_size(ignores); i++) {
243     const char *ignore = json_string_value(json_array_get(ignores, i));
244 
245     if (!ignore) {
246       w_log(W_LOG_ERR, "ignore_dirs must be an array of strings\n");
247       continue;
248     }
249 
250     name = w_string_new(ignore);
251     fullname = w_string_path_cat(root->root_path, name);
252     w_ht_set(root->ignore_dirs, w_ht_ptr_val(fullname),
253         w_ht_ptr_val(fullname));
254     w_log(W_LOG_DBG, "ignoring %.*s recursively\n",
255         fullname->len, fullname->buf);
256     w_string_delref(fullname);
257     w_string_delref(name);
258   }
259 }
260 
is_case_sensitive_filesystem(const char * path)261 static bool is_case_sensitive_filesystem(const char *path) {
262 #ifdef __APPLE__
263   return pathconf(path, _PC_CASE_SENSITIVE);
264 #elif defined(_WIN32)
265   unused_parameter(path);
266   return false;
267 #else
268   unused_parameter(path);
269   return true;
270 #endif
271 }
272 
w_root_new(const char * path,char ** errmsg)273 static w_root_t *w_root_new(const char *path, char **errmsg)
274 {
275   w_root_t *root = calloc(1, sizeof(*root));
276   pthread_mutexattr_t attr;
277 
278   assert(root != NULL);
279 
280   root->refcnt = 1;
281   w_refcnt_add(&live_roots);
282   pthread_mutexattr_init(&attr);
283   pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
284   pthread_mutex_init(&root->lock, &attr);
285   pthread_mutexattr_destroy(&attr);
286 
287   root->case_sensitive = is_case_sensitive_filesystem(path);
288 
289   w_pending_coll_init(&root->pending);
290   root->root_path = w_string_new(path);
291   root->commands = w_ht_new(2, &trigger_hash_funcs);
292   root->query_cookies = w_ht_new(2, &w_ht_string_funcs);
293   root->ignore_vcs = w_ht_new(2, &w_ht_string_funcs);
294   root->ignore_dirs = w_ht_new(2, &w_ht_string_funcs);
295 
296   load_root_config(root, path);
297   root->trigger_settle = (int)cfg_get_int(
298       root, "settle", DEFAULT_SETTLE_PERIOD);
299   root->gc_age = (int)cfg_get_int(root, "gc_age_seconds", DEFAULT_GC_AGE);
300   root->gc_interval = (int)cfg_get_int(root, "gc_interval_seconds",
301       DEFAULT_GC_INTERVAL);
302   root->idle_reap_age = (int)cfg_get_int(root, "idle_reap_age_seconds",
303       DEFAULT_REAP_AGE);
304 
305   apply_ignore_configuration(root);
306 
307   if (!apply_ignore_vcs_configuration(root, errmsg)) {
308     w_root_delref(root);
309     return NULL;
310   }
311 
312   if (!w_root_init(root, errmsg)) {
313     w_root_delref(root);
314     return NULL;
315   }
316   return root;
317 }
318 
w_root_lock(w_root_t * root)319 void w_root_lock(w_root_t *root)
320 {
321   int err;
322 
323   err = pthread_mutex_lock(&root->lock);
324   if (err != 0) {
325     w_log(W_LOG_FATAL, "lock [%.*s]: %s\n",
326         root->root_path->len,
327         root->root_path->buf,
328         strerror(err)
329     );
330   }
331 }
332 
w_root_unlock(w_root_t * root)333 void w_root_unlock(w_root_t *root)
334 {
335   int err;
336 
337   err = pthread_mutex_unlock(&root->lock);
338   if (err != 0) {
339     w_log(W_LOG_FATAL, "lock: [%.*s] %s\n",
340         root->root_path->len,
341         root->root_path->buf,
342         strerror(err)
343     );
344   }
345 }
346 
w_timeoutms_to_abs_timespec(int timeoutms,struct timespec * deadline)347 void w_timeoutms_to_abs_timespec(int timeoutms, struct timespec *deadline) {
348   struct timeval now, delta, target;
349 
350   /* compute deadline */
351   gettimeofday(&now, NULL);
352   delta.tv_sec = timeoutms / 1000;
353   delta.tv_usec = (timeoutms - (delta.tv_sec * 1000)) * 1000;
354   w_timeval_add(now, delta, &target);
355   w_timeval_to_timespec(target, deadline);
356 }
357 
358 /* Ensure that we're synchronized with the state of the
359  * filesystem at the current time.
360  * We do this by touching a cookie file and waiting to
361  * observe it via inotify.  When we see it we know that
362  * we've seen everything up to the point in time at which
363  * we're asking questions.
364  * Returns true if we observe the change within the requested
365  * time, false otherwise.
366  * Must be called with the root UNLOCKED.  This function
367  * will acquire and release the root lock.
368  */
w_root_sync_to_now(w_root_t * root,int timeoutms)369 bool w_root_sync_to_now(w_root_t *root, int timeoutms)
370 {
371   uint32_t tick;
372   struct watchman_query_cookie cookie;
373   w_string_t *path_str;
374   w_stm_t file;
375   int errcode = 0;
376   struct timespec deadline;
377 
378   if (pthread_cond_init(&cookie.cond, NULL)) {
379     errcode = errno;
380     w_log(W_LOG_ERR, "sync_to_now: cond_init failed: %s\n", strerror(errcode));
381     errno = errcode;
382     return false;
383   }
384   cookie.seen = false;
385 
386   /* generate a cookie name: cookie prefix + id */
387   w_root_lock(root);
388   tick = root->ticks++;
389   path_str = w_string_make_printf("%.*s%" PRIu32 "-%" PRIu32,
390                                   root->query_cookie_prefix->len,
391                                   root->query_cookie_prefix->buf,
392                                   root->number, tick);
393   /* insert our cookie in the map */
394   w_ht_set(root->query_cookies, w_ht_ptr_val(path_str),
395       w_ht_ptr_val(&cookie));
396 
397   /* touch the file */
398   file = w_stm_open(path_str->buf, O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0700);
399   if (!file) {
400     errcode = errno;
401     w_log(W_LOG_ERR, "sync_to_now: creat(%s) failed: %s\n",
402         path_str->buf, strerror(errcode));
403     goto out;
404   }
405   w_stm_close(file);
406 
407   /* compute deadline */
408   w_timeoutms_to_abs_timespec(timeoutms, &deadline);
409 
410   w_log(W_LOG_DBG, "sync_to_now [%s] waiting\n", path_str->buf);
411 
412   /* timed cond wait (unlocks root lock, reacquires) */
413   while (!cookie.seen) {
414     errcode = pthread_cond_timedwait(&cookie.cond, &root->lock, &deadline);
415     if (errcode && !cookie.seen) {
416       w_log(W_LOG_ERR,
417           "sync_to_now: %s timedwait failed: %d: istimeout=%d %s\n",
418           path_str->buf, errcode, errcode == ETIMEDOUT, strerror(errcode));
419       goto out;
420     }
421   }
422   w_log(W_LOG_DBG, "sync_to_now [%s] done\n", path_str->buf);
423 
424 out:
425   // can't unlink the file until after the cookie has been observed because
426   // we don't know which file got changed until we look in the cookie dir
427   unlink(path_str->buf);
428   w_ht_del(root->query_cookies, w_ht_ptr_val(path_str));
429   w_root_unlock(root);
430 
431   w_string_delref(path_str);
432   pthread_cond_destroy(&cookie.cond);
433 
434   if (!cookie.seen) {
435     errno = errcode;
436     return false;
437   }
438 
439   return true;
440 }
441 
w_root_process_pending(w_root_t * root,struct watchman_pending_collection * coll,bool pull_from_root)442 bool w_root_process_pending(w_root_t *root,
443     struct watchman_pending_collection *coll,
444     bool pull_from_root)
445 {
446   struct watchman_pending_fs *p, *pending;
447 
448   if (pull_from_root) {
449     // You MUST own root->pending lock for this
450     w_pending_coll_append(coll, &root->pending);
451   }
452 
453   if (!coll->pending) {
454     return false;
455   }
456 
457   w_log(W_LOG_DBG, "processing %d events in %s\n",
458       w_ht_size(coll->pending_uniq), root->root_path->buf);
459 
460   // Steal the contents
461   pending = coll->pending;
462   coll->pending = NULL;
463   w_ht_free_entries(coll->pending_uniq);
464 
465   while (pending) {
466     p = pending;
467     pending = p->next;
468 
469     if (!root->cancelled) {
470       w_root_process_path(root, coll, p->path, p->now, p->flags, NULL);
471     }
472 
473     w_pending_fs_free(p);
474   }
475 
476   return true;
477 }
478 
w_root_resolve_dir(w_root_t * root,w_string_t * dir_name,bool create)479 struct watchman_dir *w_root_resolve_dir(w_root_t *root,
480     w_string_t *dir_name, bool create)
481 {
482   struct watchman_dir *dir, *parent;
483   w_string_t *parent_name;
484 
485   dir = w_ht_val_ptr(w_ht_get(root->dirname_to_dir, w_ht_ptr_val(dir_name)));
486   if (dir || !create) {
487     return dir;
488   }
489 
490   parent_name = w_string_dirname(dir_name);
491   parent = w_root_resolve_dir(root, parent_name, create);
492   w_string_delref(parent_name);
493 
494   assert(parent != NULL);
495 
496   dir = calloc(1, sizeof(*dir));
497   dir->path = dir_name;
498   w_string_addref(dir->path);
499 
500   if (!parent->dirs) {
501     parent->dirs = w_ht_new(2, &w_ht_string_funcs);
502   }
503 
504   assert(w_ht_set(parent->dirs, w_ht_ptr_val(dir_name), w_ht_ptr_val(dir)));
505   assert(w_ht_set(root->dirname_to_dir,
506         w_ht_ptr_val(dir_name), w_ht_ptr_val(dir)));
507 
508   return dir;
509 }
510 
apply_dir_size_hint(struct watchman_dir * dir,uint32_t ndirs,uint32_t nfiles)511 static void apply_dir_size_hint(struct watchman_dir *dir,
512     uint32_t ndirs, uint32_t nfiles) {
513 
514   if (nfiles > 0) {
515     if (!dir->files) {
516       dir->files = w_ht_new(nfiles, &w_ht_string_funcs);
517     }
518   }
519   if (!dir->dirs && ndirs > 0) {
520     dir->dirs = w_ht_new(ndirs, &w_ht_string_funcs);
521   }
522 }
523 
watch_file(w_root_t * root,struct watchman_file * file)524 static void watch_file(w_root_t *root, struct watchman_file *file)
525 {
526   watcher_ops->root_start_watch_file(watcher, root, file);
527 }
528 
stop_watching_file(w_root_t * root,struct watchman_file * file)529 static void stop_watching_file(w_root_t *root, struct watchman_file *file)
530 {
531   watcher_ops->root_stop_watch_file(watcher, root, file);
532 }
533 
remove_from_file_list(w_root_t * root,struct watchman_file * file)534 static void remove_from_file_list(w_root_t *root, struct watchman_file *file)
535 {
536   if (root->latest_file == file) {
537     root->latest_file = file->next;
538   }
539   if (file->next) {
540     file->next->prev = file->prev;
541   }
542   if (file->prev) {
543     file->prev->next = file->next;
544   }
545 }
546 
remove_from_suffix_list(w_root_t * root,struct watchman_file * file)547 static void remove_from_suffix_list(w_root_t *root, struct watchman_file *file)
548 {
549   w_string_t *suffix = w_string_suffix(file->name);
550   struct watchman_file *sufhead;
551 
552   if (!suffix) {
553     return;
554   }
555 
556   sufhead = w_ht_val_ptr(w_ht_get(root->suffixes, w_ht_ptr_val(suffix)));
557   if (sufhead) {
558     if (file->suffix_prev) {
559       file->suffix_prev->suffix_next = file->suffix_next;
560     }
561     if (file->suffix_next) {
562       file->suffix_next->suffix_prev = file->suffix_prev;
563     }
564     if (sufhead == file) {
565       sufhead = file->suffix_next;
566       w_ht_replace(root->suffixes, w_ht_ptr_val(suffix),
567           w_ht_ptr_val(sufhead));
568     }
569   }
570 
571   w_string_delref(suffix);
572 }
573 
w_root_mark_file_changed(w_root_t * root,struct watchman_file * file,struct timeval now)574 void w_root_mark_file_changed(w_root_t *root, struct watchman_file *file,
575     struct timeval now)
576 {
577   if (file->exists) {
578     watch_file(root, file);
579   } else {
580     stop_watching_file(root, file);
581   }
582 
583   file->otime.tv = now;
584   file->otime.ticks = root->ticks;
585 
586   if (root->latest_file != file) {
587     // unlink from list
588     remove_from_file_list(root, file);
589 
590     // and move to the head
591     file->next = root->latest_file;
592     if (file->next) {
593       file->next->prev = file;
594     }
595     file->prev = NULL;
596     root->latest_file = file;
597   }
598 
599   // Flag that we have pending trigger info
600   root->pending_trigger_tick = root->ticks;
601   root->pending_sub_tick = root->ticks;
602 }
603 
w_root_resolve_file(w_root_t * root,struct watchman_dir * dir,w_string_t * file_name,struct timeval now)604 struct watchman_file *w_root_resolve_file(w_root_t *root,
605     struct watchman_dir *dir, w_string_t *file_name,
606     struct timeval now)
607 {
608   struct watchman_file *file, *sufhead;
609   w_string_t *suffix;
610 
611   if (dir->files) {
612     file = w_ht_val_ptr(w_ht_get(dir->files, w_ht_ptr_val(file_name)));
613     if (file) {
614       return file;
615     }
616   } else {
617     dir->files = w_ht_new(2, &w_ht_string_funcs);
618   }
619 
620   file = calloc(1, sizeof(*file));
621   file->name = file_name;
622   w_string_addref(file->name);
623   file->parent = dir;
624   file->exists = true;
625   file->ctime.ticks = root->ticks;
626   file->ctime.tv = now;
627 
628   suffix = w_string_suffix(file_name);
629   if (suffix) {
630     sufhead = w_ht_val_ptr(w_ht_get(root->suffixes, w_ht_ptr_val(suffix)));
631     file->suffix_next = sufhead;
632     if (sufhead) {
633       sufhead->suffix_prev = file;
634     }
635     w_ht_replace(root->suffixes, w_ht_ptr_val(suffix), w_ht_ptr_val(file));
636     w_string_delref(suffix);
637   }
638 
639   w_ht_set(dir->files, w_ht_ptr_val(file->name), w_ht_ptr_val(file));
640   watch_file(root, file);
641 
642   return file;
643 }
644 
stop_watching_dir(w_root_t * root,struct watchman_dir * dir)645 void stop_watching_dir(w_root_t *root, struct watchman_dir *dir)
646 {
647   w_ht_iter_t i;
648 
649   w_log(W_LOG_DBG, "stop_watching_dir %.*s\n",
650       dir->path->len, dir->path->buf);
651 
652   if (w_ht_first(dir->dirs, &i)) do {
653     struct watchman_dir *child = w_ht_val_ptr(i.value);
654 
655     stop_watching_dir(root, child);
656   } while (w_ht_next(dir->dirs, &i));
657 
658   watcher_ops->root_stop_watch_dir(watcher, root, dir);
659 }
660 
did_file_change(struct watchman_stat * saved,struct watchman_stat * fresh)661 static bool did_file_change(struct watchman_stat *saved,
662     struct watchman_stat *fresh)
663 {
664   /* we have to compare this way because the stat structure
665    * may contain fields that vary and that don't impact our
666    * understanding of the file */
667 
668 #define FIELD_CHG(name) \
669   if (saved->name != fresh->name) { \
670     return true; \
671   }
672 
673   // Can't compare with memcmp due to padding and garbage in the struct
674   // on OpenBSD, which has a 32-bit tv_sec + 64-bit tv_nsec
675 #define TIMESPEC_FIELD_CHG(wat) { \
676   struct timespec a = saved->wat##time; \
677   struct timespec b = fresh->wat##time; \
678   if (a.tv_sec != b.tv_sec || a.tv_nsec != b.tv_nsec) { \
679     return true; \
680   } \
681 }
682 
683   FIELD_CHG(mode);
684 
685   if (!S_ISDIR(saved->mode)) {
686     FIELD_CHG(size);
687     FIELD_CHG(nlink);
688   }
689   FIELD_CHG(dev);
690   FIELD_CHG(ino);
691   FIELD_CHG(uid);
692   FIELD_CHG(gid);
693   // Don't care about st_blocks
694   // Don't care about st_blksize
695   // Don't care about st_atimespec
696   TIMESPEC_FIELD_CHG(m);
697   TIMESPEC_FIELD_CHG(c);
698 
699   return false;
700 }
701 
702 // POSIX says open with O_NOFOLLOW should set errno to ELOOP if the path is a
703 // symlink. However, FreeBSD (which ironically originated O_NOFOLLOW) sets it to
704 // EMLINK.
705 #ifdef __FreeBSD__
706 #define ENOFOLLOWSYMLINK EMLINK
707 #else
708 #define ENOFOLLOWSYMLINK ELOOP
709 #endif
710 
struct_stat_to_watchman_stat(const struct stat * st,struct watchman_stat * target)711 static void struct_stat_to_watchman_stat(const struct stat *st,
712     struct watchman_stat *target) {
713   target->size = (off_t)st->st_size;
714   target->mode = st->st_mode;
715   target->uid = st->st_uid;
716   target->gid = st->st_gid;
717   target->ino = st->st_ino;
718   target->dev = st->st_dev;
719   target->nlink = st->st_nlink;
720   memcpy(&target->atime, &st->WATCHMAN_ST_TIMESPEC(a),
721       sizeof(target->atime));
722   memcpy(&target->mtime, &st->WATCHMAN_ST_TIMESPEC(m),
723       sizeof(target->mtime));
724   memcpy(&target->ctime, &st->WATCHMAN_ST_TIMESPEC(c),
725       sizeof(target->ctime));
726 }
727 
stat_path(w_root_t * root,struct watchman_pending_collection * coll,w_string_t * full_path,struct timeval now,int flags,struct watchman_dir_ent * pre_stat)728 static void stat_path(w_root_t *root,
729     struct watchman_pending_collection *coll, w_string_t *full_path,
730     struct timeval now,
731     int flags,
732     struct watchman_dir_ent *pre_stat)
733 {
734   struct watchman_stat st;
735   int res, err;
736   char path[WATCHMAN_NAME_MAX];
737   struct watchman_dir *dir;
738   struct watchman_dir *dir_ent = NULL;
739   struct watchman_file *file = NULL;
740   w_string_t *dir_name;
741   w_string_t *file_name;
742   bool recursive = flags & W_PENDING_RECURSIVE;
743   bool via_notify = flags & W_PENDING_VIA_NOTIFY;
744 
745   if (w_ht_get(root->ignore_dirs, w_ht_ptr_val(full_path))) {
746     w_log(W_LOG_DBG, "%.*s matches ignore_dir rules\n",
747         full_path->len, full_path->buf);
748     return;
749   }
750 
751   if (full_path->len > sizeof(path)-1) {
752     w_log(W_LOG_FATAL, "path %.*s is too big\n",
753         full_path->len, full_path->buf);
754   }
755 
756   memcpy(path, full_path->buf, full_path->len);
757   path[full_path->len] = 0;
758 
759   dir_name = w_string_dirname(full_path);
760   file_name = w_string_basename(full_path);
761   dir = w_root_resolve_dir(root, dir_name, true);
762 
763   if (dir->files) {
764     file = w_ht_val_ptr(w_ht_get(dir->files, w_ht_ptr_val(file_name)));
765   }
766 
767   if (dir->dirs) {
768     dir_ent = w_ht_val_ptr(w_ht_get(dir->dirs, w_ht_ptr_val(full_path)));
769   }
770 
771   if (pre_stat && pre_stat->has_stat) {
772     memcpy(&st, &pre_stat->stat, sizeof(st));
773     res = 0;
774     err = 0;
775   } else {
776     struct stat struct_stat;
777     res = w_lstat(path, &struct_stat, root->case_sensitive);
778     err = res == 0 ? 0 : errno;
779     w_log(W_LOG_DBG, "w_lstat(%s) file=%p dir=%p res=%d %s\n",
780         path, file, dir_ent, res, strerror(err));
781     if (err == 0) {
782       struct_stat_to_watchman_stat(&struct_stat, &st);
783     } else {
784       // To suppress warning on win32
785       memset(&st, 0, sizeof(st));
786     }
787   }
788 
789   if (res && (err == ENOENT || err == ENOTDIR)) {
790     /* it's not there, update our state */
791     if (dir_ent) {
792       w_root_mark_deleted(root, dir_ent, now, true);
793       w_log(W_LOG_DBG, "w_lstat(%s) -> %s so stopping watch on %.*s\n", path,
794             strerror(err), dir_ent->path->len, dir_ent->path->buf);
795       stop_watching_dir(root, dir_ent);
796     }
797     if (file) {
798       if (file->exists) {
799         w_log(W_LOG_DBG, "w_lstat(%s) -> %s so marking %.*s deleted\n",
800             path, strerror(err), file->name->len, file->name->buf);
801         file->exists = false;
802         w_root_mark_file_changed(root, file, now);
803       }
804     } else {
805       // It was created and removed before we could ever observe it
806       // in the filesystem.  We need to generate a deleted file
807       // representation of it now, so that subscription clients can
808       // be notified of this event
809       file = w_root_resolve_file(root, dir, file_name, now);
810       w_log(W_LOG_DBG, "w_lstat(%s) -> %s and file node was NULL. "
811           "Generating a deleted node.\n", path, strerror(err));
812       file->exists = false;
813       w_root_mark_file_changed(root, file, now);
814     }
815 
816     if (!root->case_sensitive &&
817         !w_string_equal(dir_name, root->root_path)) {
818       /* If we rejected the name because it wasn't canonical,
819        * we need to ensure that we look in the parent dir to discover
820        * the new item(s) */
821       w_log(W_LOG_DBG, "we're case insensitive, and %s is ENOENT, "
822                        "speculatively look at parent dir %.*s\n",
823             path, dir_name->len, dir_name->buf);
824       stat_path(root, coll, dir_name, now, 0, NULL);
825     }
826 
827   } else if (res) {
828     w_log(W_LOG_ERR, "w_lstat(%s) %d %s\n",
829         path, err, strerror(err));
830   } else {
831     if (!file) {
832       file = w_root_resolve_file(root, dir, file_name, now);
833     }
834 
835     if (!file->exists) {
836       /* we're transitioning from deleted to existing,
837        * so we're effectively new again */
838       file->ctime.ticks = root->ticks;
839       file->ctime.tv = now;
840       /* if a dir was deleted and now exists again, we want
841        * to crawl it again */
842       recursive = true;
843     }
844     if (!file->exists || via_notify || did_file_change(&file->stat, &st)) {
845       w_log(W_LOG_DBG,
846           "file changed exists=%d via_notify=%d stat-changed=%d isdir=%d %s\n",
847           (int)file->exists,
848           (int)via_notify,
849           (int)(file->exists && !via_notify),
850           S_ISDIR(st.mode),
851           path
852       );
853       file->exists = true;
854       w_root_mark_file_changed(root, file, now);
855     }
856 
857     memcpy(&file->stat, &st, sizeof(file->stat));
858 
859     if (S_ISDIR(st.mode)) {
860       if (dir_ent == NULL) {
861         recursive = true;
862       }
863 
864       // Don't recurse if our parent is an ignore dir
865       if (!w_ht_get(root->ignore_vcs, w_ht_ptr_val(dir_name)) ||
866           // but do if we're looking at the cookie dir (stat_path is never
867           // called for the root itself)
868           w_string_equal(full_path, root->query_cookie_dir)) {
869 
870         if (!watcher_ops->flags & WATCHER_HAS_PER_FILE_NOTIFICATIONS) {
871           /* we always need to crawl, but may not need to be fully recursive */
872           w_pending_coll_add(coll, full_path, now,
873               W_PENDING_CRAWL_ONLY | (recursive ? W_PENDING_RECURSIVE : 0));
874         } else {
875           /* we get told about changes on the child, so we only
876            * need to crawl if we've never seen the dir before.
877            * An exception is that fsevents will only report the root
878            * of a dir rename and not a rename event for all of its
879            * children. */
880           if (recursive) {
881             w_pending_coll_add(coll, full_path, now,
882                 W_PENDING_RECURSIVE|W_PENDING_CRAWL_ONLY);
883           }
884         }
885       }
886     } else if (dir_ent) {
887       // We transitioned from dir to file (see fishy.php), so we should prune
888       // our former tree here
889       w_root_mark_deleted(root, dir_ent, now, true);
890     }
891     if ((watcher_ops->flags & WATCHER_HAS_PER_FILE_NOTIFICATIONS) &&
892         !S_ISDIR(st.mode) &&
893         !w_string_equal(dir_name, root->root_path)) {
894       /* Make sure we update the mtime on the parent directory. */
895       stat_path(root, coll, dir_name, now, flags & W_PENDING_VIA_NOTIFY, NULL);
896     }
897   }
898 
899   // out is only used on some platforms, so on others compilers will complain
900   // about it being unused
901   goto out;
902 
903 out:
904   w_string_delref(dir_name);
905   w_string_delref(file_name);
906 }
907 
908 
w_root_process_path(w_root_t * root,struct watchman_pending_collection * coll,w_string_t * full_path,struct timeval now,int flags,struct watchman_dir_ent * pre_stat)909 void w_root_process_path(w_root_t *root,
910     struct watchman_pending_collection *coll, w_string_t *full_path,
911     struct timeval now, int flags,
912     struct watchman_dir_ent *pre_stat)
913 {
914   /* From a particular query's point of view, there are four sorts of cookies we
915    * can observe:
916    * 1. Cookies that this query has created. This marks the end of this query's
917    *    sync_to_now, so we hide it from the results.
918    * 2. Cookies that another query on the same watch by the same process has
919    *    created. This marks the end of that other query's sync_to_now, so from
920    *    the point of view of this query we turn a blind eye to it.
921    * 3. Cookies created by another process on the same watch. We're independent
922    *    of other processes, so we report these.
923    * 4. Cookies created by a nested watch by the same or a different process.
924    *    We're independent of other watches, so we report these.
925    *
926    * The below condition is true for cases 1 and 2 and false for 3 and 4.
927    */
928   if (w_string_startswith(full_path, root->query_cookie_prefix)) {
929     struct watchman_query_cookie *cookie;
930     bool consider_cookie =
931       (watcher_ops->flags & WATCHER_HAS_PER_FILE_NOTIFICATIONS) ?
932       ((flags & W_PENDING_VIA_NOTIFY) || !root->done_initial) : true;
933 
934     if (!consider_cookie) {
935       // Never allow cookie files to show up in the tree
936       return;
937     }
938 
939     cookie = w_ht_val_ptr(w_ht_get(root->query_cookies,
940                                    w_ht_ptr_val(full_path)));
941     w_log(W_LOG_DBG, "cookie! %.*s cookie=%p\n",
942         full_path->len, full_path->buf, cookie);
943 
944     if (cookie) {
945       cookie->seen = true;
946       pthread_cond_signal(&cookie->cond);
947     }
948 
949     // Never allow cookie files to show up in the tree
950     return;
951   }
952 
953   if (w_string_equal(full_path, root->root_path)
954       || (flags & W_PENDING_CRAWL_ONLY) == W_PENDING_CRAWL_ONLY) {
955     crawler(root, coll, full_path, now,
956         (flags & W_PENDING_RECURSIVE) == W_PENDING_RECURSIVE);
957   } else {
958     stat_path(root, coll, full_path, now, flags, pre_stat);
959   }
960 }
961 
962 /* recursively mark the dir contents as deleted */
w_root_mark_deleted(w_root_t * root,struct watchman_dir * dir,struct timeval now,bool recursive)963 void w_root_mark_deleted(w_root_t *root, struct watchman_dir *dir,
964     struct timeval now, bool recursive)
965 {
966   w_ht_iter_t i;
967 
968   if (w_ht_first(dir->files, &i)) do {
969     struct watchman_file *file = w_ht_val_ptr(i.value);
970 
971     if (file->exists) {
972       w_log(W_LOG_DBG, "mark_deleted: %.*s%c%.*s\n",
973           dir->path->len, dir->path->buf,
974           WATCHMAN_DIR_SEP,
975           file->name->len, file->name->buf);
976       file->exists = false;
977       w_root_mark_file_changed(root, file, now);
978     }
979 
980   } while (w_ht_next(dir->files, &i));
981 
982   if (recursive && w_ht_first(dir->dirs, &i)) do {
983     struct watchman_dir *child = w_ht_val_ptr(i.value);
984 
985     w_root_mark_deleted(root, child, now, true);
986   } while (w_ht_next(dir->dirs, &i));
987 }
988 
handle_open_errno(w_root_t * root,struct watchman_dir * dir,struct timeval now,const char * syscall,int err,const char * reason)989 void handle_open_errno(w_root_t *root, struct watchman_dir *dir,
990     struct timeval now, const char *syscall, int err, const char *reason)
991 {
992   w_string_t *dir_name = dir->path;
993   w_string_t *warn = NULL;
994   bool log_warning = true;
995   bool transient = false;
996 
997   if (err == ENOENT || err == ENOTDIR || err == ENOFOLLOWSYMLINK) {
998     log_warning = false;
999     transient = false;
1000   } else if (err == EACCES || err == EPERM) {
1001     log_warning = true;
1002     transient = false;
1003   } else {
1004     log_warning = true;
1005     transient = true;
1006   }
1007 
1008   if (w_string_equal(dir_name, root->root_path)) {
1009     if (!transient) {
1010       w_log(W_LOG_ERR,
1011             "%s(%.*s) -> %s. Root was deleted; cancelling watch\n",
1012             syscall, dir_name->len, dir_name->buf,
1013             reason ? reason : strerror(err));
1014       w_root_cancel(root);
1015       return;
1016     }
1017   }
1018 
1019   warn = w_string_make_printf(
1020       "%s(%.*s) -> %s. Marking this portion of the tree deleted",
1021       syscall, dir_name->len, dir_name->buf,
1022       reason ? reason : strerror(err));
1023 
1024   w_log(W_LOG_ERR, "%.*s\n", warn->len, warn->buf);
1025   if (log_warning) {
1026     w_root_set_warning(root, warn);
1027   }
1028   w_string_delref(warn);
1029 
1030   stop_watching_dir(root, dir);
1031   w_root_mark_deleted(root, dir, now, true);
1032 }
1033 
w_root_set_warning(w_root_t * root,w_string_t * str)1034 void w_root_set_warning(w_root_t *root, w_string_t *str) {
1035   if (root->warning) {
1036     w_string_delref(root->warning);
1037   }
1038   root->warning = str;
1039   if (root->warning) {
1040     w_string_addref(root->warning);
1041   }
1042 }
1043 
set_poison_state(w_root_t * root,w_string_t * dir,struct timeval now,const char * syscall,int err,const char * reason)1044 void set_poison_state(w_root_t *root, w_string_t *dir,
1045     struct timeval now, const char *syscall, int err, const char *reason)
1046 {
1047   char *why = NULL;
1048 
1049   unused_parameter(root);
1050 
1051   if (poisoned_reason) {
1052     return;
1053   }
1054 
1055   ignore_result(asprintf(&why,
1056 "A non-recoverable condition has triggered.  Watchman needs your help!\n"
1057 "The triggering condition was at timestamp=%ld: %s(%.*s) -> %s\n"
1058 "All requests will continue to fail with this message until you resolve\n"
1059 "the underlying problem.  You will find more information on fixing this at\n"
1060 "%s#poison-%s\n",
1061     (long)now.tv_sec,
1062     syscall,
1063     dir->len,
1064     dir->buf,
1065     reason ? reason : strerror(err),
1066     cfg_get_trouble_url(),
1067     syscall
1068   ));
1069 
1070   w_log(W_LOG_ERR, "%s", why);
1071 
1072   // This assignment can race for store with other threads.  We don't
1073   // care about that; we consider ourselves broken and the worst case
1074   // is that we leak a handful of strings around the race
1075   poisoned_reason = why;
1076 }
1077 
crawler(w_root_t * root,struct watchman_pending_collection * coll,w_string_t * dir_name,struct timeval now,bool recursive)1078 static void crawler(w_root_t *root, struct watchman_pending_collection *coll,
1079     w_string_t *dir_name, struct timeval now, bool recursive)
1080 {
1081   struct watchman_dir *dir;
1082   struct watchman_file *file;
1083   struct watchman_dir_handle *osdir;
1084   struct watchman_dir_ent *dirent;
1085   w_ht_iter_t i;
1086   char path[WATCHMAN_NAME_MAX];
1087   bool stat_all = false;
1088 
1089   if (watcher_ops->flags & WATCHER_HAS_PER_FILE_NOTIFICATIONS) {
1090     stat_all = watcher_ops->flags & WATCHER_COALESCED_RENAME;
1091   } else {
1092     // If the watcher doesn't give us per-file notifications for
1093     // watched dirs, then we'll end up explicitly tracking them
1094     // and will get updates for the files explicitly.
1095     // We don't need to look at the files again when we crawl
1096     stat_all = false;
1097   }
1098 
1099   dir = w_root_resolve_dir(root, dir_name, true);
1100 
1101   memcpy(path, dir_name->buf, dir_name->len);
1102   path[dir_name->len] = 0;
1103 
1104   w_log(W_LOG_DBG, "opendir(%s) recursive=%s\n",
1105       path, recursive ? "true" : "false");
1106 
1107   /* Start watching and open the dir for crawling.
1108    * Whether we open the dir prior to watching or after is watcher specific,
1109    * so the operations are rolled together in our abstraction */
1110   osdir = watcher_ops->root_start_watch_dir(watcher, root, dir, now, path);
1111   if (!osdir) {
1112     return;
1113   }
1114 
1115   if (!dir->files) {
1116     // Pre-size our hash(es) if we can, so that we can avoid collisions
1117     // and re-hashing during initial crawl
1118     uint32_t num_dirs = 0;
1119 #ifndef _WIN32
1120     struct stat st;
1121     int dfd = w_dir_fd(osdir);
1122     if (dfd != -1 && fstat(dfd, &st) == 0) {
1123       num_dirs = (uint32_t)st.st_nlink;
1124     }
1125 #endif
1126     // st.st_nlink is usually number of dirs + 2 (., ..).
1127     // If it is less than 2 then it doesn't follow that convention.
1128     // We just pass it through for the dir size hint and the hash
1129     // table implementation will round that up to the next power of 2
1130     apply_dir_size_hint(dir, num_dirs, (uint32_t)cfg_get_int(
1131                                            root, "hint_num_files_per_dir", 64));
1132   }
1133 
1134   /* flag for delete detection */
1135   if (w_ht_first(dir->files, &i)) do {
1136     file = w_ht_val_ptr(i.value);
1137     if (file->exists) {
1138       file->maybe_deleted = true;
1139     }
1140   } while (w_ht_next(dir->files, &i));
1141 
1142   while ((dirent = w_dir_read(osdir)) != NULL) {
1143     w_string_t *name;
1144 
1145     // Don't follow parent/self links
1146     if (dirent->d_name[0] == '.' && (
1147           !strcmp(dirent->d_name, ".") ||
1148           !strcmp(dirent->d_name, "..")
1149         )) {
1150       continue;
1151     }
1152 
1153     // Queue it up for analysis if the file is newly existing
1154     name = w_string_new(dirent->d_name);
1155     if (dir->files) {
1156       file = w_ht_val_ptr(w_ht_get(dir->files, w_ht_ptr_val(name)));
1157     } else {
1158       file = NULL;
1159     }
1160     if (file) {
1161       file->maybe_deleted = false;
1162     }
1163     if (!file || !file->exists || stat_all || recursive) {
1164       w_string_t *full_path = w_string_path_cat_cstr(dir->path,
1165                                 dirent->d_name);
1166       if (full_path) {
1167         w_log(W_LOG_DBG, "in crawler[%.*s], calling process_path on %.*s\n",
1168             dir->path->len, dir->path->buf,
1169             full_path->len, full_path->buf);
1170         w_root_process_path(root, coll, full_path, now,
1171                                 ((recursive || !file || !file->exists)
1172                                      ? W_PENDING_RECURSIVE
1173                                      : 0),
1174                             dirent);
1175         w_string_delref(full_path);
1176       } else {
1177         w_log(W_LOG_ERR, "OOM during crawl\n");
1178       }
1179     }
1180     w_string_delref(name);
1181   }
1182   w_dir_close(osdir);
1183 
1184   // Anything still in maybe_deleted is actually deleted.
1185   // Arrange to re-process it shortly
1186   if (w_ht_first(dir->files, &i)) do {
1187     file = w_ht_val_ptr(i.value);
1188     if (file->exists && (file->maybe_deleted ||
1189           (S_ISDIR(file->stat.mode) && recursive))) {
1190       w_pending_coll_add_rel(coll, dir, file->name->buf,
1191           now, recursive ? W_PENDING_RECURSIVE : 0);
1192     }
1193   } while (w_ht_next(dir->files, &i));
1194 }
1195 
vcs_file_exists(w_root_t * root,const char * dname,const char * fname)1196 static bool vcs_file_exists(w_root_t *root,
1197     const char *dname, const char *fname)
1198 {
1199   struct watchman_dir *dir;
1200   struct watchman_file *file;
1201   w_string_t *file_name;
1202   w_string_t *dir_name;
1203   w_string_t *rel_dir_name;
1204 
1205   rel_dir_name = w_string_new(dname);
1206   dir_name = w_string_path_cat(root->root_path, rel_dir_name);
1207   w_string_delref(rel_dir_name);
1208 
1209   dir = w_root_resolve_dir(root, dir_name, false);
1210   w_string_delref(dir_name);
1211 
1212   if (!dir) {
1213     return false;
1214   }
1215 
1216   if (!dir->files) {
1217     return false;
1218   }
1219 
1220   file_name = w_string_new(fname);
1221   file = w_ht_val_ptr(w_ht_get(dir->files, w_ht_ptr_val(file_name)));
1222   w_string_delref(file_name);
1223 
1224   if (!file) {
1225     return false;
1226   }
1227 
1228   return file->exists;
1229 }
1230 
is_vcs_op_in_progress(w_root_t * root)1231 static bool is_vcs_op_in_progress(w_root_t *root) {
1232   return vcs_file_exists(root, ".hg", "wlock") ||
1233          vcs_file_exists(root, ".git", "index.lock");
1234 }
1235 
process_subscriptions(w_root_t * root)1236 static void process_subscriptions(w_root_t *root)
1237 {
1238   w_ht_iter_t iter;
1239   bool vcs_in_progress;
1240 
1241   pthread_mutex_lock(&w_client_lock);
1242 
1243   if (!w_ht_first(clients, &iter)) {
1244     // No subscribers
1245     goto done;
1246   }
1247 
1248   // If it looks like we're in a repo undergoing a rebase or
1249   // other similar operation, we want to defer subscription
1250   // notifications until things settle down
1251   vcs_in_progress = is_vcs_op_in_progress(root);
1252 
1253   do {
1254     struct watchman_client *client = w_ht_val_ptr(iter.value);
1255     w_ht_iter_t citer;
1256 
1257     if (w_ht_first(client->subscriptions, &citer)) do {
1258       struct watchman_client_subscription *sub = w_ht_val_ptr(citer.value);
1259       bool defer = false;
1260       bool drop = false;
1261 
1262       if (sub->root != root) {
1263         w_log(W_LOG_DBG, "root doesn't match, skipping\n");
1264         continue;
1265       }
1266       w_log(W_LOG_DBG, "client->stm=%p sub=%p %s, last=%" PRIu32
1267           " pending=%" PRIu32 "\n",
1268           client->stm, sub, sub->name->buf, sub->last_sub_tick,
1269           root->pending_sub_tick);
1270 
1271       if (sub->last_sub_tick == root->pending_sub_tick) {
1272         continue;
1273       }
1274 
1275       if (root->asserted_states && w_ht_size(root->asserted_states) > 0
1276           && sub->drop_or_defer) {
1277         w_ht_iter_t policy_iter;
1278         w_string_t *policy_name = NULL;
1279 
1280         // There are 1 or more states asserted and this subscription
1281         // has some policy for states.  Figure out what we should do.
1282         if (w_ht_first(sub->drop_or_defer, &policy_iter)) do {
1283           w_string_t *name = w_ht_val_ptr(policy_iter.key);
1284           bool policy_is_drop = policy_iter.value;
1285 
1286           if (!w_ht_get(root->asserted_states, policy_iter.key)) {
1287             continue;
1288           }
1289 
1290           if (!defer) {
1291             // This policy is active
1292             defer = true;
1293             policy_name = name;
1294           }
1295 
1296           if (policy_is_drop) {
1297             drop = true;
1298 
1299             // If we're dropping, we don't need to look at any
1300             // other policies
1301             policy_name = name;
1302             break;
1303           }
1304           // Otherwise keep looking until we find a drop
1305         } while (w_ht_next(sub->drop_or_defer, &policy_iter));
1306 
1307         if (drop) {
1308           // fast-forward over any notifications while in the drop state
1309           sub->last_sub_tick = root->pending_sub_tick;
1310           w_log(W_LOG_DBG, "dropping subscription notifications for %s "
1311               "until state %s is vacated\n", sub->name->buf, policy_name->buf);
1312           continue;
1313         }
1314 
1315         if (defer) {
1316           w_log(W_LOG_DBG, "deferring subscription notifications for %s "
1317               "until state %s is vacated\n", sub->name->buf, policy_name->buf);
1318           continue;
1319         }
1320       }
1321 
1322       if (sub->vcs_defer && vcs_in_progress) {
1323         w_log(W_LOG_DBG, "deferring subscription notifications for %s "
1324           "until VCS operations complete\n", sub->name->buf);
1325         continue;
1326       }
1327 
1328       w_run_subscription_rules(client, sub, root);
1329       sub->last_sub_tick = root->pending_sub_tick;
1330 
1331     } while (w_ht_next(client->subscriptions, &citer));
1332 
1333   } while (w_ht_next(clients, &iter));
1334 done:
1335   pthread_mutex_unlock(&w_client_lock);
1336 }
1337 
1338 /* process any pending triggers.
1339  * must be called with root locked
1340  */
process_triggers(w_root_t * root)1341 static void process_triggers(w_root_t *root)
1342 {
1343   w_ht_iter_t iter;
1344 
1345   if (root->last_trigger_tick == root->pending_trigger_tick) {
1346     return;
1347   }
1348 
1349   // If it looks like we're in a repo undergoing a rebase or
1350   // other similar operation, we want to defer triggers until
1351   // things settle down
1352   if (is_vcs_op_in_progress(root)) {
1353     w_log(W_LOG_DBG, "deferring triggers until VCS operations complete\n");
1354     return;
1355   }
1356 
1357   w_log(W_LOG_DBG, "last=%" PRIu32 "  pending=%" PRIu32 "\n",
1358       root->last_trigger_tick,
1359       root->pending_trigger_tick);
1360 
1361   /* walk the list of triggers, and run their rules */
1362   if (w_ht_first(root->commands, &iter)) do {
1363     struct watchman_trigger_command *cmd = w_ht_val_ptr(iter.value);
1364 
1365     if (cmd->current_proc) {
1366       // Don't spawn if there's one already running
1367       w_log(W_LOG_DBG, "process_triggers: %.*s is already running\n",
1368           cmd->triggername->len, cmd->triggername->buf);
1369       continue;
1370     }
1371 
1372     w_assess_trigger(root, cmd);
1373 
1374   } while (w_ht_next(root->commands, &iter));
1375 
1376   root->last_trigger_tick = root->pending_trigger_tick;
1377 }
1378 
1379 /* fsevents won't tell us about creation events for dangling symlinks;
1380  * we have to check to find those for ourselves.  To manage this, every
1381  * time we transition into being initially settled, we'll collect a
1382  * list of dirs that were modified since the last settle event and rescan
1383  * them (non-recursive).
1384  * We'll do this inspection in the context of the IO thread.
1385  * If we return true it means that we found something that the watcher
1386  * missed.
1387  */
recheck_dirs(w_root_t * root,struct watchman_pending_collection * coll)1388 static bool recheck_dirs(w_root_t *root,
1389     struct watchman_pending_collection *coll) {
1390   struct watchman_file *f;
1391   struct timeval now;
1392 
1393   if (root->last_recheck_tick >= root->ticks) {
1394     return false;
1395   }
1396 
1397   w_log(W_LOG_DBG, "recheck!, last_recheck_tick=%d root->ticks=%d\n",
1398         root->last_recheck_tick, root->ticks);
1399 
1400   gettimeofday(&now, NULL);
1401 
1402   // First pass: collect a list of recently changed dirs
1403   for (f = root->latest_file; f; f = f->next) {
1404     // check dirs, but only if we've seen them change recently
1405     if (f->otime.ticks <= root->last_recheck_tick) {
1406       continue;
1407     }
1408 
1409     if (S_ISDIR(f->stat.mode)) {
1410       // This was a dir, so check it again
1411       w_pending_coll_add_rel(coll, f->parent, f->name->buf, now, 0);
1412     } else {
1413       // Crawl the parent dir
1414       w_pending_coll_add(coll, f->parent->path, now, 0);
1415     }
1416   }
1417 
1418   if (w_pending_coll_size(coll) == 0) {
1419     // We're all up to date
1420     root->last_recheck_tick = root->ticks;
1421     w_log(W_LOG_DBG,
1422           "recheck complete, last_recheck_tick=%d root->ticks=%d\n",
1423           root->last_recheck_tick, root->ticks);
1424     return false;
1425   }
1426 
1427   w_log(W_LOG_DBG, "Re-checking %d dirs (before considering symlinks)\n",
1428       w_pending_coll_size(coll));
1429 
1430   // Now that we know that something recently changed, let's go looking
1431   // for symlinks and explicitly check their containing dirs for changes too
1432   for (f = root->latest_file; f; f = f->next) {
1433     if (S_ISLNK(f->stat.mode) && f->exists) {
1434       // Re-examine this symlink
1435       w_pending_coll_add_rel(coll, f->parent, f->name->buf, now, 0);
1436       // and re-crawl its parent dir to discover other potentially newly
1437       // created symlinks that were previously dangling
1438       w_pending_coll_add(coll, f->parent->path, now, 0);
1439     }
1440   }
1441 
1442   w_log(W_LOG_DBG, "Re-checking %d dirs (after considering symlinks)\n",
1443       w_pending_coll_size(coll));
1444   // Move the recheck window forward, and bump the tick counter
1445   // ready to observe anything new in the crawl(s) that we trigger next
1446   root->last_recheck_tick = root->ticks++;
1447 
1448   // Now re-examine the list of dirs
1449   while (w_root_process_pending(root, coll, false)) {
1450     ;
1451   }
1452   w_log(W_LOG_DBG, "recheck complete, last_recheck_tick=%d root->ticks=%d\n",
1453         root->last_recheck_tick, root->ticks);
1454 
1455   // This is a bit icky, but let's find out how many things we observed
1456   // change as a result of this check; if none, then we return false
1457   for (f = root->latest_file; f; f = f->next) {
1458     if (f->otime.ticks <= root->last_recheck_tick) {
1459       // No more changes in the appropriate time range;
1460       // nothing changed as a result of this recheck
1461       return false;
1462     }
1463     if (f->otime.ticks == root->ticks) {
1464       // Yep, something was updated.
1465       // Log what it was so that we can debug situations where we don't
1466       // really settle.
1467       w_log(W_LOG_DBG, "Re-check: %.*s/%.*s was updated at tick=%d\n",
1468           f->parent->path->len, f->parent->path->buf,
1469           f->name->len, f->name->buf,
1470           f->otime.ticks);
1471       return true;
1472     }
1473   }
1474 
1475   return false;
1476 }
1477 
handle_should_recrawl(w_root_t * root)1478 static bool handle_should_recrawl(w_root_t *root)
1479 {
1480   if (root->should_recrawl && !root->cancelled) {
1481     char *errmsg;
1482     // be careful, this is a bit of a switcheroo
1483     w_root_teardown(root);
1484     if (!w_root_init(root, &errmsg)) {
1485       w_log(W_LOG_ERR, "failed to init root %.*s, cancelling watch: %s\n",
1486           root->root_path->len, root->root_path->buf, errmsg);
1487       // this should cause us to exit from the notify loop
1488       w_root_cancel(root);
1489     }
1490     root->recrawl_count++;
1491     if (!watcher_ops->root_start(watcher, root)) {
1492       w_log(W_LOG_ERR, "failed to start root %.*s, cancelling watch: %.*s\n",
1493           root->root_path->len, root->root_path->buf,
1494           root->failure_reason->len, root->failure_reason->buf);
1495       w_root_cancel(root);
1496     }
1497     w_pending_coll_ping(&root->pending);
1498     return true;
1499   }
1500   return false;
1501 }
1502 
wait_for_notify(w_root_t * root,int timeoutms)1503 static bool wait_for_notify(w_root_t *root, int timeoutms)
1504 {
1505   return watcher_ops->root_wait_notify(watcher, root, timeoutms);
1506 }
1507 
consume_notify(w_root_t * root,struct watchman_pending_collection * coll)1508 static bool consume_notify(w_root_t *root,
1509     struct watchman_pending_collection *coll)
1510 {
1511   return watcher_ops->root_consume_notify(watcher, root, coll);
1512 }
1513 
free_file_node(struct watchman_file * file)1514 static void free_file_node(struct watchman_file *file)
1515 {
1516   watcher_ops->file_free(watcher, file);
1517   w_string_delref(file->name);
1518   free(file);
1519 }
1520 
record_aged_out_dir(w_root_t * root,w_ht_t * aged_dir_names,struct watchman_dir * dir)1521 static void record_aged_out_dir(w_root_t *root, w_ht_t *aged_dir_names,
1522     struct watchman_dir *dir)
1523 {
1524   w_ht_iter_t i;
1525 
1526   w_log(W_LOG_DBG, "age_out: remember dir %.*s\n",
1527       dir->path->len, dir->path->buf);
1528   w_ht_insert(aged_dir_names, w_ht_ptr_val(dir->path),
1529         w_ht_ptr_val(dir), false);
1530 
1531   if (dir->dirs && w_ht_first(dir->dirs, &i)) do {
1532     struct watchman_dir *child = w_ht_val_ptr(i.value);
1533 
1534     record_aged_out_dir(root, aged_dir_names, child);
1535     w_ht_iter_del(dir->dirs, &i);
1536   } while (w_ht_next(dir->dirs, &i));
1537 }
1538 
age_out_file(w_root_t * root,w_ht_t * aged_dir_names,struct watchman_file * file)1539 static void age_out_file(w_root_t *root, w_ht_t *aged_dir_names,
1540     struct watchman_file *file)
1541 {
1542   struct watchman_dir *dir;
1543   w_string_t *full_name;
1544 
1545   // Revise tick for fresh instance reporting
1546   root->last_age_out_tick = MAX(root->last_age_out_tick, file->otime.ticks);
1547 
1548   // And remove from the overall file list
1549   remove_from_file_list(root, file);
1550   remove_from_suffix_list(root, file);
1551 
1552   full_name = w_string_path_cat(file->parent->path, file->name);
1553 
1554   if (file->parent->files) {
1555     // Remove the entry from the containing file hash
1556     w_ht_del(file->parent->files, w_ht_ptr_val(file->name));
1557   }
1558   if (file->parent->dirs) {
1559     // Remove the entry from the containing dir hash
1560     w_ht_del(file->parent->dirs, w_ht_ptr_val(full_name));
1561   }
1562 
1563   // resolve the dir of the same name and mark it for later removal
1564   // from our internal datastructures
1565   dir = w_root_resolve_dir(root, full_name, false);
1566   if (dir) {
1567     record_aged_out_dir(root, aged_dir_names, dir);
1568   }
1569 
1570   // And free it.  We don't need to stop watching it, because we already
1571   // stopped watching it when we marked it as !exists
1572   free_file_node(file);
1573 
1574   w_string_delref(full_name);
1575 }
1576 
age_out_dir(w_root_t * root,struct watchman_dir * dir)1577 static void age_out_dir(w_root_t *root, struct watchman_dir *dir)
1578 {
1579   w_log(W_LOG_DBG, "age_out: ht_del dir %.*s\n",
1580       dir->path->len, dir->path->buf);
1581 
1582   assert(!dir->files || w_ht_size(dir->files) == 0);
1583 
1584   // This will implicitly call delete_dir() which will tear down
1585   // the files and dirs hashes
1586   w_ht_del(root->dirname_to_dir, w_ht_ptr_val(dir->path));
1587 }
1588 
1589 // Find deleted nodes older than the gc_age setting.
1590 // This is particularly useful in cases where your tree observes a
1591 // large number of creates and deletes for many unique filenames in
1592 // a given dir (eg: temporary/randomized filenames generated as part
1593 // of build tooling or atomic renames)
w_root_perform_age_out(w_root_t * root,int min_age)1594 void w_root_perform_age_out(w_root_t *root, int min_age)
1595 {
1596   struct watchman_file *file, *tmp;
1597   time_t now;
1598   w_ht_iter_t i;
1599   w_ht_t *aged_dir_names;
1600 
1601   time(&now);
1602   root->last_age_out_timestamp = now;
1603   aged_dir_names = w_ht_new(2, &w_ht_string_funcs);
1604 
1605   file = root->latest_file;
1606   while (file) {
1607     if (file->exists || file->otime.tv.tv_sec + min_age > now) {
1608       file = file->next;
1609       continue;
1610     }
1611 
1612     // Get the next file before we remove the current one
1613     tmp = file->next;
1614 
1615     w_log(W_LOG_DBG, "age_out file=%.*s%c%.*s\n",
1616         file->parent->path->len, file->parent->path->buf,
1617         WATCHMAN_DIR_SEP,
1618         file->name->len, file->name->buf);
1619 
1620     age_out_file(root, aged_dir_names, file);
1621 
1622     file = tmp;
1623   }
1624 
1625   // For each dir that matched a pruned file node, delete from
1626   // our internal structures
1627   if (w_ht_first(aged_dir_names, &i)) do {
1628     struct watchman_dir *dir = w_ht_val_ptr(i.value);
1629 
1630     age_out_dir(root, dir);
1631   } while (w_ht_next(aged_dir_names, &i));
1632   w_ht_free(aged_dir_names);
1633 
1634   // Age out cursors too.
1635   if (w_ht_first(root->cursors, &i)) do {
1636     if (i.value < root->last_age_out_tick) {
1637       w_ht_iter_del(root->cursors, &i);
1638     }
1639   } while (w_ht_next(root->cursors, &i));
1640 }
1641 
root_has_subscriptions(w_root_t * root)1642 static bool root_has_subscriptions(w_root_t *root) {
1643   bool has_subscribers = false;
1644   w_ht_iter_t iter;
1645 
1646   pthread_mutex_lock(&w_client_lock);
1647   if (w_ht_first(clients, &iter)) do {
1648     struct watchman_client *client = w_ht_val_ptr(iter.value);
1649     w_ht_iter_t citer;
1650 
1651     if (w_ht_first(client->subscriptions, &citer)) do {
1652       struct watchman_client_subscription *sub = w_ht_val_ptr(citer.value);
1653 
1654       if (sub->root == root) {
1655         has_subscribers = true;
1656         break;
1657       }
1658 
1659     } while (w_ht_next(client->subscriptions, &citer));
1660   } while (!has_subscribers && w_ht_next(clients, &iter));
1661   pthread_mutex_unlock(&w_client_lock);
1662   return has_subscribers;
1663 }
1664 
consider_age_out(w_root_t * root)1665 static void consider_age_out(w_root_t *root)
1666 {
1667   time_t now;
1668 
1669   if (root->gc_interval == 0) {
1670     return;
1671   }
1672 
1673   time(&now);
1674 
1675   if (now <= root->last_age_out_timestamp + root->gc_interval) {
1676     // Don't check too often
1677     return;
1678   }
1679 
1680   w_root_perform_age_out(root, root->gc_age);
1681 }
1682 
1683 // This is a little tricky.  We have to be called with root->lock
1684 // held, but we must not call w_root_stop_watch with the lock held,
1685 // so we return true if the caller should do that
consider_reap(w_root_t * root)1686 static bool consider_reap(w_root_t *root) {
1687   time_t now;
1688 
1689   if (root->idle_reap_age == 0) {
1690     return false;
1691   }
1692 
1693   time(&now);
1694 
1695   if (now > root->last_cmd_timestamp + root->idle_reap_age &&
1696       (root->commands == NULL || w_ht_size(root->commands) == 0) &&
1697       (now > root->last_reap_timestamp) &&
1698       !root_has_subscriptions(root)) {
1699     // We haven't had any activity in a while, and there are no registered
1700     // triggers or subscriptions against this watch.
1701     w_log(W_LOG_ERR, "root %.*s has had no activity in %d seconds and has "
1702         "no triggers or subscriptions, cancelling watch.  "
1703         "Set idle_reap_age_seconds in your .watchmanconfig to control "
1704         "this behavior\n",
1705         root->root_path->len, root->root_path->buf, root->idle_reap_age);
1706     return true;
1707   }
1708 
1709   root->last_reap_timestamp = now;
1710 
1711   return false;
1712 }
1713 
1714 // we want to consume inotify events as quickly as possible
1715 // to minimize the risk that the kernel event buffer overflows,
1716 // so we do this as a blocking thread that reads the inotify
1717 // descriptor and then queues the filesystem IO work until after
1718 // we have drained the inotify descriptor
notify_thread(w_root_t * root)1719 static void notify_thread(w_root_t *root)
1720 {
1721   struct watchman_pending_collection pending;
1722 
1723   if (!w_pending_coll_init(&pending)) {
1724     w_root_cancel(root);
1725     return;
1726   }
1727 
1728   if (!watcher_ops->root_start(watcher, root)) {
1729     w_log(W_LOG_ERR, "failed to start root %.*s, cancelling watch: %.*s\n",
1730         root->root_path->len, root->root_path->buf,
1731         root->failure_reason->len, root->failure_reason->buf);
1732     w_root_cancel(root);
1733     w_pending_coll_destroy(&pending);
1734     return;
1735   }
1736 
1737   // signal that we're done here, so that we can start the
1738   // io thread after this point
1739   w_pending_coll_lock(&root->pending);
1740   root->pending.pinged = true;
1741   w_pending_coll_ping(&root->pending);
1742   w_pending_coll_unlock(&root->pending);
1743 
1744   while (!root->cancelled) {
1745     // big number because not all watchers can deal with
1746     // -1 meaning infinite wait at the moment
1747     if (wait_for_notify(root, 86400)) {
1748       while (consume_notify(root, &pending)) {
1749         if (w_pending_coll_size(&pending) >= WATCHMAN_BATCH_LIMIT) {
1750           break;
1751         }
1752         if (!wait_for_notify(root, 0)) {
1753           break;
1754         }
1755       }
1756       if (w_pending_coll_size(&pending) > 0) {
1757         w_pending_coll_lock(&root->pending);
1758         w_pending_coll_append(&root->pending, &pending);
1759         w_pending_coll_ping(&root->pending);
1760         w_pending_coll_unlock(&root->pending);
1761       }
1762     }
1763 
1764     w_root_lock(root);
1765     handle_should_recrawl(root);
1766     w_root_unlock(root);
1767   }
1768 
1769   w_pending_coll_destroy(&pending);
1770 }
1771 
io_thread(w_root_t * root)1772 static void io_thread(w_root_t *root)
1773 {
1774   int timeoutms, biggest_timeout, recheck_timeout;
1775   struct watchman_pending_collection pending;
1776 
1777   timeoutms = root->trigger_settle;
1778 
1779   // Upper bound on sleep delay.  These options are measured in seconds.
1780   biggest_timeout = root->gc_interval;
1781   if (biggest_timeout == 0 ||
1782       (root->idle_reap_age != 0 && root->idle_reap_age < biggest_timeout)) {
1783     biggest_timeout = root->idle_reap_age;
1784   }
1785   if (biggest_timeout == 0) {
1786     biggest_timeout = 86400;
1787   }
1788   // And convert to milliseconds
1789   biggest_timeout *= 1000;
1790 
1791   recheck_timeout = (int)cfg_get_int(root, "recheck_dirs_interval_ms", 0);
1792   recheck_timeout = MIN(recheck_timeout, biggest_timeout);
1793 
1794   w_pending_coll_init(&pending);
1795 
1796   while (!root->cancelled) {
1797     bool pinged;
1798 
1799     if (!root->done_initial) {
1800       struct timeval start;
1801 
1802       /* first order of business is to find all the files under our root */
1803       if (cfg_get_bool(root, "iothrottle", false)) {
1804         w_ioprio_set_low();
1805       }
1806       w_root_lock(root);
1807       // Ensure that we observe these files with a new, distinct clock,
1808       // otherwise a fresh subscription established immediately after a watch
1809       // can get stuck with an empty view until another change is observed
1810       root->ticks++;
1811       gettimeofday(&start, NULL);
1812       w_pending_coll_add(&root->pending, root->root_path, start, 0);
1813       while (w_root_process_pending(root, &pending, true)) {
1814         ;
1815       }
1816       root->done_initial = true;
1817       // We just crawled everything, no need to recheck right now
1818       root->last_recheck_tick = root->ticks + 1;
1819       w_root_unlock(root);
1820       if (cfg_get_bool(root, "iothrottle", false)) {
1821         w_ioprio_set_normal();
1822       }
1823 
1824       w_log(W_LOG_ERR, "%scrawl complete\n", root->recrawl_count ? "re" : "");
1825       timeoutms = root->trigger_settle;
1826     }
1827 
1828     // Wait for the notify thread to give us pending items, or for
1829     // the settle period to expire
1830     w_log(W_LOG_DBG, "poll_events timeout=%dms\n", timeoutms);
1831     pinged = w_pending_coll_lock_and_wait(&root->pending, timeoutms);
1832     w_log(W_LOG_DBG, " ... wake up (pinged=%s)\n", pinged ? "true" : "false");
1833     w_pending_coll_append(&pending, &root->pending);
1834     w_pending_coll_unlock(&root->pending);
1835 
1836     if (!pinged && w_pending_coll_size(&pending) == 0) {
1837       // No new pending items were given to us, so consider that
1838       // we may now be settled.
1839 
1840       w_root_lock(root);
1841       if (!root->done_initial) {
1842         // we need to recrawl, stop what we're doing here
1843         w_root_unlock(root);
1844         continue;
1845       }
1846 
1847       // If we just settled, the timeout will be the base timeout.
1848       // This is an appropriate time to second guess the watcher
1849       // and locate anything that we think we may have missed
1850       if (recheck_timeout > 0 && timeoutms >= recheck_timeout) {
1851         if (recheck_dirs(root, &pending)) {
1852           // We're no longer settled, so reset the timeout
1853           timeoutms = root->trigger_settle;
1854         }
1855       }
1856 
1857       process_subscriptions(root);
1858       process_triggers(root);
1859       if (consider_reap(root)) {
1860         w_root_unlock(root);
1861         w_root_stop_watch(root);
1862         break;
1863       }
1864       consider_age_out(root);
1865       w_root_unlock(root);
1866 
1867       timeoutms = MIN(biggest_timeout, timeoutms * 2);
1868       continue;
1869     }
1870 
1871     // Otherwise we have pending items to stat and crawl
1872 
1873     // We are now, by definition, unsettled, so reduce sleep timeout
1874     // to the settle duration ready for the next loop through
1875     timeoutms = root->trigger_settle;
1876 
1877     w_root_lock(root);
1878     if (!root->done_initial) {
1879       // we need to recrawl.  Discard these notifications
1880       w_pending_coll_drain(&pending);
1881       w_root_unlock(root);
1882       continue;
1883     }
1884 
1885     root->ticks++;
1886     // If we're not settled, we need an opportunity to age out
1887     // dead file nodes.  This happens in the test harness.
1888     consider_age_out(root);
1889 
1890     while (w_root_process_pending(root, &pending, false)) {
1891       ;
1892     }
1893 
1894     w_root_unlock(root);
1895   }
1896 
1897   w_pending_coll_destroy(&pending);
1898 }
1899 
1900 /* This function always returns a buffer that needs to
1901  * be released via free(3).  We use the native feature
1902  * of the system libc if we know it is present, otherwise
1903  * we need to malloc a buffer for ourselves.  This
1904  * is made more fun because some systems have a dynamic
1905  * buffer size obtained via sysconf().
1906  */
w_realpath(const char * filename)1907 char *w_realpath(const char *filename)
1908 {
1909 #if defined(__GLIBC__) || defined(__APPLE__) || defined(_WIN32)
1910   return realpath(filename, NULL);
1911 #else
1912   char *buf = NULL;
1913   char *retbuf;
1914   int path_max = 0;
1915 
1916 #ifdef _SC_PATH_MAX
1917   path_max = sysconf(path, _SC_PATH_MAX);
1918 #endif
1919   if (path_max <= 0) {
1920     path_max = WATCHMAN_NAME_MAX;
1921   }
1922   buf = malloc(path_max);
1923   if (!buf) {
1924     return NULL;
1925   }
1926 
1927   retbuf = realpath(filename, buf);
1928 
1929   if (retbuf != buf) {
1930     free(buf);
1931     return NULL;
1932   }
1933 
1934   return retbuf;
1935 #endif
1936 }
1937 
w_root_addref(w_root_t * root)1938 void w_root_addref(w_root_t *root)
1939 {
1940   w_refcnt_add(&root->refcnt);
1941 }
1942 
w_root_teardown(w_root_t * root)1943 static void w_root_teardown(w_root_t *root)
1944 {
1945   struct watchman_file *file;
1946 
1947   watcher_ops->root_dtor(watcher, root);
1948 
1949   if (root->dirname_to_dir) {
1950     w_ht_free(root->dirname_to_dir);
1951     root->dirname_to_dir = NULL;
1952   }
1953   w_pending_coll_drain(&root->pending);
1954 
1955   while (root->latest_file) {
1956     file = root->latest_file;
1957     root->latest_file = file->next;
1958     free_file_node(file);
1959   }
1960 
1961   if (root->cursors) {
1962     w_ht_free(root->cursors);
1963     root->cursors = NULL;
1964   }
1965   if (root->suffixes) {
1966     w_ht_free(root->suffixes);
1967     root->suffixes = NULL;
1968   }
1969 }
1970 
w_root_delref(w_root_t * root)1971 void w_root_delref(w_root_t *root)
1972 {
1973   if (!w_refcnt_del(&root->refcnt)) return;
1974 
1975   w_log(W_LOG_DBG, "root: final ref on %s\n",
1976       root->root_path->buf);
1977 
1978   w_root_teardown(root);
1979 
1980   pthread_mutex_destroy(&root->lock);
1981   w_string_delref(root->root_path);
1982   w_ht_free(root->ignore_vcs);
1983   w_ht_free(root->ignore_dirs);
1984   w_ht_free(root->commands);
1985   w_ht_free(root->query_cookies);
1986 
1987   if (root->config_file) {
1988     json_decref(root->config_file);
1989   }
1990 
1991   if (root->last_recrawl_reason) {
1992     w_string_delref(root->last_recrawl_reason);
1993   }
1994   if (root->failure_reason) {
1995     w_string_delref(root->failure_reason);
1996   }
1997   if (root->warning) {
1998     w_string_delref(root->warning);
1999   }
2000 
2001   if (root->query_cookie_dir) {
2002     w_string_delref(root->query_cookie_dir);
2003   }
2004   if (root->query_cookie_prefix) {
2005     w_string_delref(root->query_cookie_prefix);
2006   }
2007   w_pending_coll_destroy(&root->pending);
2008 
2009   free(root);
2010   w_refcnt_del(&live_roots);
2011 }
2012 
root_copy_val(w_ht_val_t val)2013 static w_ht_val_t root_copy_val(w_ht_val_t val)
2014 {
2015   w_root_t *root = w_ht_val_ptr(val);
2016 
2017   w_root_addref(root);
2018 
2019   return val;
2020 }
2021 
root_del_val(w_ht_val_t val)2022 static void root_del_val(w_ht_val_t val)
2023 {
2024   w_root_t *root = w_ht_val_ptr(val);
2025 
2026   w_root_delref(root);
2027 }
2028 
2029 static const struct watchman_hash_funcs root_funcs = {
2030   w_ht_string_copy,
2031   w_ht_string_del,
2032   w_ht_string_equal,
2033   w_ht_string_hash,
2034   root_copy_val,
2035   root_del_val
2036 };
2037 
watchman_watcher_init(void)2038 void watchman_watcher_init(void) {
2039   watched_roots = w_ht_new(4, &root_funcs);
2040 
2041 #if HAVE_FSEVENTS
2042   watcher_ops = &fsevents_watcher;
2043 #elif defined(HAVE_PORT_CREATE)
2044   // We prefer portfs if you have both portfs and inotify on the assumption
2045   // that this is an Illumos based system with both and that the native
2046   // mechanism will yield more correct behavior.
2047   // https://github.com/facebook/watchman/issues/84
2048   watcher_ops = &portfs_watcher;
2049 #elif defined(HAVE_INOTIFY_INIT)
2050   watcher_ops = &inotify_watcher;
2051 #elif defined(HAVE_KQUEUE)
2052   watcher_ops = &kqueue_watcher;
2053 #elif defined(_WIN32)
2054   watcher_ops = &win32_watcher;
2055 #else
2056 # error you need to assign watcher_ops for this system
2057 #endif
2058 
2059   watcher = watcher_ops->global_init();
2060 
2061   w_log(W_LOG_ERR, "Using watcher mechanism %s\n", watcher_ops->name);
2062 }
2063 
watchman_watcher_dtor(void)2064 void watchman_watcher_dtor(void) {
2065   watcher_ops->global_dtor(watcher);
2066 }
2067 
2068 // Must not be called with root->lock held :-/
remove_root_from_watched(w_root_t * root)2069 static bool remove_root_from_watched(w_root_t *root)
2070 {
2071   bool removed = false;
2072   pthread_mutex_lock(&root_lock);
2073   // it's possible that the root has already been removed and replaced with
2074   // another, so make sure we're removing the right object
2075   if (w_ht_val_ptr(w_ht_get(watched_roots, w_ht_ptr_val(root->root_path))) ==
2076       root) {
2077     w_ht_del(watched_roots, w_ht_ptr_val(root->root_path));
2078     removed = true;
2079   }
2080   pthread_mutex_unlock(&root_lock);
2081   return removed;
2082 }
2083 
2084 /* Returns true if the global config root_restrict_files is not defined or if
2085  * one of the files in root_restrict_files exists, false otherwise. */
root_check_restrict(const char * watch_path)2086 static bool root_check_restrict(const char *watch_path)
2087 {
2088   json_t *root_restrict_files = NULL;
2089   uint32_t i;
2090   bool enforcing;
2091 
2092   root_restrict_files = cfg_compute_root_files(&enforcing);
2093   if (!root_restrict_files) {
2094     return true;
2095   }
2096   if (!enforcing) {
2097     json_decref(root_restrict_files);
2098     return true;
2099   }
2100 
2101   for (i = 0; i < json_array_size(root_restrict_files); i++) {
2102     json_t *obj = json_array_get(root_restrict_files, i);
2103     const char *restrict_file = json_string_value(obj);
2104     char *restrict_path;
2105     bool rv;
2106 
2107     if (!restrict_file) {
2108       w_log(W_LOG_ERR, "resolve_root: global config root_restrict_files "
2109             "element %" PRIu32 " should be a string\n", i);
2110       continue;
2111     }
2112 
2113     ignore_result(asprintf(&restrict_path, "%s%c%s", watch_path,
2114           WATCHMAN_DIR_SEP, restrict_file));
2115     rv = w_path_exists(restrict_path);
2116     free(restrict_path);
2117     if (rv)
2118       return true;
2119   }
2120 
2121   return false;
2122 }
2123 
check_allowed_fs(const char * filename,char ** errmsg)2124 static bool check_allowed_fs(const char *filename, char **errmsg)
2125 {
2126   w_string_t *fs_type = w_fstype(filename);
2127   json_t *illegal_fstypes = NULL;
2128   json_t *advice_string;
2129   uint32_t i;
2130   const char *advice = NULL;
2131 
2132   // Report this to the log always, as it is helpful in understanding
2133   // problem reports
2134   w_log(W_LOG_ERR, "path %s is on filesystem type %.*s\n",
2135       filename, fs_type->len, fs_type->buf);
2136 
2137   illegal_fstypes = cfg_get_json(NULL, "illegal_fstypes");
2138   if (!illegal_fstypes) {
2139     w_string_delref(fs_type);
2140     return true;
2141   }
2142 
2143   advice_string = cfg_get_json(NULL, "illegal_fstypes_advice");
2144   if (advice_string) {
2145     advice = json_string_value(advice_string);
2146   }
2147   if (!advice) {
2148     advice = "relocate the dir to an allowed filesystem type";
2149   }
2150 
2151   if (!json_is_array(illegal_fstypes)) {
2152     w_log(W_LOG_ERR,
2153           "resolve_root: global config illegal_fstypes is not an array\n");
2154     w_string_delref(fs_type);
2155     return true;
2156   }
2157 
2158   for (i = 0; i < json_array_size(illegal_fstypes); i++) {
2159     json_t *obj = json_array_get(illegal_fstypes, i);
2160     const char *name = json_string_value(obj);
2161 
2162     if (!name) {
2163       w_log(W_LOG_ERR, "resolve_root: global config illegal_fstypes "
2164             "element %" PRIu32 " should be a string\n", i);
2165       continue;
2166     }
2167 
2168     if (!w_string_equal_cstring(fs_type, name)) {
2169       continue;
2170     }
2171 
2172     ignore_result(asprintf(errmsg,
2173       "path uses the \"%.*s\" filesystem "
2174       "and is disallowed by global config illegal_fstypes: %s",
2175       fs_type->len, fs_type->buf, advice));
2176 
2177     w_string_delref(fs_type);
2178     return false;
2179   }
2180 
2181   w_string_delref(fs_type);
2182   return true;
2183 }
2184 
is_slash(char c)2185 static inline bool is_slash(char c) {
2186   return (c == '/') || (c == '\\');
2187 }
2188 
2189 // Given a filename, walk the current set of watches.
2190 // If a watch is a prefix match for filename then we consider it to
2191 // be an enclosing watch and we'll return the root path and the relative
2192 // path to filename.
2193 // Returns NULL if there were no matches.
2194 // If multiple watches have the same prefix, it is undefined which one will
2195 // match.
w_find_enclosing_root(const char * filename,char ** relpath)2196 char *w_find_enclosing_root(const char *filename, char **relpath) {
2197   w_ht_iter_t i;
2198   w_root_t *root = NULL;
2199   w_string_t *name = w_string_new(filename);
2200   char *prefix = NULL;
2201 
2202   pthread_mutex_lock(&root_lock);
2203   if (w_ht_first(watched_roots, &i)) do {
2204     w_string_t *root_name = w_ht_val_ptr(i.key);
2205     if (w_string_startswith(name, root_name) && (
2206           name->len == root_name->len /* exact match */ ||
2207           is_slash(name->buf[root_name->len]) /* dir container matches */)) {
2208       root = w_ht_val_ptr(i.value);
2209       w_root_addref(root);
2210       break;
2211     }
2212   } while (w_ht_next(watched_roots, &i));
2213   pthread_mutex_unlock(&root_lock);
2214 
2215   if (!root) {
2216     goto out;
2217   }
2218 
2219   // extract the path portions
2220   prefix = malloc(root->root_path->len + 1);
2221   if (!prefix) {
2222     goto out;
2223   }
2224   memcpy(prefix, filename, root->root_path->len);
2225   prefix[root->root_path->len] = '\0';
2226 
2227   if (root->root_path->len == name->len) {
2228     *relpath = NULL;
2229   } else {
2230     *relpath = strdup(filename + root->root_path->len + 1);
2231   }
2232 
2233 out:
2234   if (root) {
2235     w_root_delref(root);
2236   }
2237   w_string_delref(name);
2238 
2239   return prefix;
2240 }
2241 
w_is_path_absolute(const char * path)2242 bool w_is_path_absolute(const char *path) {
2243 #ifdef _WIN32
2244   char drive_letter;
2245   size_t len = strlen(path);
2246 
2247   if (len <= 2) {
2248     return false;
2249   }
2250 
2251   // "\something"
2252   if (is_slash(path[0])) {
2253     // "\\something" is absolute, "\something" is relative to the current
2254     // dir of the current drive, whatever that may be, for a given process
2255     return is_slash(path[1]);
2256   }
2257 
2258   drive_letter = (char)tolower(path[0]);
2259   // "C:something"
2260   if (drive_letter >= 'a' && drive_letter <= 'z' && path[1] == ':') {
2261     // "C:\something" is absolute, but "C:something" is relative to
2262     // the current dir on the C drive(!)
2263     return is_slash(path[2]);
2264   }
2265   // we could check for things like NUL:, COM: and so on here.
2266   // While those are technically absolute names, we can't watch them, so
2267   // we don't consider them absolute for the purposes of checking whether
2268   // the path is a valid watchable root
2269   return false;
2270 #else
2271   return path[0] == '/';
2272 #endif
2273 }
2274 
root_resolve(const char * filename,bool auto_watch,bool * created,char ** errmsg)2275 static w_root_t *root_resolve(const char *filename, bool auto_watch,
2276     bool *created, char **errmsg)
2277 {
2278   struct watchman_root *root = NULL, *existing = NULL;
2279   w_ht_val_t root_val;
2280   char *watch_path;
2281   w_string_t *root_str;
2282   int realpath_err;
2283 
2284   *created = false;
2285 
2286   // Sanity check that the path is absolute
2287   if (!w_is_path_absolute(filename)) {
2288     ignore_result(asprintf(errmsg, "path \"%s\" must be absolute", filename));
2289     w_log(W_LOG_ERR, "resolve_root: %s", *errmsg);
2290     return NULL;
2291   }
2292 
2293   if (!strcmp(filename, "/")) {
2294     ignore_result(asprintf(errmsg, "cannot watch \"/\""));
2295     w_log(W_LOG_ERR, "resolve_root: %s", *errmsg);
2296     return NULL;
2297   }
2298 
2299   watch_path = w_realpath(filename);
2300   realpath_err = errno;
2301 
2302   if (!watch_path) {
2303     watch_path = (char*)filename;
2304   }
2305 
2306   root_str = w_string_new(watch_path);
2307   pthread_mutex_lock(&root_lock);
2308   // This will addref if it returns root
2309   if (w_ht_lookup(watched_roots, w_ht_ptr_val(root_str), &root_val, true)) {
2310     root = w_ht_val_ptr(root_val);
2311   }
2312   pthread_mutex_unlock(&root_lock);
2313   w_string_delref(root_str);
2314 
2315   if (!root && watch_path == filename) {
2316     // Path didn't resolve and neither did the name they passed in
2317     ignore_result(asprintf(errmsg,
2318           "realpath(%s) -> %s", filename, strerror(realpath_err)));
2319     w_log(W_LOG_ERR, "resolve_root: %s\n", *errmsg);
2320     return NULL;
2321   }
2322 
2323   if (root || !auto_watch) {
2324     if (!root) {
2325       ignore_result(asprintf(errmsg,
2326             "directory %s is not watched", watch_path));
2327       w_log(W_LOG_DBG, "resolve_root: %s\n", *errmsg);
2328     }
2329     if (watch_path != filename) {
2330       free(watch_path);
2331     }
2332 
2333     // Treat this as new activity for aging purposes; this roughly maps
2334     // to a client querying something about the root and should extend
2335     // the lifetime of the root
2336     if (root) {
2337       w_root_lock(root);
2338       time(&root->last_cmd_timestamp);
2339       w_root_unlock(root);
2340     }
2341 
2342     // caller owns a ref
2343     return root;
2344   }
2345 
2346   w_log(W_LOG_DBG, "Want to watch %s -> %s\n", filename, watch_path);
2347 
2348   if (!check_allowed_fs(watch_path, errmsg)) {
2349     w_log(W_LOG_ERR, "resolve_root: %s\n", *errmsg);
2350     if (watch_path != filename) {
2351       free(watch_path);
2352     }
2353     return NULL;
2354   }
2355 
2356   if (!root_check_restrict(watch_path)) {
2357     ignore_result(asprintf(errmsg,
2358           "none of the files listed in global config root_files are "
2359           "present and enforce_root_files is set to true"));
2360     w_log(W_LOG_ERR, "resolve_root: %s\n", *errmsg);
2361     if (watch_path != filename) {
2362       free(watch_path);
2363     }
2364     return NULL;
2365   }
2366 
2367   // created with 1 ref
2368   root = w_root_new(watch_path, errmsg);
2369 
2370   if (watch_path != filename) {
2371     free(watch_path);
2372   }
2373 
2374   if (!root) {
2375     return NULL;
2376   }
2377 
2378   pthread_mutex_lock(&root_lock);
2379   existing = w_ht_val_ptr(w_ht_get(watched_roots,
2380                 w_ht_ptr_val(root->root_path)));
2381   if (existing) {
2382     // Someone beat us in this race
2383     w_root_addref(existing);
2384     w_root_delref(root);
2385     root = existing;
2386     *created = false;
2387   } else {
2388     // adds 1 ref
2389     w_ht_set(watched_roots, w_ht_ptr_val(root->root_path), w_ht_ptr_val(root));
2390     *created = true;
2391   }
2392   pthread_mutex_unlock(&root_lock);
2393 
2394   // caller owns 1 ref
2395   return root;
2396 }
2397 
run_notify_thread(void * arg)2398 static void *run_notify_thread(void *arg)
2399 {
2400   w_root_t *root = arg;
2401 
2402   w_set_thread_name("notify %.*s", root->root_path->len, root->root_path->buf);
2403   notify_thread(root);
2404 
2405   w_log(W_LOG_DBG, "out of loop\n");
2406 
2407   /* we'll remove it from watched roots if it isn't
2408    * already out of there */
2409   remove_root_from_watched(root);
2410 
2411   w_root_delref(root);
2412   return 0;
2413 }
2414 
run_io_thread(void * arg)2415 static void *run_io_thread(void *arg)
2416 {
2417   w_root_t *root = arg;
2418 
2419   w_set_thread_name("io %.*s", root->root_path->len, root->root_path->buf);
2420   io_thread(root);
2421   w_log(W_LOG_DBG, "out of loop\n");
2422 
2423   w_root_delref(root);
2424   return 0;
2425 }
2426 
start_detached_root_thread(w_root_t * root,char ** errmsg,void * (* func)(void *),pthread_t * thr)2427 static bool start_detached_root_thread(w_root_t *root, char **errmsg,
2428     void*(*func)(void*), pthread_t *thr) {
2429   pthread_attr_t attr;
2430   int err;
2431 
2432   pthread_attr_init(&attr);
2433   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2434 
2435   w_root_addref(root);
2436   err = pthread_create(thr, &attr, func, root);
2437   pthread_attr_destroy(&attr);
2438 
2439   if (err == 0) {
2440     return true;
2441   }
2442 
2443   ignore_result(asprintf(errmsg,
2444         "failed to pthread_create: %s\n", strerror(err)));
2445   w_root_delref(root);
2446   return false;
2447 }
2448 
root_start(w_root_t * root,char ** errmsg)2449 static bool root_start(w_root_t *root, char **errmsg)
2450 {
2451   if (!start_detached_root_thread(root, errmsg,
2452         run_notify_thread, &root->notify_thread)) {
2453     return false;
2454   }
2455 
2456   // Wait for it to signal that the watcher has been initialized
2457   w_pending_coll_lock_and_wait(&root->pending, -1 /* infinite */);
2458   w_pending_coll_unlock(&root->pending);
2459 
2460   if (!start_detached_root_thread(root, errmsg,
2461         run_io_thread, &root->io_thread)) {
2462     w_root_cancel(root);
2463     return false;
2464   }
2465   return true;
2466 }
2467 
w_root_resolve_for_client_mode(const char * filename,char ** errmsg)2468 w_root_t *w_root_resolve_for_client_mode(const char *filename, char **errmsg)
2469 {
2470   struct watchman_root *root;
2471   bool created = false;
2472 
2473   root = root_resolve(filename, true, &created, errmsg);
2474   if (created) {
2475     struct timeval start;
2476     struct watchman_pending_collection pending;
2477 
2478     w_pending_coll_init(&pending);
2479 
2480     /* force a walk now */
2481     gettimeofday(&start, NULL);
2482     w_root_lock(root);
2483     w_pending_coll_add(&root->pending, root->root_path,
2484         start, W_PENDING_RECURSIVE);
2485     while (w_root_process_pending(root, &pending, true)) {
2486       ;
2487     }
2488     w_root_unlock(root);
2489 
2490     w_pending_coll_destroy(&pending);
2491   }
2492   return root;
2493 }
2494 
signal_root_threads(w_root_t * root)2495 static void signal_root_threads(w_root_t *root)
2496 {
2497   // Send SIGUSR1 to interrupt blocking syscalls on the
2498   // worker threads.  They'll self-terminate.
2499   if (!pthread_equal(root->notify_thread, pthread_self())) {
2500     pthread_kill(root->notify_thread, SIGUSR1);
2501   }
2502   w_pending_coll_ping(&root->pending);
2503   watcher_ops->root_signal_threads(watcher, root);
2504 }
2505 
w_root_schedule_recrawl(w_root_t * root,const char * why)2506 void w_root_schedule_recrawl(w_root_t *root, const char *why)
2507 {
2508   if (!root->should_recrawl) {
2509     if (root->last_recrawl_reason) {
2510       w_string_delref(root->last_recrawl_reason);
2511     }
2512 
2513     root->last_recrawl_reason = w_string_make_printf(
2514         "%.*s: %s",
2515         root->root_path->len, root->root_path->buf, why);
2516 
2517     w_log(W_LOG_ERR, "%.*s: %s: scheduling a tree recrawl\n",
2518         root->root_path->len, root->root_path->buf, why);
2519   }
2520   root->should_recrawl = true;
2521   signal_root_threads(root);
2522 }
2523 
2524 // Cancels a watch.
2525 // Caller must have locked root
w_root_cancel(w_root_t * root)2526 bool w_root_cancel(w_root_t *root)
2527 {
2528   bool cancelled = false;
2529 
2530   if (!root->cancelled) {
2531     cancelled = true;
2532 
2533     w_log(W_LOG_DBG, "marked %s cancelled\n",
2534         root->root_path->buf);
2535     root->cancelled = true;
2536 
2537     signal_root_threads(root);
2538   }
2539 
2540   return cancelled;
2541 }
2542 
w_root_stop_watch(w_root_t * root)2543 bool w_root_stop_watch(w_root_t *root)
2544 {
2545   bool stopped = remove_root_from_watched(root);
2546 
2547   if (stopped) {
2548     w_root_cancel(root);
2549     w_state_save();
2550   }
2551   signal_root_threads(root);
2552 
2553   return stopped;
2554 }
2555 
w_root_stop_watch_all(void)2556 json_t *w_root_stop_watch_all(void)
2557 {
2558   uint32_t roots_count, i;
2559   w_root_t **roots;
2560   w_ht_iter_t iter;
2561   json_t *stopped;
2562 
2563   pthread_mutex_lock(&root_lock);
2564   roots_count = w_ht_size(watched_roots);
2565   roots = calloc(roots_count, sizeof(*roots));
2566 
2567   i = 0;
2568   if (w_ht_first(watched_roots, &iter)) do {
2569     w_root_t *root = w_ht_val_ptr(iter.value);
2570     w_root_addref(root);
2571     roots[i++] = root;
2572   } while (w_ht_next(watched_roots, &iter));
2573 
2574   stopped = json_array();
2575   for (i = 0; i < roots_count; i++) {
2576     w_root_t *root = roots[i];
2577     w_string_t *path = root->root_path;
2578     if (w_ht_del(watched_roots, w_ht_ptr_val(path))) {
2579       w_root_cancel(root);
2580       json_array_append_new(stopped, w_string_to_json(path));
2581     }
2582     w_root_delref(root);
2583   }
2584   free(roots);
2585   pthread_mutex_unlock(&root_lock);
2586 
2587   w_state_save();
2588 
2589   return stopped;
2590 }
2591 
w_root_resolve(const char * filename,bool auto_watch,char ** errmsg)2592 w_root_t *w_root_resolve(const char *filename, bool auto_watch, char **errmsg)
2593 {
2594   struct watchman_root *root;
2595   bool created = false;
2596 
2597   root = root_resolve(filename, auto_watch, &created, errmsg);
2598   if (created) {
2599     if (!root_start(root, errmsg)) {
2600       w_root_cancel(root);
2601       w_root_delref(root);
2602       return NULL;
2603     }
2604     w_state_save();
2605   }
2606   return root;
2607 }
2608 
2609 // Caller must have locked root
w_root_trigger_list_to_json(w_root_t * root)2610 json_t *w_root_trigger_list_to_json(w_root_t *root)
2611 {
2612   w_ht_iter_t iter;
2613   json_t *arr;
2614 
2615   arr = json_array();
2616   if (w_ht_first(root->commands, &iter)) do {
2617     struct watchman_trigger_command *cmd = w_ht_val_ptr(iter.value);
2618 
2619     json_array_append(arr, cmd->definition);
2620   } while (w_ht_next(root->commands, &iter));
2621 
2622   return arr;
2623 }
2624 
w_root_watch_list_to_json(void)2625 json_t *w_root_watch_list_to_json(void)
2626 {
2627   w_ht_iter_t iter;
2628   json_t *arr;
2629 
2630   arr = json_array();
2631 
2632   pthread_mutex_lock(&root_lock);
2633   if (w_ht_first(watched_roots, &iter)) do {
2634     w_root_t *root = w_ht_val_ptr(iter.value);
2635     json_array_append_new(arr, w_string_to_json(root->root_path));
2636   } while (w_ht_next(watched_roots, &iter));
2637   pthread_mutex_unlock(&root_lock);
2638 
2639   return arr;
2640 }
2641 
w_root_load_state(json_t * state)2642 bool w_root_load_state(json_t *state)
2643 {
2644   json_t *watched;
2645   size_t i;
2646 
2647   watched = json_object_get(state, "watched");
2648   if (!watched) {
2649     return true;
2650   }
2651 
2652   if (!json_is_array(watched)) {
2653     return false;
2654   }
2655 
2656   for (i = 0; i < json_array_size(watched); i++) {
2657     json_t *obj = json_array_get(watched, i);
2658     w_root_t *root;
2659     bool created = false;
2660     const char *filename;
2661     json_t *triggers;
2662     size_t j;
2663     char *errmsg = NULL;
2664 
2665     triggers = json_object_get(obj, "triggers");
2666     filename = json_string_value(json_object_get(obj, "path"));
2667     root = root_resolve(filename, true, &created, &errmsg);
2668 
2669     if (!root) {
2670       free(errmsg);
2671       continue;
2672     }
2673 
2674     w_root_lock(root);
2675 
2676     /* re-create the trigger configuration */
2677     for (j = 0; j < json_array_size(triggers); j++) {
2678       json_t *tobj = json_array_get(triggers, j);
2679       json_t *rarray;
2680       struct watchman_trigger_command *cmd;
2681 
2682       // Legacy rules format
2683       rarray = json_object_get(tobj, "rules");
2684       if (rarray) {
2685         continue;
2686       }
2687 
2688       cmd = w_build_trigger_from_def(root, tobj, &errmsg);
2689       if (!cmd) {
2690         w_log(W_LOG_ERR, "loading trigger for %s: %s\n",
2691             root->root_path->buf, errmsg);
2692         free(errmsg);
2693         continue;
2694       }
2695 
2696       w_ht_replace(root->commands, w_ht_ptr_val(cmd->triggername),
2697           w_ht_ptr_val(cmd));
2698     }
2699 
2700     w_root_unlock(root);
2701 
2702     if (created) {
2703       if (!root_start(root, &errmsg)) {
2704         w_log(W_LOG_ERR, "root_start(%s) failed: %s\n",
2705             root->root_path->buf, errmsg);
2706         free(errmsg);
2707         w_root_cancel(root);
2708       }
2709     }
2710 
2711     w_root_delref(root);
2712   }
2713 
2714   return true;
2715 }
2716 
w_root_save_state(json_t * state)2717 bool w_root_save_state(json_t *state)
2718 {
2719   w_ht_iter_t root_iter;
2720   bool result = true;
2721   json_t *watched_dirs;
2722 
2723   watched_dirs = json_array();
2724 
2725   w_log(W_LOG_DBG, "saving state\n");
2726 
2727   pthread_mutex_lock(&root_lock);
2728   if (w_ht_first(watched_roots, &root_iter)) do {
2729     w_root_t *root = w_ht_val_ptr(root_iter.value);
2730     json_t *obj;
2731     json_t *triggers;
2732 
2733     obj = json_object();
2734 
2735     json_object_set_new(obj, "path", w_string_to_json(root->root_path));
2736 
2737     w_root_lock(root);
2738     triggers = w_root_trigger_list_to_json(root);
2739     w_root_unlock(root);
2740     json_object_set_new(obj, "triggers", triggers);
2741 
2742     json_array_append_new(watched_dirs, obj);
2743 
2744   } while (w_ht_next(watched_roots, &root_iter));
2745 
2746   pthread_mutex_unlock(&root_lock);
2747 
2748   json_object_set_new(state, "watched", watched_dirs);
2749 
2750   return result;
2751 }
2752 
w_reap_children(bool block)2753 bool w_reap_children(bool block)
2754 {
2755   pid_t pid;
2756   int reaped = 0;
2757 
2758   // Reap any children so that we can release their
2759   // references on the root
2760   do {
2761 #ifndef _WIN32
2762     int st;
2763     pid = waitpid(-1, &st, block ? 0 : WNOHANG);
2764     if (pid == -1) {
2765       break;
2766     }
2767 #else
2768     if (!w_wait_for_any_child(block ? INFINITE : 0, &pid)) {
2769       break;
2770     }
2771 #endif
2772     w_mark_dead(pid);
2773     reaped++;
2774   } while (1);
2775 
2776   return reaped != 0;
2777 }
2778 
w_root_free_watched_roots(void)2779 void w_root_free_watched_roots(void)
2780 {
2781   w_ht_iter_t root_iter;
2782   int last, interval;
2783   time_t started;
2784 
2785   // Reap any children so that we can release their
2786   // references on the root
2787   w_reap_children(true);
2788 
2789   pthread_mutex_lock(&root_lock);
2790   if (w_ht_first(watched_roots, &root_iter)) do {
2791     w_root_t *root = w_ht_val_ptr(root_iter.value);
2792     if (!w_root_cancel(root)) {
2793       signal_root_threads(root);
2794     }
2795   } while (w_ht_next(watched_roots, &root_iter));
2796   pthread_mutex_unlock(&root_lock);
2797 
2798   last = live_roots;
2799   time(&started);
2800   w_log(W_LOG_DBG, "waiting for roots to cancel and go away %d\n", last);
2801   interval = 100;
2802   for (;;) {
2803     int current = __sync_fetch_and_add(&live_roots, 0);
2804     if (current == 0) {
2805       break;
2806     }
2807     if (time(NULL) > started + 3) {
2808       w_log(W_LOG_ERR, "%d roots were still live at exit\n", current);
2809       break;
2810     }
2811     if (current != last) {
2812       w_log(W_LOG_DBG, "waiting: %d live\n", current);
2813       last = current;
2814     }
2815     usleep(interval);
2816     interval = MIN(interval * 2, 1000000);
2817   }
2818 
2819   w_log(W_LOG_DBG, "all roots are gone\n");
2820 }
2821 
2822 /* vim:ts=2:sw=2:et:
2823  */
2824