1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +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:
Stefan Metzmacher 2014-02-13 15:36:27 +01:00
parent 9677fae6aa
commit 33f10d06ba

View File

@ -2503,9 +2503,28 @@ static void smbd_server_echo_handler(struct tevent_context *ev,
struct smbd_release_ip_state {
struct smbd_server_connection *sconn;
struct tevent_immediate *im;
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
****************************************************************************/
@ -2517,6 +2536,11 @@ static bool release_ip(const char *ip, void *priv)
const char *addr = state->addr;
const char *p = addr;
if (!NT_STATUS_IS_OK(state->sconn->status)) {
/* avoid recursion */
return false;
}
if (strncmp("::ffff:", addr, 7) == 0) {
p = addr + 7;
}
@ -2543,9 +2567,18 @@ static bool release_ip(const char *ip, void *priv)
* triggered and has implication on our process model,
* we can just use smbd_server_connection_terminate()
* (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,
"CTDB_SRVID_RELEASE_IP");
tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
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;
}
@ -2569,6 +2602,10 @@ static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
return NT_STATUS_NO_MEMORY;
}
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) {
return NT_STATUS_NO_MEMORY;
}