[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