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/<guest_scale_agent pid>/fd",
"ps aux |grep guest_scale_agent"

Closes-Bug: 1794898

Change-Id: I51674d5e3bf330441f473ebfe8fa2a6066a94dfa
Signed-off-by: SidneyAn <ran1.an@intel.com>
This commit is contained in:
SidneyAn 2018-10-25 13:41:05 +08:00
parent f14c851b42
commit 3d29430fa9
2 changed files with 15 additions and 5 deletions

View File

@ -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:

View File

@ -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;
}