mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
Added total memory allocated counter to talloc, so we can tell if a talloc
pool is getting bloated. Also added a talloc_zero function to return zeroed memory.
Added debug in rpc_server/srv_pipe_hnd.c so we know when a talloc pool is being
freed. Syncup with srv_pipe_hnd.c from 2.2 so we are freeing memory at the same time.
Jeremy.
(This used to be commit d3a56c6042
)
This commit is contained in:
parent
dbc5cace14
commit
5265ce7837
@ -367,6 +367,8 @@ TALLOC_CTX *talloc_init(void);
|
||||
void *talloc(TALLOC_CTX *t, size_t size);
|
||||
void talloc_destroy_pool(TALLOC_CTX *t);
|
||||
void talloc_destroy(TALLOC_CTX *t);
|
||||
size_t talloc_pool_size(TALLOC_CTX *t);
|
||||
void *talloc_zero(TALLOC_CTX *t, size_t size);
|
||||
|
||||
/*The following definitions come from lib/time.c */
|
||||
|
||||
@ -2398,7 +2400,11 @@ BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, in
|
||||
|
||||
/*The following definitions come from rpc_parse/parse_misc.c */
|
||||
|
||||
void parse_talloc_free(void);
|
||||
TALLOC_CTX *get_current_rpc_talloc(void);
|
||||
void set_current_rpc_talloc( TALLOC_CTX *ctx);
|
||||
void main_loop_talloc_free(void);
|
||||
TALLOC_CTX *main_loop_talloc_get(void);
|
||||
TALLOC_CTX *get_talloc_ctx(void);
|
||||
BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
|
||||
BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
|
||||
uint32 get_enum_hnd(ENUM_HND *enh);
|
||||
@ -3311,6 +3317,14 @@ BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int
|
||||
|
||||
BOOL api_netdfs_rpc(pipes_struct *p);
|
||||
|
||||
/*The following definitions come from rpc_server/srv_dfs_nt.c */
|
||||
|
||||
uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u);
|
||||
uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u);
|
||||
uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u);
|
||||
uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
|
||||
uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u);
|
||||
|
||||
/*The following definitions come from rpc_server/srv_lsa.c */
|
||||
|
||||
#if OLD_NTDOMAIN
|
||||
|
@ -36,6 +36,7 @@ struct talloc_chunk {
|
||||
|
||||
typedef struct {
|
||||
struct talloc_chunk *list;
|
||||
size_t total_alloc_size;
|
||||
} TALLOC_CTX;
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@ TALLOC_CTX *talloc_init(void)
|
||||
if (!t) return NULL;
|
||||
|
||||
t->list = NULL;
|
||||
t->total_alloc_size = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
@ -82,6 +83,7 @@ void *talloc(TALLOC_CTX *t, size_t size)
|
||||
c->alloc_size = 0;
|
||||
c->total_size = asize;
|
||||
t->list = c;
|
||||
t->total_alloc_size += asize;
|
||||
}
|
||||
|
||||
p = ((char *)t->list->ptr) + t->list->alloc_size;
|
||||
@ -107,6 +109,7 @@ void talloc_destroy_pool(TALLOC_CTX *t)
|
||||
}
|
||||
|
||||
t->list = NULL;
|
||||
t->total_alloc_size = 0;
|
||||
}
|
||||
|
||||
/* destroy a whole pool including the context */
|
||||
@ -117,3 +120,22 @@ void talloc_destroy(TALLOC_CTX *t)
|
||||
talloc_destroy_pool(t);
|
||||
free(t);
|
||||
}
|
||||
|
||||
/* return the current total size of the pool. */
|
||||
size_t talloc_pool_size(TALLOC_CTX *t)
|
||||
{
|
||||
if (!t->list)
|
||||
return 0;
|
||||
return t->total_alloc_size;
|
||||
}
|
||||
|
||||
/* talloc and zero memory. */
|
||||
void *talloc_zero(TALLOC_CTX *t, size_t size)
|
||||
{
|
||||
void *p = talloc(t, size);
|
||||
|
||||
if (p)
|
||||
memset(p, '\0', size);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -708,7 +708,7 @@ static BOOL lsa_io_dom_query_2(char *desc, DOM_QUERY_2 *d_q, prs_struct *ps, int
|
||||
return False;
|
||||
|
||||
if (UNMARSHALLING(ps)) {
|
||||
d_q->auditsettings = (uint32 *)talloc(ps->mem_ctx, d_q->count2 * sizeof(uint32));
|
||||
d_q->auditsettings = (uint32 *)talloc_zero(ps->mem_ctx, d_q->count2 * sizeof(uint32));
|
||||
}
|
||||
|
||||
if (d_q->auditsettings == NULL) {
|
||||
@ -829,13 +829,13 @@ void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
|
||||
|
||||
if (num_entries == 0) return;
|
||||
|
||||
if ((sen->ptr_sid = (uint32 *)talloc(mem_ctx, num_entries *
|
||||
if ((sen->ptr_sid = (uint32 *)talloc_zero(mem_ctx, num_entries *
|
||||
sizeof(uint32))) == NULL) {
|
||||
DEBUG(3, ("init_lsa_sid_enum(): out of memory for ptr_sid\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sen->sid = (DOM_SID2 *)talloc(mem_ctx, num_entries *
|
||||
if ((sen->sid = (DOM_SID2 *)talloc_zero(mem_ctx, num_entries *
|
||||
sizeof(DOM_SID2))) == NULL) {
|
||||
DEBUG(3, ("init_lsa_sid_enum(): out of memory for sids\n"));
|
||||
return;
|
||||
@ -1070,13 +1070,13 @@ void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l,
|
||||
q_l->num_entries2 = num_names;
|
||||
q_l->lookup_level = 1;
|
||||
|
||||
if ((q_l->uni_name = (UNISTR2 *)talloc(
|
||||
if ((q_l->uni_name = (UNISTR2 *)talloc_zero(
|
||||
mem_ctx, num_names * sizeof(UNISTR2))) == NULL) {
|
||||
DEBUG(3, ("init_q_lookup_names(): out of memory\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((q_l->hdr_name = (UNIHDR *)talloc(
|
||||
if ((q_l->hdr_name = (UNIHDR *)talloc_zero(
|
||||
mem_ctx, num_names * sizeof(UNIHDR))) == NULL) {
|
||||
DEBUG(3, ("init_q_lookup_names(): out of memory\n"));
|
||||
return;
|
||||
|
@ -26,18 +26,66 @@
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
static TALLOC_CTX *parse_misc_talloc = NULL;
|
||||
/****************************************************************************
|
||||
A temporary TALLOC context for things like unistrs, that is valid for
|
||||
the life of a complete RPC call.
|
||||
****************************************************************************/
|
||||
|
||||
/******************************************************************* a
|
||||
static TALLOC_CTX *current_rpc_talloc = NULL;
|
||||
|
||||
TALLOC_CTX *get_current_rpc_talloc(void)
|
||||
{
|
||||
return current_rpc_talloc;
|
||||
}
|
||||
|
||||
void set_current_rpc_talloc( TALLOC_CTX *ctx)
|
||||
{
|
||||
current_rpc_talloc = ctx;
|
||||
}
|
||||
|
||||
static TALLOC_CTX *main_loop_talloc = NULL;
|
||||
|
||||
/*******************************************************************
|
||||
free up temporary memory - called from the main loop
|
||||
********************************************************************/
|
||||
|
||||
void parse_talloc_free(void)
|
||||
void main_loop_talloc_free(void)
|
||||
{
|
||||
if (!parse_misc_talloc)
|
||||
if (!main_loop_talloc)
|
||||
return;
|
||||
talloc_destroy(parse_misc_talloc);
|
||||
parse_misc_talloc = NULL;
|
||||
talloc_destroy(main_loop_talloc);
|
||||
main_loop_talloc = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Get a talloc context that is freed in the main loop...
|
||||
********************************************************************/
|
||||
|
||||
TALLOC_CTX *main_loop_talloc_get(void)
|
||||
{
|
||||
if (!main_loop_talloc) {
|
||||
main_loop_talloc = talloc_init();
|
||||
if (!main_loop_talloc)
|
||||
smb_panic("main_loop_talloc: malloc fail\n");
|
||||
}
|
||||
|
||||
return main_loop_talloc;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Try and get a talloc context. Get the rpc one if possible, else
|
||||
get the main loop one. The main loop one is more dangerous as it
|
||||
goes away between packets, the rpc one will stay around for as long
|
||||
as a current RPC lasts.
|
||||
********************************************************************/
|
||||
|
||||
TALLOC_CTX *get_talloc_ctx(void)
|
||||
{
|
||||
TALLOC_CTX *tc = get_current_rpc_talloc();
|
||||
|
||||
if (tc)
|
||||
return tc;
|
||||
return main_loop_talloc_get();
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -483,19 +531,14 @@ void init_unistr(UNISTR *str, const char *buf)
|
||||
|
||||
len = strlen(buf) + 1;
|
||||
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_UNISTRLEN)
|
||||
len = MAX_UNISTRLEN;
|
||||
len *= sizeof(uint16);
|
||||
|
||||
str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
|
||||
str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
|
||||
if (str->buffer == NULL)
|
||||
smb_panic("init_unistr: malloc fail\n");
|
||||
|
||||
memset(str->buffer, '\0', len);
|
||||
|
||||
/* store the string (null-terminated copy) */
|
||||
dos_struni2((char *)str->buffer, buf, len);
|
||||
}
|
||||
@ -527,15 +570,12 @@ BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
|
||||
|
||||
static void create_buffer3(BUFFER3 *str, size_t len)
|
||||
{
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_BUFFERLEN)
|
||||
len = MAX_BUFFERLEN;
|
||||
|
||||
str->buffer = talloc(parse_misc_talloc, len);
|
||||
str->buffer = talloc_zero(get_talloc_ctx(), len);
|
||||
if (str->buffer == NULL)
|
||||
smb_panic("create_buffer3: malloc fail\n");
|
||||
smb_panic("create_buffer3: talloc fail\n");
|
||||
|
||||
}
|
||||
|
||||
@ -673,14 +713,11 @@ void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
|
||||
str->buf_len = buf != NULL ? len : 0;
|
||||
|
||||
if (buf != NULL) {
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_BUFFERLEN)
|
||||
len = MAX_BUFFERLEN;
|
||||
str->buffer = talloc(parse_misc_talloc, len);
|
||||
str->buffer = talloc_zero(get_talloc_ctx(), len);
|
||||
if (str->buffer == NULL)
|
||||
smb_panic("init_buffer2: malloc fail\n");
|
||||
smb_panic("init_buffer2: talloc fail\n");
|
||||
memcpy(str->buffer, buf, MIN(str->buf_len, len));
|
||||
}
|
||||
}
|
||||
@ -767,17 +804,14 @@ void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
|
||||
if (str->buffer == NULL) {
|
||||
size_t len = from->uni_max_len * sizeof(uint16);
|
||||
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_UNISTRLEN)
|
||||
len = MAX_UNISTRLEN;
|
||||
len *= sizeof(uint16);
|
||||
|
||||
str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
|
||||
str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
|
||||
if ((str->buffer == NULL) && (len > 0 ))
|
||||
{
|
||||
smb_panic("copy_unistr2: malloc fail\n");
|
||||
smb_panic("copy_unistr2: talloc fail\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -801,12 +835,9 @@ void init_string2(STRING2 *str, char *buf, int len)
|
||||
|
||||
/* store the string */
|
||||
if(len != 0) {
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_STRINGLEN)
|
||||
alloc_len = MAX_STRINGLEN;
|
||||
str->buffer = talloc(parse_misc_talloc, alloc_len);
|
||||
str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
|
||||
if (str->buffer == NULL)
|
||||
smb_panic("init_string2: malloc fail\n");
|
||||
memcpy(str->buffer, buf, len);
|
||||
@ -869,14 +900,11 @@ void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
|
||||
str->undoc = 0;
|
||||
str->uni_str_len = (uint32)len;
|
||||
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
if (len < MAX_UNISTRLEN)
|
||||
len = MAX_UNISTRLEN;
|
||||
len *= sizeof(uint16);
|
||||
|
||||
str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
|
||||
str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
|
||||
if ((str->buffer == NULL) && (len > 0))
|
||||
{
|
||||
smb_panic("init_unistr2: malloc fail\n");
|
||||
@ -917,11 +945,8 @@ void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from)
|
||||
to->undoc = 0;
|
||||
to->uni_str_len = i;
|
||||
|
||||
if (!parse_misc_talloc)
|
||||
parse_misc_talloc = talloc_init();
|
||||
|
||||
/* allocate the space and copy the string buffer */
|
||||
to->buffer = (uint16 *)talloc(parse_misc_talloc, sizeof(uint16)*(to->uni_str_len));
|
||||
to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
|
||||
if (to->buffer == NULL)
|
||||
smb_panic("init_unistr2_from_unistr: malloc fail\n");
|
||||
memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
|
||||
|
@ -401,10 +401,10 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
|
||||
|
||||
/* Tallocate memory for string */
|
||||
|
||||
DEBUG(0, ("** tallocating memory\n"));
|
||||
DEBUG(10, ("** tallocating memory\n"));
|
||||
|
||||
data->notify_data.data.string = (uint16 *)
|
||||
talloc(ps->mem_ctx, x * 2);
|
||||
talloc_zero(ps->mem_ctx, x * 2);
|
||||
if (!data->notify_data.data.string)
|
||||
return False;
|
||||
|
||||
|
@ -485,14 +485,6 @@ static ssize_t process_complete_pdu(pipes_struct *p)
|
||||
char *data_p = (char *)&p->in_data.current_in_pdu[0];
|
||||
BOOL reply = False;
|
||||
|
||||
if (p->mem_ctx) {
|
||||
talloc_destroy_pool(p->mem_ctx);
|
||||
} else {
|
||||
p->mem_ctx = talloc_init();
|
||||
if (p->mem_ctx == NULL)
|
||||
p->fault_state = True;
|
||||
}
|
||||
|
||||
if(p->fault_state) {
|
||||
DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
|
||||
p->name ));
|
||||
@ -713,7 +705,7 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
|
||||
|
||||
memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);
|
||||
p->out_data.current_pdu_sent += (uint32)data_returned;
|
||||
return data_returned;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -727,9 +719,10 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
|
||||
|
||||
if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
|
||||
/*
|
||||
* We have sent all possible data. Return 0.
|
||||
* We have sent all possible data, return 0.
|
||||
*/
|
||||
return 0;
|
||||
data_returned = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -748,6 +741,26 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
|
||||
|
||||
memcpy( data, p->out_data.current_pdu, (size_t)data_returned);
|
||||
p->out_data.current_pdu_sent += (uint32)data_returned;
|
||||
|
||||
out:
|
||||
|
||||
if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
|
||||
/*
|
||||
* We have copied all possible data into the current_pdu. This RPC is finished.
|
||||
* Reset the talloc context to free any allocated data from this RPC.
|
||||
*/
|
||||
|
||||
if (p->mem_ctx) {
|
||||
DEBUG(3,("read_from_pipe: destroying talloc pool of size %u\n", talloc_pool_size(p->mem_ctx) ));
|
||||
talloc_destroy_pool(p->mem_ctx);
|
||||
} else {
|
||||
p->mem_ctx = talloc_init();
|
||||
if (p->mem_ctx == NULL)
|
||||
p->fault_state = True;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data_returned;
|
||||
}
|
||||
|
||||
@ -872,5 +885,4 @@ pipes_struct *get_rpc_pipe(int pnum)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef OLD_NTDOMAIN
|
||||
|
@ -1209,7 +1209,7 @@ void smbd_process(void)
|
||||
|
||||
/* free up temporary memory */
|
||||
lp_talloc_free();
|
||||
parse_talloc_free();
|
||||
main_loop_talloc_free();
|
||||
|
||||
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout)) {
|
||||
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
|
||||
|
Loading…
Reference in New Issue
Block a user