[icinga-checkins] icinga.org: icinga-core/r1.6: * core: protect downtime and comment list modification with a lock ( Andreas Ericsson) #2025

git at icinga.org git at icinga.org
Wed Nov 9 16:43:12 CET 2011


Module: icinga-core
Branch: r1.6
Commit: 205f72e17f2b6bf58aaf52175ece694ffe3d4423
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=205f72e17f2b6bf58aaf52175ece694ffe3d4423

Author: Michael Friedrich <michael.friedrich at univie.ac.at>
Date:   Sat Oct 22 15:28:26 2011 +0200

* core: protect downtime and comment list modification with a lock (Andreas Ericsson) #2025

this will prevent multiple threads from fetching
the comment and downtime lists in memory
competing about pointers and leading into
possible segfaults then.

modules that need to issue the lock themselves must
import its declaration first and then manipulate the
lock without using the locking core apis.

icinga_downtime_lock
icinga_comment_lock

refs #2025

---

 Changelog         |    1 +
 common/comments.c |   21 ++++++++++++++++++++-
 common/downtime.c |   22 +++++++++++++++++++++-
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/Changelog b/Changelog
index 7facd98..b9b171f 100644
--- a/Changelog
+++ b/Changelog
@@ -11,6 +11,7 @@ ENHANCEMENTS
 * core: allow startup with no hosts/services/contacts defined, only warn #2015
 * core: log error on non-existing host/service/contact/*group when sending a command to the core #1737
 * core: reduce notification load by moving notification viability check into notification list creation (Opsview Team) #1744
+* core: protect downtime and comment list modification with a lock (Andreas Ericsson) #2025
 
 * classic ui: add expiry option and end_time to acknowledgements on cmd.cgi #770
 
diff --git a/common/comments.c b/common/comments.c
index 28da14a..84da9cd 100644
--- a/common/comments.c
+++ b/common/comments.c
@@ -52,6 +52,7 @@ comment     **comment_hashlist = NULL;
 
 
 #ifdef NSCORE
+pthread_mutex_t icinga_comment_lock = PTHREAD_MUTEX_INITIALIZER;
 
 /******************************************************************/
 /**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/
@@ -174,6 +175,11 @@ int delete_comment(int type, unsigned long comment_id) {
 	comment *this_hash = NULL;
 	comment *last_hash = NULL;
 
+	/* lock the comments so we can modify them safely */
+#ifdef NSCORE
+	pthread_mutex_lock(&icinga_comment_lock);
+#endif
+
 	/* find the comment we should remove */
 	for (this_comment = comment_list, last_comment = comment_list; this_comment != NULL; this_comment = next_comment) {
 		next_comment = this_comment->next;
@@ -237,6 +243,10 @@ int delete_comment(int type, unsigned long comment_id) {
 		result = xcddefault_delete_service_comment(comment_id);
 #endif
 
+#ifdef NSCORE
+	pthread_mutex_unlock(&icinga_comment_lock);
+#endif
+
 	return result;
 }
 
@@ -509,7 +519,13 @@ int add_comment(int comment_type, int entry_type, char *host_name, char *svc_des
 		new_comment->next = comment_list;
 		comment_list = new_comment;
 	} else {
-		/* add new comment to comment list, sorted by comment id */
+		/* add new comment to comment list, sorted by comment id,
+		 * but lock the list first so broker threads doesn't crash
+		 * out in case they're modifying this list too
+		 */
+#ifdef NSCORE
+		pthread_mutex_lock(&icinga_comment_lock);
+#endif
 		last_comment = comment_list;
 		for (temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) {
 			if (new_comment->comment_id < temp_comment->comment_id) {
@@ -529,6 +545,9 @@ int add_comment(int comment_type, int entry_type, char *host_name, char *svc_des
 			new_comment->next = NULL;
 			last_comment->next = new_comment;
 		}
+#ifdef NSCORE
+		pthread_mutex_unlock(&icinga_comment_lock);
+#endif
 	}
 
 #ifdef NSCORE
diff --git a/common/downtime.c b/common/downtime.c
index 2b92a63..e9d7227 100644
--- a/common/downtime.c
+++ b/common/downtime.c
@@ -52,6 +52,7 @@ int		   defer_downtime_sorting = 0;
 #ifdef NSCORE
 extern timed_event *event_list_high;
 extern timed_event *event_list_high_tail;
+pthread_mutex_t icinga_downtime_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
 int dummy;	/* reduce compiler warnings */
@@ -765,6 +766,10 @@ int delete_downtime(int type, unsigned long downtime_id) {
 	scheduled_downtime *last_downtime = NULL;
 	scheduled_downtime *next_downtime = NULL;
 
+#ifdef NSCORE
+	pthread_mutex_lock(&icinga_downtime_lock);
+#endif
+
 	/* find the downtime we should remove */
 	for (this_downtime = scheduled_downtime_list, last_downtime = scheduled_downtime_list; this_downtime != NULL; this_downtime = next_downtime) {
 		next_downtime = this_downtime->next;
@@ -806,6 +811,10 @@ int delete_downtime(int type, unsigned long downtime_id) {
 	} else
 		result = ERROR;
 
+#ifdef NSCORE
+	pthread_mutex_unlock(&icinga_downtime_lock);
+#endif
+
 	return result;
 }
 
@@ -970,7 +979,14 @@ int add_downtime(int downtime_type, char *host_name, char *svc_description, time
 		new_downtime->next = scheduled_downtime_list;
 		scheduled_downtime_list = new_downtime;
 	} else {
-		/* add new downtime to downtime list, sorted by start time */
+		/*
+		 * add new downtime to downtime list, sorted by start time,
+		 * but lock the lists first so broker modules fiddling
+		 * with them at the same time doesn't crash out.
+		 */
+#ifdef NSCORE
+		pthread_mutex_lock(&icinga_downtime_lock);
+#endif
 		last_downtime = scheduled_downtime_list;
 		for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) {
 			if (new_downtime->start_time < temp_downtime->start_time) {
@@ -983,6 +999,7 @@ int add_downtime(int downtime_type, char *host_name, char *svc_description, time
 			} else
 				last_downtime = temp_downtime;
 		}
+
 		if (scheduled_downtime_list == NULL) {
 			new_downtime->next = NULL;
 			scheduled_downtime_list = new_downtime;
@@ -990,6 +1007,9 @@ int add_downtime(int downtime_type, char *host_name, char *svc_description, time
 			new_downtime->next = NULL;
 			last_downtime->next = new_downtime;
 		}
+#ifdef NSCORE
+		pthread_mutex_unlock(&icinga_downtime_lock);
+#endif
 	}
 #ifdef NSCORE
 #ifdef USE_EVENT_BROKER





More information about the icinga-checkins mailing list