How to renice a group of processes

ioniceniceprocess

lb build can build live system image, and it invokes many processes while building the image. If I start it as below:

# nice -n 19 ionice -n 7 -c 3 lb build

all the children processes get the same nice level:

  PID USER       IORR  IOWR    IO IO PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                                                 
26196 morfik        0     0     0 B4  20   0 23888   672   668 S  0.0  0.1  0:00.24 │  ├─ -bash
30926 root          0     0     0 B4  20   0 53668   536   536 S  0.0  0.1  0:00.02 │  │  └─ su -
31008 root          0     0     0 B4  20   0 34656  6260  1144 S  0.0  0.6  0:02.60 │  │     └─ -su
11784 root          0     0     0 ??  39  19  4496   796   524 S  0.0  0.1  0:00.01 │  │        └─ /bin/sh /usr/lib/live/build/build               
11797 root          0     0     0 ??  39  19  4328   612   512 S  0.0  0.1  0:00.00 │  │           └─ /bin/sh ./auto/build
11806 root          0     0     0 ??  39  19  7028   604   504 S  0.0  0.1  0:00.00 │  │              ├─ tee build.log
11798 root          0     0     0 ??  39  19  4496   824   532 S  0.0  0.1  0:00.01 │  │              └─ /bin/sh /usr/lib/live/build/build noauto  
11915 root          0     0     0 ??  39  19  4496   836   544 S  0.0  0.1  0:00.01 │  │                 └─ /bin/sh /usr/lib/live/build/bootstrap  
12753 root          0     0     0 ??  39  19  4496   856   548 S  0.0  0.1  0:00.02 │  │                    └─ /bin/sh /usr/lib/live/build/bootstra
12867 root          0     0     0 ??  39  19 62980  3508  2132 S 11.2  0.3  0:07.00 │  │                       └─ aptitude --assume-yes update
12943 root          0     0     0 ??  39  19 24296  1916  1568 S  0.0  0.2  0:00.14 │  │                          ├─ /usr/lib/apt/methods/xz
12927 root          0     0     0 ??  39  19 53280 30688 30172 R 86.5  3.0  0:28.65 │  │                          ├─ /usr/lib/apt/methods/rred
12891 root          0     0     0 ??  39  19 24304  1784  1440 S  0.0  0.2  0:00.00 │  │                          ├─ /usr/lib/apt/methods/gpgv
12889 root          0     0     0 ??  39  19 24292  1624  1384 S  0.0  0.2  0:00.00 │  │                          ├─ /usr/lib/apt/methods/copy
12887 root          0     0     0 ??  39  19 32860  1956  1560 S  0.0  0.2  0:00.17 │  │                          ├─ /usr/lib/apt/methods/http
12886 root          0     0     0 ??  39  19 24292  1696  1444 S  0.0  0.2  0:00.00 │  │                          └─ /usr/lib/apt/methods/fil

But I forgot to add this nice -n 19 ionice -n 7 -c 3 and ran just lb build. So, I tried to renice the parent process:

# renice -n 19 -p 6187

But this doesn't renice the other processes. So, it looks like this:

26196 morfik        0     0     0 B4  20   0 23888   668   664 S  0.0  0.1  0:00.24 │  ├─ -bash
30926 root          0     0     0 B4  20   0 53668   528   528 S  0.0  0.1  0:00.02 │  │  └─ su -
31008 root          0     0     0 B4  20   0 34656  5952  1224 S  0.0  0.6  0:02.62 │  │     └─ -su
 6187 root          0     0     0 B7  39  19  4496   800   524 S  0.0  0.1  0:00.00 │  │        └─ /bin/sh /usr/lib/live/build/build
 6349 root          0     0     0 B4  20   0  4328   612   512 S  0.0  0.1  0:00.00 │  │           └─ /bin/sh ./auto/build
 6351 root          0     0     0 B4  20   0  7028   592   488 S  0.0  0.1  0:00.00 │  │              ├─ tee build.log
 6350 root          0     0     0 B4  20   0  4496   828   532 S  0.0  0.1  0:00.01 │  │              └─ /bin/sh /usr/lib/live/build/build noauto  
 6445 root          0     0     0 B4  20   0  4496   840   548 S  0.0  0.1  0:00.00 │  │                 └─ /bin/sh /usr/lib/live/build/bootstrap  
 7580 root          0     0     0 B4  20   0  4496   856   552 S  0.0  0.1  0:00.02 │  │                    └─ /bin/sh /usr/lib/live/build/bootstra
 7692 root          0     0     0 B4  20   0 62924  5236  3848 S 15.5  0.5  0:03.78 │  │                       └─ aptitude --assume-yes update
 7932 root          0     0     0 B4  20   0 54776 16480 15916 R 84.1  1.6  0:16.60 │  │                          ├─ /usr/lib/apt/methods/rred
 7912 root          0     0     0 B4  20   0 24296  2036  1648 S  0.0  0.2  0:01.62 │  │                          ├─ /usr/lib/apt/methods/gzip
 7733 root          0     0     0 B4  20   0 27948  5552  1632 S  0.0  0.5  0:02.85 │  │                          ├─ /usr/lib/apt/methods/bzip2
 7711 root          0     0     0 B4  20   0 24304  1780  1436 S  0.0  0.2  0:00.00 │  │                          ├─ /usr/lib/apt/methods/gpgv
 7709 root          0     0     0 B4  20   0 30800  2200  1812 S  0.0  0.2  0:01.01 │  │                          └─ /usr/lib/apt/methods/http     

