#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;
-
- 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 */
+ if (rec->msg_type != MSG_REQ_POOL_USAGE) {
+ return false;
+ }
+
+ 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)
-{
- char *report = NULL;
- char *mreport = NULL;
- int iov_size = 0;
- struct iovec iov[2];
- SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE);
- DEBUG(2,("Got POOL_USAGE\n"));
+static void msg_pool_usage_do(struct tevent_req *req)
+{
+ struct messaging_context *msg_ctx = tevent_req_callback_data(
+ req, struct messaging_context);
+ struct messaging_rec *rec = NULL;
+ FILE *f = NULL;
+ int ret;
- 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_full_report_printf(NULL, f);
+
+ fclose(f);
+ f = NULL;
- TALLOC_FREE(report);
- TALLOC_FREE(mreport);
+ 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);
}
/**
**/
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"));
-}
+}
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,
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);
-
- /* Send a message and register our interest in a reply */
-
- 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");
+ if (pid == 0) {
+ fprintf(stderr, "Can only send to a specific PID\n");
+ return false;
+ }
- messaging_deregister(msg_ctx, MSG_POOL_USAGE, NULL);
+ messaging_send_iov(
+ msg_ctx,
+ dst,
+ MSG_REQ_POOL_USAGE,
+ NULL,
+ 0,
+ &stdout_fd,
+ 1);
- return num_replies;
+ return true;
}
/* Fetch and print the ringbuf log */
#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"
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,