diff options
author | Volker Lendecke <vl@samba.org> | 2011-10-23 21:38:54 +0200 |
---|---|---|
committer | Volker Lendecke <vlendec@samba.org> | 2011-10-27 20:28:31 +0200 |
commit | 1c4fe3903333e9fa24c375c95cfc52a608f9b27b (patch) | |
tree | bfd58ae37908328ae7f2636d7c46a35265aef7f7 | |
parent | c2edecf6bd3df1be7b94cbe7dc29f308b9b1d8e0 (diff) | |
download | samba-1c4fe3903333e9fa24c375c95cfc52a608f9b27b.tar.gz samba-1c4fe3903333e9fa24c375c95cfc52a608f9b27b.tar.bz2 samba-1c4fe3903333e9fa24c375c95cfc52a608f9b27b.zip |
s3-ctdb: Add ctdb_processes_exist
This sends out a number of process_exists controls in parallel and collects the
replies as they come in.
-rw-r--r-- | source3/include/ctdbd_conn.h | 3 | ||||
-rw-r--r-- | source3/lib/ctdbd_conn.c | 98 |
2 files changed, 101 insertions, 0 deletions
diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h index cf257bf115..1d52577fe8 100644 --- a/source3/include/ctdbd_conn.h +++ b/source3/include/ctdbd_conn.h @@ -43,6 +43,9 @@ NTSTATUS ctdbd_messaging_send(struct ctdbd_connection *conn, bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn, pid_t pid); +bool ctdb_processes_exist(struct ctdbd_connection *conn, + const struct server_id *pids, int num_pids, + bool *results); char *ctdbd_dbpath(struct ctdbd_connection *conn, TALLOC_CTX *mem_ctx, uint32_t db_id); diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index f94860a762..f172bdfed4 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -932,6 +932,104 @@ bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn, pid_t pid) return cstatus == 0; } +bool ctdb_processes_exist(struct ctdbd_connection *conn, + const struct server_id *pids, int num_pids, + bool *results) +{ + TALLOC_CTX *frame = talloc_stackframe(); + int i, num_received; + NTSTATUS status; + uint32_t *reqids; + bool result = false; + + reqids = talloc_array(talloc_tos(), uint32_t, num_pids); + if (reqids == NULL) { + goto fail; + } + + for (i=0; i<num_pids; i++) { + struct ctdb_req_control req; + + results[i] = false; + reqids[i] = ctdbd_next_reqid(conn); + + ZERO_STRUCT(req); + + req.hdr.length = offsetof(struct ctdb_req_control, data); + req.hdr.length += sizeof(pid_t); + req.hdr.ctdb_magic = CTDB_MAGIC; + req.hdr.ctdb_version = CTDB_VERSION; + req.hdr.operation = CTDB_REQ_CONTROL; + req.hdr.reqid = reqids[i]; + req.hdr.destnode = pids[i].vnn; + req.opcode = CTDB_CONTROL_PROCESS_EXISTS; + req.srvid = 0; + req.datalen = sizeof(pids[i].pid); + req.flags = 0; + + DEBUG(10, ("ctdbd_control: Sending ctdb packet\n")); + ctdb_packet_dump(&req.hdr); + + status = ctdb_packet_send( + conn->pkt, 2, + data_blob_const( + &req, offsetof(struct ctdb_req_control, data)), + data_blob_const(&pids[i].pid, sizeof(pids[i].pid))); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ctdb_packet_send failed: %s\n", + nt_errstr(status))); + goto fail; + } + } + + status = ctdb_packet_flush(conn->pkt); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ctdb_packet_flush failed: %s\n", + nt_errstr(status))); + goto fail; + } + + num_received = 0; + + while (num_received < num_pids) { + struct ctdb_reply_control *reply = NULL; + uint32_t reqid; + + status = ctdb_read_req(conn, 0, talloc_tos(), (void *)&reply); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ctdb_read_req failed: %s\n", + nt_errstr(status))); + goto fail; + } + + if (reply->hdr.operation != CTDB_REPLY_CONTROL) { + DEBUG(10, ("Received invalid reply\n")); + goto fail; + } + + reqid = reply->hdr.reqid; + + for (i=0; i<num_pids; i++) { + if (reqid == reqids[i]) { + break; + } + } + if (i == num_pids) { + DEBUG(10, ("Received unknown record number %u\n", + (unsigned)reqid)); + goto fail; + } + results[i] = ((reply->status) == 0); + TALLOC_FREE(reply); + num_received += 1; + } + + result = true; +fail: + TALLOC_FREE(frame); + return result; +} + /* * Get a db path */ |