From: Ondřej Surý Date: Thu, 22 Oct 2020 10:32:18 +0000 (+0200) Subject: Postpone the isc_app_shutdown() after rndc response has been sent X-Git-Tag: v9.17.7~46^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64e56a9704e7dbe7579b7f1dbc71e0bf57028975;p=thirdparty%2Fbind9.git Postpone the isc_app_shutdown() after rndc response has been sent When `rndc stop` is received, the isc_app_shutdown() was being called before response to the rndc client has been sent; as the isc_app_shutdown() also tears down the netmgr, the message was never sent and rndc would complain about connection being interrupted in the middle of the transaction. We now postpone the shutdown after the rndc response has been sent. --- diff --git a/bin/named/control.c b/bin/named/control.c index 3320a8fe9db..55a469925d2 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -183,8 +183,7 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly, /* Do not flush master files */ named_server_flushonshutdown(named_g_server, false); named_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; + result = ISC_R_SHUTTINGDOWN; } else if (command_compare(command, NAMED_COMMAND_STOP)) { /* * "stop" is the same as "halt" except it does @@ -201,8 +200,7 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly, #endif /* ifdef HAVE_LIBSCF */ named_server_flushonshutdown(named_g_server, true); named_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; + result = ISC_R_SHUTTINGDOWN; } else if (command_compare(command, NAMED_COMMAND_ADDZONE) || command_compare(command, NAMED_COMMAND_MODZONE)) { diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 4bfa6af4c18..871cb459b7b 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -225,6 +226,11 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { conn->sending = false; + if (conn->result == ISC_R_SHUTTINGDOWN) { + isc_app_shutdown(); + goto cleanup_sendhandle; + } + if (atomic_load_acquire(&listener->controls->shuttingdown) || result == ISC_R_CANCELED) { @@ -284,12 +290,12 @@ conn_cleanup(controlconnection_t *conn) { } static void -control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) { - controlconnection_t *conn = (controlconnection_t *)arg; +control_respond(isc_nmhandle_t *handle, controlconnection_t *conn) { controllistener_t *listener = conn->listener; isccc_sexpr_t *data = NULL; isc_buffer_t b; isc_region_t r; + isc_result_t result; result = isccc_cc_createresponse(conn->request, conn->now, conn->now + 60, &conn->response); @@ -297,17 +303,22 @@ control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) { goto cleanup; } + if (conn->result == ISC_R_SHUTTINGDOWN) { + result = ISC_R_SUCCESS; + } else { + result = conn->result; + } + data = isccc_alist_lookup(conn->response, "_data"); if (data != NULL) { - if (isccc_cc_defineuint32(data, "result", conn->result) == NULL) - { + if (isccc_cc_defineuint32(data, "result", result) == NULL) { goto cleanup; } } - if (conn->result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS) { if (data != NULL) { - const char *estr = isc_result_totext(conn->result); + const char *estr = isc_result_totext(result); if (isccc_cc_definestring(data, "err", estr) == NULL) { goto cleanup; } @@ -380,7 +391,7 @@ control_command(isc_task_t *task, isc_event_t *event) { conn->result = named_control_docommand(conn->request, listener->readonly, &conn->text); - control_respond(conn->cmdhandle, conn->result, conn); + control_respond(conn->cmdhandle, conn); done: isc_event_free(&event); @@ -521,7 +532,7 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) { isc_nonce_buf(&conn->nonce, sizeof(conn->nonce)); } conn->result = ISC_R_SUCCESS; - control_respond(handle, result, conn); + control_respond(handle, conn); return; }