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