I could renice all the processes manually but they are changing.

EDIT#1

The following command:

# nice -n 19 ionice -n 7 -c 3 lb build

sets also:

ionice – sets or gets process io scheduling class and priority. …

-c, –class scheduling class name or number
0: none, 1: realtime, 2: best-effort, 3: idle

-n, –classdata scheduling class data
0-7 for realtime and best-effort classes

How to set -c and -n option of ionice to the processes?

Best Answer

Since all the child processes are still a part of the session id (sess in ps output) we could exploit that fact using this command:

$ parent=6187
$ ps -eo sess:1=,pid:1= |sed -n "s/^$parent //p"

This should return to us all the process IDs of the child processes spawned from lb load. We can also get this directly from pgrep, using the -s switch too.

$ pgrep -s $parent

We can then renice them like so:

$ renice $(pgrep -s $parent)

Example

Here's a contrived example which hopefully illustrates how this all works. We start with a shell, "PID=10515".

1. Confirm Session ID
$ ps -j
  PID  PGID   SID TTY          TIME CMD
10515 10515 10515 pts/8    00:00:00 bash
30781 30781 10515 pts/8    00:00:00 ps
2. Fake jobs

We then start up some fake jobs that we forget to renice.

$ sleep 10000 &
$ sleep 10000 &

We confirm they're under our shell's session ID (SID).

$ ps -j
  PID  PGID   SID TTY          TIME CMD
10515 10515 10515 pts/8    00:00:00 bash
31107 31107 10515 pts/8    00:00:00 sleep
31111 31111 10515 pts/8    00:00:00 sleep
31140 31140 10515 pts/8    00:00:00 ps
3. Get PIDs associated to SID

We can get a list of all the processes, whose SID is 10515.

$ pgrep -s 10515
10515
31107
31111
4. Confirm current nice

What's everyone's nice level currently? Use this command to check:

$ ps -eo sess:1=,pid:1=,nice:1= | grep [1]0515
10515 10515 0
10515 31107 0
10515 31111 0
10515 31354 0
10515 31355 0
5. Change nice of all SID descendants

OK so everyone's nice at 0, let's change that.

$ renice $(pgrep -s 10515)
31107 (process ID) old priority 0, new priority 19
31111 (process ID) old priority 0, new priority 19
6. Confirm

Check our work:

$ ps -eo sess:1=,pid:1=,nice:1= | grep [1]0515
10515 10515 0
10515 31107 19
10515 31111 19
10515 31426 0
10515 31427 0

PIDs 31107 & 31111 are our sleep processes and we just bulk changed their nice to 19 with just the information about what SID they're associated to.

7. Double check

You can also check ps output if you're really paranoid:

$ ps -eaf | grep -E "31107|31111"
saml     31107 10515  0 22:30 pts/8    00:00:00 sleep 10000
saml     31111 10515  0 22:30 pts/8    00:00:00 sleep 10000
saml     31531 10515  0 22:35 pts/8    00:00:00 grep --color=auto -E 31107|31111

References

ionice

If you're attempting to control the processes' I/O priority as well as their nice level you should be able to change the above command example around to something like this:

$ renice -n 19 $(pgrep -s $parent)
$ ionice -c 3 -p $(pgrep -s $parent)

If you look at the man page for ionice you cannot mix -c 3 with -n.

   -c, --class class
          Specify the name or number of the scheduling class to use; 0 for
         none, 1 for realtime, 2 for best-effort, 3 for idle.

   -n, --classdata level
          Specify  the  scheduling class data.  This only has an effect if 
          the class accepts an argument.  For realtime and best-effort, 0-7 
          are valid data (priority levels).
Related Question