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:
parent
f14c851b42
commit
3d29430fa9
@ -130,14 +130,17 @@ int online_cpu(unsigned cpu)
|
|||||||
rc = read(fd, &val, 1);
|
rc = read(fd, &val, 1);
|
||||||
if (rc != 1){
|
if (rc != 1){
|
||||||
ERR_LOG("can't read cpu online value: %m");
|
ERR_LOG("can't read cpu online value: %m");
|
||||||
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (val == '1') {
|
if (val == '1') {
|
||||||
ERR_LOG("cpu %d is already online", cpu);
|
ERR_LOG("cpu %d is already online", cpu);
|
||||||
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
val = '1';
|
val = '1';
|
||||||
rc = write(fd, &val, 1);
|
rc = write(fd, &val, 1);
|
||||||
|
close(fd);
|
||||||
if (rc != 1){
|
if (rc != 1){
|
||||||
ERR_LOG("can't set cpu %d online", cpu);
|
ERR_LOG("can't set cpu %d online", cpu);
|
||||||
return -1;
|
return -1;
|
||||||
@ -160,14 +163,17 @@ int offline_cpu(unsigned cpu)
|
|||||||
rc = read(fd, &val, 1);
|
rc = read(fd, &val, 1);
|
||||||
if (rc != 1){
|
if (rc != 1){
|
||||||
ERR_LOG("can't read cpu online value: %m");
|
ERR_LOG("can't read cpu online value: %m");
|
||||||
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (val == '0') {
|
if (val == '0') {
|
||||||
ERR_LOG("cpu %d is already offline\n", cpu);
|
ERR_LOG("cpu %d is already offline\n", cpu);
|
||||||
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
val = '0';
|
val = '0';
|
||||||
rc = write(fd, &val, 1);
|
rc = write(fd, &val, 1);
|
||||||
|
close(fd);
|
||||||
if (rc != 1){
|
if (rc != 1){
|
||||||
ERR_LOG("can't set cpu %d offline", cpu);
|
ERR_LOG("can't set cpu %d offline", cpu);
|
||||||
return -1;
|
return -1;
|
||||||
@ -189,6 +195,7 @@ int get_highest_online_cpu(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = read(fd, buf, sizeof(buf));
|
rc = read(fd, buf, sizeof(buf));
|
||||||
|
close(fd);
|
||||||
if (rc < 2) {
|
if (rc < 2) {
|
||||||
ERR_LOG("error parsing /sys/devices/system/cpu/online, too few chars");
|
ERR_LOG("error parsing /sys/devices/system/cpu/online, too few chars");
|
||||||
return -1;
|
return -1;
|
||||||
@ -304,6 +311,7 @@ pick_cpu:
|
|||||||
// no need to release jobj_array as its ownership is transferred to jobj_response
|
// 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);
|
struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus);
|
||||||
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
||||||
|
free(current_online_cpus);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
failed:
|
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
|
// 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);
|
struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus);
|
||||||
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
||||||
|
free(current_online_cpus);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
failed:
|
failed:
|
||||||
|
@ -65,15 +65,15 @@ struct online_cpus *range_to_array(const char *range)
|
|||||||
struct online_cpus *cpuarray = (struct online_cpus *) malloc(BUFLEN);
|
struct online_cpus *cpuarray = (struct online_cpus *) malloc(BUFLEN);
|
||||||
int start, end;
|
int start, end;
|
||||||
int inrange = 0;
|
int inrange = 0;
|
||||||
char *token, *tmp;
|
char *token, *tmp, *tobe_free;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
tmp = strdup(range);
|
tobe_free = strdup(range);
|
||||||
strcpy(tmp, range);
|
token = tmp = tobe_free;
|
||||||
token = tmp;
|
|
||||||
|
|
||||||
if (*tmp == '\0') {
|
if (*tmp == '\0') {
|
||||||
/* empty string, no online cpus */
|
/* empty string, no online cpus */
|
||||||
cpuarray->numcpus = 0;
|
cpuarray->numcpus = 0;
|
||||||
|
free(tobe_free);
|
||||||
return cpuarray;
|
return cpuarray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,9 +125,11 @@ struct online_cpus *range_to_array(const char *range)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cpuarray->numcpus = end+1;
|
cpuarray->numcpus = end+1;
|
||||||
|
free(tobe_free);
|
||||||
return cpuarray;
|
return cpuarray;
|
||||||
error:
|
error:
|
||||||
free(cpuarray);
|
free(cpuarray);
|
||||||
|
free(tobe_free);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user