2 Test stubs and support functions for some CTDB client functions
4 Copyright (C) Martin Schwenke 2011
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* Read a nodemap from stdin. Each line looks like:
21 * <PNN> <FLAGS> [RECMASTER] [CURRENT]
22 * EOF or a blank line terminates input.
24 void ctdb_test_stubs_read_nodemap(struct ctdb_context
*ctdb
)
28 TALLOC_FREE(ctdb
->nodes
);
34 while ((fgets(line
, sizeof(line
), stdin
) != NULL
) &&
41 /* Get rid of pesky newline */
42 if ((t
= strchr(line
, '\n')) != NULL
) {
47 tok
= strtok(line
, " \t");
49 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line (PNN) ignored \"%s\"\n", line
));
52 pnn
= (uint32_t)strtoul(tok
, NULL
, 0);
55 tok
= strtok(NULL
, " \t");
57 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line (no IP) ignored \"%s\"\n", line
));
60 if (!parse_ip(tok
, NULL
, 0, &saddr
)) {
61 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line (IP) ignored \"%s\"\n", line
));
64 ip
= talloc_strdup(ctdb
, tok
);
67 tok
= strtok(NULL
, " \t");
69 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line (flags) ignored \"%s\"\n", line
));
72 flags
= (uint32_t)strtoul(tok
, NULL
, 0);
74 tok
= strtok(NULL
, " \t");
76 if (strcmp(tok
, "CURRENT") == 0) {
78 } else if (strcmp(tok
, "RECMASTER") == 0) {
79 ctdb
->recovery_master
= pnn
;
81 tok
= strtok(NULL
, " \t");
84 ctdb
->nodes
= talloc_realloc(ctdb
, ctdb
->nodes
, struct ctdb_node
*, ctdb
->num_nodes
+ 1);
85 if (ctdb
->nodes
== NULL
) {
86 DEBUG(DEBUG_ERR
, ("OOM allocating nodes array\n"));
89 ctdb
->nodes
[ctdb
->num_nodes
] = talloc_zero(ctdb
, struct ctdb_node
);
90 if (ctdb
->nodes
[ctdb
->num_nodes
] == NULL
) {
91 DEBUG(DEBUG_ERR
, ("OOM allocating node structure\n"));
95 ctdb
->nodes
[ctdb
->num_nodes
]->ctdb
= ctdb
;
96 ctdb
->nodes
[ctdb
->num_nodes
]->name
= "fakectdb";
97 ctdb
->nodes
[ctdb
->num_nodes
]->pnn
= pnn
;
98 ctdb
->nodes
[ctdb
->num_nodes
]->address
.address
= ip
;
99 ctdb
->nodes
[ctdb
->num_nodes
]->address
.port
= 0;
100 ctdb
->nodes
[ctdb
->num_nodes
]->flags
= flags
;
105 void ctdb_test_stubs_print_nodemap(struct ctdb_context
*ctdb
)
109 for (i
= 0; i
< ctdb
->num_nodes
; i
++) {
110 printf("%ld\t0x%lx%s%s\n",
111 (unsigned long) ctdb
->nodes
[i
]->pnn
,
112 (unsigned long) ctdb
->nodes
[i
]->flags
,
113 ctdb
->nodes
[i
]->pnn
== ctdb
->pnn
? "\tCURRENT" : "",
114 ctdb
->nodes
[i
]->pnn
== ctdb
->recovery_master
? "\tRECMASTER" : "");
118 /* Read interfaces information. Same format as "ctdb ifaces -Y"
120 * :Name:LinkStatus:References:
126 struct ctdb_iface
*prev
, *next
;
132 void ctdb_test_stubs_read_ifaces(struct ctdb_context
*ctdb
)
135 struct ctdb_iface
*iface
;
137 while ((fgets(line
, sizeof(line
), stdin
) != NULL
) &&
141 char *tok
, *t
, *name
;
143 /* Get rid of pesky newline */
144 if ((t
= strchr(line
, '\n')) != NULL
) {
148 if (strcmp(line
, ":Name:LinkStatus:References:") == 0) {
153 //tok = strtok(line, ":"); /* Leading colon... */
154 tok
= strtok(line
, ":");
156 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line ignored \"%s\"\n", line
));
162 tok
= strtok(NULL
, ":");
164 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line ignored \"%s\"\n", line
));
167 link_state
= (uint16_t)strtoul(tok
, NULL
, 0);
170 tok
= strtok(NULL
, ":");
172 DEBUG(DEBUG_ERR
, (__location__
" WARNING, bad line ignored \"%s\"\n", line
));
175 references
= (uint32_t)strtoul(tok
, NULL
, 0);
177 iface
= talloc_zero(ctdb
, struct ctdb_iface
);
180 DEBUG(DEBUG_ERR
, ("OOM allocating iface\n"));
184 iface
->name
= talloc_strdup(iface
, name
);
185 iface
->link_up
= link_state
;
186 iface
->references
= references
;
188 DLIST_ADD(ctdb
->ifaces
, iface
);
192 void ctdb_test_stubs_print_ifaces(struct ctdb_context
*ctdb
)
194 struct ctdb_iface
*iface
;
196 printf(":Name:LinkStatus:References:\n");
197 for (iface
= ctdb
->ifaces
; iface
!= NULL
; iface
= iface
->next
) {
198 printf(":%s:%u:%u:\n",
214 struct ctdb_vnn_map {
220 void ctdb_test_stubs_read_vnnmap(struct ctdb_context
*ctdb
)
224 TALLOC_FREE(ctdb
->vnn_map
);
226 ctdb
->vnn_map
= talloc_zero(ctdb
, struct ctdb_vnn_map
);
227 if (ctdb
->vnn_map
== NULL
) {
228 DEBUG(DEBUG_ERR
, ("OOM allocating vnnmap\n"));
231 ctdb
->vnn_map
->generation
= INVALID_GENERATION
;
232 ctdb
->vnn_map
->size
= 0;
233 ctdb
->vnn_map
->map
= NULL
;
235 while ((fgets(line
, sizeof(line
), stdin
) != NULL
) &&
240 /* Get rid of pesky newline */
241 if ((t
= strchr(line
, '\n')) != NULL
) {
245 n
= (uint32_t) strtol(line
, NULL
, 0);
248 if (ctdb
->vnn_map
->generation
== INVALID_GENERATION
) {
249 ctdb
->vnn_map
->generation
= n
;
253 ctdb
->vnn_map
->map
= talloc_realloc(ctdb
, ctdb
->vnn_map
->map
, uint32_t, ctdb
->vnn_map
->size
+ 1);
254 if (ctdb
->vnn_map
->map
== NULL
) {
255 DEBUG(DEBUG_ERR
, ("OOM allocating vnn_map->map\n"));
259 ctdb
->vnn_map
->map
[ctdb
->vnn_map
->size
] = n
;
260 ctdb
->vnn_map
->size
++;
264 void ctdb_test_stubs_print_vnnmap(struct ctdb_context
*ctdb
)
268 printf("%d\n", ctdb
->vnn_map
->generation
);
269 for (i
= 0; i
< ctdb
->vnn_map
->size
; i
++) {
270 printf("%d\n", ctdb
->vnn_map
->map
[i
]);
274 void ctdb_test_stubs_fake_setup(struct ctdb_context
*ctdb
)
278 while (fgets(line
, sizeof(line
), stdin
) != NULL
) {
281 /* Get rid of pesky newline */
282 if ((t
= strchr(line
, '\n')) != NULL
) {
286 if (strcmp(line
, "NODEMAP") == 0) {
287 ctdb_test_stubs_read_nodemap(ctdb
);
288 } else if (strcmp(line
, "IFACES") == 0) {
289 ctdb_test_stubs_read_ifaces(ctdb
);
290 } else if (strcmp(line
, "VNNMAP") == 0) {
291 ctdb_test_stubs_read_vnnmap(ctdb
);
293 printf("Unknown line %s\n", line
);
300 static bool current_node_is_connected (struct ctdb_context
*ctdb
)
303 for (i
= 0; i
< ctdb
->num_nodes
; i
++) {
304 if (ctdb
->nodes
[i
]->pnn
== ctdb
->pnn
) {
305 if (ctdb
->nodes
[i
]->flags
&
306 (NODE_FLAGS_DISCONNECTED
| NODE_FLAGS_DELETED
)) {
314 /* Shouldn't really happen, so fag an error */
320 struct ctdb_context
*ctdb_cmdline_client_stub(struct tevent_context
*ev
,
321 struct timeval req_timeout
)
323 struct ctdb_context
*ctdb
;
325 ctdb
= talloc_zero(NULL
, struct ctdb_context
);
327 ctdb_set_socketname(ctdb
, "fake");
329 ctdb_test_stubs_fake_setup(ctdb
);
334 /* Copied from ctdb_recover.c */
336 ctdb_control_getnodemap(struct ctdb_context
*ctdb
, uint32_t opcode
, TDB_DATA indata
, TDB_DATA
*outdata
)
338 uint32_t i
, num_nodes
;
339 struct ctdb_node_map
*node_map
;
341 CHECK_CONTROL_DATA_SIZE(0);
343 num_nodes
= ctdb
->num_nodes
;
345 outdata
->dsize
= offsetof(struct ctdb_node_map
, nodes
) + num_nodes
*sizeof(struct ctdb_node_and_flags
);
346 outdata
->dptr
= (unsigned char *)talloc_zero_size(outdata
, outdata
->dsize
);
347 if (!outdata
->dptr
) {
348 DEBUG(DEBUG_ALERT
, (__location__
" Failed to allocate nodemap array\n"));
352 node_map
= (struct ctdb_node_map
*)outdata
->dptr
;
353 node_map
->num
= num_nodes
;
354 for (i
=0; i
<num_nodes
; i
++) {
355 if (parse_ip(ctdb
->nodes
[i
]->address
.address
,
356 NULL
, /* TODO: pass in the correct interface here*/
358 &node_map
->nodes
[i
].addr
) == 0)
360 DEBUG(DEBUG_ERR
, (__location__
" Failed to parse %s into a sockaddr\n", ctdb
->nodes
[i
]->address
.address
));
363 node_map
->nodes
[i
].pnn
= ctdb
->nodes
[i
]->pnn
;
364 node_map
->nodes
[i
].flags
= ctdb
->nodes
[i
]->flags
;
371 ctdb_ctrl_getnodemap_stub(struct ctdb_context
*ctdb
,
372 struct timeval timeout
, uint32_t destnode
,
374 struct ctdb_node_map
**nodemap
)
381 if (!current_node_is_connected(ctdb
)) {
388 outdata
= talloc_zero(ctdb
, TDB_DATA
);
390 ret
= ctdb_control_getnodemap(ctdb
, CTDB_CONTROL_GET_NODEMAP
,
394 *nodemap
= (struct ctdb_node_map
*) outdata
->dptr
;
401 ctdb_ctrl_getvnnmap_stub(struct ctdb_context
*ctdb
,
402 struct timeval timeout
, uint32_t destnode
,
403 TALLOC_CTX
*mem_ctx
, struct ctdb_vnn_map
**vnnmap
)
405 *vnnmap
= talloc(ctdb
, struct ctdb_vnn_map
);
406 if (*vnnmap
== NULL
) {
407 DEBUG(DEBUG_ERR
, (__location__
"OOM\n"));
410 (*vnnmap
)->map
= talloc_array(*vnnmap
, uint32_t, ctdb
->vnn_map
->size
);
412 (*vnnmap
)->generation
= ctdb
->vnn_map
->generation
;
413 (*vnnmap
)->size
= ctdb
->vnn_map
->size
;
414 memcpy((*vnnmap
)->map
, ctdb
->vnn_map
->map
, sizeof(uint32_t) * (*vnnmap
)->size
);
420 ctdb_ctrl_getrecmode_stub(struct ctdb_context
*ctdb
, TALLOC_CTX
*mem_ctx
,
421 struct timeval timeout
, uint32_t destnode
,
424 *recmode
= ctdb
->recovery_mode
;
430 ctdb_ctrl_getrecmaster_stub(struct ctdb_context
*ctdb
, TALLOC_CTX
*mem_ctx
,
431 struct timeval timeout
, uint32_t destnode
,
434 *recmaster
= ctdb
->recovery_master
;
440 ctdb_ctrl_getpnn_stub(struct ctdb_context
*ctdb
, struct timeval timeout
,
443 if (!current_node_is_connected(ctdb
)) {
447 if (destnode
== CTDB_CURRENT_NODE
) {
454 /* From ctdb_takeover.c */
455 int32_t ctdb_control_get_ifaces(struct ctdb_context
*ctdb
,
456 struct ctdb_req_control
*c
,
460 struct ctdb_control_get_ifaces
*ifaces
;
461 struct ctdb_iface
*cur
;
463 /* count how many public ip structures we have */
465 for (cur
=ctdb
->ifaces
;cur
;cur
=cur
->next
) {
469 len
= offsetof(struct ctdb_control_get_ifaces
, ifaces
) +
470 num
*sizeof(struct ctdb_control_iface_info
);
471 ifaces
= talloc_zero_size(outdata
, len
);
472 CTDB_NO_MEMORY(ctdb
, ifaces
);
475 for (cur
=ctdb
->ifaces
;cur
;cur
=cur
->next
) {
476 strcpy(ifaces
->ifaces
[i
].name
, cur
->name
);
477 ifaces
->ifaces
[i
].link_state
= cur
->link_up
;
478 ifaces
->ifaces
[i
].references
= cur
->references
;
482 len
= offsetof(struct ctdb_control_get_ifaces
, ifaces
) +
483 i
*sizeof(struct ctdb_control_iface_info
);
485 outdata
->dsize
= len
;
486 outdata
->dptr
= (uint8_t *)ifaces
;
492 ctdb_ctrl_get_ifaces_stub(struct ctdb_context
*ctdb
,
493 struct timeval timeout
, uint32_t destnode
,
495 struct ctdb_control_get_ifaces
**ifaces
)
500 if (!current_node_is_connected(ctdb
)) {
504 outdata
= talloc(mem_ctx
, TDB_DATA
);
506 ret
= ctdb_control_get_ifaces(ctdb
, NULL
, outdata
);
509 *ifaces
= (struct ctdb_control_get_ifaces
*)outdata
->dptr
;
515 int ctdb_client_check_message_handlers_stub(struct ctdb_context
*ctdb
,
516 uint64_t *ids
, uint32_t num
,
519 DEBUG(DEBUG_ERR
, (__location__
" NOT IMPLEMENTED\n"));
523 int ctdb_ctrl_getcapabilities_stub(struct ctdb_context
*ctdb
,
524 struct timeval timeout
, uint32_t destnode
,
525 uint32_t *capabilities
)
527 *capabilities
= CTDB_CAP_RECMASTER
|CTDB_CAP_LMASTER
|CTDB_CAP_NATGW
;