From 3d29430fa9b4454203b2dae91c527a61c1de80ce Mon Sep 17 00:00:00 2001 From: SidneyAn Date: Thu, 25 Oct 2018 13:41:05 +0800 Subject: [PATCH] free memory and file handle when it is no longer in use leaked_storage: 1. in function cpu_scale_down() and cpu_scale_up() memory obtained from range_to_array() is done dynamically using malloc(). it should be freed when it is no longer in use. 2. in function range_to_array() memory obtained from malloc() do not free at lable 'error' leaked_handle: in function get_highest_online_cpu(), online_cpu(), offline_cpu() function handle 'fd' do not close until the end of function. test case: 1. one controller + one compute deploy success. 2. scaling instance's cpu up/down by nova for 200 times, with whom "guest_scale_agent" and "guest_agent" is installed: With origin code: each time of cpu scale up/down, a new fd was created without close. each time of cpu scale up, there were some bytes memory leak. Though it can be detected after hundreds of times of scale up. With patch code: after 200 times of scale up and down, there is no fd or memory leak found Steps to Reproduce: 1. make test images and flavor according to docs in /guest-agent/guest-scale-agent-2.0/docs/README.txt 2. On controller, use nova command to scale cpu up/down 3. check release by cmd "ll /proc//fd", "ps aux |grep guest_scale_agent" Closes-Bug: 1794898 Change-Id: I51674d5e3bf330441f473ebfe8fa2a6066a94dfa Signed-off-by: SidneyAn --- guest-agent/guest-scale-agent-2.0/guest_scale_agent.c | 10 +++++++++- guest-agent/guest-scale-agent-2.0/parser.c | 10 ++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/guest-agent/guest-scale-agent-2.0/guest_scale_agent.c b/guest-agent/guest-scale-agent-2.0/guest_scale_agent.c index 6863ee50..39c5e62c 100644 --- a/guest-agent/guest-scale-agent-2.0/guest_scale_agent.c +++ b/guest-agent/guest-scale-agent-2.0/guest_scale_agent.c @@ -130,14 +130,17 @@ int online_cpu(unsigned cpu) rc = read(fd, &val, 1); if (rc != 1){ ERR_LOG("can't read cpu online value: %m"); + close(fd); return -1; } if (val == '1') { ERR_LOG("cpu %d is already online", cpu); + close(fd); return 0; } val = '1'; rc = write(fd, &val, 1); + close(fd); if (rc != 1){ ERR_LOG("can't set cpu %d online", cpu); return -1; @@ -160,14 +163,17 @@ int offline_cpu(unsigned cpu) rc = read(fd, &val, 1); if (rc != 1){ ERR_LOG("can't read cpu online value: %m"); + close(fd); return -1; } if (val == '0') { ERR_LOG("cpu %d is already offline\n", cpu); + close(fd); return 0; } val = '0'; rc = write(fd, &val, 1); + close(fd); if (rc != 1){ ERR_LOG("can't set cpu %d offline", cpu); return -1; @@ -189,6 +195,7 @@ int get_highest_online_cpu(void) } rc = read(fd, buf, sizeof(buf)); + close(fd); if (rc < 2) { ERR_LOG("error parsing /sys/devices/system/cpu/online, too few chars"); return -1; @@ -304,6 +311,7 @@ pick_cpu: // no need to release jobj_array as its ownership is transferred to jobj_response struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus); json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array); + free(current_online_cpus); return; failed: @@ -374,7 +382,7 @@ void cpu_scale_up(json_object *jobj_request, // no need to release jobj_array as its ownership is transferred to jobj_response struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus); json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array); - + free(current_online_cpus); return; failed: diff --git a/guest-agent/guest-scale-agent-2.0/parser.c b/guest-agent/guest-scale-agent-2.0/parser.c index 3eaef1c1..6a4e2068 100644 --- a/guest-agent/guest-scale-agent-2.0/parser.c +++ b/guest-agent/guest-scale-agent-2.0/parser.c @@ -65,15 +65,15 @@ struct online_cpus *range_to_array(const char *range) struct online_cpus *cpuarray = (struct online_cpus *) malloc(BUFLEN); int start, end; int inrange = 0; - char *token, *tmp; + char *token, *tmp, *tobe_free; int done = 0; - tmp = strdup(range); - strcpy(tmp, range); - token = tmp; + tobe_free = strdup(range); + token = tmp = tobe_free; if (*tmp == '\0') { /* empty string, no online cpus */ cpuarray->numcpus = 0; + free(tobe_free); return cpuarray; } @@ -125,9 +125,11 @@ struct online_cpus *range_to_array(const char *range) break; } cpuarray->numcpus = end+1; + free(tobe_free); return cpuarray; error: free(cpuarray); + free(tobe_free); return 0; }