return 0;
}
+/*
+ get vnn map from a remote node
+ */
+int ctdb_getvnnmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_vnn_map *vnnmap)
+{
+ int ret;
+ TDB_DATA data, outdata;
+ int32_t i, res;
+
+ ZERO_STRUCT(data);
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_GETVNNMAP, data,
+ ctdb, &outdata, &res);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for getvnnmap failed\n"));
+ return -1;
+ }
+
+ vnnmap->generation = ((uint32_t *)outdata.dptr)[0];
+ vnnmap->size = ((uint32_t *)outdata.dptr)[1];
+ if (vnnmap->map) {
+ talloc_free(vnnmap->map);
+ vnnmap->map = NULL;
+ }
+ vnnmap->map = talloc_array(vnnmap, uint32_t, vnnmap->size);
+ for (i=0;i<vnnmap->size;i++) {
+ vnnmap->map[i] = ((uint32_t *)outdata.dptr)[i+2];
+ }
+
+ return 0;
+}
+
/*
ping a node
*/
return 0;
}
+ case CTDB_CONTROL_GETVNNMAP: {
+ uint32_t i, len;
+
+ len = 2+ctdb->vnn_map->size;
+ outdata->dsize = 4*len;
+ outdata->dptr = (unsigned char *)talloc_array(outdata, uint32_t, len);
+
+ ((uint32_t *)outdata->dptr)[0] = ctdb->vnn_map->generation;
+ ((uint32_t *)outdata->dptr)[1] = ctdb->vnn_map->size;
+ for (i=0;i<ctdb->vnn_map->size;i++) {
+ ((uint32_t *)outdata->dptr)[i+2] = ctdb->vnn_map->map[i];
+ }
+
+ return 0;
+ }
+
case CTDB_CONTROL_CONFIG: {
outdata->dptr = (uint8_t *)ctdb;
outdata->dsize = sizeof(*ctdb);
void ctdb_request_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
{
struct ctdb_req_control *c = (struct ctdb_req_control *)hdr;
- TDB_DATA data, outdata;
+ TDB_DATA data, *outdata;
struct ctdb_reply_control *r;
int32_t status;
size_t len;
data.dptr = &c->data[0];
data.dsize = c->datalen;
- ZERO_STRUCT(outdata);
- status = ctdb_control_dispatch(ctdb, c->opcode, data, &outdata);
+ outdata = talloc_zero(c, TDB_DATA);
+ status = ctdb_control_dispatch(ctdb, c->opcode, data, outdata);
- len = offsetof(struct ctdb_reply_control, data) + outdata.dsize;
+ len = offsetof(struct ctdb_reply_control, data) + outdata->dsize;
r = ctdb->methods->allocate_pkt(ctdb, len);
CTDB_NO_MEMORY_VOID(ctdb, r);
talloc_set_name_const(r, "ctdb_reply_control packet");
r->hdr.srcnode = ctdb->vnn;
r->hdr.reqid = hdr->reqid;
r->status = status;
- r->datalen = outdata.dsize;
- if (outdata.dsize) {
- memcpy(&r->data[0], outdata.dptr, outdata.dsize);
+ r->datalen = outdata->dsize;
+ if (outdata->dsize) {
+ memcpy(&r->data[0], outdata->dptr, outdata->dsize);
}
ctdb_queue_packet(ctdb, &r->hdr);
struct ctdb_status;
int ctdb_status(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_status *status);
+struct ctdb_vnn_map;
+int ctdb_getvnnmap(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_vnn_map *vnnmap);
+
int ctdb_getdbpath(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, const char **path);
int ctdb_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid);
CTDB_CONTROL_STATUS,
CTDB_CONTROL_CONFIG,
CTDB_CONTROL_PING,
- CTDB_CONTROL_GETDBPATH};
+ CTDB_CONTROL_GETDBPATH,
+ CTDB_CONTROL_GETVNNMAP};
enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
printf(" ping\n");
printf(" process-exists <vnn:pid>\n");
printf(" status <vnn>\n");
+ printf(" getvnnmap <vnn>\n");
exit(1);
}
return 0;
}
+static int control_getvnnmap(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ uint32_t vnn;
+ int i, ret;
+ struct ctdb_vnn_map *vnnmap;
+ if (argc < 1) {
+ usage();
+ }
+
+ vnn = strtoul(argv[0], NULL, 0);
+
+ vnnmap = talloc_zero(ctdb, struct ctdb_vnn_map);
+ ret = ctdb_getvnnmap(ctdb, vnn, vnnmap);
+ if (ret != 0) {
+ printf("Unable to get vnnmap from node %u\n", vnn);
+ return ret;
+ }
+ printf("Generation:%d\n",vnnmap->generation);
+ printf("Size:%d\n",vnnmap->size);
+ for(i=0;i<vnnmap->size;i++){
+ printf("hash:%d lmaster:%d\n",i,vnnmap->map[i]);
+ }
+ return 0;
+}
static int control_ping(struct ctdb_context *ctdb, int argc, const char **argv)
{
ret = control_process_exists(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "status") == 0) {
ret = control_status(ctdb, extra_argc-1, extra_argv+1);
+ } else if (strcmp(control, "getvnnmap") == 0) {
+ ret = control_getvnnmap(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "ping") == 0) {
ret = control_ping(ctdb, extra_argc-1, extra_argv+1);
} else {