diff options
author | Andrew Cady <d@cryptonomic.net> | 2022-11-29 12:00:08 -0500 |
---|---|---|
committer | Andrew Cady <d@cryptonomic.net> | 2022-11-29 12:00:08 -0500 |
commit | 61564e4d18058031d96e207862f72f0628934ea3 (patch) | |
tree | 1a43ee54623384f0b09387c68062905aeefe36f5 /src | |
parent | 42a4367a83645b2bca1f0a4d48917fb9ec3bbf5b (diff) |
move files to src; add README.txt
Diffstat (limited to 'src')
-rwxr-xr-x | src/cgroup-show-each-new-process | 51 | ||||
-rwxr-xr-x | src/fireslay | 38 | ||||
-rwxr-xr-x | src/ioslay-firefox | 87 | ||||
-rwxr-xr-x | src/ioslay-mgr.sh | 105 | ||||
-rwxr-xr-x | src/slice | 47 | ||||
-rwxr-xr-x | src/sliceuser | 13 | ||||
-rwxr-xr-x | src/sliceweasel | 15 | ||||
-rwxr-xr-x | src/sliceweasel.lib.sh | 154 | ||||
-rw-r--r-- | src/your-fired.sh | 136 |
9 files changed, 646 insertions, 0 deletions
diff --git a/src/cgroup-show-each-new-process b/src/cgroup-show-each-new-process new file mode 100755 index 0000000..d1473f1 --- /dev/null +++ b/src/cgroup-show-each-new-process | |||
@@ -0,0 +1,51 @@ | |||
1 | #!/bin/bash | ||
2 | cgroup=${1:-firefox~$(id -u)} | ||
3 | |||
4 | show_new_pids() | ||
5 | { | ||
6 | if [ -e "$procs" ] | ||
7 | then | ||
8 | sort < "$procs" > pids | ||
9 | if [ -e old-pids ] | ||
10 | then | ||
11 | comm -13 old-pids pids | ||
12 | else | ||
13 | cat pids | ||
14 | fi | ||
15 | mv pids old-pids | ||
16 | fi | ||
17 | } | ||
18 | |||
19 | show_pid_comm() | ||
20 | { | ||
21 | local pid comm | ||
22 | pid=$1 | ||
23 | if 2>/dev/null read comm < /proc/$pid/comm | ||
24 | then | ||
25 | echo "$pid $comm" | ||
26 | else | ||
27 | echo $pid '(disappeared)' >&2 | ||
28 | fi | ||
29 | } | ||
30 | |||
31 | each_line() | ||
32 | { | ||
33 | local line | ||
34 | while read line | ||
35 | do "$@" "$line" | ||
36 | done | ||
37 | } | ||
38 | |||
39 | RUNTIME_DIR=$(mktemp -d) || exit | ||
40 | trap 'cd /; rm -rf "$RUNTIME_DIR"' EXIT | ||
41 | cd "$RUNTIME_DIR" | ||
42 | |||
43 | enable -f /usr/lib/bash/sleep sleep | ||
44 | procs=/sys/fs/cgroup/$cgroup/cgroup.procs | ||
45 | |||
46 | while true | ||
47 | do | ||
48 | show_new_pids | ||
49 | sleep 1 | ||
50 | done | each_line show_pid_comm | ||
51 | |||
diff --git a/src/fireslay b/src/fireslay new file mode 100755 index 0000000..3c68ad5 --- /dev/null +++ b/src/fireslay | |||
@@ -0,0 +1,38 @@ | |||
1 | #!/bin/sh | ||
2 | set -e | ||
3 | . sliceweasel.lib.sh | ||
4 | |||
5 | is_web_content() | ||
6 | { | ||
7 | local comm state | ||
8 | read comm < /proc/"$1"/comm && [ "$comm" = 'Web Content' ] && | ||
9 | read _ _ state _ < /proc/"$1"/stat && [ "$state" != Z ] || return | ||
10 | } | ||
11 | |||
12 | web_content_pids() | ||
13 | { | ||
14 | while read pid | ||
15 | do | ||
16 | if is_web_content $pid | ||
17 | then | ||
18 | echo $pid | ||
19 | fi | ||
20 | done < $FIREFOX_GROUP_PROCS | ||
21 | } | ||
22 | |||
23 | FIREFOX_GROUP_PROCS=$(get_firefox_cgroup_procs) | ||
24 | |||
25 | [ -e "$FIREFOX_GROUP_PROCS" ] || die "Firefox group not found ($FIREFOX_GROUP_PROCS)" | ||
26 | |||
27 | set -- $(web_content_pids) | ||
28 | |||
29 | if [ $# = 0 ] | ||
30 | then | ||
31 | exit | ||
32 | fi | ||
33 | |||
34 | ( | ||
35 | set -x | ||
36 | ps $* >&2 | ||
37 | kill $* | ||
38 | ) | ||
diff --git a/src/ioslay-firefox b/src/ioslay-firefox new file mode 100755 index 0000000..41aa6a4 --- /dev/null +++ b/src/ioslay-firefox | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/bin/bash | ||
2 | sum() | ||
3 | { | ||
4 | local total=0 n | ||
5 | for n in $* | ||
6 | do | ||
7 | total=$((total + n)) | ||
8 | done | ||
9 | echo $total | ||
10 | } | ||
11 | |||
12 | last() | ||
13 | { | ||
14 | local n=$1 | ||
15 | shift | ||
16 | set -- $* | ||
17 | while [ $# -ge "$n" ] | ||
18 | do | ||
19 | shift | ||
20 | done | ||
21 | printf '%s\n' "$*" | ||
22 | } | ||
23 | |||
24 | iotop_reader() | ||
25 | { | ||
26 | log= | ||
27 | pct_log= | ||
28 | while read line | ||
29 | do | ||
30 | case "$line" in | ||
31 | "Total DISK"*) | ||
32 | pct=$(sum $pct_log) | ||
33 | [ "$pct" -ge 85 ] && over=y || over= | ||
34 | pct_log= | ||
35 | if [ "$over" ] | ||
36 | then | ||
37 | log=$(last 10 $log 1) | ||
38 | over= | ||
39 | sum=$(sum $log) | ||
40 | if [ "$(sum $log)" -gt 4 ] | ||
41 | then | ||
42 | log= # this is year zero; all past history is erased. | ||
43 | ( | ||
44 | set -x | ||
45 | kill $pids | ||
46 | ) | ||
47 | fi | ||
48 | else | ||
49 | log=$(last 10 $log 0) | ||
50 | fi | ||
51 | case "$log" in | ||
52 | *1* ) | ||
53 | echo IO '!!' $log >&2 | ||
54 | ;; | ||
55 | # * ) | ||
56 | # echo IO OK $log >&2 | ||
57 | # ;; | ||
58 | esac | ||
59 | ;; | ||
60 | "Current DISK"*) continue ;; | ||
61 | *) | ||
62 | set -- $line | ||
63 | pct=${10%.*} | ||
64 | pct_log="$pct_log $pct" | ||
65 | ;; | ||
66 | esac | ||
67 | done | ||
68 | } | ||
69 | |||
70 | sudo_iotop() | ||
71 | { | ||
72 | if [ "$UID" = 0 ] | ||
73 | then | ||
74 | command iotop "$@" | ||
75 | else | ||
76 | sudo iotop "$@" | ||
77 | fi | ||
78 | } | ||
79 | |||
80 | if [ $# -le 0 ] | ||
81 | then | ||
82 | exit | ||
83 | fi | ||
84 | |||
85 | pids=$* | ||
86 | |||
87 | sudo_iotop -qq -b $(printf '\55\55pid=%s\n' "$@") | iotop_reader | ||
diff --git a/src/ioslay-mgr.sh b/src/ioslay-mgr.sh new file mode 100755 index 0000000..56ab849 --- /dev/null +++ b/src/ioslay-mgr.sh | |||
@@ -0,0 +1,105 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | UNIT_NAME=ioslay | ||
4 | if [ "$1" = launch-unit ] | ||
5 | then | ||
6 | if systemctl --user is-active "$UNIT_NAME" | ||
7 | then systemctl --user restart "$UNIT_NAME" | ||
8 | else systemd-run --user -u "$UNIT_NAME" "$0" | ||
9 | fi | ||
10 | exit | ||
11 | fi | ||
12 | |||
13 | if [ -e /usr/lib/bash/sleep ] | ||
14 | then | ||
15 | enable -f /usr/lib/bash/sleep sleep | ||
16 | fi | ||
17 | |||
18 | export NOTICE=y | ||
19 | noticeLOG() { [ "$NOTICE" ] || return; echo "Notice: $*" >&2; } | ||
20 | debugLOG() { [ "$DBG" ] || return; echo "Debug: $*" >&2; } | ||
21 | |||
22 | . sliceweasel.lib.sh | ||
23 | |||
24 | vkill() | ||
25 | { | ||
26 | if [ $# = 0 ] | ||
27 | then | ||
28 | return | ||
29 | fi | ||
30 | ( | ||
31 | if [ "$(id -u)" = 0 ] | ||
32 | then sudo= | ||
33 | else sudo=sudo | ||
34 | fi | ||
35 | set -x | ||
36 | ps u "$@" | ||
37 | $sudo kill "$@" | ||
38 | ) | ||
39 | } | ||
40 | |||
41 | slay_slayer() | ||
42 | { | ||
43 | if [ "$ioslay" ] | ||
44 | then | ||
45 | children=$(for pid in $ioslay; do pgrep -P $ioslay; done) | ||
46 | grandchildren=$(for pid in $children; do pgrep -P $pid; done) | ||
47 | vkill $ioslay $children $grandchildren | ||
48 | fi | ||
49 | } | ||
50 | |||
51 | GROUP_BASENAME=firefox | ||
52 | |||
53 | group_procs=$(get_firefox_cgroup_procs) | ||
54 | |||
55 | ioslay= | ||
56 | lastprocs= | ||
57 | SIGNALLED= | ||
58 | trap 'SIGNALLED=y' SIGINT SIGTERM SIGHUP | ||
59 | while [ ! "$SIGNALLED" ] | ||
60 | do | ||
61 | if ! [ -e "$group_procs" ] | ||
62 | then | ||
63 | [ "$warned" ] || echo "Warning: firefox not running or cgroup not found" >&2 | ||
64 | warned=y | ||
65 | else | ||
66 | if [ "$warned" ] | ||
67 | then | ||
68 | echo "Found firefox cgroup: $group_procs" >&2 | ||
69 | warned= | ||
70 | fi | ||
71 | read -N 1000100 procs < "$group_procs" | ||
72 | if [ "$procs" ] | ||
73 | then | ||
74 | set -- | ||
75 | for pid in $procs | ||
76 | do | ||
77 | read comm < /proc/$pid/comm | ||
78 | case "$comm" in | ||
79 | 'Isolated Web Content' | 'Web Content' | 'Isolated Web Co') | ||
80 | set -- "$@" "$pid" | ||
81 | debugLOG "accept /proc/$pid/comm $comm" | ||
82 | ;; | ||
83 | *) | ||
84 | debugLOG "reject /proc/$pid/comm $comm" | ||
85 | esac | ||
86 | done | ||
87 | |||
88 | # echo "pids: ($*|$(echo $procs))" >&2 | ||
89 | if [ "$lastargs" != "$*" ] | ||
90 | then | ||
91 | slay_slayer | ||
92 | wait $ioslay | ||
93 | if [ $# -gt 0 ] | ||
94 | then | ||
95 | ioslay-firefox "$@" & | ||
96 | ioslay=$! | ||
97 | noticeLOG "Launched ioslay-firefox[$ioslay] $*" | ||
98 | fi | ||
99 | fi | ||
100 | lastargs=$* | ||
101 | fi | ||
102 | fi | ||
103 | sleep 1 | ||
104 | done | ||
105 | slay_slayer | ||
diff --git a/src/slice b/src/slice new file mode 100755 index 0000000..44ae13e --- /dev/null +++ b/src/slice | |||
@@ -0,0 +1,47 @@ | |||
1 | #!/bin/bash | ||
2 | default_percent='50' | ||
3 | keep_env=(XAUTHORITY DISPLAY) | ||
4 | set -e | ||
5 | |||
6 | usage() | ||
7 | { | ||
8 | cat <<EOF | ||
9 | Usage: $0 [percentage]% [--] command [arguments...] | ||
10 | |||
11 | The [percentage] argument must end with a literal '%'. | ||
12 | |||
13 | E.g.: | ||
14 | |||
15 | slice 50% firefox | ||
16 | |||
17 | The command cannot start with a literal '-'. | ||
18 | EOF | ||
19 | } | ||
20 | |||
21 | percent=$1 | ||
22 | case "$1" in | ||
23 | --) percent=$default_percent ;; | ||
24 | '' | -*) usage >&2; exit 1;; | ||
25 | *.*%) percent=${1%.*} ;; | ||
26 | *%) percent=${1%\%} ;; | ||
27 | esac | ||
28 | [ "$percent" -ge 0 ] | ||
29 | [ "$percent" -le 100 ] | ||
30 | |||
31 | shift | ||
32 | case "$1" in | ||
33 | --) shift ;; | ||
34 | esac | ||
35 | unit_name=$1 | ||
36 | |||
37 | keep_env_opts=() | ||
38 | for v in "${keep_env[@]}" | ||
39 | do | ||
40 | keep_env_opts+=(-E "${!v}") | ||
41 | done | ||
42 | |||
43 | systemd-run -u "$unit_name" \ | ||
44 | "${keep_env_opts[@]}" | ||
45 | "$0" "$@" | ||
46 | "$@" | ||
47 | |||
diff --git a/src/sliceuser b/src/sliceuser new file mode 100755 index 0000000..16d441f --- /dev/null +++ b/src/sliceuser | |||
@@ -0,0 +1,13 @@ | |||
1 | #!/bin/sh | ||
2 | . sliceweasel.lib.sh | ||
3 | |||
4 | set -e | ||
5 | IO_ROOT_DIR=$HOME/.cache/mozilla/firefox/ | ||
6 | [ -d "$IO_ROOT_DIR" ] | ||
7 | [ "$(id -un)" = 0 ] && AS_ROOT= || AS_ROOT='sudo --' | ||
8 | |||
9 | group=$(get_current_group) | ||
10 | set -x | ||
11 | set_max_ratio "$group" memory 3/4 | ||
12 | set_max_ratio "$group" io 8/10 | ||
13 | |||
diff --git a/src/sliceweasel b/src/sliceweasel new file mode 100755 index 0000000..f9df2c8 --- /dev/null +++ b/src/sliceweasel | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/bin/sh | ||
2 | . sliceweasel.lib.sh | ||
3 | |||
4 | set -e | ||
5 | IO_ROOT_DIR=$HOME/.cache/mozilla/firefox/ | ||
6 | [ -d "$IO_ROOT_DIR" ] | ||
7 | [ "$(id -un)" = 0 ] && AS_ROOT= || AS_ROOT='sudo --' | ||
8 | |||
9 | group=/sys/fs/cgroup/user.slice/user-$(id -u).slice/firefox | ||
10 | join_group "$group" | ||
11 | set_max_ratio "$group" memory 1/2 | ||
12 | set_max_ratio "$group" io 7/10 | ||
13 | exec firefox "$@" | ||
14 | |||
15 | |||
diff --git a/src/sliceweasel.lib.sh b/src/sliceweasel.lib.sh new file mode 100755 index 0000000..549e1e8 --- /dev/null +++ b/src/sliceweasel.lib.sh | |||
@@ -0,0 +1,154 @@ | |||
1 | #!/bin/sh | ||
2 | die() | ||
3 | { | ||
4 | printf '%s: Error: %s\n' "$0" "$*" >&2 | ||
5 | exit 1 | ||
6 | } | ||
7 | |||
8 | get_age() | ||
9 | { | ||
10 | local mtime now | ||
11 | mtime=$(stat --format=%Y "$1") || return | ||
12 | now=$(date +%s) || return | ||
13 | echo $(( now - mtime )) | ||
14 | } | ||
15 | |||
16 | get_filesystem() | ||
17 | { | ||
18 | echo / | ||
19 | } | ||
20 | |||
21 | get_total_memory() | ||
22 | { | ||
23 | free -b | { | ||
24 | read _ | ||
25 | read _ total _ | ||
26 | echo $total | ||
27 | } | ||
28 | } | ||
29 | |||
30 | math() | ||
31 | { | ||
32 | printf '%s\n' "$*" | bc -lq | ||
33 | } | ||
34 | |||
35 | get_total_io() | ||
36 | { | ||
37 | results=$IO_ROOT_DIR/io.test.result | ||
38 | zeroes=$IO_ROOT_DIR/io.test | ||
39 | if [ -e "$results" ] | ||
40 | then | ||
41 | age=$(get_age "$results") || return | ||
42 | if [ "$age" -gt $((60 * 60 * 24 * 7)) ] | ||
43 | then | ||
44 | rm "$results" | ||
45 | fi | ||
46 | fi | ||
47 | |||
48 | if ! [ -e "$results" ] | ||
49 | then | ||
50 | MEGS=128 | ||
51 | then=$(date +%s.%N) || return | ||
52 | dd if=/dev/zero of="$zeroes" bs=${MEGS}M count=1 || return | ||
53 | now=$(date +%s.%N) || return | ||
54 | rm "$zeroes" | ||
55 | speed=$(math $now - $then / $((MEGS * 1024 * 1024))) || return | ||
56 | echo $speed > "$results" | ||
57 | fi | ||
58 | read total < "$results" || return | ||
59 | echo ${total%.*} | ||
60 | } | ||
61 | |||
62 | root_write() | ||
63 | { | ||
64 | $AS_ROOT sh -c 'cat > "$1"' sh "$1" || true | ||
65 | } | ||
66 | |||
67 | join_group() | ||
68 | { | ||
69 | GROUP_DIR="$1" | ||
70 | [ -d "$GROUP_DIR" ] || $AS_ROOT mkdir "$GROUP_DIR" | ||
71 | echo $$ | root_write "$GROUP_DIR"/cgroup.procs | ||
72 | } | ||
73 | |||
74 | add_subtree_controller() | ||
75 | { | ||
76 | local group="$1" controller="$2" control_file | ||
77 | control_file="$group/cgroup.subtree_control" | ||
78 | |||
79 | [ "$group" ] && [ "$controller" ] && [ -d "$group" ] && [ -e "$control_file" ] || return | ||
80 | |||
81 | case "$group" in | ||
82 | /sys/fs/cgroup) ;; | ||
83 | *) add_subtree_controller "$(realpath "$group/..")" "$2" ;; | ||
84 | esac | ||
85 | |||
86 | if ! grep -qe "\\b${controller}\\b" "$control_file" | ||
87 | then | ||
88 | echo +"$controller" | root_write "$control_file" | ||
89 | fi | ||
90 | } | ||
91 | |||
92 | set_max() | ||
93 | { | ||
94 | max_file=$group/$2.max | ||
95 | if [ ! -e "$max_file" ] | ||
96 | then | ||
97 | add_subtree_controller "$1"/.. "$2" | ||
98 | [ -e "$max_file" ] || return | ||
99 | fi | ||
100 | printf '%s\n' "$3" | root_write "$max_file" | ||
101 | } | ||
102 | |||
103 | set_max_ratio() | ||
104 | { | ||
105 | local group="$1" controller="$2" ratio="$3" limit | ||
106 | total=$(get_total_$controller) | ||
107 | n=${ratio%%/*} | ||
108 | d=${ratio#$n/} | ||
109 | [ "$d" = "${d%/*}" ] || return | ||
110 | limit=$(( total * n / d )) | ||
111 | [ "$limit" ] || return | ||
112 | [ "$limit" -gt 0 ] || return | ||
113 | case "$controller" in | ||
114 | io) | ||
115 | fsroot=$(get_filesystem "$IO_ROOT_DIR") || return | ||
116 | # TODO: Do not use lsblk, because it fails to report the correct | ||
117 | # MOUNTPOINT when a bind mount is present. | ||
118 | majmin=$(lsblk -o 'MOUNTPOINT,MAJ:MIN' | sed -ne "s?^$fsroot *??p") || return | ||
119 | case "$majmin" in | ||
120 | *:*) ;; | ||
121 | *) echo "Error: majmin=$majmin" >&2; return 1 ;; | ||
122 | esac | ||
123 | set_max "$group" "$controller" "$majmin wbps=$limit rbps=$limit" | ||
124 | ;; | ||
125 | *) set_max "$group" "$controller" "$limit" | ||
126 | esac | ||
127 | } | ||
128 | |||
129 | get_uid() | ||
130 | { | ||
131 | ( | ||
132 | if [ "$SUDO_USER" ] | ||
133 | then | ||
134 | IFS=: | ||
135 | set -- $(getent passwd "${SUDO_USER}") || return | ||
136 | echo $3 | ||
137 | else | ||
138 | id -u | ||
139 | fi | ||
140 | ) | ||
141 | } | ||
142 | |||
143 | get_firefox_cgroup_procs() | ||
144 | { | ||
145 | uid=$(get_uid) | ||
146 | [ "$uid" ] || return | ||
147 | echo /sys/fs/cgroup/user.slice/user-$uid.slice/user@$uid.service/app.slice/firefox.service/cgroup.procs | ||
148 | } | ||
149 | |||
150 | get_current_group() | ||
151 | { | ||
152 | read g < /proc/$$/cgroup | ||
153 | echo /sys/fs/cgroup/${g#0::/} | ||
154 | } | ||
diff --git a/src/your-fired.sh b/src/your-fired.sh new file mode 100644 index 0000000..59efaf7 --- /dev/null +++ b/src/your-fired.sh | |||
@@ -0,0 +1,136 @@ | |||
1 | #!/bin/bash | ||
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 | enable -f /usr/lib/bash/sleep sleep 2>/dev/null || true | ||
129 | |||
130 | case "$*" in | ||
131 | forever) firefix_all_forever ;; | ||
132 | install) install_self firefixer "$0" forever 'Firefixer - adjust firefox OOM scores';; | ||
133 | once) firefix_all ;; | ||
134 | -h|--help) usage; exit ;; | ||
135 | *) usage; exit 1 ;; | ||
136 | esac | ||