/* Test stubs and support functions for some libctdb functions 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 #include "ctdb.h" /* Can't use the real definition, since including libctdb_private.h * causes macro conflicts */ struct ctdb_connection { struct ctdb_node_map *nodemap; uint32_t current_node; uint32_t recmaster; struct ctdb_ifaces_list *ifaces; struct ctdb_vnn_map *vnnmap; }; /* Read a nodemap from stdin. Each line looks like: * [RECMASTER] [CURRENT] * EOF or a blank line terminates input. */ void libctdb_test_read_nodemap(struct ctdb_connection *ctdb) { char line[1024]; ctdb->nodemap = (struct ctdb_node_map *) malloc(offsetof(struct ctdb_node_map, nodes)); if (ctdb->nodemap == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating nodemap\n")); exit (1); } ctdb->nodemap->num = 0; while ((fgets(line, sizeof(line), stdin) != NULL) && (line[0] != '\n')) { uint32_t pnn, flags; char *tok, *t; /* Get rid of pesky newline */ if ((t = strchr(line, '\n')) != NULL) { *t = '\0'; } /* Get PNN */ tok = strtok(line, " \t"); if (tok == NULL) { DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignoed \"%s\"\n", line)); continue; } pnn = (uint32_t)strtoul(tok, NULL, 0); /* Get flags */ tok = strtok(NULL, " \t"); if (tok == NULL) { DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line)); continue; } flags = (uint32_t)strtoul(tok, NULL, 0); tok = strtok(NULL, " \t"); while (tok != NULL) { if (strcmp(tok, "CURRENT") == 0) { ctdb->current_node = pnn; } else if (strcmp(tok, "RECMASTER") == 0) { ctdb->recmaster = pnn; } tok = strtok(NULL, " \t"); } ctdb->nodemap = (struct ctdb_node_map *) realloc(ctdb->nodemap, offsetof(struct ctdb_node_map, nodes) + (ctdb->nodemap->num + 1) * sizeof(struct ctdb_node_and_flags)); if (ctdb->nodemap == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating nodemap\n")); exit (1); } ctdb->nodemap->nodes[ctdb->nodemap->num].pnn = pnn; ctdb->nodemap->nodes[ctdb->nodemap->num].flags = flags; ctdb->nodemap->num++; } } void libctdb_test_print_nodemap(struct ctdb_connection *ctdb) { int i; for (i = 0; i < ctdb->nodemap->num; i++) { printf("%ld\t0x%lx%s%s\n", (unsigned long) ctdb->nodemap->nodes[i].pnn, (unsigned long) ctdb->nodemap->nodes[i].flags, ctdb->nodemap->nodes[i].pnn == ctdb->current_node ? "\tCURRENT" : "", ctdb->nodemap->nodes[i].pnn == ctdb->recmaster ? "\tRECMASTER" : ""); } } /* Read interfaces information. Same format as "ctdb ifaces -Y" * output: * :Name:LinkStatus:References: * :eth2:1:4294967294 * :eth1:1:4294967292 */ void libctdb_test_read_ifaces(struct ctdb_connection *ctdb) { char line[1024]; ctdb->ifaces = (struct ctdb_ifaces_list *) malloc(offsetof(struct ctdb_ifaces_list, ifaces)); if (ctdb->ifaces == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating ifaces\n")); exit (1); } ctdb->ifaces->num = 0; while ((fgets(line, sizeof(line), stdin) != NULL) && (line[0] != '\n')) { uint16_t link_state; uint32_t references; char *tok, *t, *name; /* Get rid of pesky newline */ if ((t = strchr(line, '\n')) != NULL) { *t = '\0'; } if (strcmp(line, ":Name:LinkStatus:References:") == 0) { continue; } /* name */ //tok = strtok(line, ":"); /* Leading colon... */ tok = strtok(line, ":"); if (tok == NULL) { DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignoed \"%s\"\n", line)); continue; } name = tok; /* link_state */ tok = strtok(NULL, ":"); if (tok == NULL) { DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line)); continue; } link_state = (uint16_t)strtoul(tok, NULL, 0); /* references... */ tok = strtok(NULL, ":"); if (tok == NULL) { DEBUG(DEBUG_ERR, (__location__ " WARNING, bad line ignored \"%s\"\n", line)); continue; } references = (uint32_t)strtoul(tok, NULL, 0); ctdb->ifaces = (struct ctdb_ifaces_list *) realloc(ctdb->ifaces, offsetof(struct ctdb_ifaces_list, ifaces) + (ctdb->ifaces->num + 1) * sizeof(struct ctdb_iface_info)); if (ctdb->ifaces == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating ifaces\n")); exit (1); } strcpy(&(ctdb->ifaces->ifaces[ctdb->ifaces->num].name[0]), name); ctdb->ifaces->ifaces[ctdb->ifaces->num].link_state = link_state; ctdb->ifaces->ifaces[ctdb->ifaces->num].references = references; ctdb->ifaces->num++; } } void libctdb_test_print_ifaces(struct ctdb_connection *ctdb) { int i; printf(":Name:LinkStatus:References:\n"); for (i = 0; i < ctdb->ifaces->num; i++) { printf(":%s:%u:%u:\n", ctdb->ifaces->ifaces[i].name, ctdb->ifaces->ifaces[i].link_state, ctdb->ifaces->ifaces[i].references); } } /* Read vnn map. * output: * * * * ... */ void libctdb_test_read_vnnmap(struct ctdb_connection *ctdb) { char line[1024]; ctdb->vnnmap = (struct ctdb_vnn_map *) malloc(sizeof(struct ctdb_vnn_map)); if (ctdb->vnnmap == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating vnnmap\n")); exit (1); } ctdb->vnnmap->generation = INVALID_GENERATION; ctdb->vnnmap->size = 0; ctdb->vnnmap->map = NULL; while ((fgets(line, sizeof(line), stdin) != NULL) && (line[0] != '\n')) { uint32_t n; char *t; /* Get rid of pesky newline */ if ((t = strchr(line, '\n')) != NULL) { *t = '\0'; } n = (uint32_t) strtol(line, NULL, 0); /* generation */ if (ctdb->vnnmap->generation == INVALID_GENERATION) { ctdb->vnnmap->generation = n; continue; } ctdb->vnnmap->map = (uint32_t *) realloc(ctdb->vnnmap->map, (ctdb->vnnmap->size + 1) * sizeof(uint32_t)); if (ctdb->vnnmap->map == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating vnnmap->map\n")); exit (1); } ctdb->vnnmap->map[ctdb->vnnmap->size] = n; ctdb->vnnmap->size++; } } void libctdb_test_print_vnnmap(struct ctdb_connection *ctdb) { int i; printf("%d\n", ctdb->vnnmap->generation); for (i = 0; i < ctdb->vnnmap->size; i++) { printf("%d\n", ctdb->vnnmap->map[i]); } } void libctdb_test_fake_setup(struct ctdb_connection *ctdb) { char line[1024]; while (fgets(line, sizeof(line), stdin) != NULL) { char *t; /* Get rid of pesky newline */ if ((t = strchr(line, '\n')) != NULL) { *t = '\0'; } if (strcmp(line, "NODEMAP") == 0) { libctdb_test_read_nodemap(ctdb); } else if (strcmp(line, "IFACES") == 0) { libctdb_test_read_ifaces(ctdb); } else if (strcmp(line, "VNNMAP") == 0) { libctdb_test_read_vnnmap(ctdb); } else { printf("Unknown line %s\n", line); exit(1); } } } /* Stubs... */ bool ctdb_getnodemap(struct ctdb_connection *ctdb, uint32_t destnode, struct ctdb_node_map **nodemap) { *nodemap = ctdb->nodemap; return true; } void ctdb_free_nodemap(struct ctdb_node_map *nodemap) { return; } bool ctdb_getifaces(struct ctdb_connection *ctdb, uint32_t destnode, struct ctdb_ifaces_list **ifaces) { *ifaces = ctdb->ifaces; return true; } void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces) { return; } bool ctdb_getpnn(struct ctdb_connection *ctdb, uint32_t destnode, uint32_t *pnn) { if (destnode == CTDB_CURRENT_NODE) { *pnn = ctdb->current_node; } else { *pnn = destnode; } return true; } bool ctdb_getrecmode(struct ctdb_connection *ctdb, uint32_t destnode, uint32_t *recmode) { *recmode = 0; return true; } bool ctdb_getrecmaster(struct ctdb_connection *ctdb, uint32_t destnode, uint32_t *recmaster) { *recmaster = ctdb->recmaster; return true; } bool ctdb_getvnnmap(struct ctdb_connection *ctdb, uint32_t destnode, struct ctdb_vnn_map **vnnmap) { *vnnmap = ctdb->vnnmap; return true; } void ctdb_free_vnnmap(struct ctdb_vnn_map *vnnmap) { return; } bool ctdb_getdbseqnum(struct ctdb_connection *ctdb, uint32_t destnode, uint32_t dbid, uint64_t *seqnum) { *seqnum = 0; return false; /* Not implemented */ } bool ctdb_check_message_handlers(struct ctdb_connection *ctdb, uint32_t destnode, uint32_t num, uint64_t *mhs, uint8_t *result) { *result = 0; return false; /* Not implemented */ } /* Not a stub, a copy */ void ctdb_log_file(FILE *outf, int priority, const char *format, va_list ap) { fprintf(outf, "%s:", priority == LOG_EMERG ? "EMERG" : priority == LOG_ALERT ? "ALERT" : priority == LOG_CRIT ? "CRIT" : priority == LOG_ERR ? "ERR" : priority == LOG_WARNING ? "WARNING" : priority == LOG_NOTICE ? "NOTICE" : priority == LOG_INFO ? "INFO" : priority == LOG_DEBUG ? "DEBUG" : "Unknown Error Level"); vfprintf(outf, format, ap); if (priority == LOG_ERR) { fprintf(outf, " (%s)", strerror(errno)); } fprintf(outf, "\n"); } /* Remove type-safety macro. */ #undef ctdb_connect struct ctdb_connection *ctdb_connect(const char *addr, ctdb_log_fn_t log_func, void *log_priv) { struct ctdb_connection *ctdb; ctdb = malloc(sizeof(struct ctdb_connection)); if (ctdb == NULL) { DEBUG(DEBUG_ERR, ("OOM allocating ctdb_connection\n")); exit (1); } ctdb->nodemap = NULL; ctdb->current_node = 0; ctdb->recmaster = 0; ctdb->ifaces = NULL; ctdb->vnnmap = NULL; return ctdb; } void ctdb_disconnect(struct ctdb_connection *ctdb) { if (ctdb->nodemap != NULL) { free(ctdb->nodemap); } if (ctdb->ifaces != NULL) { free(ctdb->ifaces); } if (ctdb->vnnmap != NULL) { if (ctdb->vnnmap->map != NULL) { free(ctdb->vnnmap->map); } free(ctdb->vnnmap); } free(ctdb); }