1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-25 17:57:42 +03:00

messaging: Do POOL_USAGE via a socket

This makes debugging run-away processes much more efficient and even
possible at all: If the pool-usage output is more than 256MB, the
previous code could not realloc it and threw it away. Also, it is not
helpful for an already huge process to allocate even more.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Sep 18 21:27:30 UTC 2019 on sn-devel-184
This commit is contained in:
Volker Lendecke 2019-08-30 15:08:40 +02:00 committed by Jeremy Allison
parent 23bee5da95
commit bc4e8b1aba
4 changed files with 90 additions and 112 deletions

View File

@ -18,92 +18,69 @@
#include "includes.h"
#include "messages.h"
#include "lib/util/talloc_report.h"
#include "lib/util/talloc_report_printf.h"
#ifdef HAVE_MALLINFO
#include <malloc.h>
#endif /* HAVE_MALLINFO */
/**
* Prepare memory allocation report based on mallinfo()
**/
static char *get_mallinfo_report(void *mem_ctx)
static bool pool_usage_filter(struct messaging_rec *rec, void *private_data)
{
char *report = NULL;
#ifdef HAVE_MALLINFO
struct mallinfo mi;
if (rec->msg_type != MSG_REQ_POOL_USAGE) {
return false;
}
mi = mallinfo();
report = talloc_asprintf(mem_ctx,
"mallinfo:\n"
" arena: %d\n"
" ordblks: %d\n"
" smblks: %d\n"
" hblks: %d\n"
" hblkhd: %d\n"
" usmblks: %d\n"
" fsmblks: %d\n"
" uordblks: %d\n"
" fordblks: %d\n"
" keepcost: %d\n",
mi.arena,
mi.ordblks,
mi.smblks,
mi.hblks,
mi.hblkhd,
mi.usmblks,
mi.fsmblks,
mi.uordblks,
mi.fordblks,
mi.keepcost);
#endif /* HAVE_MALLINFO */
DBG_DEBUG("Got MSG_REQ_POOL_USAGE\n");
return report;
if (rec->num_fds != 1) {
DBG_DEBUG("Got %"PRIu8" fds, expected one\n", rec->num_fds);
return false;
}
return true;
}
/**
* Respond to a POOL_USAGE message by sending back string form of memory
* usage stats.
**/
static void msg_pool_usage(struct messaging_context *msg_ctx,
void *private_data,
uint32_t msg_type,
struct server_id src,
DATA_BLOB *data)
static void msg_pool_usage_do(struct tevent_req *req)
{
char *report = NULL;
char *mreport = NULL;
int iov_size = 0;
struct iovec iov[2];
struct messaging_context *msg_ctx = tevent_req_callback_data(
req, struct messaging_context);
struct messaging_rec *rec = NULL;
FILE *f = NULL;
int ret;
SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE);
DEBUG(2,("Got POOL_USAGE\n"));
report = talloc_report_str(msg_ctx, NULL);
if (report != NULL) {
iov[iov_size].iov_base = report;
iov[iov_size].iov_len = talloc_get_size(report) - 1;
iov_size++;
ret = messaging_filtered_read_recv(req, talloc_tos(), &rec);
TALLOC_FREE(req);
if (ret != 0) {
DBG_DEBUG("messaging_filtered_read_recv returned %s\n",
strerror(ret));
return;
}
mreport = get_mallinfo_report(msg_ctx);
if (mreport != NULL) {
iov[iov_size].iov_base = mreport;
iov[iov_size].iov_len = talloc_get_size(mreport) - 1;
iov_size++;
f = fdopen(rec->fds[0], "w");
if (f == NULL) {
close(rec->fds[0]);
TALLOC_FREE(rec);
DBG_DEBUG("fdopen failed: %s\n", strerror(errno));
}
if (iov_size) {
messaging_send_iov(msg_ctx,
src,
MSG_POOL_USAGE,
iov,
iov_size,
NULL,
0);
}
TALLOC_FREE(rec);
TALLOC_FREE(report);
TALLOC_FREE(mreport);
talloc_full_report_printf(NULL, f);
fclose(f);
f = NULL;
req = messaging_filtered_read_send(
msg_ctx,
messaging_tevent_context(msg_ctx),
msg_ctx,
pool_usage_filter,
NULL);
if (req == NULL) {
DBG_WARNING("messaging_filtered_read_send failed\n");
return;
}
tevent_req_set_callback(req, msg_pool_usage_do, msg_ctx);
}
/**
@ -111,6 +88,18 @@ static void msg_pool_usage(struct messaging_context *msg_ctx,
**/
void register_msg_pool_usage(struct messaging_context *msg_ctx)
{
messaging_register(msg_ctx, NULL, MSG_REQ_POOL_USAGE, msg_pool_usage);
struct tevent_req *req = NULL;
req = messaging_filtered_read_send(
msg_ctx,
messaging_tevent_context(msg_ctx),
msg_ctx,
pool_usage_filter,
NULL);
if (req == NULL) {
DBG_WARNING("messaging_filtered_read_send failed\n");
return;
}
tevent_req_set_callback(req, msg_pool_usage_do, msg_ctx);
DEBUG(2, ("Registered MSG_REQ_POOL_USAGE\n"));
}
}

