ctdb-tests: Factor out reading of known public IP addresses
authorMartin Schwenke <martin@meltin.net>
Sat, 3 Dec 2016 05:20:01 +0000 (16:20 +1100)
committerAmitay Isaacs <amitay@samba.org>
Mon, 19 Dec 2016 03:07:07 +0000 (04:07 +0100)
One change in behaviour is to actually copy the known IPs per node
instead of just assigning the pointer.  When this is used by
fake_ctdbd the resulting structure will be used to keep state for
individual nodes, so data for nodes needs to be independent.

Also, drop some asserts in the factored code and do (slightly) better
error handling.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/tests/src/ctdb_takeover_tests.c
ctdb/tests/src/ipalloc_read_known_ips.c [new file with mode: 0644]
ctdb/tests/src/ipalloc_read_known_ips.h [new file with mode: 0644]
ctdb/wscript

index 6204c0a09ebf3e34520317e24d9e4f3de6ed164b..1f463300aecbfff3748d4ddbbf3035e0f2fb692d 100644 (file)
@@ -32,6 +32,8 @@
 
 #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)
 {
@@ -49,86 +51,6 @@ static uint32_t *get_tunable_values(TALLOC_CTX *tmp_ctx,
 static enum ctdb_runstate *get_runstate(TALLOC_CTX *tmp_ctx,
                                        int numnodes);
 
-static void add_ip(TALLOC_CTX *mem_ctx,
-                  struct ctdb_public_ip_list *l,
-                  ctdb_sock_addr *addr,
-                  uint32_t pnn)
-{
-
-       l->ip = talloc_realloc(mem_ctx, l->ip,
-                              struct ctdb_public_ip, l->num + 1);
-       assert(l->ip != NULL);
-
-       l->ip[l->num].addr = *addr;
-       l->ip[l->num].pnn  = pnn;
-       l->num++;
-}
-
-/* Format of each line is "IP CURRENT_PNN [ALLOWED_PNN,...]".
- * If multi is true then ALLOWED_PNNs are not allowed.  */
-static void read_ctdb_public_ip_info_node(int numnodes,
-                                         bool multi,
-                                         struct ctdb_public_ip_list **k,
-                                         struct ctdb_public_ip_list *known)
-{
-       char line[1024];
-       ctdb_sock_addr addr;
-       char *t, *tok;
-       int pnn, n;
-
-       /* Known public IPs */
-       *k = talloc_zero(known, struct ctdb_public_ip_list);
-       assert(k != NULL);
-
-       while (fgets(line, sizeof(line), stdin) != NULL) {
-
-               /* Get rid of pesky newline */
-               if ((t = strchr(line, '\n')) != NULL) {
-                       *t = '\0';
-               }
-
-               /* Exit on an empty line */
-               if (line[0] == '\0') {
-                       break;
-               }
-
-               /* Get the IP address */
-               tok = strtok(line, " \t");
-               if (tok == NULL) {
-                       DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored :%s\n", line));
-                       continue;
-               }
-
-               if (!parse_ip(tok, NULL, 0, &addr)) {
-                       DEBUG(DEBUG_ERR, (__location__ " ERROR, bad address :%s\n", tok));
-                       continue;
-               }
-
-               /* Get the PNN */
-               pnn = -1;
-               tok = strtok(NULL, " \t");
-               if (tok != NULL) {
-                       pnn = (int) strtol(tok, (char **) NULL, 10);
-               }
-
-               add_ip(*k, *k, &addr, pnn);
-
-               tok = strtok(NULL, " \t#");
-               if (tok == NULL) {
-                       continue;
-               }
-
-               /* Handle allowed nodes for addr */
-               assert(multi == false);
-               t = strtok(tok, ",");
-               while (t != NULL) {
-                       n = (int) strtol(t, (char **) NULL, 10);
-                       add_ip(known, &known[n], &addr, pnn);
-                       t = strtok(NULL, ",");
-               }
-       }
-}
-
 static void read_ctdb_public_ip_info(TALLOC_CTX *ctx,
                                     int numnodes,
                                     bool multi,
@@ -136,34 +58,15 @@ static void read_ctdb_public_ip_info(TALLOC_CTX *ctx,
                                     struct ctdb_public_ip_list ** avail)
 {
        int n;
-       struct ctdb_public_ip_list * k;
        enum ctdb_runstate *runstate;
 
-       *known = talloc_zero_array(ctx, struct ctdb_public_ip_list,
-                                  numnodes);
+       *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);
 
-       if (multi) {
-               for (n = 0; n < numnodes; n++) {
-                       read_ctdb_public_ip_info_node(numnodes, multi,
-                                                     &k, *known);
-
-                       (*known)[n] = *k;
-               }
-       } else {
-               read_ctdb_public_ip_info_node(numnodes, multi, &k, *known);
-
-               /* Assign it to any nodes that don't have a list assigned */
-               for (n = 0; n < numnodes; n++) {
-                       if ((*known)[n].num == 0) {
-                               (*known)[n] = *k;
-                       }
-               }
-       }
-
        runstate = get_runstate(ctx, numnodes);
        for (n = 0; n < numnodes; n++) {
                if (runstate[n] == CTDB_RUNSTATE_RUNNING) {
diff --git a/ctdb/tests/src/ipalloc_read_known_ips.c b/ctdb/tests/src/ipalloc_read_known_ips.c
new file mode 100644 (file)
index 0000000..bd4366c
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+   Tests support for CTDB IP allocation
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+
+#include "replace.h"
+#include "system/network.h"
+
+#include "lib/util/debug.h"
+
+#include "protocol/protocol.h"
+#include "common/logging.h"
+#include "common/system.h"
+
+#include "ipalloc_read_known_ips.h"
+
+static bool add_ip(TALLOC_CTX *mem_ctx,
+                  struct ctdb_public_ip_list *l,
+                  ctdb_sock_addr *addr,
+                  uint32_t pnn)
+{
+
+       l->ip = talloc_realloc(mem_ctx, l->ip,
+                              struct ctdb_public_ip, l->num + 1);
+       if (l->ip == NULL) {
+               D_ERR(__location__ " out of memory\n");
+               return false;
+       }
+
+       l->ip[l->num].addr = *addr;
+       l->ip[l->num].pnn  = pnn;
+       l->num++;
+
+       return true;
+}
+
+/* Format of each line is "IP CURRENT_PNN [ALLOWED_PNN,...]".
+ * If multi is true then ALLOWED_PNNs are not allowed.  */
+static bool read_ctdb_public_ip_info_node(bool multi,
+                                         struct ctdb_public_ip_list **k,
+                                         struct ctdb_public_ip_list *known)
+{
+       char line[1024];
+       ctdb_sock_addr addr;
+       char *t, *tok;
+       int pnn, n;
+
+       /* Known public IPs */
+       *k = talloc_zero(known, struct ctdb_public_ip_list);
+       if (*k == NULL) {
+               goto fail;
+       }
+
+       while (fgets(line, sizeof(line), stdin) != NULL) {
+
+               /* Get rid of pesky newline */
+               if ((t = strchr(line, '\n')) != NULL) {
+                       *t = '\0';
+               }
+
+               /* Exit on an empty line */
+               if (line[0] == '\0') {
+                       break;
+               }
+
+               /* Get the IP address */
+               tok = strtok(line, " \t");
+               if (tok == NULL) {
+                       D_WARNING("WARNING, bad line ignored :%s\n", line);
+                       continue;
+               }
+
+               if (!parse_ip(tok, NULL, 0, &addr)) {
+                       D_ERR("ERROR, bad address :%s\n", tok);
+                       continue;
+               }
+
+               /* Get the PNN */
+               pnn = -1;
+               tok = strtok(NULL, " \t");
+               if (tok != NULL) {
+                       pnn = (int) strtol(tok, (char **) NULL, 10);
+               }
+
+               if (! add_ip(*k, *k, &addr, pnn)) {
+                       goto fail;
+               }
+
+               tok = strtok(NULL, " \t#");
+               if (tok == NULL) {
+                       continue;
+               }
+
+               /* Handle allowed nodes for addr */
+               if (multi) {
+                       D_ERR("ERROR, bad token\n");
+                       goto fail;
+               }
+               t = strtok(tok, ",");
+               while (t != NULL) {
+                       n = (int) strtol(t, (char **) NULL, 10);
+                       if (! add_ip(known, &known[n], &addr, pnn)) {
+                               goto fail;
+                       }
+                       t = strtok(NULL, ",");
+               }
+       }
+
+       return true;
+
+fail:
+       TALLOC_FREE(*k);
+       return false;
+}
+
+struct ctdb_public_ip_list * ipalloc_read_known_ips(TALLOC_CTX *ctx,
+                                                   int numnodes,
+                                                   bool multi)
+{
+       int n;
+       struct ctdb_public_ip_list *k;
+       struct ctdb_public_ip_list *known;
+
+       known = talloc_zero_array(ctx, struct ctdb_public_ip_list,
+                                 numnodes);
+       if (known == NULL) {
+               D_ERR(__location__ " out of memory\n");
+               goto fail;
+       }
+
+       if (multi) {
+               for (n = 0; n < numnodes; n++) {
+                       if (! read_ctdb_public_ip_info_node(multi, &k, known)) {
+                               goto fail;
+                       }
+
+                       known[n] = *k;
+               }
+       } else {
+               if (! read_ctdb_public_ip_info_node(multi, &k, known)) {
+                       goto fail;
+               }
+
+               /* Copy it to any nodes that don't have a
+                * list assigned
+                */
+               for (n = 0; n < numnodes; n++) {
+                       if (known[n].num == 0) {
+                               known[n].num = k->num;
+                               known[n].ip = talloc_memdup(
+                                       known, k->ip,
+                                       k->num * sizeof(struct ctdb_public_ip));
+                               if (known[n].ip == NULL) {
+                                       goto fail;
+                               }
+                       }
+               }
+       }
+
+       return known;
+
+fail:
+       talloc_free(known);
+       return NULL;
+}
diff --git a/ctdb/tests/src/ipalloc_read_known_ips.h b/ctdb/tests/src/ipalloc_read_known_ips.h
new file mode 100644 (file)
index 0000000..aa6d154
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+   Tests support for CTDB IP allocation
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __IPALLOC_READ_KNOWN_IPS_H__
+#define __IPALLOC_READ_KNOWN_IPS_H__
+
+#include <stdbool.h>
+#include <talloc.h>
+
+#include "protocol/protocol.h"
+
+struct ctdb_public_ip_list * ipalloc_read_known_ips(TALLOC_CTX *ctx,
+                                                   int numnodes,
+                                                   bool multi);
+
+#endif /* __IPALLOC_READ_KNOWN_IPS_H__ */
index 0665e181f94e0617f08913b4d7dd224ff1431a8d..e9b0d750e9febe45642f908d189f27b33f99b2ba 100644 (file)
@@ -799,7 +799,8 @@ def build(bld):
                          install_path='${CTDB_TEST_LIBEXECDIR}')
 
     bld.SAMBA_BINARY('ctdb_takeover_tests',
-                     source='tests/src/ctdb_takeover_tests.c',
+                     source='''tests/src/ctdb_takeover_tests.c
+                               tests/src/ipalloc_read_known_ips.c''',
                      deps='''replace popt tdb tevent talloc ctdb-system
                              samba-util tdb-wrap talloc_report
                              ctdb-ipalloc ctdb-protocol ctdb-util''',