/*
Tests for ctdb_takeover.c
Copyright (C) Martin Schwenke 2011
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see .
*/
#include "replace.h"
#include "system/network.h"
#include
#include
#include "lib/util/debug.h"
#include "protocol/protocol.h"
#include "protocol/protocol_util.h"
#include "common/logging.h"
#include "common/system.h"
#include "server/ipalloc.h"
#include "ipalloc_read_known_ips.h"
static void print_ctdb_public_ip_list(TALLOC_CTX *mem_ctx,
struct public_ip_list * ips)
{
while (ips) {
printf("%s %d\n",
ctdb_sock_addr_to_string(mem_ctx, &(ips->addr), false),
ips->pnn);
ips = ips->next;
}
}
static uint32_t *get_tunable_values(TALLOC_CTX *tmp_ctx,
int numnodes,
const char *tunable);
static enum ctdb_runstate *get_runstate(TALLOC_CTX *tmp_ctx,
int numnodes);
static void read_ctdb_public_ip_info(TALLOC_CTX *ctx,
int numnodes,
bool multi,
struct ctdb_public_ip_list ** known,
struct ctdb_public_ip_list ** avail)
{
int n;
enum ctdb_runstate *runstate;
*known = ipalloc_read_known_ips(ctx, numnodes, multi);
assert(*known != NULL);
*avail = talloc_zero_array(ctx, struct ctdb_public_ip_list,
numnodes);
assert(*avail != NULL);
runstate = get_runstate(ctx, numnodes);
for (n = 0; n < numnodes; n++) {
if (runstate[n] == CTDB_RUNSTATE_RUNNING) {
(*avail)[n] = (*known)[n];
}
}
}
static uint32_t *get_tunable_values(TALLOC_CTX *tmp_ctx,
int numnodes,
const char *tunable)
{
int i;
char *tok;
uint32_t *tvals = talloc_zero_array(tmp_ctx, uint32_t, numnodes);
char *t = getenv(tunable);
if (t) {
if (strcmp(t, "1") == 0) {
for (i=0; inum = 0;
tok = strtok(ns, ",");
while (tok != NULL) {
n = nodemap->num;
nodemap->node = talloc_realloc(nodemap, nodemap->node,
struct ctdb_node_and_flags, n+1);
nodemap->node[n].pnn = n;
nodemap->node[n].flags = (uint32_t) strtol(tok, NULL, 0);
nodemap->node[n].addr = sa_zero;
nodemap->num++;
tok = strtok(NULL, ",");
}
algorithm = IPALLOC_LCP2;
if ((t = getenv("CTDB_IP_ALGORITHM"))) {
if (strcmp(t, "lcp2") == 0) {
algorithm = IPALLOC_LCP2;
} else if (strcmp(t, "nondet") == 0) {
algorithm = IPALLOC_NONDETERMINISTIC;
} else if (strcmp(t, "det") == 0) {
algorithm = IPALLOC_DETERMINISTIC;
} else {
DEBUG(DEBUG_ERR,
("ERROR: unknown IP algorithm %s\n", t));
exit(1);
}
}
t = getenv("CTDB_SET_NoIPTakeover");
if (t != NULL) {
noiptakeover = (uint32_t) strtol(t, NULL, 0);
} else {
noiptakeover = 0;
}
*ipalloc_state = ipalloc_state_init(mem_ctx, nodemap->num,
algorithm,
(noiptakeover != 0),
false,
NULL);
assert(*ipalloc_state != NULL);
read_ctdb_public_ip_info(mem_ctx, nodemap->num,
read_ips_for_multiple_nodes,
&known, &avail);
/* Drop available IPs for INACTIVE/DISABLED nodes */
for (n = 0; n < nodemap->num; n++) {
uint32_t flags = nodemap->node[n].flags;
if ((flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED)) != 0) {
avail[n].num = 0;
}
}
ipalloc_set_public_ips(*ipalloc_state, known, avail);
}
/* IP layout is read from stdin. See comment for ctdb_test_init() for
* explanation of read_ips_for_multiple_nodes.
*/
static void ctdb_test_ipalloc(const char nodestates[],
bool read_ips_for_multiple_nodes)
{
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
struct ipalloc_state *ipalloc_state;
ctdb_test_init(tmp_ctx, nodestates, &ipalloc_state,
read_ips_for_multiple_nodes);
print_ctdb_public_ip_list(tmp_ctx, ipalloc(ipalloc_state));
talloc_free(tmp_ctx);
}
static void usage(void)
{
fprintf(stderr, "usage: ctdb_takeover_tests \n");
exit(1);
}
int main(int argc, const char *argv[])
{
int loglevel;
const char *debuglevelstr = getenv("CTDB_TEST_LOGLEVEL");
setup_logging("ctdb_takeover_tests", DEBUG_STDERR);
if (! debug_level_parse(debuglevelstr, &loglevel)) {
loglevel = DEBUG_DEBUG;
}
debuglevel_set(loglevel);
if (argc < 2) {
usage();
}
if (argc == 3 &&
strcmp(argv[1], "ipalloc") == 0) {
ctdb_test_ipalloc(argv[2], false);
} else if (argc == 4 &&
strcmp(argv[1], "ipalloc") == 0 &&
strcmp(argv[3], "multi") == 0) {
ctdb_test_ipalloc(argv[2], true);
} else {
usage();
}
return 0;
}