ctdb-server: Replace ctdb_logging.h with common/logging.h
[obnox/samba/samba-obnox.git] / ctdb / server / ctdb_vacuum.c
index 35f1fe1bfb0f8e786bdcf0e3fc0d8cfc6c811dff..a81bd54b287cfc8c442944d796c195d4c49e678d 100644 (file)
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "includes.h"
-#include "tdb.h"
+#include "replace.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "system/dir.h"
-#include "../include/ctdb_private.h"
+#include "system/time.h"
+
+#include <talloc.h>
+#include <tevent.h>
+
 #include "lib/tdb_wrap/tdb_wrap.h"
 #include "lib/util/dlinklist.h"
-#include "../include/ctdb_private.h"
-#include "../common/rb_tree.h"
+#include "lib/util/debug.h"
+#include "lib/util/samba_util.h"
+
+#include "ctdb_private.h"
+#include "ctdb_client.h"
+
+#include "common/rb_tree.h"
+#include "common/system.h"
+#include "common/common.h"
+#include "common/logging.h"
 
 #define TIMELIMIT() timeval_current_ofs(10, 0)
 
@@ -202,7 +212,8 @@ static int add_record_to_vacuum_fetch_list(struct vacuum_data *vdata,
 }
 
 
-static void ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
+static void ctdb_vacuum_event(struct tevent_context *ev,
+                             struct tevent_timer *te,
                              struct timeval t, void *private_data);
 
 static int vacuum_record_parser(TDB_DATA key, TDB_DATA data, void *private_data)
@@ -317,12 +328,8 @@ static int delete_marshall_traverse_first(void *param, void *data)
        uint32_t hash = ctdb_hash(&(dd->key));
        int res;
 
-       res = tdb_chainlock(ctdb_db->ltdb->tdb, dd->key);
+       res = tdb_chainlock_nonblock(ctdb_db->ltdb->tdb, dd->key);
        if (res != 0) {
-               DEBUG(DEBUG_ERR,
-                     (__location__ " Error getting chainlock on record with "
-                      "key hash [0x%08x] on database db[%s].\n",
-                      hash, ctdb_db->db_name));
                recs->vdata->count.delete_list.skipped++;
                recs->vdata->count.delete_list.left--;
                talloc_free(dd);
@@ -446,12 +453,8 @@ static int delete_queue_traverse(void *param, void *data)
 
        vdata->count.delete_queue.total++;
 
-       res = tdb_chainlock(ctdb_db->ltdb->tdb, dd->key);
+       res = tdb_chainlock_nonblock(ctdb_db->ltdb->tdb, dd->key);
        if (res != 0) {
-               DEBUG(DEBUG_ERR,
-                     (__location__ " Error getting chainlock on record with "
-                      "key hash [0x%08x] on database db[%s].\n",
-                      hash, ctdb_db->db_name));
                vdata->count.delete_queue.error++;
                return 0;
        }
@@ -819,7 +822,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
        struct ctdb_context *ctdb = ctdb_db->ctdb;
        struct delete_records_list *recs;
        TDB_DATA indata;
-       struct ctdb_node_map *nodemap;
+       struct ctdb_node_map_old *nodemap;
        uint32_t *active_nodes;
        int num_active_nodes;
        TALLOC_CTX *tmp_ctx;
@@ -905,7 +908,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
 
        for (i = 0; i < num_active_nodes; i++) {
                struct ctdb_marshall_buffer *records;
-               struct ctdb_rec_data *rec;
+               struct ctdb_rec_data_old *rec;
                int32_t res;
                TDB_DATA outdata;
 
@@ -927,7 +930,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
                 * the list to process further.
                 */
                records = (struct ctdb_marshall_buffer *)outdata.dptr;
-               rec = (struct ctdb_rec_data *)&records->data[0];
+               rec = (struct ctdb_rec_data_old *)&records->data[0];
                while (records->count-- > 1) {
                        TDB_DATA reckey, recdata;
                        struct ctdb_ltdb_header *rechdr;
@@ -969,7 +972,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
                                vdata->count.delete_list.left--;
                        }
 
-                       rec = (struct ctdb_rec_data *)(rec->length + (uint8_t *)rec);
+                       rec = (struct ctdb_rec_data_old *)(rec->length + (uint8_t *)rec);
                }
        }
 
