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)
}
-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)
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);
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;
}
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;
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;
* 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;
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);
}
}
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;
* 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;
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);
}
}
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) {
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;
}
/*
* 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);
/*
* 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;
/*
* 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;
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,
: 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;
}
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;
}
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;
}
"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;
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;
}
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.
*/