summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--your-fired.sh134
2 files changed, 136 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5db24a3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
1install:
2 sh your-fired.sh install
diff --git a/your-fired.sh b/your-fired.sh
new file mode 100644
index 0000000..dacfc37
--- /dev/null
+++ b/your-fired.sh
@@ -0,0 +1,134 @@
1#!/bin/sh
2
3WEB_CONTENT_OOM_ADJ=500
4FIREFIX_REPEAT_INTERVAL=5
5
6ploop()
7{
8 local p
9 for p in /proc/[0-9]*
10 do
11 "$@"
12 done
13}
14
15match_parent()
16{
17 # This isn't a file to which we will write (we write to the child's
18 # oom_score_adj), but this ignores processes we don't own.
19 2>/dev/null [ -w "$p"/oom_score_adj ] || return
20
21 local stat
22 2>/dev/null read stat < "$p"/stat || return
23 case "$stat" in
24 *") "?" $1 "*) echo "${p##*/}" ;;
25 esac
26}
27
28match_comm()
29{
30 local comm
31 2>/dev/null read comm < "$p"/comm || return
32 [ "$comm" = "$1" ] && echo "${p##*/}"
33}
34
35firefix()
36{
37 parent=$1
38 read parent_oom_score < /proc/$parent/oom_score
39 read parent_oom_score_adj < /proc/$parent/oom_score_adj
40
41 for child in $(ploop match_parent $parent)
42 do
43 2>/dev/null read comm < /proc/$child/comm || continue
44 [ "$comm" = 'Web Content' ] || continue
45
46 read oom_score < /proc/$child/oom_score
47 read oom_score_adj < /proc/$child/oom_score_adj
48
49 want_adj=$((parent_oom_score_adj + ${WEB_CONTENT_OOM_ADJ:-500}))
50 if [ "$want_adj" -gt "$oom_score_adj" ]
51 then
52 printf 'Setting oom_score_adj for pid=%d to %d (from %d)\n' $child $want_adj $oom_score_adj >&2
53 printf '%d\n' "$want_adj" > /proc/$child/oom_score_adj
54 fi
55 done
56}
57
58firefix_all()
59{
60 for parent in $(ploop match_comm firefox-bin)
61 do
62 firefix $parent &
63 done
64 wait
65}
66
67firefix_all_forever()
68{
69 while true
70 do
71 firefix_all
72 sleep ${FIREFIX_REPEAT_INTERVAL:-5}
73 done
74}
75
76unit_file()
77{
78 cat <<EOF
79[Unit]
80Description=$1
81[Service]
82ExecStart=$2
83[Install]
84WantedBy=default.target
85EOF
86}
87
88install_self()
89{
90 unit_file_name=$1
91 unit_executable=$2
92 unit_args=$3
93 unit_desc=$4
94
95 [ -e "$unit_executable" ] || return
96
97 if [ "$(id -u)" = 0 ]
98 then
99 service_dir=/etc/systemd/system
100 systemctl=systemctl
101 instdir=/usr/local/bin
102 else
103 service_dir=$HOME/.config/systemd/user
104 systemctl='systemctl --user'
105 instdir=$HOME/.local/bin
106 fi
107 unit_executable_installed=$instdir/${unit_executable##*/}
108
109 [ "$unit_executable_installed" -ef "$unit_executable" ] ||
110 install -D -t "$instdir" "$unit_executable" || return
111
112 [ -d "$service_dir" ] || mkdir -p "$service_dir" || return
113
114 unit_file=${service_dir}/${unit_file_name}.service
115 unit_file "$unit_desc" "$unit_executable_installed $unit_args" > "$unit_file"
116
117 $systemctl daemon-reload
118 $systemctl enable "$unit_file_name"
119 $systemctl restart "$unit_file_name"
120 $systemctl status "$unit_file_name"
121}
122
123usage()
124{
125 echo "Usage: $0 <install|once|forever>" >&2
126}
127
128case "$*" in
129 forever) firefix_all_forever ;;
130 install) install_self firefixer "$0" forever 'Firefixer - adjust firefox OOM scores';;
131 once) firefix_all ;;
132 -h|--help) usage; exit ;;
133 *) usage; exit 1 ;;
134esac