diff options
author | Andrew Cady <d@jerkface.net> | 2018-06-12 16:48:48 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2018-06-12 16:48:48 -0400 |
commit | 097abc2307be83290743b15045ecf5a1f03637af (patch) | |
tree | 7df39ba46b6e163aed836fbaed22847f2612d5ff | |
parent | 5148ebc85dc3e663eee3fc8156fa8589cf899acc (diff) |
sliceweasel
-rw-r--r-- | dot/local/bin/sliceweasel | 101 |
1 files changed, 89 insertions, 12 deletions
diff --git a/dot/local/bin/sliceweasel b/dot/local/bin/sliceweasel index 944f12a..1ec45db 100644 --- a/dot/local/bin/sliceweasel +++ b/dot/local/bin/sliceweasel | |||
@@ -1,4 +1,5 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | VERBOSE=y | ||
2 | 3 | ||
3 | command=iceweasel | 4 | command=iceweasel |
4 | memory_ratio=0.5 | 5 | memory_ratio=0.5 |
@@ -7,20 +8,96 @@ control_group=$command | |||
7 | as_root=sudo | 8 | as_root=sudo |
8 | 9 | ||
9 | total_memory() { free -b | (read line; read Mem total _; echo $total); } | 10 | total_memory() { free -b | (read line; read Mem total _; echo $total); } |
10 | mkdir_idem() { [ -d "$1" ] || $as_root mkdir "$1"; } | ||
11 | out() { $as_root tee "$@" >/dev/null; } | 11 | out() { $as_root tee "$@" >/dev/null; } |
12 | 12 | ||
13 | total_memory=$(total_memory) || exit 1 | 13 | die() { printf 'Error: %s\n' "$*" >&2; exit 1; } |
14 | memory_limit_in_bytes=$(bc -q <<< "$total_memory * $memory_ratio / 1" ) | 14 | verbose() { [ ! "$VERBOSE" ] || printf '%s\n' "$*" >&2; } |
15 | control_group_dir=/sys/fs/cgroup/memory/"$control_group" | ||
16 | 15 | ||
17 | mkdir_idem "$control_group_dir" | 16 | total_memory=$(total_memory) || die "could not ascertain total system memory; probable bug" |
18 | out "$control_group_dir"/memory.limit_in_bytes <<< $memory_limit_in_bytes | 17 | memory_limit_in_bytes=$(bc -q <<< "$total_memory * $memory_ratio / 1" ) || die "process 'bc' failed. Is it installed?" |
19 | 18 | ||
20 | # This method works (tested). | 19 | init_control_group() |
21 | # username=$(id -u) | 20 | { |
22 | # exec sudo -E -- cgexec -g memory:"$control_group" -- su "$username" -c "exec $command" | 21 | control_group_dir=/sys/fs/cgroup/memory/"$control_group" |
22 | [ -d "$control_group_dir" ] && return | ||
23 | $as_root mkdir "$control_group_dir" || die "mkdir failed" | ||
24 | set_memory_limit $memory_limit_in_bytes || die "set_memory_limit failed" | ||
25 | } | ||
23 | 26 | ||
24 | # This method is untested. Should work the same. | 27 | get_memory_limit() |
25 | out "$control_group_dir"/cgroup.procs <<< $$ | 28 | { |
26 | exec $command | 29 | cat "$control_group_dir"/memory.limit_in_bytes |
30 | } | ||
31 | |||
32 | set_memory_limit() | ||
33 | { | ||
34 | prev=$(get_memory_limit) | ||
35 | if [ "$1" -ne "$prev" ]; then | ||
36 | out "$control_group_dir"/memory.limit_in_bytes <<< $1 | ||
37 | verbose "changed memory limit ($prev -> $1)" | ||
38 | else | ||
39 | verbose "memory limit unchanged ($prev)" | ||
40 | fi | ||
41 | } | ||
42 | |||
43 | join_control_group() | ||
44 | { | ||
45 | out "$control_group_dir"/cgroup.procs <<< $$ | ||
46 | } | ||
47 | |||
48 | get_cgroup() | ||
49 | { | ||
50 | local key="$1" pid="${2:-$$}" line val | ||
51 | while read line; do | ||
52 | line=${line#*:} | ||
53 | val=${line#$key:} | ||
54 | [ "$val" != "$line" ] || continue | ||
55 | echo "$val" | ||
56 | return | ||
57 | done < /proc/"$pid"/cgroup | ||
58 | false | ||
59 | } | ||
60 | |||
61 | launch_command() | ||
62 | { | ||
63 | init_control_group || die "init_control_group failed" | ||
64 | cg=$(get_cgroup memory) || die "failed to ascertain current control group" | ||
65 | [ "$cg" = / ] || die "current control group should be '/', but is instead '$cg'" | ||
66 | join_control_group || die "join_control_group failed" | ||
67 | exec $command "$@" | ||
68 | } | ||
69 | |||
70 | pretty_show_memory_limit() | ||
71 | { | ||
72 | local memory_limit="$(get_memory_limit)" | ||
73 | printf "current memory limit: %d bytes (%d%%)\n" \ | ||
74 | "$memory_limit" \ | ||
75 | "$((memory_limit * 100 / total_memory))" | ||
76 | } | ||
77 | |||
78 | resize_control_group() | ||
79 | { | ||
80 | init_control_group | ||
81 | case "$1" in | ||
82 | '') pretty_show_memory_limit >&2 ;; | ||
83 | [0-9]*%) set_memory_limit $((total_memory * "${1%\%}" / 100)) ;; | ||
84 | [0-9]*) set_memory_limit "$1" ;; | ||
85 | [-+*/][0-9]*) set_memory_limit $(( $(get_memory_limit) "$1" )) ;; | ||
86 | esac | ||
87 | } | ||
88 | |||
89 | usage() | ||
90 | { | ||
91 | cat >&2 <<EOF | ||
92 | usage: ${0##*/} [--resize|--resize <bytes>|--resize=<bytes>] [--] [pass-through-options] [...] | ||
93 | ${0##*/} --help | ||
94 | EOF | ||
95 | } | ||
96 | |||
97 | case "$1" in | ||
98 | --) shift; launch_command "$@" ;; | ||
99 | --resize) resize_control_group "$2" ;; | ||
100 | --resize=*) resize_control_group "${1#--resize=}" ;; | ||
101 | --*) usage; [ "$1" = '--help' -o "$1" = '--usage' ] ;; | ||
102 | *) launch_command "$@" ;; | ||
103 | esac | ||