소스 검색

Add handle checking to the hdb system.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1842 fd59a12c-fef9-0310-b244-a6a79926bd2f
Steven Dake 17 년 전
부모
커밋
2b84d1075b
4개의 변경된 파일77개의 추가작업 그리고 13개의 파일을 삭제
  1. 2 2
      exec/totempg.c
  2. 1 1
      include/corosync/confdb.h
  3. 1 1
      include/corosync/engine/objdb.h
  4. 73 9
      include/corosync/hdb.h

+ 2 - 2
exec/totempg.c

@@ -430,7 +430,7 @@ static inline void app_deliver_fn (
 
 	for (i = 0; i <= totempg_max_handle; i++) {
 		res = hdb_handle_get (&totempg_groups_instance_database,
-			i, (void *)&instance);
+			hdb_nocheck_convert (i), (void *)&instance);
 
 		if (res == 0) {
 			assert (iov_len == 1);
@@ -459,7 +459,7 @@ static inline void app_deliver_fn (
 					endian_conversion_required);
 			}
 
-			hdb_handle_put (&totempg_groups_instance_database, i);
+			hdb_handle_put (&totempg_groups_instance_database, hdb_nocheck_convert(i));
 		}
 	}
 }

+ 1 - 1
include/corosync/confdb.h

@@ -44,7 +44,7 @@
  */
 typedef uint64_t confdb_handle_t;
 
-#define OBJECT_PARENT_HANDLE 0
+#define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL
 
 typedef enum {
 	CONFDB_TRACK_DEPTH_ONE,

+ 1 - 1
include/corosync/engine/objdb.h

@@ -36,7 +36,7 @@
 #ifndef OBJDB_H_DEFINED
 #define OBJDB_H_DEFINED
 
-#define OBJECT_PARENT_HANDLE 0
+#define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL 
 
 #include <stdio.h>
 #include <corosync/hdb.h>

+ 73 - 9
include/corosync/hdb.h

@@ -52,6 +52,7 @@ enum HDB_HANDLE_STATE {
 struct hdb_handle {
 	int state;
 	void *instance;
+	int check;
 	int ref_count;
 };
 
@@ -86,9 +87,11 @@ static inline int hdb_handle_create (
 	hdb_handle_t *handle_id_out)
 {
 	int handle;
+	unsigned int check;
 	void *new_handles;
 	int found = 0;
 	void *instance;
+	int i;
 
 	pthread_mutex_lock (&handle_database->mutex);
 
@@ -114,6 +117,20 @@ static inline int hdb_handle_create (
 	if (instance == 0) {
 		return (-1);
 	}
+
+	/*
+	 * This code makes sure the random number isn't zero
+	 * We use 0 to specify an invalid handle out of the 1^64 address space
+	 * If we get 0 200 times in a row, the RNG may be broken
+	 */
+	for (i = 0; i < 200; i++) {
+		check = random();
+
+		if (check != 0 && check != 0xffffffff) {
+			break;
+		}
+	}
+
 	memset (instance, 0, instance_size);
 
 	handle_database->handles[handle].state = HDB_HANDLE_STATE_ACTIVE;
@@ -122,7 +139,9 @@ static inline int hdb_handle_create (
 
 	handle_database->handles[handle].ref_count = 1;
 
-	*handle_id_out = handle;
+	handle_database->handles[handle].check = check;
+
+	*handle_id_out = (((unsigned long long)(check)) << 32) | handle;
 
 	pthread_mutex_unlock (&handle_database->mutex);
 
@@ -131,11 +150,21 @@ static inline int hdb_handle_create (
 
 static inline int hdb_handle_get (
 	struct hdb_handle_database *handle_database,
-	hdb_handle_t handle,
+	hdb_handle_t handle_in,
 	void **instance)
 {
+	unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
+	unsigned int handle = handle_in & 0xffffffff;
+
 	pthread_mutex_lock (&handle_database->mutex);
 
+	if (check != 0xffffffff &&
+		check != handle_database->handles[handle].check) {
+
+		pthread_mutex_unlock (&handle_database->mutex);
+		return (-1);
+	}
+
 	*instance = NULL;
 	if (handle >= handle_database->handle_count) {
 		pthread_mutex_unlock (&handle_database->mutex);
@@ -155,11 +184,22 @@ static inline int hdb_handle_get (
 	return (0);
 }
 
-static inline void hdb_handle_put (
+static inline int hdb_handle_put (
 	struct hdb_handle_database *handle_database,
-	hdb_handle_t handle)
+	hdb_handle_t handle_in)
 {
+	unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
+	unsigned int handle = handle_in & 0xffffffff;
+
 	pthread_mutex_lock (&handle_database->mutex);
+
+	if (check != 0xffffffff &&
+		check != handle_database->handles[handle].check) {
+
+		pthread_mutex_unlock (&handle_database->mutex);
+		return (-1);
+	}
+		
 	handle_database->handles[handle].ref_count -= 1;
 	assert (handle_database->handles[handle].ref_count >= 0);
 
@@ -168,17 +208,29 @@ static inline void hdb_handle_put (
 		memset (&handle_database->handles[handle], 0, sizeof (struct hdb_handle));
 	}
 	pthread_mutex_unlock (&handle_database->mutex);
+	return (0);
 }
 
-static inline void hdb_handle_destroy (
+static inline int hdb_handle_destroy (
 	struct hdb_handle_database *handle_database,
-	unsigned int handle)
+	hdb_handle_t handle_in)
 {
+	unsigned int check = ((unsigned int)(((unsigned long long)handle_in) >> 32));
+	unsigned int handle = handle_in & 0xffffffff;
+	int res;
+
 	pthread_mutex_lock (&handle_database->mutex);
 
+	if (check != 0xffffffff &&
+		check != handle_database->handles[handle].check) {
+		pthread_mutex_unlock (&handle_database->mutex);
+		return (-1);
+	}
+
 	handle_database->handles[handle].state = HDB_HANDLE_STATE_PENDINGREMOVAL;
 	pthread_mutex_unlock (&handle_database->mutex);
-	hdb_handle_put (handle_database, handle);
+	res = hdb_handle_put (handle_database, handle);
+	return (res);
 }
 
 static inline void hdb_iterator_reset (
@@ -195,10 +247,10 @@ static inline int hdb_iterator_next (
 	int res = -1;
 
 	while (handle_database->iterator < handle_database->handle_count) {
-		*handle = handle_database->iterator;
+		*handle = ((unsigned long long)(handle_database->handles[handle_database->iterator].check) << 32) | handle_database->iterator;
 		res = hdb_handle_get (
 			handle_database,
-			handle_database->iterator,
+			*handle,
 			instance);
 
 		handle_database->iterator += 1;
@@ -209,4 +261,16 @@ static inline int hdb_iterator_next (
 	return (res);
 }
 
+static inline unsigned int hdb_base_convert (hdb_handle_t handle)
+{
+	return (handle & 0xffffffff);
+}
+
+static inline unsigned long long hdb_nocheck_convert (unsigned int handle)
+{
+	unsigned long long retvalue = 0xffffffffULL << 32 | handle;
+
+	return (retvalue);
+}
+
 #endif /* HDB_H_DEFINED */