Skip to content

Commit

Permalink
dird: Fix memory leak with configure usage string.
Browse files Browse the repository at this point in the history
As the old buffer was defined as static inside the
get_configure_parameter() function it means its scope is still active at
the time the daemon ends and it will never be freed and as such
smartalloc whines in the following way:

bareos-dir: smartall.c:414-0 Orphaned buffer: bareos-dir 10016 bytes at
6e6b68 from mem_pool.c:242

The new approach is to use a static global variable and a dynamic
allocate of the POOL_MEM buffer and an extra cleanup function
destroy_configure_usage_string() which is called from terminate_dird().
I also renamed the original function from get_configure_parameter() to
get_configure_usage_string() which describes the function a bit better.
  • Loading branch information
Marco van Wieringen committed May 9, 2016
1 parent 6544312 commit 37b2bd8
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/dird/dird.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ void terminate_dird(int sig)
already_here = true;
debug_level = 0; /* turn off debug */

destroy_configure_usage_string();
stop_statistics_thread();
stop_watchdog();
db_sql_pool_destroy();
Expand Down
39 changes: 26 additions & 13 deletions src/dird/dird_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ extern struct s_kw RunFields[];
*/
static RES *sres_head[R_LAST - R_FIRST + 1];
static RES **res_head = sres_head;
static POOL_MEM *configure_usage_string = NULL;

/*
* Set default indention e.g. 2 spaces.
Expand Down Expand Up @@ -901,7 +902,7 @@ bool print_config_schema_json(POOL_MEM &buffer)
}
#endif

static inline bool cmdline_item(POOL_MEM &buffer, RES_ITEM *item)
static inline bool cmdline_item(POOL_MEM *buffer, RES_ITEM *item)
{
POOL_MEM temp;
POOL_MEM key;
Expand Down Expand Up @@ -939,7 +940,7 @@ static inline bool cmdline_item(POOL_MEM &buffer, RES_ITEM *item)
return true;
}

static inline bool cmdline_items(POOL_MEM &buffer, RES_ITEM items[])
static inline bool cmdline_items(POOL_MEM *buffer, RES_ITEM items[])
{
if (!items) {
return false;
Expand All @@ -953,35 +954,47 @@ static inline bool cmdline_items(POOL_MEM &buffer, RES_ITEM items[])
}

/*
* Get the parameter string for the console "configure" command.
* Get the usage string for the console "configure" command.
*
* This will be all available resource directives.
* They are formated in a way to be usable for command line completion.
*/
const char *get_configure_parameter()
const char *get_configure_usage_string()
{
static POOL_MEM buffer;
POOL_MEM resourcename;

if (!configure_usage_string) {
configure_usage_string = new POOL_MEM(PM_BSOCK);
}

/*
* Only fill the buffer once. The content is static.
* Only fill the configure_usage_string once. The content is static.
*/
if (buffer.strlen() == 0) {
buffer.strcpy("add [");
if (configure_usage_string->strlen() == 0) {
configure_usage_string->strcpy("add [");
for (int r = 0; resources[r].name; r++) {
if (resources[r].items) {
resourcename.strcpy(resources[r].name);
resourcename.toLower();
buffer.strcat(resourcename);
cmdline_items(buffer, resources[r].items);
configure_usage_string->strcat(resourcename);
cmdline_items(configure_usage_string, resources[r].items);
}
if (resources[r+1].items) {
buffer.strcat("] | [");
configure_usage_string->strcat("] | [");
}
}
buffer.strcat("]");
configure_usage_string->strcat("]");
}

return buffer.c_str();
return configure_usage_string->c_str();
}

void destroy_configure_usage_string()
{
if (configure_usage_string) {
delete configure_usage_string;
configure_usage_string = NULL;
}
}

/*
Expand Down
3 changes: 2 additions & 1 deletion src/dird/protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ json_t *json_datatype(const int type, RES_ITEM items[]);
const char *auth_protocol_to_str(uint32_t auth_protocol);
const char *level_to_str(int level);
extern "C" char *job_code_callback_director(JCR *jcr, const char*);
const char *get_configure_parameter();
const char *get_configure_usage_string();
void destroy_configure_usage_string();
bool populate_defs();

/* expand.c */
Expand Down
2 changes: 1 addition & 1 deletion src/dird/ua_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ static struct cmdstruct commands[] = {
{ NT_("cancel"), cancel_cmd, _("Cancel a job"),
NT_("storage=<storage-name> | jobid=<jobid> | job=<job-name> | ujobid=<unique-jobid> | state=<job_state> | all yes"), false, true },
{ NT_("configure"), configure_cmd, _("Configure director resources"),
NT_(get_configure_parameter()), false, true },
NT_(get_configure_usage_string()), false, true },
{ NT_("create"), create_cmd, _("Create DB Pool from resource"),
NT_("pool=<pool-name>"), false, true },
{ NT_("delete"), delete_cmd, _("Delete volume, pool or job"),
Expand Down

0 comments on commit 37b2bd8

Please sign in to comment.