traverse: fix traversing with empty records by adding a new (internal) control CTDB_C...
authorMichael Adam <obnox@samba.org>
Sat, 3 Dec 2011 01:15:30 +0000 (02:15 +0100)
committerMichael Adam <obnox@samba.org>
Sat, 3 Dec 2011 01:15:30 +0000 (02:15 +0100)
By this, the original CTDB_CONTROL_TRAVERSE_START control that is
used by e.g. samba's smbstatus, is not changed, so that samba
continues working without code change.

The  CTDB_CONTROL_TRAVERSE_START currently just adds the "withemptyrecords"
flag to the state and processon on as CTDB_CONTROL_TRAVERSE_START_EXT.

client/ctdb_client.c
include/ctdb_private.h
include/ctdb_protocol.h
server/ctdb_control.c
server/ctdb_traverse.c

index 75ad0e134fa1aa8662a97fbdb328e7839aa34e48..224cdc03ee472b218707b0fbe9bacef211ac86e9 100644 (file)
@@ -2059,7 +2059,7 @@ static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
                             void *private_data)
 {
        TDB_DATA data;
-       struct ctdb_traverse_start t;
+       struct ctdb_traverse_start_ext t;
        int32_t status;
        int ret;
        uint64_t srvid = (getpid() | 0xFLL<<60);
@@ -2085,7 +2085,7 @@ static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
        data.dptr = (uint8_t *)&t;
        data.dsize = sizeof(t);
 
-       ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0,
+       ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START_EXT, 0,
                           data, NULL, NULL, &status, NULL, NULL);
        if (ret != 0 || status != 0) {
                DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
index 4155bac45bcedcacc4c0cfa48dfbede99dab5a03..f545eaa4b414bf6a31e0ef919f7c237f4b428595 100644 (file)
@@ -955,6 +955,11 @@ struct ctdb_client_call_state {
 };
 
 
+int32_t ctdb_control_traverse_start_ext(struct ctdb_context *ctdb,
+                                       TDB_DATA indata,
+                                       TDB_DATA *outdata,
+                                       uint32_t srcnode,
+                                       uint32_t client_id);
 int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA indata, 
                                    TDB_DATA *outdata, uint32_t srcnode, uint32_t client_id);
 int32_t ctdb_control_traverse_all(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata);
index 99e3f4fd9effa5cba84aad18292149e11325a01e..c71bafaaebaf57cc008be3705d42177e473bef0a 100644 (file)
@@ -374,6 +374,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
                    CTDB_CONTROL_SCHEDULE_FOR_DELETION   = 128,
                    CTDB_CONTROL_SET_DB_READONLY         = 129,
                    CTDB_CONTROL_CHECK_SRVIDS            = 130,
+                   CTDB_CONTROL_TRAVERSE_START_EXT      = 131,
 };
 
 /*
@@ -582,6 +583,12 @@ struct ctdb_traverse_start {
        uint32_t db_id;
        uint32_t reqid;
        uint64_t srvid;
+};
+
+struct ctdb_traverse_start_ext {
+       uint32_t db_id;
+       uint32_t reqid;
+       uint64_t srvid;
        bool withemptyrecords;
 };
 
index 602e994b1d8388629c1be0c4d7629b13d0e084df..060f2c5cf3368a2f5e1b5d8e2efb189d6a340453 100644 (file)
@@ -247,6 +247,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
                return ctdb_control_traverse_start(ctdb, indata, outdata, srcnode, client_id);
 
+       case CTDB_CONTROL_TRAVERSE_START_EXT:
+               CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start_ext));
+               return ctdb_control_traverse_start_ext(ctdb, indata, outdata, srcnode, client_id);
+
        case CTDB_CONTROL_TRAVERSE_ALL:
                return ctdb_control_traverse_all(ctdb, indata, outdata);
 
index d719f6f4106c93c0330a124880365373c98cd836..da5a548da50d37ca36fa184ef1c7cd705622abf3 100644 (file)
@@ -557,13 +557,17 @@ static void traverse_start_callback(void *p, TDB_DATA key, TDB_DATA data)
 }
 
 
-/*
-  start a traverse_all - called as a control from a client
+/**
+ * start a traverse_all - called as a control from a client.
+ * extended version to take the "withemptyrecords" parameter.
  */
-int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA data, 
-                                   TDB_DATA *outdata, uint32_t srcnode, uint32_t client_id)
+int32_t ctdb_control_traverse_start_ext(struct ctdb_context *ctdb,
+                                       TDB_DATA data,
+                                       TDB_DATA *outdata,
+                                       uint32_t srcnode,
+                                       uint32_t client_id)
 {
-       struct ctdb_traverse_start *d = (struct ctdb_traverse_start *)data.dptr;
+       struct ctdb_traverse_start_ext *d = (struct ctdb_traverse_start_ext *)data.dptr;
        struct traverse_start_state *state;
        struct ctdb_db_context *ctdb_db;
        struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
@@ -615,3 +619,28 @@ int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA data,
 
        return 0;
 }
+
+/**
+ * start a traverse_all - called as a control from a client.
+ */
+int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb,
+                                   TDB_DATA data,
+                                   TDB_DATA *outdata,
+                                   uint32_t srcnode,
+                                   uint32_t client_id)
+{
+       struct ctdb_traverse_start *d = (struct ctdb_traverse_start *)data.dptr;
+       struct ctdb_traverse_start_ext d2;
+       TDB_DATA data2;
+
+       ZERO_STRUCT(d2);
+       d2.db_id = d->db_id;
+       d2.reqid = d->reqid;
+       d2.srvid = d->srvid;
+       d2.withemptyrecords = false;
+
+       data2.dsize = sizeof(d2);
+       data2.dptr = (uint8_t *)&d2;
+
+       return ctdb_control_traverse_start_ext(ctdb, data2, outdata, srcnode, client_id);
+}