mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
add a rndc command to toggle jemalloc profiling
The new command is `rndc memprof`. The memory profiling status is also
reported inside `rndc status`. The status also shows whether named can
toggle memory profiling or not and if the server is built with jemalloc.
(cherry picked from commit b495e9918e)
This commit is contained in:
parent
5c27e9cdda
commit
dde251b773
6 changed files with 205 additions and 0 deletions
|
|
@ -229,6 +229,8 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly,
|
|||
command_compare(command, NAMED_COMMAND_SIGN))
|
||||
{
|
||||
result = named_server_rekey(named_g_server, lex, text);
|
||||
} else if (command_compare(command, NAMED_COMMAND_MEMPROF)) {
|
||||
result = named_server_togglememprof(lex);
|
||||
} else if (command_compare(command, NAMED_COMMAND_MKEYS)) {
|
||||
result = named_server_mkeys(named_g_server, lex, text);
|
||||
} else if (command_compare(command, NAMED_COMMAND_NOTIFY)) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#define NAMED_COMMAND_FREEZE "freeze"
|
||||
#define NAMED_COMMAND_HALT "halt"
|
||||
#define NAMED_COMMAND_LOADKEYS "loadkeys"
|
||||
#define NAMED_COMMAND_MEMPROF "memprof"
|
||||
#define NAMED_COMMAND_MKEYS "managed-keys"
|
||||
#define NAMED_COMMAND_MODZONE "modzone"
|
||||
#define NAMED_COMMAND_NOTIFY "notify"
|
||||
|
|
|
|||
|
|
@ -391,3 +391,15 @@ named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
|
|||
*/
|
||||
isc_result_t
|
||||
named_server_skr(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text);
|
||||
|
||||
/*%
|
||||
* Toggle memory profiling if supported.
|
||||
*/
|
||||
isc_result_t
|
||||
named_server_togglememprof(isc_lex_t *lex);
|
||||
|
||||
/*%
|
||||
* Get status of memory profiling.
|
||||
*/
|
||||
const char *
|
||||
named_server_getmemprof(void);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,15 @@
|
|||
#include <named/smf_globals.h>
|
||||
#endif /* ifdef HAVE_LIBSCF */
|
||||
|
||||
/* On DragonFly BSD the header does not provide jemalloc API */
|
||||
#if defined(HAVE_MALLOC_NP_H) && !defined(__DragonFly__)
|
||||
#include <malloc_np.h>
|
||||
#define JEMALLOC_API_SUPPORTED 1
|
||||
#elif defined(HAVE_JEMALLOC)
|
||||
#include <jemalloc/jemalloc.h>
|
||||
#define JEMALLOC_API_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LMDB
|
||||
#include <lmdb.h>
|
||||
#define configure_newzones configure_newzones_db
|
||||
|
|
@ -360,6 +369,22 @@ typedef struct {
|
|||
isc_result_t result;
|
||||
} ns_dzarg_t;
|
||||
|
||||
typedef enum {
|
||||
MEMPROF_UNSUPPORTED = 0x00,
|
||||
MEMPROF_INACTIVE = 0x01,
|
||||
MEMPROF_FAILING = 0x02,
|
||||
MEMPROF_OFF = 0x03,
|
||||
MEMPROF_ON = 0x04,
|
||||
} memprof_status;
|
||||
|
||||
static const char *memprof_status_text[] = {
|
||||
[MEMPROF_UNSUPPORTED] = "UNSUPPORTED",
|
||||
[MEMPROF_INACTIVE] = "INACTIVE",
|
||||
[MEMPROF_FAILING] = "FAILING",
|
||||
[MEMPROF_OFF] = "OFF",
|
||||
[MEMPROF_ON] = "ON",
|
||||
};
|
||||
|
||||
/*
|
||||
* These zones should not leak onto the Internet.
|
||||
*/
|
||||
|
|
@ -10715,6 +10740,39 @@ named_server_reloadwanted(void *arg, int signum) {
|
|||
isc_async_run(named_g_mainloop, named_server_reload, server);
|
||||
}
|
||||
|
||||
#ifdef JEMALLOC_API_SUPPORTED
|
||||
static isc_result_t
|
||||
memprof_toggle(bool active) {
|
||||
if (mallctl("prof.active", NULL, NULL, &active, sizeof(active)) != 0) {
|
||||
return ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
memprof_dump(void) {
|
||||
if (mallctl("prof.dump", NULL, NULL, NULL, 0) != 0) {
|
||||
return ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static isc_result_t
|
||||
memprof_toggle(bool active) {
|
||||
UNUSED(active);
|
||||
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
memprof_dump(void) {
|
||||
return ISC_R_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
#endif /* JEMALLOC_API_SUPPORTED */
|
||||
|
||||
void
|
||||
named_server_scan_interfaces(named_server_t *server) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
|
|
@ -12598,6 +12656,10 @@ named_server_status(named_server_t *server, isc_buffer_t **text) {
|
|||
: "OFF");
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "memory profiling is %s\n",
|
||||
named_server_getmemprof());
|
||||
CHECK(putstr(text, line));
|
||||
|
||||
snprintf(line, sizeof(line), "recursive clients: %u/%u/%u\n",
|
||||
isc_quota_getused(&server->sctx->recursionquota),
|
||||
isc_quota_getsoft(&server->sctx->recursionquota),
|
||||
|
|
@ -16821,3 +16883,114 @@ cleanup:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
named_server_togglememprof(isc_lex_t *lex) {
|
||||
isc_result_t result = ISC_R_FAILURE;
|
||||
bool active;
|
||||
char *ptr;
|
||||
|
||||
/* Skip the command name. */
|
||||
ptr = next_token(lex, NULL);
|
||||
if (ptr == NULL) {
|
||||
return ISC_R_UNEXPECTEDEND;
|
||||
}
|
||||
|
||||
ptr = next_token(lex, NULL);
|
||||
if (ptr == NULL) {
|
||||
return ISC_R_UNEXPECTEDEND;
|
||||
} else if (!strcasecmp(ptr, "dump")) {
|
||||
result = memprof_dump();
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||
"failed to dump memory profile");
|
||||
|
||||
} else {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
"memory profile dumped");
|
||||
}
|
||||
|
||||
goto done;
|
||||
} else if (!strcasecmp(ptr, "on") || !strcasecmp(ptr, "yes") ||
|
||||
!strcasecmp(ptr, "enable") || !strcasecmp(ptr, "true"))
|
||||
{
|
||||
active = true;
|
||||
} else if (!strcasecmp(ptr, "off") || !strcasecmp(ptr, "no") ||
|
||||
!strcasecmp(ptr, "disable") || !strcasecmp(ptr, "false"))
|
||||
{
|
||||
active = false;
|
||||
} else {
|
||||
return DNS_R_SYNTAX;
|
||||
}
|
||||
|
||||
result = memprof_toggle(active);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||
"failed to toggle memory profiling");
|
||||
} else {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
"memory profiling %s",
|
||||
active ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef JEMALLOC_API_SUPPORTED
|
||||
const char *
|
||||
named_server_getmemprof(void) {
|
||||
memprof_status status = MEMPROF_ON;
|
||||
bool is_enabled;
|
||||
size_t len = sizeof(is_enabled);
|
||||
|
||||
if (mallctl("config.prof", &is_enabled, &len, NULL, 0) != 0) {
|
||||
status = MEMPROF_FAILING;
|
||||
goto done;
|
||||
}
|
||||
|
||||
INSIST(len == sizeof(is_enabled));
|
||||
|
||||
if (!is_enabled) {
|
||||
status = MEMPROF_UNSUPPORTED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mallctl("opt.prof", &is_enabled, &len, NULL, 0) != 0) {
|
||||
status = MEMPROF_FAILING;
|
||||
goto done;
|
||||
}
|
||||
|
||||
INSIST(len == sizeof(is_enabled));
|
||||
|
||||
if (!is_enabled) {
|
||||
status = MEMPROF_INACTIVE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
len = sizeof(is_enabled);
|
||||
if (mallctl("prof.active", &is_enabled, &len, NULL, 0) != 0) {
|
||||
status = MEMPROF_FAILING;
|
||||
goto done;
|
||||
}
|
||||
|
||||
INSIST(len == sizeof(is_enabled));
|
||||
|
||||
if (!is_enabled) {
|
||||
status = MEMPROF_OFF;
|
||||
}
|
||||
|
||||
done:
|
||||
return memprof_status_text[status];
|
||||
}
|
||||
|
||||
#else /* JEMALLOC_API_SUPPORTED */
|
||||
const char *
|
||||
named_server_getmemprof(void) {
|
||||
return memprof_status_text[MEMPROF_UNSUPPORTED];
|
||||
}
|
||||
#endif /* JEMALLOC_API_SUPPORTED */
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ command is one of the following:\n\
|
|||
Display RFC 5011 managed keys information\n\
|
||||
managed-keys sync [class [view]]\n\
|
||||
Write RFC 5011 managed keys to disk\n\
|
||||
memprof [ on | off | dump ]\n\
|
||||
Enable / disable memory profiling or dump the profile.\n\
|
||||
Requires named to built with jemalloc and run with the relevant\n\
|
||||
MALLOC_CONF environment variables.\n\
|
||||
modzone zone [class [view]] { zone-options }\n\
|
||||
Modify a zone's configuration.\n\
|
||||
Requires allow-new-zones option.\n\
|
||||
|
|
|
|||
|
|
@ -313,6 +313,19 @@ Currently supported commands are:
|
|||
keys in the event of a trust anchor rollover, or as a brute-force
|
||||
repair for key maintenance problems.
|
||||
|
||||
.. option:: memprof [(on | off | dump)]
|
||||
|
||||
This command controls memory profiling. To have any effect, :iscman:`named` must be
|
||||
built with jemalloc, the library have profiling support enabled and run with the
|
||||
``prof:true`` allocator configuration. (either via ``MALLOC_CONF`` or ``/etc/malloc.conf``)
|
||||
|
||||
The ``prof_active:false`` option is recommended to ensure the profiling overhead does
|
||||
not affect :iscman:`named` when not needed.
|
||||
|
||||
The ``on`` and ``off`` options will start and stop the jemalloc memory profiling respectively.
|
||||
When run with the `dump` option, :iscman:`named` will dump the profile to the working
|
||||
directory. The name will be chosen automatically by jemalloc.
|
||||
|
||||
.. option:: modzone zone [class [view]] configuration
|
||||
|
||||
This command modifies the configuration of a zone while the server is running. This
|
||||
|
|
|
|||
Loading…
Reference in a new issue