mirror of
https://github.com/samba-team/samba.git
synced 2025-01-31 01:48:16 +03:00
ctdb: add/implement CTDB_CONTROL_TCP_CLIENT_PASSED
With multichannel a tcp connection is registered first with a temporary smbd process, that calls CTDB_CONTROL_TCP_CLIENT first and then passes the tcp connection to the longterm smbd that already handles all connections belonging to the specific client_guid. That smbd process calls CTDB_CONTROL_TCP_CLIENT again, but the 'tickle' information is already there. When the temporary smbd process exists/disconnects from ctdb or calls CTDB_CONTROL_TCP_CLIENT_DISCONNECTED, the 'tickle' information is removed, while the longterm smbd process still serves the tcp connection. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
parent
c6602b686b
commit
037e8e449d
@ -895,6 +895,9 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
|
|||||||
int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
|
int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
|
||||||
uint32_t client_id,
|
uint32_t client_id,
|
||||||
TDB_DATA indata);
|
TDB_DATA indata);
|
||||||
|
int32_t ctdb_control_tcp_client_passed(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);
|
bool tcp_update_needed);
|
||||||
int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata);
|
int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata);
|
||||||
|
@ -382,6 +382,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0,
|
|||||||
CTDB_CONTROL_DISABLE_NODE = 157,
|
CTDB_CONTROL_DISABLE_NODE = 157,
|
||||||
CTDB_CONTROL_ENABLE_NODE = 158,
|
CTDB_CONTROL_ENABLE_NODE = 158,
|
||||||
CTDB_CONTROL_TCP_CLIENT_DISCONNECTED = 159,
|
CTDB_CONTROL_TCP_CLIENT_DISCONNECTED = 159,
|
||||||
|
CTDB_CONTROL_TCP_CLIENT_PASSED = 160,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_COUNT_BUCKETS 16
|
#define MAX_COUNT_BUCKETS 16
|
||||||
|
@ -414,6 +414,10 @@ static size_t ctdb_req_control_data_len(struct ctdb_req_control_data *cd)
|
|||||||
case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
|
case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
|
||||||
len = ctdb_connection_len(cd->data.conn);
|
len = ctdb_connection_len(cd->data.conn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CTDB_CONTROL_TCP_CLIENT_PASSED:
|
||||||
|
len = ctdb_connection_len(cd->data.conn);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
@ -1028,6 +1032,14 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
|
|||||||
&cd->data.conn,
|
&cd->data.conn,
|
||||||
&np);
|
&np);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CTDB_CONTROL_TCP_CLIENT_PASSED:
|
||||||
|
ret = ctdb_connection_pull(buf,
|
||||||
|
buflen,
|
||||||
|
mem_ctx,
|
||||||
|
&cd->data.conn,
|
||||||
|
&np);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -1391,6 +1403,9 @@ static size_t ctdb_reply_control_data_len(struct ctdb_reply_control_data *cd)
|
|||||||
|
|
||||||
case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
|
case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CTDB_CONTROL_TCP_CLIENT_PASSED:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
@ -246,6 +246,7 @@ static void ctdb_opcode_print(uint32_t opcode, FILE *fp)
|
|||||||
{ CTDB_CONTROL_DISABLE_NODE, "DISABLE_NODE" },
|
{ CTDB_CONTROL_DISABLE_NODE, "DISABLE_NODE" },
|
||||||
{ CTDB_CONTROL_ENABLE_NODE, "ENABLE_NODE" },
|
{ CTDB_CONTROL_ENABLE_NODE, "ENABLE_NODE" },
|
||||||
{ CTDB_CONTROL_TCP_CLIENT_DISCONNECTED, "TCP_CLIENT_DISCONNECTED" },
|
{ CTDB_CONTROL_TCP_CLIENT_DISCONNECTED, "TCP_CLIENT_DISCONNECTED" },
|
||||||
|
{ CTDB_CONTROL_TCP_CLIENT_PASSED, "TCP_CLIENT_PASSED" },
|
||||||
{ MAP_END, "" },
|
{ MAP_END, "" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -872,6 +872,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
|
|||||||
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
|
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
|
||||||
return ctdb_control_tcp_client_disconnected(ctdb, client_id, indata);
|
return ctdb_control_tcp_client_disconnected(ctdb, client_id, indata);
|
||||||
|
|
||||||
|
case CTDB_CONTROL_TCP_CLIENT_PASSED:
|
||||||
|
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
|
||||||
|
return ctdb_control_tcp_client_passed(ctdb, client_id, indata);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
|
DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1463,6 +1463,55 @@ int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
called by a client to inform us of a TCP connection was passed to a different
|
||||||
|
"client" (typically with multichannel to another smbd process).
|
||||||
|
*/
|
||||||
|
int32_t ctdb_control_tcp_client_passed(struct ctdb_context *ctdb,
|
||||||
|
uint32_t client_id,
|
||||||
|
TDB_DATA indata)
|
||||||
|
{
|
||||||
|
struct ctdb_client *client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
|
||||||
|
struct ctdb_connection *tcp_sock = NULL;
|
||||||
|
int ret;
|
||||||
|
char conn_str[132] = { 0, };
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
tcp_sock = (struct ctdb_connection *)indata.dptr;
|
||||||
|
|
||||||
|
ctdb_canonicalize_ip_inplace(&tcp_sock->src);
|
||||||
|
ctdb_canonicalize_ip_inplace(&tcp_sock->dst);
|
||||||
|
|
||||||
|
ret = ctdb_connection_to_buf(conn_str,
|
||||||
|
sizeof(conn_str),
|
||||||
|
tcp_sock,
|
||||||
|
false,
|
||||||
|
" -> ");
|
||||||
|
if (ret != 0) {
|
||||||
|
strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
found = ctdb_client_remove_tcp(client, tcp_sock);
|
||||||
|
if (!found) {
|
||||||
|
DBG_DEBUG("TCP connection from %s not found "
|
||||||
|
"(client_id %u pid %u).\n",
|
||||||
|
conn_str, client_id, client->pid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
D_INFO("TCP connection from %s "
|
||||||
|
"(client_id %u pid %u) passed to another client\n",
|
||||||
|
conn_str, client_id, client->pid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't call CTDB_CONTROL_TCP_REMOVE
|
||||||
|
* nor ctdb_remove_connection() as the connection
|
||||||
|
* is still alive, but handled by another client
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
find a tcp address on a list
|
find a tcp address on a list
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user