* New upstream maintainer and location:
[debian/cpulimit.git] / debian / patches / 01_priority.patch
1 Author: Ariel <asdebian@dsgml.com>
2 Description: only drop priority if it can be raised too
3              and implement RLIMIT_NICE option.
4 Bugs: #412421
5
6 --- cpulimit-1.1.orig/cpulimit.c
7 +++ cpulimit-1.1/cpulimit.c
8 @@ -42,6 +42,7 @@
9  #include <dirent.h>
10  #include <errno.h>
11  #include <string.h>
12 +#include <limits.h> //for INT_MAX, could also hardcode some large number
13  
14  //kernel time resolution (inverse of one jiffy interval) in Hertz
15  //i don't know how to detect it, then define to the default (not very clean!)
16 @@ -59,6 +60,8 @@
17  int verbose=0;
18  //lazy mode
19  int lazy=0;
20 +//is higher priority nice possible?
21 +int nice_lim;
22  
23  //reverse byte search
24  void *memrchr(const void *s, int c, size_t n);
25 @@ -71,7 +74,7 @@
26  
27  int waitforpid(int pid) {
28         //switch to low priority
29 -       if (setpriority(PRIO_PROCESS,getpid(),19)!=0) {
30 +       if (nice_lim < INT_MAX && setpriority(PRIO_PROCESS,getpid(),19)!=0) {
31                 printf("Warning: cannot renice\n");
32         }
33  
34 @@ -127,8 +130,8 @@
35  done:
36         printf("Process %d detected\n",pid);
37         //now set high priority, if possible
38 -       if (setpriority(PRIO_PROCESS,getpid(),-20)!=0) {
39 -               printf("Warning: cannot renice.\nTo work better you should run this program as root.\n");
40 +       if (nice_lim < INT_MAX && setpriority(PRIO_PROCESS,getpid(),nice_lim)!=0) {
41 +               printf("Warning: cannot renice.\n");
42         }
43         return 0;
44  
45 @@ -143,7 +146,7 @@
46  int getpidof(const char *process) {
47  
48         //set low priority
49 -       if (setpriority(PRIO_PROCESS,getpid(),19)!=0) {
50 +       if (nice_lim < INT_MAX && setpriority(PRIO_PROCESS,getpid(),19)!=0) {
51                 printf("Warning: cannot renice\n");
52         }
53  
54 @@ -219,8 +222,8 @@
55  done:
56         printf("Process %d detected\n",pid);
57         //now set high priority, if possible
58 -       if (setpriority(PRIO_PROCESS,getpid(),-20)!=0) {
59 -               printf("Warning: cannot renice.\nTo work better you should run this program as root.\n");
60 +       if (nice_lim < INT_MAX && setpriority(PRIO_PROCESS,getpid(),nice_lim)!=0) {
61 +               printf("Warning: cannot renice.\n");
62         }
63         return pid;
64  
65 @@ -373,6 +376,7 @@
66         int pid_ok=0;
67         int process_ok=0;
68         int limit_ok=0;
69 +       struct rlimit maxlimit;
70  
71         do {
72                 next_option = getopt_long (argc, argv, short_options,long_options, NULL);
73 @@ -437,6 +441,35 @@
74         signal(SIGINT,quit);
75         signal(SIGTERM,quit);
76  
77 +       //now test high priority
78 +       if (setpriority(PRIO_PROCESS,getpid(),-20)!=0) {
79 +               //if that failed, check if we have a limit by how much we can raise the priority
80 +#ifdef RLIMIT_NICE //check if non-root can even make changes (ifdef because it's only available in linux >= 2.6.13)
81 +               nice_lim=getpriority(PRIO_PROCESS,getpid());
82 +               getrlimit(RLIMIT_NICE, &maxlimit);
83 +
84 +               if( (20 - (signed)maxlimit.rlim_cur) < nice_lim &&  //if we can do better then current
85 +                   setpriority(PRIO_PROCESS,getpid(),20 - (signed)maxlimit.rlim_cur)==0 //and it actually works
86 +                 ) {
87 +
88 +                       //if we can do better, but not by much, warn about it
89 +                       if( (nice_lim - (20 - (signed)maxlimit.rlim_cur)) < 9) {
90 +                               printf("Warning, can only increase priority by %d.\n", nice_lim - (20 - (signed)maxlimit.rlim_cur));
91 +                       }
92 +
93 +                       nice_lim = 20 - (signed)maxlimit.rlim_cur; //our new limit
94 +
95 +               } else //otherwise don't try to change priority. The below will also run if it's not possible for non-root to change priority
96 +#endif
97 +               {
98 +                       printf("Warning: cannot renice.\nTo work better you should run this program as root, or adjust RLIMIT_NICE.\nFor example in /etc/security/limits.conf add a line with: * - nice -10\n\n");
99 +                       nice_lim=INT_MAX;
100 +               }
101 +       } else {
102 +               nice_lim=-20;
103 +       }
104 +       //don't bother putting setpriority back down, since getpidof and waitforpid twiddle it anyway
105 +
106         //time quantum in microseconds. it's splitted in a working period and a sleeping one
107         int period=100000;
108         struct timespec twork,tsleep;   //working and sleeping intervals