@@ -1012,7 +1015,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
 
        for (i = 0; i < num_active_nodes; i++) {
                struct ctdb_marshall_buffer *records;
-               struct ctdb_rec_data *rec;
+               struct ctdb_rec_data_old *rec;
                int32_t res;
                TDB_DATA outdata;
 
@@ -1034,7 +1037,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
                 * the list to delete locally.
                 */
                records = (struct ctdb_marshall_buffer *)outdata.dptr;
-               rec = (struct ctdb_rec_data *)&records->data[0];
+               rec = (struct ctdb_rec_data_old *)&records->data[0];
                while (records->count-- > 1) {
                        TDB_DATA reckey, recdata;
                        struct ctdb_ltdb_header *rechdr;
@@ -1076,7 +1079,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db,
                                vdata->count.delete_list.left--;
                        }
 
-                       rec = (struct ctdb_rec_data *)(rec->length + (uint8_t *)rec);
+                       rec = (struct ctdb_rec_data_old *)(rec->length + (uint8_t *)rec);
                }
        }
 
@@ -1364,6 +1367,7 @@ static int vacuum_child_destructor(struct ctdb_vacuum_child_context *child_ctx)
        struct ctdb_db_context *ctdb_db = child_ctx->vacuum_handle->ctdb_db;
        struct ctdb_context *ctdb = ctdb_db->ctdb;
 
+       CTDB_UPDATE_DB_LATENCY(ctdb_db, "vacuum", vacuum.latency, l);
        DEBUG(DEBUG_INFO,("Vacuuming took %.3f seconds for database %s\n", l, ctdb_db->db_name));
 
        if (child_ctx->child_pid != -1) {
@@ -1375,9 +1379,9 @@ static int vacuum_child_destructor(struct ctdb_vacuum_child_context *child_ctx)
 
        DLIST_REMOVE(ctdb->vacuumers, child_ctx);
 
-       event_add_timed(ctdb->ev, child_ctx->vacuum_handle,
-                       timeval_current_ofs(get_vacuum_interval(ctdb_db), 0), 
-                       ctdb_vacuum_event, child_ctx->vacuum_handle);
+       tevent_add_timer(ctdb->ev, child_ctx->vacuum_handle,
+                        timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
+                        ctdb_vacuum_event, child_ctx->vacuum_handle);
 
        return 0;
 }
@@ -1385,8 +1389,9 @@ static int vacuum_child_destructor(struct ctdb_vacuum_child_context *child_ctx)
 /*
  * this event is generated when a vacuum child process times out
  */
