struct tevent_signal * ctdb_init_sigchld(struct ctdb_context *ctdb) { struct tevent_signal *se; ctdb->child_processes = trbt_create(ctdb, 0); se = tevent_add_signal(ctdb->ev, ctdb, SIGCHLD, 0, ctdb_sigchld_handler, ctdb); return se; }
/* wipe a database - only possible when in a frozen transaction */ int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata) { struct ctdb_transdb w = *(struct ctdb_transdb *)indata.dptr; struct ctdb_db_context *ctdb_db; ctdb_db = find_ctdb_db(ctdb, w.db_id); if (!ctdb_db) { DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%x\n", w.db_id)); return -1; } if (ctdb_db->freeze_mode != CTDB_FREEZE_FROZEN) { DEBUG(DEBUG_ERR,(__location__ " Failed transaction_start while not frozen\n")); return -1; } if (!ctdb_db->freeze_transaction_started) { DEBUG(DEBUG_ERR,(__location__ " transaction not started\n")); return -1; } if (w.tid != ctdb_db->freeze_transaction_id) { DEBUG(DEBUG_ERR,(__location__ " incorrect transaction id 0x%x in commit\n", w.tid)); return -1; } if (tdb_wipe_all(ctdb_db->ltdb->tdb) != 0) { DEBUG(DEBUG_ERR,(__location__ " Failed to wipe database for db '%s'\n", ctdb_db->db_name)); return -1; } if (!ctdb_db->persistent) { talloc_free(ctdb_db->delete_queue); ctdb_db->delete_queue = trbt_create(ctdb_db, 0); if (ctdb_db->delete_queue == NULL) { DEBUG(DEBUG_ERR, (__location__ " Failed to re-create " "the vacuum tree.\n")); return -1; } } return 0; }
void test_tree(void) { trbt_tree_t *tree; char *str; int i, ret; int NUM=15; int cnt=0; tree=trbt_create(talloc_new(NULL)); #if 0 for(i=0;i<10;i++){ printf("adding node %i\n",i); trbt_insert32(tree, i, NULL); print_tree(tree); } printf("deleting node %i\n",3); trbt_delete32(tree, 3); print_tree(tree); for(i=0;i<10;i++){ printf("deleting node %i\n",i); trbt_delete32(tree, i); print_tree(tree); } exit(0); #endif while(++cnt){ int i; printf("iteration : %d\n",cnt); i=random()%20; printf("adding node %i\n",i); trbt_insert32(tree, i, NULL); print_tree(tree); i=random()%20; printf("deleting node %i\n",i); trbt_delete32(tree, i); print_tree(tree); } }
/* startup daemon side of ctdb according to command line options */ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev) { struct ctdb_context *ctdb; int ret; /* initialise ctdb */ ctdb = ctdb_init(ev); if (ctdb == NULL) { printf("Failed to init ctdb\n"); exit(1); } if (ctdb_cmdline.torture) { ctdb_set_flags(ctdb, CTDB_FLAG_TORTURE); } /* command line specified a socket name */ if (ctdb_cmdline.socketname != NULL) { setenv("CTDB_SOCKET", ctdb_cmdline.socketname, 1); ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname); if (ret == -1) { printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb)); exit(1); } } /* Set the debug level */ if (isalpha(ctdb_cmdline.debuglevel[0]) || ctdb_cmdline.debuglevel[0] == '-') { LogLevel = get_debug_by_desc(ctdb_cmdline.debuglevel); } else { LogLevel = strtol(ctdb_cmdline.debuglevel, NULL, 0); } /* set up the tree to store server ids */ ctdb->server_ids = trbt_create(ctdb, 0); return ctdb; }
static void *array_insert_callback(void *p, void *data) { struct trbt_array_param *param = (struct trbt_array_param *)p; trbt_tree_t *tree = NULL; /* if keylen has reached 0 we are done and can call the users callback function with the users parameters */ if (param->keylen == 0) { return param->callback(param->param, data); } /* keylen is not zero yes so we must create/process more subtrees */ /* if data is NULL this means we did not yet have a subtree here and we must create one. */ if (data == NULL) { /* create a new subtree and hang it off our current tree set it to autofree so that the tree is freed when the last node in it has been released. */ tree = trbt_create(param->tree, TRBT_AUTOFREE); } else { /* we already have a subtree for this path */ tree = (trbt_tree_t *)data; } trbt_insertarray32_callback(tree, param->keylen, param->key, param->callback, param->param); /* now return either the old tree we got in *data or the new tree we created to our caller so he can update his pointer in his tree to point to our subtree */ return tree; }
/* startup daemon side of ctdb according to command line options */ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev) { struct ctdb_context *ctdb; int ret; /* initialise ctdb */ ctdb = ctdb_init(ev); if (ctdb == NULL) { printf("Failed to init ctdb\n"); exit(1); } if (ctdb_cmdline.torture) { ctdb_set_flags(ctdb, CTDB_FLAG_TORTURE); } /* command line specified a socket name */ if (ctdb_cmdline.socketname != NULL) { setenv("CTDB_SOCKET", ctdb_cmdline.socketname, 1); ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname); if (ret == -1) { printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb)); exit(1); } } /* Set the debug level */ if (!parse_debug(ctdb_cmdline.debuglevel, &DEBUGLEVEL)) { DEBUGLEVEL = DEBUG_ERR; } /* set up the tree to store server ids */ ctdb->server_ids = trbt_create(ctdb, 0); return ctdb; }
/* main program */ int main(int argc, const char *argv[]) { int traverse_count; int i,j,k; trbt_tree_t *tree; uint32_t *data; uint32_t key[3]; uint32_t key1[3] = {0,10,20}; uint32_t key2[3] = {0,10,21}; uint32_t key3[3] = {0,11,20}; uint32_t key4[3] = {2,10,20}; TALLOC_CTX *memctx; uint32_t **u32array; uint32_t checksum; /* testing trbt_insert32_callback for num_records */ memctx = talloc_new(NULL); assert(memctx != NULL); u32array = talloc_array(memctx, uint32_t *, num_records); assert(u32array != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); for (i=0; i<num_records; i++) { u32array[i] = talloc(u32array, uint32_t); assert(u32array[i] != NULL); *u32array[i] = 0; trbt_insert32_callback(tree, i, callback, u32array[i]); } for (i=3; i<num_records; i++) { trbt_insert32_callback(tree, i, callback, NULL); } /* first 3 keys should have data == 1 * the rest of the keys should have data == 2 */ for (i=0; i<num_records; i++) { data = trbt_lookup32(tree, i); if (i < 3) { assert(*data == 1); } else { assert(*data == 2); } } /* deleting key 2 */ talloc_free(u32array[2]); /* deleting key 1 */ talloc_free(u32array[1]); assert(talloc_total_size(memctx) == 212); /* freeing tree */ talloc_free(memctx); printf("testing trbt_insertarray32_callback\n"); memctx = talloc_new(NULL); assert(memctx != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); u32array = talloc_array(memctx, uint32_t *, 4); assert(u32array != NULL); for (i=0; i<4; i++) { u32array[i] = talloc(u32array, uint32_t); assert(u32array[i] != NULL); *u32array[i] = 0; } trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]); trbt_insertarray32_callback(tree, 3, key3, callback, u32array[2]); trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]); trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data != NULL && *data == 2); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key4\n"); talloc_free(trbt_lookuparray32(tree, 3, key4)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data != NULL && *data == 2); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key2\n"); talloc_free(trbt_lookuparray32(tree, 3, key2)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key3\n"); talloc_free(trbt_lookuparray32(tree, 3, key3)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key1\n"); talloc_free(trbt_lookuparray32(tree, 3, key1)); data = trbt_lookuparray32(tree, 3, key1); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); talloc_free(tree); talloc_free(memctx); printf("\nrun random insert and delete for 60 seconds\n"); memctx = talloc_new(NULL); assert(memctx != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); i=0; start_timer(); checksum = 0; /* add and delete nodes from a 3 level tree fro 60 seconds. each time a node is added or deleted, traverse the tree and compute a checksum over the data stored in the tree and compare this with a checksum we keep which contains what the checksum should be */ while(end_timer() < 60.0) { char *str; i++; key[0]=random()%10; key[1]=random()%10; key[2]=random()%10; if (random()%2) { if (trbt_lookuparray32(tree, 3, key) == NULL) { /* this node does not yet exist, add it to the tree and update the checksum */ str=talloc_asprintf(memctx, "%d.%d.%d", key[0],key[1],key[2]); trbt_insertarray32_callback(tree, 3, key, random_add, str); checksum += key[0]*100+key[1]*10+key[2]; } } else { if ((str=trbt_lookuparray32(tree, 3, key)) != NULL) { /* this node does exist in the tree, delete it and update the checksum accordingly */ talloc_free(str); checksum -= key[0]*100+key[1]*10+key[2]; } } /* traverse all nodes in the tree and calculate the checksum it better match the one we keep track of in 'checksum' */ calc_checksum = 0; trbt_traversearray32(tree, 3, traverse_checksum, NULL); assert(checksum == calc_checksum); } /* printf("\niterations passed:%d\n", i); trbt_traversearray32(tree, 3, random_traverse, NULL); printf("\n"); printf("first node: %s\n", (char *)trbt_findfirstarray32(tree, 3)); */ traverse_count = 0; trbt_traversearray32(tree, 3, count_traverse, &traverse_count); assert(traverse_count > 0); traverse_count = 0; trbt_traversearray32(tree, 3, count_traverse_abort, &traverse_count); assert(traverse_count == 1); printf("\ndeleting all entries\n"); for(i=0; i<10; i++) { for(j=0; j<10; j++) { for(k=0; k<10; k++) { key[0]=i; key[1]=j; key[2]=k; talloc_free(trbt_lookuparray32(tree, 3, key)); } } } trbt_traversearray32(tree, 3, random_traverse, NULL); assert(talloc_total_size(memctx) == 16); return 0; }