1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

added code to kill registered clients on a IP release

(This used to be ctdb commit ca0243b544987ce0618a99ac87b4abf598991e93)
This commit is contained in:
Andrew Tridgell 2007-06-19 03:54:06 +10:00
parent f532ada445
commit 6399cf9542
5 changed files with 69 additions and 6 deletions

View File

@ -101,6 +101,7 @@ struct ctdb_client {
int fd;
struct ctdb_queue *queue;
uint32_t client_id;
pid_t pid;
struct ctdb_tcp_list *tcp_list;
};
@ -267,7 +268,6 @@ struct ctdb_takeover {
TALLOC_CTX *last_ctx;
};
/* main state of the ctdb daemon */
struct ctdb_context {
struct event_context *ev;
@ -306,6 +306,7 @@ struct ctdb_context {
struct ctdb_call_state *pending_calls;
struct ctdb_takeover takeover;
struct ctdb_tcp_list *tcp_list;
struct ctdb_client_ip *client_ip_list;
};
struct ctdb_db_context {
@ -926,7 +927,7 @@ int32_t ctdb_control_thaw(struct ctdb_context *ctdb);
int ctdb_start_recoverd(struct ctdb_context *ctdb);
uint32_t ctdb_get_num_enabled_nodes(struct ctdb_context *ctdb);
uint32_t ctdb_get_num_active_nodes(struct ctdb_context *ctdb);
void ctdb_stop_monitoring(struct ctdb_context *ctdb);
void ctdb_start_monitoring(struct ctdb_context *ctdb);

View File

@ -211,6 +211,14 @@ int daemon_register_message_handler(struct ctdb_context *ctdb, uint32_t client_i
DEBUG(2,(__location__ " Registered message handler for srvid=%llu\n",
(unsigned long long)srvid));
}
/* this is a hack for Samba - we now know the pid of the Samba client */
if ((srvid & 0xFFFFFFFF) == srvid &&
kill(srvid, 0) == 0) {
client->pid = srvid;
DEBUG(0,(__location__ " Registered PID %u for client %u\n",
(unsigned)client->pid, client_id));
}
return res;
}

View File

@ -193,15 +193,15 @@ int ctdb_set_address(struct ctdb_context *ctdb, const char *address)
/*
return the number of enabled nodes
return the number of active nodes
*/
uint32_t ctdb_get_num_enabled_nodes(struct ctdb_context *ctdb)
uint32_t ctdb_get_num_active_nodes(struct ctdb_context *ctdb)
{
int i;
uint32_t count=0;
for (i=0;i<ctdb->vnn_map->size;i++) {
struct ctdb_node *node = ctdb->nodes[ctdb->vnn_map->map[i]];
if (!(node->flags & (NODE_FLAGS_INACTIVE|NODE_FLAGS_DISABLED))) {
if (!(node->flags & NODE_FLAGS_INACTIVE)) {
count++;
}
}

View File

@ -373,7 +373,7 @@ int32_t ctdb_control_traverse_data(struct ctdb_context *ctdb, TDB_DATA data, TDB
if (key.dsize == 0 && data.dsize == 0) {
state->null_count++;
if (state->null_count != ctdb_get_num_enabled_nodes(ctdb)) {
if (state->null_count != ctdb_get_num_active_nodes(ctdb)) {
return 0;
}
}

View File

@ -51,6 +51,16 @@ struct ctdb_tcp_list {
};
/*
list of clients to kill on IP release
*/
struct ctdb_client_ip {
struct ctdb_client_ip *prev, *next;
struct ctdb_context *ctdb;
struct sockaddr_in ip;
uint32_t client_id;
};
/*
send a gratuitous arp
@ -211,6 +221,27 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
return 0;
}
/*
kill any clients that are registered with a IP that is being released
*/
static void release_kill_clients(struct ctdb_context *ctdb, struct sockaddr_in *sin)
{
struct ctdb_client_ip *ip;
for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
if (ip->ip.sin_addr.s_addr == sin->sin_addr.s_addr) {
struct ctdb_client *client = ctdb_reqid_find(ctdb,
ip->client_id,
struct ctdb_client);
if (client->pid != 0) {
DEBUG(0,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
(unsigned)client->pid, inet_ntoa(sin->sin_addr),
ip->client_id));
kill(client->pid, SIGKILL);
}
}
}
}
/*
called when releaseip event finishes
@ -234,6 +265,10 @@ static void release_ip_callback(struct ctdb_context *ctdb, int status,
ctdb_daemon_send_message(ctdb, ctdb->vnn, CTDB_SRVID_RELEASE_IP, data);
/* kill clients that have registered with this IP */
release_kill_clients(ctdb, state->sin);
/* tell other nodes about any tcp connections we were holding with this IP */
for (tcp=ctdb->tcp_list;tcp;tcp=tcp->next) {
if (tcp->vnn == ctdb->vnn &&
@ -527,6 +562,15 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
}
/*
destroy a ctdb_client_ip structure
*/
static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
{
DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
return 0;
}
/*
called by a client to inform us of a TCP connection that it is managing
that should tickled with an ACK when IP takeover is done
@ -540,6 +584,16 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id, u
struct ctdb_control_tcp_vnn t;
int ret;
TDB_DATA data;
struct ctdb_client_ip *ip;
ip = talloc(client, struct ctdb_client_ip);
CTDB_NO_MEMORY(ctdb, ip);
ip->ctdb = ctdb;
ip->ip = p->dest;
ip->client_id = client_id;
talloc_set_destructor(ip, ctdb_client_ip_destructor);
DLIST_ADD(ctdb->client_ip_list, ip);
tcp = talloc(client, struct ctdb_tcp_list);
CTDB_NO_MEMORY(ctdb, tcp);