-static void vacuum_child_timeout(struct event_context *ev, struct timed_event *te,
-                                        struct timeval t, void *private_data)
+static void vacuum_child_timeout(struct tevent_context *ev,
+                                struct tevent_timer *te,
+                                struct timeval t, void *private_data)
 {
        struct ctdb_vacuum_child_context *child_ctx = talloc_get_type(private_data, struct ctdb_vacuum_child_context);
 
@@ -1401,8 +1406,9 @@ static void vacuum_child_timeout(struct event_context *ev, struct timed_event *t
 /*
  * this event is generated when a vacuum child process has completed
  */
-static void vacuum_child_handler(struct event_context *ev, struct fd_event *fde,
-                            uint16_t flags, void *private_data)
+static void vacuum_child_handler(struct tevent_context *ev,
+                                struct tevent_fd *fde,
+                                uint16_t flags, void *private_data)
 {
        struct ctdb_vacuum_child_context *child_ctx = talloc_get_type(private_data, struct ctdb_vacuum_child_context);
        char c = 0;
@@ -1425,9 +1431,9 @@ static void vacuum_child_handler(struct event_context *ev, struct fd_event *fde,
 /*
  * this event is called every time we need to start a new vacuum process
  */
-static void
-ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
-                              struct timeval t, void *private_data)
+static void ctdb_vacuum_event(struct tevent_context *ev,
+                             struct tevent_timer *te,
+                             struct timeval t, void *private_data)
 {
        struct ctdb_vacuum_handle *vacuum_handle = talloc_get_type(private_data, struct ctdb_vacuum_handle);
        struct ctdb_db_context *ctdb_db = vacuum_handle->ctdb_db;
@@ -1436,7 +1442,7 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
        struct tevent_fd *fde;
        int ret;
 
-       /* we dont vacuum if we are in recovery mode, or db frozen */
+       /* we don't vacuum if we are in recovery mode, or db frozen */
        if (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE ||
            ctdb->freeze_mode[ctdb_db->priority] != CTDB_FREEZE_NONE) {
                DEBUG(DEBUG_INFO, ("Not vacuuming %s (%s)\n", ctdb_db->db_name,
@@ -1444,9 +1450,20 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
                                   : ctdb->freeze_mode[ctdb_db->priority] == CTDB_FREEZE_PENDING
                                   ? "freeze pending"
                                   : "frozen"));
-               event_add_timed(ctdb->ev, vacuum_handle,
-                       timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
-                       ctdb_vacuum_event, vacuum_handle);
+               tevent_add_timer(ctdb->ev, vacuum_handle,
+                                timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
+                                ctdb_vacuum_event, vacuum_handle);
+               return;
+       }
+
+       /* Do not allow multiple vacuuming child processes to be active at the
+        * same time.  If there is vacuuming child process active, delay
+        * new vacuuming event to stagger vacuuming events.
+        */
+       if (ctdb->vacuumers != NULL) {
+               tevent_add_timer(ctdb->ev, vacuum_handle,
+                                timeval_current_ofs(0, 500*1000),
+                                ctdb_vacuum_event, vacuum_handle);
                return;
        }
 
@@ -1461,9 +1478,9 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
        if (ret != 0) {
                talloc_free(child_ctx);
                DEBUG(DEBUG_ERR, ("Failed to create pipe for vacuum child process.\n"));
-               event_add_timed(ctdb->ev, vacuum_handle,
-                       timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
-                       ctdb_vacuum_event, vacuum_handle);
+               tevent_add_timer(ctdb->ev, vacuum_handle,
+                                timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
+                                ctdb_vacuum_event, vacuum_handle);
                return;
        }
 
@@ -1477,9 +1494,9 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
                close(child_ctx->fd[1]);
                talloc_free(child_ctx);
                DEBUG(DEBUG_ERR, ("Failed to fork vacuum child process.\n"));
-               event_add_timed(ctdb->ev, vacuum_handle,
-                       timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
-                       ctdb_vacuum_event, vacuum_handle);
+               tevent_add_timer(ctdb->ev, vacuum_handle,
+                                timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
+                                ctdb_vacuum_event, vacuum_handle);
                return;
        }
 
@@ -1527,14 +1544,14 @@ ctdb_vacuum_event(struct event_context *ev, struct timed_event *te,
                                 "in parent context. Shutting down\n");
        }
 
-       event_add_timed(ctdb->ev, child_ctx,
-               timeval_current_ofs(ctdb->tunable.vacuum_max_run_time, 0),
-               vacuum_child_timeout, child_ctx);
+       tevent_add_timer(ctdb->ev, child_ctx,
+                        timeval_current_ofs(ctdb->tunable.vacuum_max_run_time, 0),
+                        vacuum_child_timeout, child_ctx);
 
        DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child vacuum process\n", child_ctx->fd[0]));
 
-       fde = event_add_fd(ctdb->ev, child_ctx, child_ctx->fd[0],
-                          EVENT_FD_READ, vacuum_child_handler, child_ctx);
+       fde = tevent_add_fd(ctdb->ev, child_ctx, child_ctx->fd[0],
+                           TEVENT_FD_READ, vacuum_child_handler, child_ctx);
        tevent_fd_set_auto_close(fde);
 
        vacuum_handle->child_ctx = child_ctx;
@@ -1569,9 +1586,9 @@ int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db)
        ctdb_db->vacuum_handle->ctdb_db         = ctdb_db;
        ctdb_db->vacuum_handle->fast_path_count = 0;
 
-       event_add_timed(ctdb_db->ctdb->ev, ctdb_db->vacuum_handle, 
-                       timeval_current_ofs(get_vacuum_interval(ctdb_db), 0), 
-                       ctdb_vacuum_event, ctdb_db->vacuum_handle);
+       tevent_add_timer(ctdb_db->ctdb->ev, ctdb_db->vacuum_handle,
+                        timeval_current_ofs(get_vacuum_interval(ctdb_db), 0),
+                        ctdb_vacuum_event, ctdb_db->vacuum_handle);
 
        return 0;
 }
@@ -1728,7 +1745,7 @@ int32_t ctdb_local_schedule_for_deletion(struct ctdb_db_context *ctdb_db,
                return ret;
        }
 
-       /* if we dont have a connection to the daemon we can not send
+       /* if we don't have a connection to the daemon we can not send
           a control. For example sometimes from update_record control child
           process.
        */