diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | your-fired.sh | 134 |
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 @@ | |||
1 | install: | ||
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 | |||
3 | WEB_CONTENT_OOM_ADJ=500 | ||
4 | FIREFIX_REPEAT_INTERVAL=5 | ||
5 | |||
6 | ploop() | ||
7 | { | ||
8 | local p | ||
9 | for p in /proc/[0-9]* | ||
10 | do | ||
11 | "$@" | ||
12 | done | ||
13 | } | ||
14 | |||
15 | match_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 | |||
28 | match_comm() | ||
29 | { | ||
30 | local comm | ||
31 | 2>/dev/null read comm < "$p"/comm || return | ||
32 | [ "$comm" = "$1" ] && echo "${p##*/}" | ||
33 | } | ||
34 | |||
35 | firefix() | ||
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 | |||
58 | firefix_all() | ||
59 | { | ||
60 | for parent in $(ploop match_comm firefox-bin) | ||
61 | do | ||
62 | firefix $parent & | ||
63 | done | ||
64 | wait | ||
65 | } | ||
66 | |||
67 | firefix_all_forever() | ||
68 | { | ||
69 | while true | ||
70 | do | ||
71 | firefix_all | ||
72 | sleep ${FIREFIX_REPEAT_INTERVAL:-5} | ||
73 | done | ||
74 | } | ||
75 | |||
76 | unit_file() | ||
77 | { | ||
78 | cat <<EOF | ||
79 | [Unit] | ||
80 | Description=$1 | ||
81 | [Service] | ||
82 | ExecStart=$2 | ||
83 | [Install] | ||
84 | WantedBy=default.target | ||
85 | EOF | ||
86 | } | ||
87 | |||
88 | install_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 | |||
123 | usage() | ||
124 | { | ||
125 | echo "Usage: $0 <install|once|forever>" >&2 | ||
126 | } | ||
127 | |||
128 | case "$*" 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 ;; | ||
134 | esac | ||