mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
add a control to read an entire tdb from a node including
key/lmaster/header and data (This used to be ctdb commit ac00d6271ba6356c1edf804df44d0d2600791610)
This commit is contained in:
parent
d81b306b93
commit
097037a055
@ -896,6 +896,68 @@ int ctdb_setvnnmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_vnn
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
get all keys for a specific database
|
||||
*/
|
||||
int ctdb_getkeys(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, struct ctdb_key_list *keys)
|
||||
{
|
||||
int i, ret;
|
||||
TDB_DATA indata, outdata;
|
||||
int32_t res;
|
||||
unsigned char *ptr;
|
||||
|
||||
indata.dsize = sizeof(uint32_t);
|
||||
indata.dptr = (unsigned char *)&dbid;
|
||||
|
||||
ret = ctdb_control(ctdb, destnode, 0,
|
||||
CTDB_CONTROL_GET_KEYS, indata,
|
||||
mem_ctx, &outdata, &res);
|
||||
if (ret != 0 || res != 0) {
|
||||
DEBUG(0,(__location__ " ctdb_control for getkeys failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
keys->num= *((uint32_t *)(&outdata.dptr[0]));
|
||||
keys->keys=talloc_array(mem_ctx, TDB_DATA, keys->num);
|
||||
keys->headers=talloc_array(mem_ctx, struct ctdb_ltdb_header, keys->num);
|
||||
keys->lmasters=talloc_array(mem_ctx, uint32_t, keys->num);
|
||||
keys->data=talloc_array(mem_ctx, TDB_DATA, keys->num);
|
||||
|
||||
/* loop over all key/data pairs */
|
||||
ptr=&outdata.dptr[4];
|
||||
for(i=0;i<keys->num;i++){
|
||||
uint32_t len;
|
||||
TDB_DATA *key, *data;
|
||||
|
||||
keys->lmasters[i]= *((uint32_t *)ptr);
|
||||
ptr+=4;
|
||||
|
||||
key=&keys->keys[i];
|
||||
key->dsize= *((uint32_t *)ptr);
|
||||
ptr+=4;
|
||||
key->dptr=talloc_size(mem_ctx, key->dsize);
|
||||
memcpy(key->dptr, ptr, key->dsize);
|
||||
len = (key->dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
ptr+=len;
|
||||
|
||||
memcpy(&keys->headers[i], ptr, sizeof(struct ctdb_ltdb_header));
|
||||
len = (sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
ptr+=len;
|
||||
|
||||
data=&keys->data[i];
|
||||
data->dsize= *((uint32_t *)ptr);
|
||||
ptr+=4;
|
||||
data->dptr=talloc_size(mem_ctx, data->dsize);
|
||||
memcpy(data->dptr, ptr, data->dsize);
|
||||
len = (data->dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
ptr+=len;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
ping a node
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "system/wait.h"
|
||||
#include "../include/ctdb_private.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "db_wrap.h"
|
||||
|
||||
struct ctdb_control_state {
|
||||
struct ctdb_context *ctdb;
|
||||
@ -41,6 +42,56 @@ struct ctdb_control_state {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
struct getkeys_params {
|
||||
struct ctdb_db_context *ctdb_db;
|
||||
TDB_DATA *outdata;
|
||||
};
|
||||
|
||||
static int traverse_getkeys(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
|
||||
{
|
||||
struct getkeys_params *params = (struct getkeys_params *)p;
|
||||
TDB_DATA *outdata = talloc_get_type(params->outdata, TDB_DATA);
|
||||
struct ctdb_db_context *ctdb_db = talloc_get_type(params->ctdb_db, struct ctdb_db_context);
|
||||
unsigned char *ptr;
|
||||
int len, ret;
|
||||
|
||||
len=outdata->dsize;
|
||||
len+=4; /*lmaster*/
|
||||
len+=4; /*key len*/
|
||||
len+=key.dsize;
|
||||
len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
len+=sizeof(struct ctdb_ltdb_header);
|
||||
len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
len+=4; /*data len */
|
||||
len+=data.dsize;
|
||||
len=(len+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
|
||||
ptr=outdata->dptr=talloc_realloc_size(outdata, outdata->dptr, len);
|
||||
ptr+=outdata->dsize;
|
||||
outdata->dsize=len;
|
||||
/* number of records is stored as the first 4 bytes */
|
||||
(*((uint32_t *)(&outdata->dptr[0])))++;
|
||||
|
||||
*((uint32_t *)ptr)=ctdb_lmaster(ctdb_db->ctdb, &key);
|
||||
ptr+=4;
|
||||
|
||||
*((uint32_t *)ptr)=key.dsize;
|
||||
ptr+=4;
|
||||
memcpy(ptr, key.dptr, key.dsize);
|
||||
ptr+= (key.dsize+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
|
||||
memcpy(ptr, data.dptr, sizeof(struct ctdb_ltdb_header));
|
||||
ptr+=(sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
|
||||
*((uint32_t *)ptr)=data.dsize-sizeof(struct ctdb_ltdb_header);
|
||||
ptr+=4;
|
||||
memcpy(ptr, data.dptr+sizeof(struct ctdb_ltdb_header), data.dsize-sizeof(struct ctdb_ltdb_header));
|
||||
ptr+= (data.dsize-sizeof(struct ctdb_ltdb_header)+CTDB_DS_ALIGNMENT-1)& ~(CTDB_DS_ALIGNMENT-1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
process a control request
|
||||
*/
|
||||
@ -167,6 +218,38 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CTDB_CONTROL_GET_KEYS: {
|
||||
uint32_t dbid;
|
||||
struct ctdb_db_context *ctdb_db;
|
||||
struct tdb_wrap *db;
|
||||
struct getkeys_params params;
|
||||
|
||||
dbid = *((uint32_t *)(&indata.dptr[0]));
|
||||
ctdb_db = find_ctdb_db(ctdb, dbid);
|
||||
if (!ctdb_db) {
|
||||
DEBUG(0,(__location__ " Unknown db\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
outdata->dsize = sizeof(uint32_t);
|
||||
outdata->dptr = (unsigned char *)talloc_array(outdata, uint32_t, 1);
|
||||
*((uint32_t *)(&outdata->dptr[0]))=0;
|
||||
|
||||
db = tdb_wrap_open(NULL, ctdb_db->db_path, 0, TDB_DEFAULT, O_RDONLY, 0);
|
||||
if (db == NULL) {
|
||||
DEBUG(0,(__location__ " failed to open db\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
params.ctdb_db = ctdb_db;
|
||||
params.outdata = outdata;
|
||||
tdb_traverse(db->tdb, traverse_getkeys, ¶ms);
|
||||
|
||||
talloc_free(db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case CTDB_CONTROL_CONFIG: {
|
||||
CHECK_CONTROL_DATA_SIZE(0);
|
||||
outdata->dptr = (uint8_t *)ctdb;
|
||||
|
@ -241,6 +241,15 @@ struct ctdb_node_map {
|
||||
};
|
||||
int ctdb_getnodemap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_node_map *nodemap);
|
||||
|
||||
struct ctdb_key_list {
|
||||
uint32_t num;
|
||||
TDB_DATA *keys;
|
||||
struct ctdb_ltdb_header *headers;
|
||||
uint32_t *lmasters;
|
||||
TDB_DATA *data;
|
||||
};
|
||||
int ctdb_getkeys(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, struct ctdb_key_list *keys);
|
||||
|
||||
int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t dbid, TALLOC_CTX *mem_ctx, const char **path);
|
||||
|
||||
int ctdb_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid);
|
||||
|
@ -254,7 +254,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS,
|
||||
CTDB_CONTROL_GET_DEBUG,
|
||||
CTDB_CONTROL_SET_DEBUG,
|
||||
CTDB_CONTROL_GET_DBMAP,
|
||||
CTDB_CONTROL_GET_NODEMAP};
|
||||
CTDB_CONTROL_GET_NODEMAP,
|
||||
CTDB_CONTROL_GET_KEYS};
|
||||
|
||||
enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
|
||||
|
||||
|
@ -247,6 +247,10 @@ int main(int argc, const char *argv[])
|
||||
|
||||
printf("DATA:\n%s\n", (char *)call.reply_data.dptr);
|
||||
|
||||
#if 1
|
||||
/* to keep the cluster up so one can play with it using the controls */
|
||||
sleep(9999999);
|
||||
#endif
|
||||
/* go into a wait loop to allow other nodes to complete */
|
||||
ctdb_shutdown(ctdb);
|
||||
|
||||
|
@ -42,6 +42,7 @@ static void usage(void)
|
||||
printf(" setvnnmap <vnn> <generation> <numslots> <lmaster>*\n");
|
||||
printf(" getdbmap <vnn> lists databases on a node\n");
|
||||
printf(" getnodemap <vnn> lists nodes known to a ctdb daemon\n");
|
||||
printf(" getkeys <vnn> <dbid> lists all keys in a remote tdb\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -156,6 +157,47 @@ static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **a
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
display remote list of keys for a tdb
|
||||
*/
|
||||
static int control_getkeys(struct ctdb_context *ctdb, int argc, const char **argv)
|
||||
{
|
||||
uint32_t vnn, dbid;
|
||||
int i, j, ret;
|
||||
struct ctdb_key_list keys;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
}
|
||||
|
||||
vnn = strtoul(argv[0], NULL, 0);
|
||||
dbid = strtoul(argv[1], NULL, 0);
|
||||
|
||||
mem_ctx = talloc_new(ctdb);
|
||||
ret = ctdb_getkeys(ctdb, vnn, dbid, mem_ctx, &keys);
|
||||
if (ret != 0) {
|
||||
printf("Unable to get keys from node %u\n", vnn);
|
||||
return ret;
|
||||
}
|
||||
printf("Number of keys:%d\n",keys.num);
|
||||
for(i=0;i<keys.num;i++){
|
||||
printf("key:");
|
||||
for(j=0;j<keys.keys[i].dsize;j++){
|
||||
printf("%02x",keys.keys[i].dptr[j]);
|
||||
}
|
||||
printf(" lmaster:%d rsn:%llu dmaster:%d laccessor:%d lacount:%d",keys.lmasters[i],keys.headers[i].rsn,keys.headers[i].dmaster,keys.headers[i].laccessor,keys.headers[i].lacount);
|
||||
printf(" data:");
|
||||
for(j=0;j<keys.data[i].dsize;j++){
|
||||
printf("%02x",keys.data[i].dptr[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
display a list of the databases on a remote ctdb
|
||||
*/
|
||||
@ -378,6 +420,8 @@ int main(int argc, const char *argv[])
|
||||
ret = control_getdbmap(ctdb, extra_argc-1, extra_argv+1);
|
||||
} else if (strcmp(control, "getnodemap") == 0) {
|
||||
ret = control_getnodemap(ctdb, extra_argc-1, extra_argv+1);
|
||||
} else if (strcmp(control, "getkeys") == 0) {
|
||||
ret = control_getkeys(ctdb, extra_argc-1, extra_argv+1);
|
||||
} else if (strcmp(control, "setvnnmap") == 0) {
|
||||
ret = control_setvnnmap(ctdb, extra_argc-1, extra_argv+1);
|
||||
} else if (strcmp(control, "ping") == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user