mirror of
https://github.com/samba-team/samba.git
synced 2025-09-10 05:44:20 +03:00
s3:smbd: avoid invalid lock_order panic triggered by "CTDB_SRVID_RELEASE_IP"
If smbd_server_connection_terminate("CTDB_SRVID_RELEASE_IP") is triggered from within ctdbd_migrate(), we got a smb_panic complaining about invalid lock_order, as ctdbd_migrate is called from dbwrap_fetch_locked(). Bug: https://bugzilla.samba.org/show_bug.cgi?id=10444 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org> Autobuild-User(master): Stefan Metzmacher <metze@samba.org> Autobuild-Date(master): Fri Feb 21 14:51:51 CET 2014 on sn-devel-104
This commit is contained in:
@@ -2503,9 +2503,28 @@ static void smbd_server_echo_handler(struct tevent_context *ev,
|
|||||||
|
|
||||||
struct smbd_release_ip_state {
|
struct smbd_release_ip_state {
|
||||||
struct smbd_server_connection *sconn;
|
struct smbd_server_connection *sconn;
|
||||||
|
struct tevent_immediate *im;
|
||||||
char addr[INET6_ADDRSTRLEN];
|
char addr[INET6_ADDRSTRLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void smbd_release_ip_immediate(struct tevent_context *ctx,
|
||||||
|
struct tevent_immediate *im,
|
||||||
|
void *private_data)
|
||||||
|
{
|
||||||
|
struct smbd_release_ip_state *state =
|
||||||
|
talloc_get_type_abort(private_data,
|
||||||
|
struct smbd_release_ip_state);
|
||||||
|
|
||||||
|
if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
|
||||||
|
/*
|
||||||
|
* smbd_server_connection_terminate() already triggered ?
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
received when we should release a specific IP
|
received when we should release a specific IP
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -2517,6 +2536,11 @@ static bool release_ip(const char *ip, void *priv)
|
|||||||
const char *addr = state->addr;
|
const char *addr = state->addr;
|
||||||
const char *p = addr;
|
const char *p = addr;
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(state->sconn->status)) {
|
||||||
|
/* avoid recursion */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp("::ffff:", addr, 7) == 0) {
|
if (strncmp("::ffff:", addr, 7) == 0) {
|
||||||
p = addr + 7;
|
p = addr + 7;
|
||||||
}
|
}
|
||||||
@@ -2543,9 +2567,18 @@ static bool release_ip(const char *ip, void *priv)
|
|||||||
* triggered and has implication on our process model,
|
* triggered and has implication on our process model,
|
||||||
* we can just use smbd_server_connection_terminate()
|
* we can just use smbd_server_connection_terminate()
|
||||||
* (also for SMB1).
|
* (also for SMB1).
|
||||||
|
*
|
||||||
|
* We don't call smbd_server_connection_terminate() directly
|
||||||
|
* as we might be called from within ctdbd_migrate(),
|
||||||
|
* we need to defer our action to the next event loop
|
||||||
*/
|
*/
|
||||||
smbd_server_connection_terminate(state->sconn,
|
tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
|
||||||
"CTDB_SRVID_RELEASE_IP");
|
smbd_release_ip_immediate, state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure we don't get any io on the connection.
|
||||||
|
*/
|
||||||
|
state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2569,6 +2602,10 @@ static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
|
|||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
state->sconn = sconn;
|
state->sconn = sconn;
|
||||||
|
state->im = tevent_create_immediate(state);
|
||||||
|
if (state->im == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
|
if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user