diff options
Diffstat (limited to 'source/lib/tallocmsg.c')
-rw-r--r-- | source/lib/tallocmsg.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/source/lib/tallocmsg.c b/source/lib/tallocmsg.c index b515093cd69..0f493538f3c 100644 --- a/source/lib/tallocmsg.c +++ b/source/lib/tallocmsg.c @@ -25,31 +25,75 @@ * Glue code between talloc profiling and the Samba messaging system. **/ +struct msg_pool_usage_state { + TALLOC_CTX *mem_ctx; + ssize_t len; + size_t buflen; + char *s; +}; + +static void msg_pool_usage_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_s) +{ + const char *name = talloc_get_name(ptr); + struct msg_pool_usage_state *state = (struct msg_pool_usage_state *)_s; + + if (is_ref) { + sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, + "%*sreference to: %s\n", depth*4, "", name); + return; + } + + if (depth == 0) { + sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, + "%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", + (max_depth < 0 ? "full " :""), name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr)); + return; + } + + sprintf_append(state->mem_ctx, &state->s, &state->len, &state->buflen, + "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", + depth*4, "", + name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr), + talloc_reference_count(ptr)); +} /** * Respond to a POOL_USAGE message by sending back string form of memory * usage stats. **/ void msg_pool_usage(int msg_type, struct process_id src_pid, - void *UNUSED(buf), size_t UNUSED(len)) + void *UNUSED(buf), size_t UNUSED(len), + void *private_data) { - char *reply = NULL; + struct msg_pool_usage_state state; SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE); DEBUG(2,("Got POOL_USAGE\n")); - reply = talloc_describe_all(); - if (!reply) { + state.mem_ctx = talloc_init("msg_pool_usage"); + if (!state.mem_ctx) { + return; + } + state.len = 0; + state.buflen = 512; + state.s = NULL; + + talloc_report_depth_cb(NULL, 0, -1, msg_pool_usage_helper, &state); + + if (!state.s) { + talloc_destroy(state.mem_ctx); return; } - become_root(); message_send_pid(src_pid, MSG_POOL_USAGE, - reply, strlen(reply)+1, True); - unbecome_root(); + state.s, strlen(state.s)+1, True); - SAFE_FREE(reply); + talloc_destroy(state.mem_ctx); } /** @@ -57,6 +101,6 @@ void msg_pool_usage(int msg_type, struct process_id src_pid, **/ void register_msg_pool_usage(void) { - message_register(MSG_REQ_POOL_USAGE, msg_pool_usage); + message_register(MSG_REQ_POOL_USAGE, msg_pool_usage, NULL); DEBUG(2, ("Registered MSG_REQ_POOL_USAGE\n")); } |