View File

@ -125,18 +125,6 @@ static void print_pid_string_cb(struct messaging_context *msg,
num_replies++;
}
/* Message handler callback that displays a string on stdout */
static void print_string_cb(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id pid,
DATA_BLOB *data)
{
printf("%*s", (int)data->length, (const char *)data->data);
num_replies++;
}
/* Send no message. Useful for testing. */
static bool do_noop(struct tevent_context *ev_ctx,
@ -861,31 +849,32 @@ static bool do_ip_dropped(struct tevent_context *ev_ctx,
static bool do_poolusage(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx,
const struct server_id pid,
const struct server_id dst,
const int argc, const char **argv)
{
pid_t pid = procid_to_pid(&dst);
int stdout_fd = 1;
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> pool-usage\n");
return False;
}
messaging_register(msg_ctx, NULL, MSG_POOL_USAGE, print_string_cb);
if (pid == 0) {
fprintf(stderr, "Can only send to a specific PID\n");
return false;
}
/* Send a message and register our interest in a reply */
messaging_send_iov(
msg_ctx,
dst,
MSG_REQ_POOL_USAGE,
NULL,
0,
&stdout_fd,
1);
if (!send_message(msg_ctx, pid, MSG_REQ_POOL_USAGE, NULL, 0))
return False;
wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
if (num_replies == 0)
printf("No replies received\n");
messaging_deregister(msg_ctx, MSG_POOL_USAGE, NULL);
return num_replies;
return true;
}
/* Fetch and print the ringbuf log */

View File

@ -429,7 +429,7 @@ bld.SAMBA3_SUBSYSTEM('samba3core',
server_id_db
messages_util
messages_dgm
talloc_report
talloc_report_printf
access
TDB_LIB
''')

View File

@ -35,7 +35,7 @@
#include "../lib/util/tevent_ntstatus.h"
#include "lib/param/param.h"
#include "lib/util/server_id_db.h"
#include "lib/util/talloc_report.h"
#include "lib/util/talloc_report_printf.h"
#include "../source3/lib/messages_dgm.h"
#include "../source3/lib/messages_dgm_ref.h"
#include "../source3/lib/messages_util.h"
@ -108,21 +108,21 @@ static void pool_message(struct imessaging_context *msg,
int *fds,
DATA_BLOB *data)
{
char *report;
FILE *f = NULL;
if (num_fds != 0) {
if (num_fds != 1) {
DBG_WARNING("Received %zu fds, ignoring message\n", num_fds);
return;
}
report = talloc_report_str(msg, NULL);
if (report != NULL) {
DATA_BLOB blob = { .data = (uint8_t *)report,
.length = talloc_get_size(report) - 1};
imessaging_send(msg, src, MSG_POOL_USAGE, &blob);
f = fdopen(fds[0], "w");
if (f == NULL) {
DBG_DEBUG("fopen failed: %s\n", strerror(errno));
return;
}
talloc_free(report);
talloc_full_report_printf(NULL, f);
fclose(f);
}
static void ringbuf_log_msg(struct imessaging_context *msg,