From mboxrd@z Thu Jan 1 00:00:00 1970 From: teigland@sourceware.org Date: 14 Sep 2006 20:49:38 -0000 Subject: [Cluster-devel] cluster/group/daemon main.c Message-ID: <20060914204938.14949.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: teigland at sourceware.org 2006-09-14 20:49:38 Modified files: group/daemon : main.c Log message: handle short/interrupted writes/reads Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/group/daemon/main.c.diff?cvsroot=cluster&r1=1.42&r2=1.43 --- cluster/group/daemon/main.c 2006/09/12 21:57:05 1.42 +++ cluster/group/daemon/main.c 2006/09/14 20:49:38 1.43 @@ -38,6 +38,42 @@ void *deadfn; }; +static int do_write(int fd, void *buf, size_t count) +{ + int rv, off = 0; + + retry: + rv = write(fd, buf + off, count); + if (rv == -1 && errno == EINTR) + goto retry; + if (rv < 0) { + log_print("write fd %d errno %d", fd, errno); + return rv; + } + + if (rv != count) { + count -= rv; + off += rv; + goto retry; + } + return 0; +} + +static int do_read(int fd, void *buf, size_t count) +{ + int rv, off = 0; + + while (off < count) { + rv = read(fd, buf + off, count - off); + if (rv == 0) + return -1; + if (rv == -1 && errno == EINTR) + continue; + off += rv; + } + return 0; +} + /* Look for any instances of gfs or dlm in the kernel, if we find any, it means they're uncontrolled by us (via gfs_controld/dlm_controld/groupd). We need to be rebooted to clear out this uncontrolled kernel state. Most @@ -130,9 +166,9 @@ log_group(a->g, "action for app: %s", buf); - rv = write(client[a->client].fd, buf, GROUPD_MSGLEN); - if (rv != GROUPD_MSGLEN) - log_print("write error %d errno %d", rv, errno); + rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN); + if (rv < 0) + log_error(a->g, "app_action write error"); } void app_deliver(app_t *a, struct save_msg *save) @@ -154,9 +190,9 @@ save->msg_long + sizeof(msg_t)); */ - rv = write(client[a->client].fd, buf, GROUPD_MSGLEN); - if (rv != GROUPD_MSGLEN) - log_print("write error %d errno %d", rv, errno); + rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN); + if (rv < 0) + log_error(a->g, "app_deliver write error"); } void app_terminate(app_t *a) @@ -325,7 +361,7 @@ if (!strncmp(act, "dump", 16)) return DO_DUMP; - return -1; + return -1; } static void client_alloc(void) @@ -459,9 +495,9 @@ i++; } - rv = write(client[ci].fd, data, len); - if (rv != len) - log_print("write error %d errno %d", rv, errno); + rv = do_write(client[ci].fd, data, len); + if (rv < 0) + log_print("do_get_groups write error"); free(data); return 0; @@ -487,9 +523,9 @@ copy_group_data(g, &data); out: - rv = write(client[ci].fd, &data, sizeof(data)); - if (rv != sizeof(data)) - log_print("write error %d errno %d", rv, errno); + rv = do_write(client[ci].fd, &data, sizeof(data)); + if (rv < 0) + log_print("do_get_group write error"); return 0; } @@ -548,14 +584,11 @@ memset(buf, 0, sizeof(buf)); memset(argv, 0, sizeof(char *) * MAXARGS); - rv = read(client[ci].fd, buf, GROUPD_MSGLEN); - if (!rv) { - client_dead(ci); - return; - } - if (rv != GROUPD_MSGLEN) { + rv = do_read(client[ci].fd, buf, GROUPD_MSGLEN); + if (rv < 0) { log_print("client %d fd %d read error %d %d", ci, client[ci].fd, rv, errno); + client_dead(ci); return; } @@ -577,7 +610,7 @@ case DO_LEAVE: get_args(buf, &argc, argv, ' ', 2); - do_leave(argv[1], client[ci].level); + do_leave(argv[1], client[ci].level); break; case DO_STOP_DONE: @@ -789,9 +822,9 @@ printf("\n"); printf("Options:\n"); printf("\n"); - printf(" -D Enable debugging code and don't fork\n"); - printf(" -h Print this help, then exit\n"); - printf(" -V Print program version information, then exit\n"); + printf(" -D Enable debugging code and don't fork\n"); + printf(" -h Print this help, then exit\n"); + printf(" -V Print program version information, then exit\n"); } static void decode_arguments(int argc, char **argv)