1

I can pause and resume a process by sending it the SIGSTOP and SIGCONT signals.

Taking Firefox as an example:

pkill --signal SIGSTOP firefox
pkill --signal SIGCONT firefox

The thing is that Firefox also has auxiliary processes like Web Content, WebExtensions, and RDD Process that keep running.

Is there a way to pause and unpause this whole group of processes, belonging to the application?

  • 1
    Are those processes part of the same process group (do they have the same PGID)? – Kusalananda Jul 10 '20 at 07:55
  • Yes, they have the same PGID, they do belong in the same process group. For whatever reason I read PID... – Rayleigh Jul 10 '20 at 08:27
  • But is that PGID specific to those process groups (meaning you can use kill -19 -$PGID as mentioned in my answer) or does the process group also include other, unrelated proceses as I have on my system? – terdon Jul 10 '20 at 10:10

3 Answers3

1

pkill is a great tool which, according to man does "look up or signal processes based on name". Moreover, it matches multiple processes. As long as all Web Content and Web Extensions ran by same filename, we may use pkill -19 firefox-esr to pause as much ALL child processes.

At some point it may not be safe and if we want to match the specific installation of Firefox (but all instances), we may query PIDs with fuser (show which processes are using a specified computer file): fuser /usr/lib/firefox-esr/firefox-esr | grep -Es "[0-9]+" | xargs kill -19 (-18 to resume).

Last result can be checked with concatenating | xargs ps, which will output processes status as 'Sl' (interruptible sleep, multi-threaded).

  • You can remove the call to grep since fuser prints only the PIDs to stdout, everything else to stderr: fuser /usr/lib/firefox/firefox | xargs kill -19 – Matthias Braun Jul 14 '20 at 08:08
1

The usual answer for this sort of thing is that you should send the signal to the process group and not the process alone. All of the processes spawned by firefox should be in the same process group. Indeed, on my system:

$ ps -aeo pgid,ppid,pid,s,comm,args | grep -E '[f]irefox|[P]PID'
   PGID    PPID     PID S COMMAND         COMMAND
   1095       1  151407 S firefox         /usr/lib/firefox/firefox
   1095  151407  151541 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151607 S WebExtensions   /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151689 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151711 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151738 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151765 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151802 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 7 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151876 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 8 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151889 S Web Content     /usr/lib/firefox/firefox -contentproc -childID 9 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151928 S Privileged Cont /usr/lib/firefox/firefox -contentproc -childID 10 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab

So normally, I could just run kill -19 -1095 and that would suspend all members of the process group 1095. Unfortunately, at least on my system, this group doesn't only contain Firefox:

$ ps -aeo pgid,ppid,pid,s,comm,args | awk '$1==1095' | wc
    104    1382   29087

There are 104 processes in that group, including such basic tools as Xorg or my display manager login. So while that would technically work in that it would suspend Firefox, it will also suspend my entire GUI rendering the system unresponsive.

So instead, you can use the -f flag of pkill:

-f, --full

The pattern is normally only matched against the process name. When -f is set, the full command line is used.

If I now run pkill -f -19 firefox, all processes whose commandline matches firefox will be suspended (look at the S column):

$ pkill -f -19 firefox
$ ps -aeo ppid,pid,s,comm,args | grep -E '[f]irefox|[P]PID'
   PGID    PPID     PID S COMMAND         COMMAND
   1095       1  151407 T firefox         /usr/lib/firefox/firefox
   1095  151407  151541 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 1 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151607 T WebExtensions   /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151689 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151711 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151738 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151765 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 6 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151802 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 7 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151876 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 8 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151889 T Web Content     /usr/lib/firefox/firefox -contentproc -childID 9 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab
   1095  151407  151928 T Privileged Cont /usr/lib/firefox/firefox -contentproc -childID 10 -isForBrowser -prefsLen 136 -prefMapSize 225550 -parentBuildID 20200603085854 -appdir /usr/lib/firefox/browser 151407 true tab

Of course this means that if you have, for example, a text file called firefoxManual open in a text editor, or any other process that matches firefox, that will also be suspended.

Alternatively, if you want to be 100% sure you only get the right processes, you can get the PID of Firefox and then send a signal to it, and to all processes that have it as a parent ID:

pkill -19 firefox; pgrep -P $(pgrep firefox) | xargs kill -19

You could even whip that up into a function:

myKill(){
    pkill "$1" "$2"; pgrep -P $(pgrep "$2") | xargs kill "$1"
}

And you can now stop them all with:

myKill -19 firefox

And restart with:

myKill -18 firefox
terdon
  • 242,166
  • Could you spend a few words on the regex [f]irefox|[P]PID? The single-letter character classes surprise me. I think the regex can be simplified to firefox|PPID. – Matthias Braun Jul 14 '20 at 08:21
  • 1
    @MatthiasBraun that's just an old trick to avoid matching the grep process itself in the output of ps when you can't use pgrep. Also, thanks for the edit, that was an embarrassing amount of typos! – terdon Jul 14 '20 at 08:40
0

Granted your Linux has already upgraded to cgroups v2 and your ID=1000:

systemd-run --user --slice=firefox.slice firefox
# To freeze
echo 1 > /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/firefox.slice/cgroup.freeze
# To unfreeze
echo 0 > /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/firefox.slice/cgroup.freeze