diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2011-11-08 14:01:22 +1100 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2011-11-08 14:01:22 +1100 |
commit | afd0b6327348554894f62d889dedae21b574106e (patch) | |
tree | 2fc02e39633980f129ca3128940265de7b018328 | |
parent | 47f20e8ae5120fd1aca5df622b2ecf08fb93c249 (diff) | |
parent | 0f92fa224c8c05b6cce0155dca7f0696987fd6e2 (diff) | |
download | samba-afd0b6327348554894f62d889dedae21b574106e.tar.gz samba-afd0b6327348554894f62d889dedae21b574106e.tar.xz samba-afd0b6327348554894f62d889dedae21b574106e.zip |
Merge branch 'master' of 10.1.1.27:/shared/ctdb/ctdb-master
(This used to be ctdb commit d772743e9a4d4d40eb95cd8d5178708e77057b79)
-rw-r--r-- | ctdb/common/rb_tree.c | 53 | ||||
-rw-r--r-- | ctdb/common/rb_tree.h | 9 | ||||
-rw-r--r-- | ctdb/server/ctdb_serverids.c | 12 | ||||
-rw-r--r-- | ctdb/server/ctdb_takeover.c | 8 | ||||
-rw-r--r-- | ctdb/server/ctdb_vacuum.c | 13 | ||||
-rw-r--r-- | ctdb/tests/src/rb_test.c | 39 | ||||
-rw-r--r-- | ctdb/tools/ctdb.c | 6 | ||||
-rw-r--r-- | ctdb/tools/ctdb_vacuum.c | 18 |
8 files changed, 110 insertions, 48 deletions
diff --git a/ctdb/common/rb_tree.c b/ctdb/common/rb_tree.c index b2c2ee83d5..8458c510be 100644 --- a/ctdb/common/rb_tree.c +++ b/ctdb/common/rb_tree.c @@ -916,13 +916,17 @@ trbt_lookuparray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key) /* traverse a tree starting at node */ -static void +static int trbt_traversearray32_node(trbt_node_t *node, uint32_t keylen, - void (*callback)(void *param, void *data), + int (*callback)(void *param, void *data), void *param) { if (node->left) { - trbt_traversearray32_node(node->left, keylen, callback, param); + int ret; + ret = trbt_traversearray32_node(node->left, keylen, callback, param); + if (ret != 0) { + return ret; + } } /* this is the smallest node in this subtree @@ -930,35 +934,52 @@ trbt_traversearray32_node(trbt_node_t *node, uint32_t keylen, otherwise we must pull the next subtree and traverse that one as well */ if (keylen == 0) { - callback(param, node->data); + int ret; + + ret = callback(param, node->data); + if (ret != 0) { + return ret; + } } else { - trbt_traversearray32(node->data, keylen, callback, param); + int ret; + + ret = trbt_traversearray32(node->data, keylen, callback, param); + if (ret != 0) { + return ret; + } } if (node->right) { - trbt_traversearray32_node(node->right, keylen, callback, param); + int ret; + + ret = trbt_traversearray32_node(node->right, keylen, callback, param); + if (ret != 0) { + return ret; + } } + + return 0; } /* traverse the tree using an array of uint32 as a key */ -void +int trbt_traversearray32(trbt_tree_t *tree, uint32_t keylen, - void (*callback)(void *param, void *data), + int (*callback)(void *param, void *data), void *param) { trbt_node_t *node; if (tree == NULL) { - return; + return 0; } node=tree->root; if (node == NULL) { - return; + return 0; } - trbt_traversearray32_node(node, keylen-1, callback, param); + return trbt_traversearray32_node(node, keylen-1, callback, param); } @@ -999,7 +1020,7 @@ trbt_findfirstarray32(trbt_tree_t *tree, uint32_t keylen) } -#if 0 +#if TEST_RB_TREE static void printtree(trbt_node_t *node, int levels) { int i; @@ -1007,7 +1028,7 @@ static void printtree(trbt_node_t *node, int levels) printtree(node->left, levels+1); for(i=0;i<levels;i++)printf(" "); - printf("key:%d COLOR:%s (node:0x%08x parent:0x%08x left:0x%08x right:0x%08x)\n",node->key32,node->rb_color==TRBT_BLACK?"BLACK":"RED",(int)node,(int)node->parent, (int)node->left,(int)node->right); + printf("key:%d COLOR:%s (node:%p parent:%p left:%p right:%p)\n",node->key32,node->rb_color==TRBT_BLACK?"BLACK":"RED", node, node->parent, node->left, node->right); printtree(node->right, levels+1); printf("\n"); @@ -1021,13 +1042,11 @@ void print_tree(trbt_tree_t *tree) } printf("---\n"); printtree(tree->root->left, 1); - printf("root node key:%d COLOR:%s (node:0x%08x left:0x%08x right:0x%08x)\n",tree->root->key32,tree->root->rb_color==TRBT_BLACK?"BLACK":"RED",(int)tree->root,(int)tree->root->left,(int)tree->root->right); + printf("root node key:%d COLOR:%s (node:%p left:%p right:%p)\n",tree->root->key32,tree->root->rb_color==TRBT_BLACK?"BLACK":"RED", tree->root, tree->root->left, tree->root->right); printtree(tree->root->right, 1); printf("===\n"); } -#endif -# if 0 void test_tree(void) { @@ -1037,7 +1056,7 @@ test_tree(void) int NUM=15; int cnt=0; - tree=trbt_create(talloc_new(NULL)); + tree=trbt_create(talloc_new(NULL), 0); #if 0 for(i=0;i<10;i++){ printf("adding node %i\n",i); diff --git a/ctdb/common/rb_tree.h b/ctdb/common/rb_tree.h index eef0bc5227..4f2ab22d36 100644 --- a/ctdb/common/rb_tree.h +++ b/ctdb/common/rb_tree.h @@ -74,8 +74,13 @@ void trbt_insertarray32_callback(trbt_tree_t *tree, uint32_t keylen, uint32_t *k and return a pointer to data or NULL */ void *trbt_lookuparray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key); -/* Traverse a tree with a key based on an array of uint32 */ -void trbt_traversearray32(trbt_tree_t *tree, uint32_t keylen, void (*callback)(void *param, void *data), void *param); +/* Traverse a tree with a key based on an array of uint32 + returns 0 if traverse completed + !0 if the traverse was aborted + + If the callback returns !0 the traverse will be aborted +*/ +int trbt_traversearray32(trbt_tree_t *tree, uint32_t keylen, int (*callback)(void *param, void *data), void *param); /* Lookup the first node in the tree with a key based on an array of uint32 and return a pointer to data or NULL */ diff --git a/ctdb/server/ctdb_serverids.c b/ctdb/server/ctdb_serverids.c index 4ed3012a30..dba25edced 100644 --- a/ctdb/server/ctdb_serverids.c +++ b/ctdb/server/ctdb_serverids.c @@ -119,20 +119,21 @@ struct count_server_ids { struct ctdb_server_id_list *list; }; -static void server_id_count(void *param, void *data) +static int server_id_count(void *param, void *data) { struct count_server_ids *svid = talloc_get_type(param, struct count_server_ids); if (svid == NULL) { DEBUG(DEBUG_ERR, (__location__ " Got null pointer for svid\n")); - return; + return -1; } svid->count++; + return 0; } -static void server_id_store(void *param, void *data) +static int server_id_store(void *param, void *data) { struct count_server_ids *svid = talloc_get_type(param, struct count_server_ids); @@ -141,16 +142,17 @@ static void server_id_store(void *param, void *data) if (svid == NULL) { DEBUG(DEBUG_ERR, (__location__ " Got null pointer for svid\n")); - return; + return -1; } if (svid->count >= svid->list->num) { DEBUG(DEBUG_ERR, (__location__ " size of server id tree changed during traverse\n")); - return; + return -1; } memcpy(&svid->list->server_ids[svid->count], server_id, sizeof(struct ctdb_server_id)); svid->count++; + return 0; } /* diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index a7f125041f..31946e70ec 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -1251,13 +1251,14 @@ static void *add_ip_callback(void *parm, void *data) return parm; } -void getips_count_callback(void *param, void *data) +static int getips_count_callback(void *param, void *data) { struct ctdb_public_ip_list **ip_list = (struct ctdb_public_ip_list **)param; struct ctdb_public_ip_list *new_ip = (struct ctdb_public_ip_list *)data; new_ip->next = *ip_list; *ip_list = new_ip; + return 0; } static struct ctdb_public_ip_list * @@ -2827,7 +2828,7 @@ static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde, by a RST) this callback is called for each connection we are currently trying to kill */ -static void tickle_connection_traverse(void *param, void *data) +static int tickle_connection_traverse(void *param, void *data) { struct ctdb_killtcp_con *con = talloc_get_type(data, struct ctdb_killtcp_con); @@ -2835,7 +2836,7 @@ static void tickle_connection_traverse(void *param, void *data) if (con->count >= 5) { /* can't delete in traverse: reparent to delete_cons */ talloc_steal(param, con); - return; + return 0; } /* othervise, try tickling it again */ @@ -2844,6 +2845,7 @@ static void tickle_connection_traverse(void *param, void *data) (ctdb_sock_addr *)&con->dst_addr, (ctdb_sock_addr *)&con->src_addr, 0, 0, 0); + return 0; } diff --git a/ctdb/server/ctdb_vacuum.c b/ctdb/server/ctdb_vacuum.c index 50ff45a01c..2be3e4b876 100644 --- a/ctdb/server/ctdb_vacuum.c +++ b/ctdb/server/ctdb_vacuum.c @@ -279,7 +279,7 @@ static int vacuum_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, * traverse the tree of records to delete and marshall them into * a blob */ -static void delete_traverse(void *param, void *data) +static int delete_traverse(void *param, void *data) { struct delete_record_data *dd = talloc_get_type(data, struct delete_record_data); struct delete_records_list *recs = talloc_get_type(param, struct delete_records_list); @@ -289,17 +289,18 @@ static void delete_traverse(void *param, void *data) rec = ctdb_marshall_record(dd, recs->records->db_id, dd->key, &dd->hdr, tdb_null); if (rec == NULL) { DEBUG(DEBUG_ERR, (__location__ " failed to marshall record\n")); - return; + return 0; } old_size = talloc_get_size(recs->records); recs->records = talloc_realloc_size(NULL, recs->records, old_size + rec->length); if (recs->records == NULL) { DEBUG(DEBUG_ERR,(__location__ " Failed to expand\n")); - return; + return 0; } recs->records->count++; memcpy(old_size+(uint8_t *)(recs->records), rec, rec->length); + return 0; } /** @@ -322,7 +323,7 @@ static void delete_traverse(void *param, void *data) * add it to the list of records that are to be sent to * the lmaster with the VACUUM_FETCH message. */ -static void delete_queue_traverse(void *param, void *data) +static int delete_queue_traverse(void *param, void *data) { struct delete_record_data *dd = talloc_get_type(data, struct delete_record_data); @@ -340,7 +341,7 @@ static void delete_queue_traverse(void *param, void *data) if (res != 0) { DEBUG(DEBUG_ERR, (__location__ " Error getting chainlock.\n")); vdata->fast_error++; - return; + return 0; } tdb_data = tdb_fetch(ctdb_db->ltdb->tdb, dd->key); @@ -431,7 +432,7 @@ done: } tdb_chainunlock(ctdb_db->ltdb->tdb, dd->key); - return; + return 0; } /* diff --git a/ctdb/tests/src/rb_test.c b/ctdb/tests/src/rb_test.c index 707f7d71de..5de6c10356 100644 --- a/ctdb/tests/src/rb_test.c +++ b/ctdb/tests/src/rb_test.c @@ -62,27 +62,44 @@ void *random_add(void *p, void *d) return p; } -void traverse(void *p, void *d) +int traverse(void *p, void *d) { uint32_t *data = (uint32_t *)d; printf("traverse data:%d\n",*data); + return 0; } -void random_traverse(void *p, void *d) +int random_traverse(void *p, void *d) { printf("%s ",(char *)d); + return 0; } static uint32_t calc_checksum = 0; -void traverse_checksum(void *p, void *d) +int traverse_checksum(void *p, void *d) { int i,j,k; sscanf(d, "%d.%d.%d", &i, &j, &k); calc_checksum += i*100+j*10+k; + return 0; +} + +int count_traverse(void *p, void *d) +{ + int *count = p; + (*count)++; + return 0; } - + +int count_traverse_abort(void *p, void *d) +{ + int *count = p; + (*count)++; + return -1; +} + /* main program */ @@ -94,7 +111,7 @@ int main(int argc, const char *argv[]) { "num-records", 'r', POPT_ARG_INT, &num_records, 0, "num_records", "integer" }, POPT_TABLEEND }; - int opt; + int opt, traverse_count; const char **extra_argv; int extra_argc = 0; poptContext pc; @@ -303,7 +320,19 @@ int main(int argc, const char *argv[]) printf("\n"); printf("first node: %s\n", (char *)trbt_findfirstarray32(tree, 3)); + traverse_count = 0; + trbt_traversearray32(tree, 3, count_traverse, &traverse_count); + printf("\n"); + printf("number of entries in traverse %d\n", traverse_count); + traverse_count = 0; + trbt_traversearray32(tree, 3, count_traverse_abort, &traverse_count); + printf("\n"); + printf("number of entries in aborted traverse %d\n", traverse_count); + if (traverse_count != 1) { + printf("Failed to abort the traverse. Should have been aborted after 1 element but did iterate over %d elements\n", traverse_count); + exit(10); + } printf("\ndeleting all entries\n"); for(i=0;i<10;i++){ for(j=0;j<10;j++){ diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 876521a3d4..5b5dd9c3de 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -1365,7 +1365,7 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv return 0; } -void getips_store_callback(void *param, void *data) +static int getips_store_callback(void *param, void *data) { struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data; struct ctdb_all_public_ips *ips = param; @@ -1374,13 +1374,15 @@ void getips_store_callback(void *param, void *data) i = ips->num++; ips->ips[i].pnn = node_ip->pnn; ips->ips[i].addr = node_ip->addr; + return 0; } -void getips_count_callback(void *param, void *data) +static int getips_count_callback(void *param, void *data) { uint32_t *count = param; (*count)++; + return 0; } #define IP_KEYLEN 4 diff --git a/ctdb/tools/ctdb_vacuum.c b/ctdb/tools/ctdb_vacuum.c index a9dc28a9a6..419e660a7f 100644 --- a/ctdb/tools/ctdb_vacuum.c +++ b/ctdb/tools/ctdb_vacuum.c @@ -160,7 +160,7 @@ struct delete_records_list { traverse the tree of records to delete and marshall them into a blob */ -static void +static int delete_traverse(void *param, void *data) { struct delete_record_data *dd = talloc_get_type(data, struct delete_record_data); @@ -171,21 +171,22 @@ delete_traverse(void *param, void *data) rec = ctdb_marshall_record(dd, recs->records->db_id, dd->key, &dd->hdr, tdb_null); if (rec == NULL) { DEBUG(DEBUG_ERR, (__location__ " failed to marshall record\n")); - return; + return 0; } old_size = talloc_get_size(recs->records); recs->records = talloc_realloc_size(NULL, recs->records, old_size + rec->length); if (recs->records == NULL) { DEBUG(DEBUG_ERR,(__location__ " Failed to expand\n")); - return; + return 0; } recs->records->count++; memcpy(old_size+(uint8_t *)(recs->records), rec, rec->length); + return 0; } -static void delete_record(void *param, void *d) +static int delete_record(void *param, void *d) { struct delete_record_data *dd = talloc_get_type(d, struct delete_record_data); struct ctdb_context *ctdb = dd->ctdb; @@ -197,18 +198,18 @@ static void delete_record(void *param, void *d) /* its deleted on all other nodes - refetch, check and delete */ if (tdb_chainlock_nonblock(ctdb_db->ltdb->tdb, dd->key) != 0) { /* the chain is busy - come back later */ - return; + return 0; } data = tdb_fetch(ctdb_db->ltdb->tdb, dd->key); if (data.dptr == NULL) { tdb_chainunlock(ctdb_db->ltdb->tdb, dd->key); - return; + return 0; } if (data.dsize != sizeof(struct ctdb_ltdb_header)) { free(data.dptr); tdb_chainunlock(ctdb_db->ltdb->tdb, dd->key); - return; + return 0; } hdr = (struct ctdb_ltdb_header *)data.dptr; @@ -219,7 +220,7 @@ static void delete_record(void *param, void *d) dd->hdr.rsn != hdr->rsn) { tdb_chainunlock(ctdb_db->ltdb->tdb, dd->key); free(data.dptr); - return; + return 0; } ctdb_block_signal(SIGALRM); @@ -229,6 +230,7 @@ static void delete_record(void *param, void *d) free(data.dptr); (*count)++; + return 0; } /* vacuum one database */ |