Report inotify instances limit error

This commit is contained in:
Roman Shevchenko
2013-02-08 20:30:26 +01:00
parent 08659b3554
commit 84dc01e773
6 changed files with 60 additions and 42 deletions
Binary file not shown.
Binary file not shown.
+8 -2
View File
@@ -21,6 +21,14 @@
#include <stdio.h>
// messaging
typedef enum {
MSG_INSTANCE_LIMIT, MSG_WATCH_LIMIT
} MSG;
void message(MSG id);
// logging
void userlog(int priority, const char* format, ...);
@@ -59,8 +67,6 @@ enum {
bool init_inotify();
void set_inotify_callback(void (* callback)(char*, int));
int get_inotify_fd();
int get_watch_count();
bool watch_limit_reached();
int watch(const char* root, array* mounts);
void unwatch(int id);
bool process_inotify_input();
+32 -30
View File
@@ -49,30 +49,18 @@ static void (* callback)(char*, int) = NULL;
#define EVENT_BUF_LEN (2048 * (EVENT_SIZE + 16))
static char event_buf[EVENT_BUF_LEN];
static void read_watch_descriptors_count() {
FILE* f = fopen(WATCH_COUNT_NAME, "r");
if (f == NULL) {
userlog(LOG_ERR, "can't open %s: %s", WATCH_COUNT_NAME, strerror(errno));
return;
}
char* str = read_line(f);
if (str == NULL) {
userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
}
else {
watch_count = atoi(str);
}
fclose(f);
}
static void read_watch_descriptors_count();
static void watch_limit_reached();
bool init_inotify() {
inotify_fd = inotify_init();
if (inotify_fd < 0) {
userlog(LOG_ERR, "inotify_init: %s", strerror(errno));
int e = errno;
userlog(LOG_ERR, "inotify_init: %s", strerror(e));
if (e == EMFILE) {
message(MSG_INSTANCE_LIMIT);
}
return false;
}
userlog(LOG_DEBUG, "inotify fd: %d", get_inotify_fd());
@@ -96,6 +84,24 @@ bool init_inotify() {
return true;
}
static void read_watch_descriptors_count() {
FILE* f = fopen(WATCH_COUNT_NAME, "r");
if (f == NULL) {
userlog(LOG_ERR, "can't open %s: %s", WATCH_COUNT_NAME, strerror(errno));
return;
}
char* str = read_line(f);
if (str == NULL) {
userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
}
else {
watch_count = atoi(str);
}
fclose(f);
}
inline void set_inotify_callback(void (* _callback)(char*, int)) {
callback = _callback;
@@ -107,16 +113,6 @@ inline int get_inotify_fd() {
}
inline int get_watch_count() {
return watch_count;
}
inline bool watch_limit_reached() {
return limit_reached;
}
#define EVENT_MASK IN_MODIFY | IN_ATTRIB | IN_CREATE | IN_DELETE | IN_MOVE | IN_DELETE_SELF
static int add_watch(const char* path, watch_node* parent) {
@@ -128,7 +124,7 @@ static int add_watch(const char* path, watch_node* parent) {
}
else if (errno == ENOSPC) {
userlog(LOG_WARNING, "inotify_add_watch(%s): %s", path, strerror(errno));
limit_reached = true;
watch_limit_reached();
return ERR_CONTINUE;
}
else {
@@ -188,6 +184,12 @@ static int add_watch(const char* path, watch_node* parent) {
return wd;
}
static void watch_limit_reached() {
if (!limit_reached) {
limit_reached = true;
message(MSG_WATCH_LIMIT);
}
}
static void rm_watch(int wd, bool update_parent) {
watch_node* node = table_get(watches, wd);
+19 -9
View File
@@ -48,8 +48,12 @@
#define HELP_MSG \
"Try 'fsnotifier --help' for more information.\n"
#define INOTIFY_LIMIT_MSG \
"The current <b>inotify</b>(7) watch limit of %d is too low. " \
#define INSTANCE_LIMIT_TEXT \
"The <b>inotify</b>(7) instances limit reached. " \
"<a href=\"http://confluence.jetbrains.net/display/IDEADEV/Inotify+Instances+Limit\">More details.</a>\n"
#define WATCH_LIMIT_TEXT \
"The current <b>inotify</b>(7) watch limit is too low. " \
"<a href=\"http://confluence.jetbrains.net/display/IDEADEV/Inotify+Watches+Limit\">More details.</a>\n"
typedef struct {
@@ -59,7 +63,6 @@ typedef struct {
static array* roots = NULL;
static bool show_warning = true;
static bool self_test = false;
static void init_log();
@@ -152,6 +155,19 @@ static void init_log() {
}
void message(MSG id) {
if (id == MSG_INSTANCE_LIMIT) {
output("MESSAGE\n" INSTANCE_LIMIT_TEXT);
}
else if (id == MSG_WATCH_LIMIT) {
output("MESSAGE\n" WATCH_LIMIT_TEXT);
}
else {
userlog(LOG_ERR, "unknown message: %d", id);
}
}
void userlog(int priority, const char* format, ...) {
va_list ap;
@@ -353,12 +369,6 @@ static bool register_roots(array* new_roots, array* unwatchable, array* mounts)
return false;
}
else if (id != ERR_IGNORE) {
if (show_warning && watch_limit_reached()) {
int limit = get_watch_count();
userlog(LOG_WARNING, "watch limit (%d) reached", limit);
output("MESSAGE\n" INOTIFY_LIMIT_MSG, limit);
show_warning = false; // warn only once
}
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false);
}
}
@@ -173,7 +173,7 @@ public class FileWatcher {
private static boolean isUpToDate(File executable) {
long length = SystemInfo.isWindows ? 70216 :
SystemInfo.isMac ? 13924 :
SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29308 : 22809 :
SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29227 : 22734 :
-1;
return length < 0 || length == executable.length();
}