aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngelo Marletta <angelo.marletta@gmail.com>2012-06-29 22:22:20 +0100
committerAngelo Marletta <angelo.marletta@gmail.com>2012-06-29 22:22:20 +0100
commitb8f9bdd32fe0c85c3472298bc704cdc31580f189 (patch)
tree0e5464a4cdc1fc383616c1ea2e02162797dd029e
parent600c781a137eb122c5799d87bf814b1c9d439ab1 (diff)
downloadcpulimit-b8f9bdd32fe0c85c3472298bc704cdc31580f189.tar.gz
fixed bug in linux iterator. added test
-rw-r--r--src/cpulimit.c40
-rw-r--r--src/process_group.c12
-rw-r--r--src/process_group.h2
-rw-r--r--src/process_iterator_linux.c7
-rw-r--r--tests/process_iterator_test.c15
5 files changed, 57 insertions, 19 deletions
diff --git a/src/cpulimit.c b/src/cpulimit.c
index 9a9ce1b..e7d5309 100644
--- a/src/cpulimit.c
+++ b/src/cpulimit.c
@@ -27,22 +27,20 @@
*
*/
-#include <getopt.h>
#include <stdio.h>
-#include <fcntl.h>
#include <stdlib.h>
-#include <time.h>
#include <unistd.h>
+#include <getopt.h>
+#include <time.h>
#include <signal.h>
#include <string.h>
-#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
+#include <sys/types.h>
#include <sys/wait.h>
#include "process_group.h"
@@ -226,13 +224,19 @@ void limit_process(pid_t pid, double limit, int include_children)
}
//resume processes
- for (node = pgroup.proclist->first; node != NULL; node = node->next) {
+ node = pgroup.proclist->first;
+ while (node != NULL)
+ {
+ struct list_node *next_node = node->next;
struct process *proc = (struct process*)(node->data);
- if (kill(proc->pid,SIGCONT)!=0) {
+ if (kill(proc->pid,SIGCONT) != 0) {
//process is dead, remove it from family
- if (verbose) fprintf(stderr, "Process %d dead!\n", proc->pid);
- //remove_process_from_family(&pf, proc->pid);
+ if (verbose) fprintf(stderr, "SIGCONT failed. Process %d dead!\n", proc->pid);
+ //remove process from group
+ delete_node(pgroup.proclist, node);
+ remove_process(&pgroup, proc->pid);
}
+ node = next_node;
}
//now processes are free to run (same working slice for all)
@@ -248,14 +252,20 @@ void limit_process(pid_t pid, double limit, int include_children)
}
if (tsleep.tv_nsec>0) {
- //stop only if tsleep>0
- for (node = pgroup.proclist->first; node != NULL; node = node->next) {
+ //stop processes only if tsleep>0
+ node = pgroup.proclist->first;
+ while (node != NULL)
+ {
+ struct list_node *next_node = node->next;
struct process *proc = (struct process*)(node->data);
if (kill(proc->pid,SIGSTOP)!=0) {
//process is dead, remove it from family
- if (verbose) fprintf(stderr,"Process %d dead!\n", proc->pid);
- //remove_process_from_family(&pf, proc->pid);
+ if (verbose) fprintf(stderr, "SIGSTOP failed. Process %d dead!\n", proc->pid);
+ //remove process from group
+ delete_node(pgroup.proclist, node);
+ remove_process(&pgroup, proc->pid);
}
+ node = next_node;
}
//now the processes are sleeping
nanosleep(&tsleep,NULL);
@@ -432,7 +442,7 @@ int main(int argc, char **argv) {
else {
//limiter code
if (verbose) printf("Limiting process %d\n",child);
- limit_process(child, limit, ignore_children);
+ limit_process(child, limit, !ignore_children);
exit(0);
}
}
@@ -471,7 +481,7 @@ int main(int argc, char **argv) {
}
printf("Process %d found\n", pid);
//control
- limit_process(pid, limit, !ignore_children);
+ limit_process(pid, limit, ignore_children);
}
if (lazy) break;
sleep(2);
diff --git a/src/process_group.c b/src/process_group.c
index 671dd73..00b8129 100644
--- a/src/process_group.c
+++ b/src/process_group.c
@@ -172,7 +172,7 @@ void update_process_group(struct process_group *pgroup)
// struct timeval t;
// gettimeofday(&t, NULL);
// printf("T=%ld.%ld PID=%d PPID=%d START=%d CPUTIME=%d\n", t.tv_sec, t.tv_usec, tmp_process.pid, tmp_process.ppid, tmp_process.starttime, tmp_process.cputime);
- int hashkey = pid_hashfn(tmp_process.pid + tmp_process.starttime);
+ int hashkey = pid_hashfn(tmp_process.pid);
if (pgroup->proctable[hashkey] == NULL)
{
//empty bucket
@@ -222,3 +222,13 @@ void update_process_group(struct process_group *pgroup)
if (dt < MIN_DT) return;
pgroup->last_update = now;
}
+
+int remove_process(struct process_group *pgroup, int pid)
+{
+ int hashkey = pid_hashfn(pid);
+ if (pgroup->proctable[hashkey] == NULL) return 1; //nothing to delete
+ struct list_node *node = (struct list_node*)locate_node(pgroup->proctable[hashkey], &pid);
+ if (node == NULL) return 2;
+ delete_node(pgroup->proctable[hashkey], node);
+ return 0;
+} \ No newline at end of file
diff --git a/src/process_group.h b/src/process_group.h
index ab86816..5a5b581 100644
--- a/src/process_group.h
+++ b/src/process_group.h
@@ -50,4 +50,6 @@ int find_process_by_pid(pid_t pid);
int find_process_by_name(const char *process_name);
+int remove_process(struct process_group *pgroup, int pid);
+
#endif
diff --git a/src/process_iterator_linux.c b/src/process_iterator_linux.c
index 9e2f7f2..3e3eea0 100644
--- a/src/process_iterator_linux.c
+++ b/src/process_iterator_linux.c
@@ -143,19 +143,20 @@ int get_next_process(struct process_iterator *it, struct process *p)
}
if (it->filter->pid > 0 && !it->filter->include_children)
{
- read_process_info(it->filter->pid, p);
+ int ret = read_process_info(it->filter->pid, p);
//p->starttime += it->boot_time;
closedir(it->dip);
it->dip = NULL;
+ if (ret != 0) return -1;
return 0;
}
- struct dirent *dit;
+ struct dirent *dit = NULL;
//read in from /proc and seek for process dirs
while ((dit = readdir(it->dip)) != NULL) {
if(strtok(dit->d_name, "0123456789") != NULL)
continue;
p->pid = atoi(dit->d_name);
- if (it->filter->pid > 0 && it->filter->pid != p->pid && !is_child_of(p->pid, it->filter->pid)) continue;
+ if (it->filter->pid != 0 && it->filter->pid != p->pid && !is_child_of(p->pid, it->filter->pid)) continue;
read_process_info(p->pid, p);
//p->starttime += it->boot_time;
break;
diff --git a/tests/process_iterator_test.c b/tests/process_iterator_test.c
index 7b1c6b5..3d5e885 100644
--- a/tests/process_iterator_test.c
+++ b/tests/process_iterator_test.c
@@ -203,6 +203,20 @@ void test_process_name(const char * command)
close_process_iterator(&it);
}
+void test_process_group_wrong_pid()
+{
+ struct process_group pgroup;
+ assert(init_process_group(&pgroup, -1, 0) == 0);
+ assert(pgroup.proclist->count == 0);
+ update_process_group(&pgroup);
+ assert(pgroup.proclist->count == 0);
+ assert(init_process_group(&pgroup, 9999999, 0) == 0);
+ assert(pgroup.proclist->count == 0);
+ update_process_group(&pgroup);
+ assert(pgroup.proclist->count == 0);
+ assert(close_process_group(&pgroup) == 0);
+}
+
int main(int argc, char **argv)
{
// printf("Pid %d\n", getpid());
@@ -212,6 +226,7 @@ int main(int argc, char **argv)
test_process_group_all();
test_process_group_single(0);
test_process_group_single(1);
+ test_process_group_wrong_pid();
test_process_name(argv[0]);
return 0;
}
Un proyecto texto-plano.xyz