uint32_t our_vnn;
uint64_t rand_srvid;
struct ctdb_packet_context *pkt;
- struct fd_event *fde;
+ struct tevent_fd *fde;
void (*release_ip_handler)(const char *ip_addr, void *private_data);
void *release_ip_priv;
CTDB_CURRENT_NODE, CTDB_CONTROL_GET_PNN, 0, 0,
tdb_null, NULL, NULL, &cstatus);
if (!NT_STATUS_IS_OK(status)) {
- cluster_fatal("ctdbd_control failed\n");
+ DEBUG(1, ("ctdbd_control failed: %s\n", nt_errstr(status)));
+ return status;
}
*vnn = (uint32_t)cstatus;
return status;
CTDB_CONTROL_GET_NODEMAP, 0, 0,
tdb_null, talloc_tos(), &outdata, &cstatus);
if (!NT_STATUS_IS_OK(status)) {
- cluster_fatal("ctdbd_control failed\n");
+ DEBUG(1, ("ctdbd_control failed: %s\n", nt_errstr(status)));
+ return false;
}
if ((cstatus != 0) || (outdata.dptr == NULL)) {
DEBUG(2, ("Received invalid ctdb data\n"));
{
struct ctdb_packet_context *result;
const char *sockname = lp_ctdbd_socket();
- struct sockaddr_un addr;
+ struct sockaddr_un addr = { 0, };
int fd;
socklen_t salen;
return map_nt_error_from_unix(errno);
}
- ZERO_STRUCT(addr);
addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, sockname, sizeof(addr.sun_path));
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", sockname);
salen = sizeof(struct sockaddr_un);
if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
* Timed event handler for the deferred message
*/
-static void deferred_message_dispatch(struct event_context *event_ctx,
- struct timed_event *te,
+static void deferred_message_dispatch(struct tevent_context *event_ctx,
+ struct tevent_timer *te,
struct timeval now,
void *private_data)
{
ctdb_packet_dump(hdr);
if (hdr->operation == CTDB_REQ_MESSAGE) {
- struct timed_event *evt;
+ struct tevent_timer *evt;
struct deferred_msg_state *msg_state;
struct ctdb_req_message *msg = (struct ctdb_req_message *)hdr;
* We're waiting for a call reply, but an async message has
* crossed. Defer dispatching to the toplevel event loop.
*/
- evt = event_add_timed(conn->msg_ctx->event_ctx,
+ evt = tevent_add_timer(conn->msg_ctx->event_ctx,
conn->msg_ctx->event_ctx,
timeval_zero(),
deferred_message_dispatch,
* The ctdbd socket is readable asynchronuously
*/
-static void ctdbd_socket_handler(struct event_context *event_ctx,
- struct fd_event *event,
+static void ctdbd_socket_handler(struct tevent_context *event_ctx,
+ struct tevent_fd *event,
uint16 flags,
void *private_data)
{
SMB_ASSERT(conn->msg_ctx == NULL);
SMB_ASSERT(conn->fde == NULL);
- if (!(conn->fde = event_add_fd(msg_ctx->event_ctx, conn,
+ if (!(conn->fde = tevent_add_fd(msg_ctx->event_ctx, conn,
ctdb_packet_get_fd(conn->pkt),
- EVENT_FD_READ,
+ TEVENT_FD_READ,
ctdbd_socket_handler,
conn))) {
DEBUG(0, ("event_add_fd failed\n"));
status = ctdbd_messaging_send_blob(conn, dst_vnn, dst_srvid,
blob.data, blob.length);
TALLOC_FREE(blob.data);
- return NT_STATUS_OK;
+ return status;
}
NTSTATUS ctdbd_messaging_send_blob(struct ctdbd_connection *conn,
struct ctdb_reply_control *reply = NULL;
struct ctdb_vnn_list *vnn;
uint32_t reqid;
+ uint8_t *reply_data;
status = ctdb_read_req(conn, 0, talloc_tos(), (void *)&reply);
if (!NT_STATUS_IS_OK(status)) {
(unsigned)vnn->vnn, vnn->num_srvids,
(unsigned)reply->datalen));
- if (reply->datalen < ((vnn->num_srvids+7)/8)) {
- DEBUG(1, ("Received short reply len %d, status %u,"
+ if (reply->datalen >= ((vnn->num_srvids+7)/8)) {
+ /*
+ * Got a real reply
+ */
+ reply_data = reply->data;
+ } else {
+ /*
+ * Got an error reply
+ */
+ DEBUG(5, ("Received short reply len %d, status %u, "
"errorlen %u\n",
(unsigned)reply->datalen,
(unsigned)reply->status,
(unsigned)reply->errorlen));
- goto fail;
+ dump_data(5, reply->data, reply->errorlen);
+
+ /*
+ * This will trigger everything set to false
+ */
+ reply_data = NULL;
}
for (i=0; i<vnn->num_srvids; i++) {
results[idx] = true;
continue;
}
- results[idx] = ((reply->data[i/8] & (1<<(i%8))) != 0);
+ results[idx] =
+ (reply_data != NULL) &&
+ ((reply_data[i/8] & (1<<(i%8))) != 0);
}
TALLOC_FREE(reply);
}
/*
- * remotely fetch a record (read-only)
+ * Fetch a record and parse it
*/
-NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32_t db_id,
- TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data,
- bool local_copy)
+NTSTATUS ctdbd_parse(struct ctdbd_connection *conn, uint32_t db_id,
+ TDB_DATA key, bool local_copy,
+ void (*parser)(TDB_DATA key, TDB_DATA data,
+ void *private_data),
+ void *private_data)
{
struct ctdb_req_call req;
struct ctdb_reply_call *reply;
goto fail;
}
- data->dsize = reply->datalen;
- if (data->dsize == 0) {
- data->dptr = NULL;
- goto done;
- }
-
- data->dptr = (uint8 *)talloc_memdup(mem_ctx, &reply->data[0],
- reply->datalen);
- if (data->dptr == NULL) {
- DEBUG(0, ("talloc failed\n"));
- status = NT_STATUS_NO_MEMORY;
+ if (reply->datalen == 0) {
+ /*
+ * Treat an empty record as non-existing
+ */
+ status = NT_STATUS_NOT_FOUND;
goto fail;
}
- done:
+ parser(key, make_tdb_data(&reply->data[0], reply->datalen),
+ private_data);
+
status = NT_STATUS_OK;
fail:
TALLOC_FREE(reply);
return status;
}
+NTSTATUS ctdbd_probe(void)
+{
+ /*
+ * Do a very early check if ctdbd is around to avoid an abort and core
+ * later
+ */
+ struct ctdbd_connection *conn = NULL;
+ NTSTATUS status;
+
+ status = ctdbd_messaging_connection(talloc_tos(), &conn);
+
+ /*
+ * We only care if we can connect.
+ */
+ TALLOC_FREE(conn);
+
+ return status;
+}
+
#else
+NTSTATUS ctdbd_probe(void)
+{
+ return NT_STATUS_OK;
+}
+
NTSTATUS ctdbd_messaging_send_blob(struct ctdbd_connection *conn,
uint32_t dst_vnn, uint64_t dst_srvid,
const uint8_t *buf, size_t buflen)