summaryrefslogtreecommitdiff
path: root/src/bin/efreet/efreetd_cache.c
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-04-12 12:09:07 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-04-12 12:19:41 +0900
commit44fe8b987ee692e40c111b441569c96eca14d3b1 (patch)
tree6414c5c59142bd8fbbdc65859bcde06985d40524 /src/bin/efreet/efreetd_cache.c
parentf022c23166abf1cfbade4a813cf8f679cf275854 (diff)
efreetd - improve sanity checking for recursive icon monitoring
i found my efreetd was not just monitoring a small set of dirs but literally $HOME - recursively. this explains a lot of performance issues i have seen on spinning hdd's vs ssd's. i never knew if was in efreetd though... until now. for whatever reason my efret cache caused efreet to try monitro a list like: / /h /ho /hom /home /home/ /home/r ... etc. when trying to monitor something like: /home/raster/.local/share/icons that means it ended up trying $HOME as wellas a vast range of dirs it just shouldn't sensibly ever try. i have no idea how my cache ended up this way, but deleting it and re-populating it fixed it. so this ads code to detect such insanity (as wellas give actual complaints on deep recursion so we can see things better later). not a bug fix as such, but a major improvement to detecting bugs which is what we want for stability. I also noticed that one legacy pixmaps dir is not recursively monitored, but another is - so be consistent and recurs both. Also apply checks to desktop file monitoring too.
Diffstat (limited to 'src/bin/efreet/efreetd_cache.c')
-rw-r--r--src/bin/efreet/efreetd_cache.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/bin/efreet/efreetd_cache.c b/src/bin/efreet/efreetd_cache.c
index 88f969ca52..35be03d0c0 100644
--- a/src/bin/efreet/efreetd_cache.c
+++ b/src/bin/efreet/efreetd_cache.c
@@ -259,6 +259,30 @@ stat_cmp(const void *a, const void *b)
259 return 1; 259 return 1;
260} 260}
261 261
262static Eina_Bool
263_check_recurse_monitor_sanity(Eina_Inarray *stack, const char *path, unsigned int stack_limit)
264{
265 const char *home = getenv("HOME");
266
267 // protect against too deep recursion even if it's valid.
268 if (eina_inarray_count(stack) >= stack_limit)
269 {
270 ERR("Recursing too far. Level %i. Stopping at %s\n", stack_limit, path);
271 return EINA_FALSE;
272 }
273 // detect if we start recursing at $HOME - a sign of something wrong
274 if ((home) && (!strcmp(home, path)))
275 {
276 char buf[PATH_MAX];
277
278 ERR("Recursively monitor homedir! Remove cache and exit.");
279 snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
280 ecore_file_recursive_rm(buf);
281 exit(-1);
282 }
283 return EINA_TRUE;
284}
285
262static void 286static void
263icon_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool base) 287icon_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool base)
264{ 288{
@@ -268,8 +292,7 @@ icon_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Bool b
268 292
269 if (stat(path, &st) == -1) return; 293 if (stat(path, &st) == -1) return;
270 if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return; 294 if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return;
271 // protect against too deep recursion even if it's valid. 295 if (!_check_recurse_monitor_sanity(stack, path, 8)) return;
272 if (eina_inarray_count(stack) >= 8) return;
273 eina_inarray_push(stack, &st); 296 eina_inarray_push(stack, &st);
274 297
275 if ((!ecore_file_is_dir(path)) && (base)) 298 if ((!ecore_file_is_dir(path)) && (base))
@@ -306,8 +329,7 @@ desktop_changes_listen_recursive(Eina_Inarray *stack, const char *path, Eina_Boo
306 329
307 if (stat(path, &st) == -1) return; 330 if (stat(path, &st) == -1) return;
308 if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return; 331 if (eina_inarray_search(stack, &st, stat_cmp) >= 0) return;
309 // protect against too deep recursion even if it's valid. 332 if (!_check_recurse_monitor_sanity(stack, path, 3)) return;
310 if (eina_inarray_count(stack) >= 3) return;
311 eina_inarray_push(stack, &st); 333 eina_inarray_push(stack, &st);
312 if ((!ecore_file_is_dir(path)) && (base)) 334 if ((!ecore_file_is_dir(path)) && (base))
313 { 335 {
@@ -371,7 +393,8 @@ icon_changes_listen(void)
371 icon_changes_listen_recursive(stack, buf, EINA_TRUE); 393 icon_changes_listen_recursive(stack, buf, EINA_TRUE);
372 } 394 }
373#endif 395#endif
374 icon_changes_monitor_add("/usr/share/pixmaps"); 396 eina_inarray_flush(stack);
397 icon_changes_listen_recursive(stack, "/usr/share/pixmaps", EINA_TRUE);
375 eina_inarray_free(stack); 398 eina_inarray_free(stack);
376} 399}
377 400