ctdb-conn: Add ctdbd_parse
authorVolker Lendecke <vl@samba.org>
Fri, 23 Nov 2012 16:54:57 +0000 (17:54 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 26 Mar 2013 10:19:02 +0000 (11:19 +0100)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/include/ctdbd_conn.h
source3/lib/ctdbd_conn.c

index 5778a9291d99d6398171d3ffef32410b76d1173a..295d41e6b6ada0943ce136dd841b99f9284fd8c7 100644 (file)
@@ -65,6 +65,11 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32_t db_id,
 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);
 
 NTSTATUS ctdbd_traverse(uint32_t db_id,
                        void (*fn)(TDB_DATA key, TDB_DATA data,
index 2cf5e472b0a2dc6a520d075fb67fc8e2bc74f215..d77b03dc0a5ce974683a49cfec4c784b2988532d 100644 (file)
@@ -1494,6 +1494,77 @@ NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32_t db_id,
        return status;
 }
 
+/*
+ * Fetch a record and parse it
+ */
+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;
+       NTSTATUS status;
+       uint32_t flags;
+
+#ifdef HAVE_CTDB_WANT_READONLY_DECL
+       flags = local_copy ? CTDB_WANT_READONLY : 0;
+#else
+       flags = 0;
+#endif
+
+       ZERO_STRUCT(req);
+
+       req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize;
+       req.hdr.ctdb_magic   = CTDB_MAGIC;
+       req.hdr.ctdb_version = CTDB_VERSION;
+       req.hdr.operation    = CTDB_REQ_CALL;
+       req.hdr.reqid        = ctdbd_next_reqid(conn);
+       req.flags            = flags;
+       req.callid           = CTDB_FETCH_FUNC;
+       req.db_id            = db_id;
+       req.keylen           = key.dsize;
+
+       status = ctdb_packet_send(
+               conn->pkt, 2,
+               data_blob_const(&req, offsetof(struct ctdb_req_call, data)),
+               data_blob_const(key.dptr, key.dsize));
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
+               return status;
+       }
+
+       status = ctdb_packet_flush(conn->pkt);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
+               cluster_fatal("cluster dispatch daemon control write error\n");
+       }
+
+       status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("ctdb_read_req failed: %s\n", nt_errstr(status)));
+               goto fail;
+       }
+
+       if (reply->hdr.operation != CTDB_REPLY_CALL) {
+               DEBUG(0, ("received invalid reply\n"));
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto fail;
+       }
+
+       parser(key, make_tdb_data(&reply->data[0], reply->datalen),
+              private_data);
+
+       status = NT_STATUS_OK;
+ fail:
+       TALLOC_FREE(reply);
+       return status;
+}
+
 struct ctdbd_traverse_state {
        void (*fn)(TDB_DATA key, TDB_DATA data, void *private_data);
        void *private_data;