along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include "tdb.h"
+#include "replace.h"
#include "system/network.h"
#include "system/filesys.h"
#include "system/wait.h"
-#include "../include/ctdb_private.h"
+
+#include <tdb.h>
+
+#include "lib/util/debug.h"
+#include "lib/util/samba_util.h"
+
+#include "ctdb_private.h"
+
+#include "protocol/protocol_util.h"
+
+#include "common/reqid.h"
+#include "common/system.h"
+#include "common/common.h"
+#include "common/logging.h"
/*
return error string for last error
void ctdb_external_trace(void)
{
int ret;
- const char * t = getenv("CTDB_EXTERNAL_TRACE");
+ static char external_trace[PATH_MAX+1] = "";
char * cmd;
- if (t == NULL) {
+ if (!ctdb_set_helper("external trace handler",
+ external_trace, sizeof(external_trace),
+ "CTDB_EXTERNAL_TRACE", NULL, NULL)) {
return;
}
- cmd = talloc_asprintf(NULL, "%s %lu", t, (unsigned long) getpid());
+ cmd = talloc_asprintf(NULL, "%s %lu", external_trace, (unsigned long) getpid());
DEBUG(DEBUG_WARNING,("begin external trace: %s\n", cmd));
ret = system(cmd);
if (ret == -1) {
{
struct servent *se;
int port;
+ int ret;
setservent(0);
se = getservbyname("ctdb", "tcp");
port = ntohs(se->s_port);
}
- if (! parse_ip(str, NULL, port, address)) {
+ ret = ctdb_sock_addr_from_string(str, address, false);
+ if (ret != 0) {
return -1;
}
+ ctdb_sock_addr_set_port(address, port);
return 0;
}
return tdb_jenkins_hash(discard_const(key));
}
-/*
- a type checking varient of idr_find
- */
-static void *_idr_find_type(struct idr_context *idp, int id, const char *type, const char *location)
-{
- void *p = idr_find(idp, id);
- if (p && talloc_check_name(p, type) == NULL) {
- DEBUG(DEBUG_ERR,("%s idr_find_type expected type %s but got %s\n",
- location, type, talloc_get_name(p)));
- return NULL;
- }
- return p;
-}
-
-uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state)
-{
- int id = idr_get_new_above(ctdb->idr, state, ctdb->lastid+1, INT_MAX);
- if (id < 0) {
- DEBUG(DEBUG_DEBUG, ("Reqid wrap!\n"));
- id = idr_get_new(ctdb->idr, state, INT_MAX);
- }
- ctdb->lastid = id;
- return id;
-}
-
-void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location)
-{
- void *p;
-
- p = _idr_find_type(ctdb->idr, reqid, type, location);
- if (p == NULL) {
- DEBUG(DEBUG_WARNING, ("Could not find idr:%u\n",reqid));
- }
-
- return p;
-}
-
-
-void ctdb_reqid_remove(struct ctdb_context *ctdb, uint32_t reqid)
-{
- int ret;
-
- ret = idr_remove(ctdb->idr, reqid);
- if (ret != 0) {
- DEBUG(DEBUG_ERR, ("Removing idr that does not exist\n"));
- }
-}
-
static uint32_t ctdb_marshall_record_size(TDB_DATA key,
struct ctdb_ltdb_header *header,
TDB_DATA data)
{
- return offsetof(struct ctdb_rec_data, data) + key.dsize +
+ return offsetof(struct ctdb_rec_data_old, data) + key.dsize +
data.dsize + (header ? sizeof(*header) : 0);
}
-static void ctdb_marshall_record_copy(struct ctdb_rec_data *rec,
+static void ctdb_marshall_record_copy(struct ctdb_rec_data_old *rec,
uint32_t reqid,
TDB_DATA key,
struct ctdb_ltdb_header *header,
note that header may be NULL. If not NULL then it is included in the data portion
of the record
*/
-struct ctdb_rec_data *ctdb_marshall_record(TALLOC_CTX *mem_ctx, uint32_t reqid,
- TDB_DATA key,
- struct ctdb_ltdb_header *header,
- TDB_DATA data)
+struct ctdb_rec_data_old *ctdb_marshall_record(TALLOC_CTX *mem_ctx,
+ uint32_t reqid,
+ TDB_DATA key,
+ struct ctdb_ltdb_header *header,
+ TDB_DATA data)
{
size_t length;
- struct ctdb_rec_data *d;
+ struct ctdb_rec_data_old *d;
length = ctdb_marshall_record_size(key, header, data);
- d = (struct ctdb_rec_data *)talloc_size(mem_ctx, length);
+ d = (struct ctdb_rec_data_old *)talloc_size(mem_ctx, length);
if (d == NULL) {
return NULL;
}
/* helper function for marshalling multiple records */
struct ctdb_marshall_buffer *ctdb_marshall_add(TALLOC_CTX *mem_ctx,
struct ctdb_marshall_buffer *m,
- uint64_t db_id,
+ uint32_t db_id,
uint32_t reqid,
TDB_DATA key,
struct ctdb_ltdb_header *header,
TDB_DATA data)
{
- struct ctdb_rec_data *r;
+ struct ctdb_rec_data_old *r;
struct ctdb_marshall_buffer *m2;
uint32_t length, offset;
m2->db_id = db_id;
}
- r = (struct ctdb_rec_data *)((uint8_t *)m2 + offset);
+ r = (struct ctdb_rec_data_old *)((uint8_t *)m2 + offset);
ctdb_marshall_record_copy(r, reqid, key, header, data, length);
m2->count++;
- pass r==NULL to start
- loop the number of times indicated by m->count
*/
-struct ctdb_rec_data *ctdb_marshall_loop_next(struct ctdb_marshall_buffer *m, struct ctdb_rec_data *r,
- uint32_t *reqid,
- struct ctdb_ltdb_header *header,
- TDB_DATA *key, TDB_DATA *data)
+struct ctdb_rec_data_old *ctdb_marshall_loop_next(
+ struct ctdb_marshall_buffer *m,
+ struct ctdb_rec_data_old *r,
+ uint32_t *reqid,
+ struct ctdb_ltdb_header *header,
+ TDB_DATA *key, TDB_DATA *data)
{
if (r == NULL) {
- r = (struct ctdb_rec_data *)&m->data[0];
+ r = (struct ctdb_rec_data_old *)&m->data[0];
} else {
- r = (struct ctdb_rec_data *)(r->length + (uint8_t *)r);
+ r = (struct ctdb_rec_data_old *)(r->length + (uint8_t *)r);
}
if (reqid != NULL) {
*/
void ctdb_canonicalize_ip(const ctdb_sock_addr *ip, ctdb_sock_addr *cip)
{
- char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
-
- memcpy(cip, ip, sizeof (*cip));
+ ZERO_STRUCTP(cip);
- if ( (ip->sa.sa_family == AF_INET6)
- && !memcmp(&ip->ip6.sin6_addr, prefix, 12)) {
- memset(cip, 0, sizeof(*cip));
+ if (ip->sa.sa_family == AF_INET6) {
+ const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
+ if (memcmp(&ip->ip6.sin6_addr, prefix, sizeof(prefix)) == 0) {
+ /* Copy IPv4-mapped IPv6 addresses as IPv4 */
+ cip->ip.sin_family = AF_INET;
#ifdef HAVE_SOCK_SIN_LEN
- cip->ip.sin_len = sizeof(*cip);
+ cip->ip.sin_len = sizeof(ctdb_sock_addr);
#endif
+ cip->ip.sin_port = ip->ip6.sin6_port;
+ memcpy(&cip->ip.sin_addr,
+ &ip->ip6.sin6_addr.s6_addr[12],
+ sizeof(cip->ip.sin_addr));
+ } else {
+ cip->ip6.sin6_family = AF_INET6;
+#ifdef HAVE_SOCK_SIN_LEN
+ cip->ip6.sin_len = sizeof(ctdb_sock_addr);
+#endif
+ cip->ip6.sin6_port = ip->ip6.sin6_port;
+ memcpy(&cip->ip6.sin6_addr,
+ &ip->ip6.sin6_addr,
+ sizeof(cip->ip6.sin6_addr));
+ }
+
+ return;
+ }
+
+ if (ip->sa.sa_family == AF_INET) {
cip->ip.sin_family = AF_INET;
- cip->ip.sin_port = ip->ip6.sin6_port;
- memcpy(&cip->ip.sin_addr, &ip->ip6.sin6_addr.s6_addr[12], 4);
+#ifdef HAVE_SOCK_SIN_LEN
+ cip->ip.sin_len = sizeof(ctdb_sock_addr);
+#endif
+ cip->ip.sin_port = ip->ip.sin_port;
+ memcpy(&cip->ip.sin_addr,
+ &ip->ip.sin_addr,
+ sizeof(ip->ip.sin_addr));
+
+ return;
}
}
return 0;
}
+/* Add a node to a node map with given address and flags */
+static bool node_map_add(TALLOC_CTX *mem_ctx,
+ const char *nstr, uint32_t flags,
+ struct ctdb_node_map_old **node_map)
+{
+ ctdb_sock_addr addr;
+ uint32_t num;
+ size_t s;
+ struct ctdb_node_and_flags *n;
+
+ /* Might as well do this before trying to allocate memory */
+ if (ctdb_parse_address(mem_ctx, nstr, &addr) == -1) {
+ return false;
+ }
+
+ num = (*node_map)->num + 1;
+ s = offsetof(struct ctdb_node_map_old, nodes) +
+ num * sizeof(struct ctdb_node_and_flags);
+ *node_map = talloc_realloc_size(mem_ctx, *node_map, s);
+ if (*node_map == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
+ return false;
+ }
+
+ n = &(*node_map)->nodes[(*node_map)->num];
+ n->addr = addr;
+ n->pnn = (*node_map)->num;
+ n->flags = flags;
+
+ (*node_map)->num++;
+
+ return true;
+}
+
+/* Read a nodes file into a node map */
+struct ctdb_node_map_old *ctdb_read_nodes_file(TALLOC_CTX *mem_ctx,
+ const char *nlist)
+{
+ char **lines;
+ int nlines;
+ int i;
+ struct ctdb_node_map_old *ret;
+
+ /* Allocate node map header */
+ ret = talloc_zero_size(mem_ctx, offsetof(struct ctdb_node_map_old, nodes));
+ if (ret == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
+ return false;
+ }
+
+ lines = file_lines_load(nlist, &nlines, 0, mem_ctx);
+ if (lines == NULL) {
+ DEBUG(DEBUG_ERR, ("Failed to read nodes file \"%s\"\n", nlist));
+ return false;
+ }
+ while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
+ nlines--;
+ }
+
+ for (i=0; i < nlines; i++) {
+ char *node;
+ uint32_t flags;
+ size_t len;
+
+ node = lines[i];
+ /* strip leading spaces */
+ while((*node == ' ') || (*node == '\t')) {
+ node++;
+ }
+
+ len = strlen(node);
+
+ while ((len > 1) &&
+ ((node[len-1] == ' ') || (node[len-1] == '\t')))
+ {
+ node[len-1] = '\0';
+ len--;
+ }
+
+ if (len == 0) {
+ continue;
+ }
+ if (*node == '#') {
+ /* A "deleted" node is a node that is
+ commented out in the nodes file. This is
+ used instead of removing a line, which
+ would cause subsequent nodes to change
+ their PNN. */
+ flags = NODE_FLAGS_DELETED;
+ node = discard_const("0.0.0.0");
+ } else {
+ flags = 0;
+ }
+ if (!node_map_add(mem_ctx, node, flags, &ret)) {
+ talloc_free(lines);
+ TALLOC_FREE(ret);
+ return NULL;
+ }
+ }
+
+ talloc_free(lines);
+ return ret;
+}
+
+struct ctdb_node_map_old *
+ctdb_node_list_to_map(struct ctdb_node **nodes, uint32_t num_nodes,
+ TALLOC_CTX *mem_ctx)
+{
+ uint32_t i;
+ size_t size;
+ struct ctdb_node_map_old *node_map;
+
+ size = offsetof(struct ctdb_node_map_old, nodes) +
+ num_nodes * sizeof(struct ctdb_node_and_flags);
+ node_map = (struct ctdb_node_map_old *)talloc_zero_size(mem_ctx, size);
+ if (node_map == NULL) {
+ DEBUG(DEBUG_ERR,
+ (__location__ " Failed to allocate nodemap array\n"));
+ return NULL;
+ }
+
+ node_map->num = num_nodes;
+ for (i=0; i<num_nodes; i++) {
+ node_map->nodes[i].addr = nodes[i]->address;
+ node_map->nodes[i].pnn = nodes[i]->pnn;
+ node_map->nodes[i].flags = nodes[i]->flags;
+ }
+
+ return node_map;
+}
const char *ctdb_eventscript_call_names[] = {
"init",
void ctdb_set_runstate(struct ctdb_context *ctdb, enum ctdb_runstate runstate)
{
+ DEBUG(DEBUG_NOTICE,("Set runstate to %s (%d)\n",
+ runstate_to_string(runstate), runstate));
+
if (runstate <= ctdb->runstate) {
ctdb_fatal(ctdb, "runstate must always increase");
}
- DEBUG(DEBUG_NOTICE,("Set runstate to %s (%d)\n",
- runstate_to_string(runstate), runstate));
ctdb->runstate = runstate;
}