diff options
author | Volker Lendecke <vl@samba.org> | 2011-10-27 15:21:29 +0200 |
---|---|---|
committer | Volker Lendecke <vlendec@samba.org> | 2011-10-27 22:12:05 +0200 |
commit | a29f7e632f999af51a0e847331af4447b5710d8e (patch) | |
tree | 070baca1fc24c984d464b2d29a3ba807dd25a88b | |
parent | 195ae03950b8130b8c3caed65123c87882af595e (diff) | |
download | samba-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.c | 40 |
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); |