summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-10-27 15:21:29 +0200
committerVolker Lendecke <vlendec@samba.org>2011-10-27 22:12:05 +0200
commita29f7e632f999af51a0e847331af4447b5710d8e (patch)
tree070baca1fc24c984d464b2d29a3ba807dd25a88b
parent195ae03950b8130b8c3caed65123c87882af595e (diff)
downloadsamba-a29f7e632f999af51a0e847331af4447b5710d8e.tar.gz
samba-a29f7e632f999af51a0e847331af4447b5710d8e.tar.xz
samba-a29f7e632f999af51a0e847331af4447b5710d8e.zip
s3-ctdb: Fix ctdb_read_req
If a complete request has come in already before we consumed it, the ctdb_packet_fd_read_sync will block indefinitely. So always try packet_handler first and only if that fails due to insufficient data, read from the socket. Autobuild-User: Volker Lendecke <vlendec@samba.org> Autobuild-Date: Thu Oct 27 22:12:05 CEST 2011 on sn-devel-104
-rw-r--r--source3/lib/ctdbd_conn.c40
1 files changed, 17 insertions, 23 deletions
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 8bd7caffb99..5c3b7c1f4f6 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -380,35 +380,29 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
struct req_pull_state state;
NTSTATUS status;
- again:
-
- status = ctdb_packet_fd_read_sync(conn->pkt);
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) {
- /* EAGAIN */
- goto again;
- } else if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
- /* EAGAIN */
- goto again;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("ctdb_packet_fd_read failed: %s\n", nt_errstr(status)));
- cluster_fatal("ctdbd died\n");
- }
-
next_pkt:
-
ZERO_STRUCT(state);
state.mem_ctx = mem_ctx;
- if (!ctdb_packet_handler(conn->pkt, ctdb_req_complete, ctdb_req_pull,
- &state, &status)) {
+ while (!ctdb_packet_handler(conn->pkt, ctdb_req_complete,
+ ctdb_req_pull, &state, &status)) {
/*
* Not enough data
*/
- DEBUG(10, ("not enough data from ctdb socket, retrying\n"));
- goto again;
+ status = ctdb_packet_fd_read_sync(conn->pkt);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) {
+ /* EAGAIN */
+ continue;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+ /* EAGAIN */
+ continue;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status)));
+ cluster_fatal("ctdbd died\n");
+ }
}
if (!NT_STATUS_IS_OK(status)) {
@@ -504,7 +498,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
DEBUG(0,("Discarding mismatched ctdb reqid %u should have "
"been %u\n", hdr->reqid, reqid));
TALLOC_FREE(hdr);
- goto again;
+ goto next_pkt;
}
*((void **)result) = talloc_move(mem_ctx, &hdr);