Added total memory allocated counter to talloc, so we can tell if a talloc
authorJeremy Allison <jra@samba.org>
Tue, 27 Feb 2001 19:22:02 +0000 (19:22 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 27 Feb 2001 19:22:02 +0000 (19:22 +0000)
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 d3a56c6042acf037bbd53de88d7636a5803ead20)

source3/include/proto.h
source3/include/talloc.h
source3/lib/talloc.c
source3/rpc_parse/parse_lsa.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_spoolss.c
source3/rpc_server/srv_pipe_hnd.c
source3/smbd/process.c

index b525b039ffbc5bf575016f4cf0a4a65273e5c8db..bcde38636258453ad0da4395aec9882845ca264b 100644 (file)
@@ -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
index 85a722d0807f28aa7e8b783689ceb303ef191b8b..32b0f28ae6d4f0a9d7bd47a18de7914fd80b77c8 100644 (file)
@@ -36,6 +36,7 @@ struct talloc_chunk {
 
 typedef struct {
        struct talloc_chunk *list;
+       size_t total_alloc_size;
 } TALLOC_CTX;
 
 #endif
index a04bd2561bb3471450560739e0e7db16e01c9eac..854a230a0e09d5b7a4a97d6b754f6790d435a5d7 100644 (file)
@@ -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;
+}
index a33c7594737dff1f91d485494b89f392e8ee413c..d86df0ee113e96ca2cd7cb8784c0066af9fadce3 100644 (file)
@@ -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;
index 329683d23add179606615ec0ffd4236899bc6c91..0a65c09493a8444e17e23b29012f15c62b32c2ac 100644 (file)
 
 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));
index 0961cda195440e14bcaed8c64f6f445609c05105..bb8c81842171c0587a8ed5db496f48094fa741d6 100644 (file)
@@ -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;
 
index b8ee2351850e0cfe065973a393dda4ba18205100..3b60c78ade35674ee036609238d5b6584bfc893f 100644 (file)
@@ -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
index 461fa99f398995e8f2a1d0f2e3295915f3ebe4e5..f8fde41b77102797c40608e55fd36341f51081f4 100644 (file)
@@ -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))