Add a new "ctdb deltickle" command to delete tickles from the database.
This can ONLY be used for tickles created by "ctdb addtickle".
Push any "addtickle/deltickle" updates to other nodes every TickleUpdateInterval seconds'
/*
a tcp connection description
+ also used by tcp_add and tcp_remove controls
*/
struct ctdb_tcp_connection {
ctdb_sock_addr src_addr;
char iface[1];
};
-/*
- struct for tcp_add and tcp_remove controls
- */
-struct ctdb_control_tcp_vnn {
- ctdb_sock_addr src;
- ctdb_sock_addr dest;
-};
-
/*
persistent store control - update this record on all other nodes
*/
int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
TDB_DATA indata);
-int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata, bool tcp_update_needed);
int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata);
int32_t ctdb_control_startup(struct ctdb_context *ctdb, uint32_t vnn);
int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata);
CTDB_CONTROL_GET_PUBLIC_IP_INFO = 123,
CTDB_CONTROL_GET_IFACES = 124,
CTDB_CONTROL_SET_IFACE_LINK_STATE = 125,
+ CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE = 126,
};
/*
return ctdb_control_startup(ctdb, srcnode);
case CTDB_CONTROL_TCP_ADD:
- CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_tcp_vnn));
- return ctdb_control_tcp_add(ctdb, indata);
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_tcp_connection));
+ return ctdb_control_tcp_add(ctdb, indata, false);
+
+ case CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_tcp_connection));
+ return ctdb_control_tcp_add(ctdb, indata, true);
+
+ case CTDB_CONTROL_TCP_REMOVE:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_tcp_connection));
+ return ctdb_control_tcp_remove(ctdb, indata);
case CTDB_CONTROL_SET_TUNABLE:
return ctdb_control_set_tunable(ctdb, indata);
struct ctdb_control_tcp_addr new_addr;
struct ctdb_control_tcp_addr *tcp_sock = NULL;
struct ctdb_tcp_list *tcp;
- struct ctdb_control_tcp_vnn t;
+ struct ctdb_tcp_connection t;
int ret;
TDB_DATA data;
struct ctdb_client_ip *ip;
DLIST_ADD(client->tcp_list, tcp);
- t.src = tcp_sock->src;
- t.dest = tcp_sock->dest;
+ t.src_addr = tcp_sock->src;
+ t.dst_addr = tcp_sock->dest;
data.dptr = (uint8_t *)&t;
data.dsize = sizeof(t);
return NULL;
}
+
+
/*
called by a daemon to inform us of a TCP connection that one of its
clients managing that should tickled with an ACK when IP takeover is
done
*/
-int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
+int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata, bool tcp_update_needed)
{
- struct ctdb_control_tcp_vnn *p = (struct ctdb_control_tcp_vnn *)indata.dptr;
+ struct ctdb_tcp_connection *p = (struct ctdb_tcp_connection *)indata.dptr;
struct ctdb_tcp_array *tcparray;
struct ctdb_tcp_connection tcp;
struct ctdb_vnn *vnn;
- vnn = find_public_ip_vnn(ctdb, &p->dest);
+ vnn = find_public_ip_vnn(ctdb, &p->dst_addr);
if (vnn == NULL) {
DEBUG(DEBUG_INFO,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
- ctdb_addr_to_str(&p->dest)));
+ ctdb_addr_to_str(&p->dst_addr)));
return -1;
}
tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
CTDB_NO_MEMORY(ctdb, tcparray->connections);
- tcparray->connections[tcparray->num].src_addr = p->src;
- tcparray->connections[tcparray->num].dst_addr = p->dest;
+ tcparray->connections[tcparray->num].src_addr = p->src_addr;
+ tcparray->connections[tcparray->num].dst_addr = p->dst_addr;
tcparray->num++;
+
+ if (tcp_update_needed) {
+ vnn->tcp_update_needed = true;
+ }
return 0;
}
/* Do we already have this tickle ?*/
- tcp.src_addr = p->src;
- tcp.dst_addr = p->dest;
+ tcp.src_addr = p->src_addr;
+ tcp.dst_addr = p->dst_addr;
if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
ctdb_addr_to_str(&tcp.dst_addr),
CTDB_NO_MEMORY(ctdb, tcparray->connections);
vnn->tcp_array = tcparray;
- tcparray->connections[tcparray->num].src_addr = p->src;
- tcparray->connections[tcparray->num].dst_addr = p->dest;
+ tcparray->connections[tcparray->num].src_addr = p->src_addr;
+ tcparray->connections[tcparray->num].dst_addr = p->dst_addr;
tcparray->num++;
DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
ntohs(tcp.dst_addr.ip.sin_port),
vnn->pnn));
+ if (tcp_update_needed) {
+ vnn->tcp_update_needed = true;
+ }
+
return 0;
}
}
+/*
+ called by a daemon to inform us of a TCP connection that one of its
+ clients used are no longer needed in the tickle database
+ */
+int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+ struct ctdb_tcp_connection *conn = (struct ctdb_tcp_connection *)indata.dptr;
+
+ ctdb_remove_tcp_connection(ctdb, conn);
+
+ return 0;
+}
+
+
/*
called when a daemon restarts - send all tickes for all public addresses
we are serving immediately to the new node.
}
/*
- add a list of all tickle to a public address
+ add a tickle to a public address
*/
static int control_add_tickle(struct ctdb_context *ctdb, int argc, const char **argv)
{
- struct ctdb_control_tcp_vnn t;
+ struct ctdb_tcp_connection t;
TDB_DATA data;
int ret;
usage();
}
- if (parse_ip_port(argv[0], &t.src) == 0) {
+ if (parse_ip_port(argv[0], &t.src_addr) == 0) {
DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
return -1;
}
- if (parse_ip_port(argv[1], &t.dest) == 0) {
+ if (parse_ip_port(argv[1], &t.dst_addr) == 0) {
DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[1]));
return -1;
}
data.dsize = sizeof(t);
/* tell all nodes about this tcp connection */
- ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_TCP_ADD,
+ ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE,
0, data, ctdb, NULL, NULL, NULL, NULL);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to add tickle\n"));
}
+/*
+ delete a tickle from a node
+ */
+static int control_del_tickle(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ struct ctdb_tcp_connection t;
+ TDB_DATA data;
+ int ret;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ if (parse_ip_port(argv[0], &t.src_addr) == 0) {
+ DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
+ return -1;
+ }
+ if (parse_ip_port(argv[1], &t.dst_addr) == 0) {
+ DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[1]));
+ return -1;
+ }
+
+ data.dptr = (uint8_t *)&t;
+ data.dsize = sizeof(t);
+
+ /* tell all nodes about this tcp connection */
+ ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_TCP_REMOVE,
+ 0, data, ctdb, NULL, NULL, NULL, NULL);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,("Failed to remove tickle\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
/*
get a list of all tickles for this pnn
*/
{ "gettickles", control_get_tickles, false, false, "get the list of tickles registered for this ip", "<ip>" },
{ "addtickle", control_add_tickle, false, false, "add a tickle for this ip", "<ip>:<port> <ip>:<port>" },
+ { "deltickle", control_del_tickle, false, false, "delete a tickle from this ip", "<ip>:<port> <ip>:<port>" },
+
{ "regsrvid", regsrvid, false, false, "register a server id", "<pnn> <type> <id>" },
{ "unregsrvid", unregsrvid, false, false, "unregister a server id", "<pnn> <type> <id>" },
{ "chksrvid", chksrvid, false, false, "check if a server id exists", "<pnn> <type> <id>" },