[Ocfs2-tools-devel] [PATCH 16/39] ocfs2_controld: Smarter client allocation code.

Joel Becker joel.becker at oracle.com
Fri Mar 14 16:52:39 PDT 2008


Steal more bits from other daemons.  Basically, make the client array
allocation easier to read and able to handle allocation failure.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 ocfs2_controld/cman.c |    7 ++++
 ocfs2_controld/cpg.c  |    7 ++++
 ocfs2_controld/main.c |   97 +++++++++++++++++++++++++++++++++++--------------
 3 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/ocfs2_controld/cman.c b/ocfs2_controld/cman.c
index e7e019d..d1815eb 100644
--- a/ocfs2_controld/cman.c
+++ b/ocfs2_controld/cman.c
@@ -236,6 +236,13 @@ int setup_cman(void)
 	statechange();
 
 	cman_ci = client_add(fd, process_cman, dead_cman);
+	if (cman_ci < 0) {
+		rv = cman_ci;
+		log_error("Unable to add cman client: %s",
+			  strerror(-cman_ci));
+		goto fail_stop;
+	}
+
 	return 0;
 
  fail_stop:
diff --git a/ocfs2_controld/cpg.c b/ocfs2_controld/cpg.c
index 9131842..80fb42b 100644
--- a/ocfs2_controld/cpg.c
+++ b/ocfs2_controld/cpg.c
@@ -233,6 +233,13 @@ int setup_cpg(void)
 	cpg_fd_get(daemon_group.cg_handle, &daemon_group.cg_fd);
 	daemon_group.cg_ci = client_add(daemon_group.cg_fd,
 					process_cpg, dead_cpg);
+	if (daemon_group.cg_ci < 0) {
+		log_error("Unable to add cpg client: %s",
+			  strerror(-daemon_group.cg_ci));
+		cpg_finalize(daemon_group.cg_handle);
+		daemon_group.cg_handle = 0;
+		return daemon_group.cg_ci;
+	}
 
 	strcpy(daemon_group.cg_name.value, "ocfs2_controld");
 	daemon_group.cg_name.length = strlen(daemon_group.cg_name.value);
diff --git a/ocfs2_controld/main.c b/ocfs2_controld/main.c
index cd8651a..f86376d 100644
--- a/ocfs2_controld/main.c
+++ b/ocfs2_controld/main.c
@@ -42,9 +42,9 @@
 
 #include "ocfs2_controld.h"
 
-#define OPTION_STRING			"DhVw"
-#define LOCKFILE_NAME			"/var/run/ocfs2_controld.pid"
-#define MAX_CLIENTS			8
+#define OPTION_STRING		"DhVw"
+#define LOCKFILE_NAME		"/var/run/ocfs2_controld.pid"
+#define NALLOC			8
 
 struct client {
 	int fd;
@@ -190,10 +190,14 @@ static int setup_sigpipe(void)
 	act.sa_handler = SIG_IGN;
 	rc += sigaction(SIGPIPE, &act, NULL);  /* Get EPIPE instead */
 
-	if (rc)
+	if (rc) {
 		log_error("Unable to set up signal handlers");
-	else
-		client_add(signal_pipe[0], handle_signal, dead_sigpipe);
+		goto out;
+	}
+
+	rc = client_add(signal_pipe[0], handle_signal, dead_sigpipe);
+	if (rc < 0)
+		log_error("Unable to add signal pipe: %s", strerror(-rc));
 
 out:
 	return rc;
@@ -250,12 +254,52 @@ void client_dead(int ci)
 }
 
 
+static int client_alloc(void)
+{
+	int i;
+	struct client *new_client;
+	struct pollfd *new_pollfd;
+
+	if (!client) {
+		new_client = malloc(NALLOC * sizeof(struct client));
+		new_pollfd = malloc(NALLOC * sizeof(struct pollfd));
+	} else {
+		new_client = realloc(client, (client_size + NALLOC) *
+					 sizeof(struct client));
+		new_pollfd = realloc(pollfd, (client_size + NALLOC) *
+					 sizeof(struct pollfd));
+	}
+	if (!new_client || !new_pollfd) {
+		log_error("Can't allocate client memory.");
+		return -ENOMEM;
+	}
+	client = new_client;
+	pollfd = new_pollfd;
+
+	for (i = client_size; i < (client_size + NALLOC); i++) {
+		client[i].work = NULL;
+		client[i].dead = NULL;
+		client[i].fd = -1;
+		pollfd[i].fd = -1;
+		pollfd[i].revents = 0;
+	}
+
+	client_size += NALLOC;
+
+	return 0;
+}
+
 int client_add(int fd, void (*work)(int ci), void (*dead)(int ci))
 {
 	int i;
 
+	if (!client) {
+		i = client_alloc();
+		if (i)
+			return i;
+	}
+
 	while (1) {
-		/* This fails the first time with client_size of zero */
 		for (i = 0; i < client_size; i++) {
 			if (client[i].fd == -1) {
 				client[i].fd = fd;
@@ -269,26 +313,12 @@ int client_add(int fd, void (*work)(int ci), void (*dead)(int ci))
 			}
 		}
 
-		/* We didn't find an empty slot, so allocate more. */
-		client_size += MAX_CLIENTS;
-
-		if (!client) {
-			client = malloc(client_size * sizeof(struct client));
-			pollfd = malloc(client_size * sizeof(struct pollfd));
-		} else {
-			client = realloc(client, client_size *
-						 sizeof(struct client));
-			pollfd = realloc(pollfd, client_size *
-						 sizeof(struct pollfd));
-		}
-		if (!client || !pollfd)
-			log_error("Can't allocate client memory.");
-
-		for (i = client_size - MAX_CLIENTS; i < client_size; i++) {
-			client[i].fd = -1;
-			pollfd[i].fd = -1;
-		}
+		i = client_alloc();
+		if (i)
+			return i;
 	}
+
+	return -ELOOP;
 }
 
 static int dump_debug(int ci)
@@ -422,7 +452,11 @@ static void process_listener(int ci)
 	}
 
 	i = client_add(fd, process_client, NULL);
-	log_debug("new client connection %d", i);
+	if (i < 0) {
+		log_error("Error adding client: %s", strerror(-i));
+		close(fd);
+	} else
+		log_debug("new client connection %d", i);
 }
 
 static void dead_listener(int ci)
@@ -440,10 +474,17 @@ static int setup_listener(void)
 	if (fd < 0) {
 		log_error("Unable to start listening socket: %s",
 			  strerror(-fd));
-		return 1;
+		return fd;
 	}
 
 	i = client_add(fd, process_listener, dead_listener);
+	if (i < 0) {
+		log_error("Unable to add listening socket: %s",
+			  strerror(-i));
+		close(fd);
+		return i;
+	}
+
 	log_debug("new listening connection %d", i);
 
 	return 0;
-- 
1.5.3.8




More information about the Ocfs2-tools-devel mailing list