Last active
May 27, 2020 08:12
-
-
Save hypersoft/b8d45379c43b0d0e2fa0c7bfc7f57669 to your computer and use it in GitHub Desktop.
User-Level: Process IO, CPU and Memory throttling using systemd-run, in a convenient shell script.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
function throttle.help() { cat<<EOF | |
throttle [OPTIONS] COMMAND | |
OPTIONS: | |
-- Stop options processing and execute COMMAND using systemd-run. | |
-c or --cpu PERCENTAGE Limit the process and children to the percentage | |
set by the following percentage. DO NOT supply | |
the percentage-sign with this option. All child | |
process will be limited to the percentage | |
specified for every cpu on the system. | |
Note that this is an integer value, for example: | |
throttle --cpu 89 ... | |
89 in the above example, means: 89% of each cpu. | |
-m or --memory BYTES Limit the process and children's memory usage to | |
the amount of BYTES specified as K, M, G, or T. | |
For example: throttle -m 248M ... | |
248M in the above example, means 248 megabytes. | |
-b or --block-io BYTES Limit the process and children's io bandwidth to | |
the amount of BYTES specified as K, M, G, or T. | |
This option will configure bandwidth limiting on | |
all block devices. | |
For example: throttle -b 480M ... | |
480M in the above example, means 480 megabytes | |
per-second. | |
-h or --help Show this help screen. | |
GUI OPTIONS | |
Fire up a zenity dialog, and request a feature setting from the user: | |
--request-memory, --request-cpu and --request-block-io | |
You will be prompted for your password to configure the systemd-units, | |
depending on your system configuration. If your system uses polkit, | |
you can typically find the configuration in: | |
/usr/share/polkit-1/actions/org.freedesktop.systemd1.policy | |
(C) 2018; Hypersoft-Systems: U.-S.-A. | |
EOF | |
} | |
while [[ ${1:0:1} == - ]]; do | |
[[ "$1" == -- ]] && { | |
shift; break; | |
} | |
[[ "$1" =~ ^-(-cpu|c) ]] && { | |
UPROC="$2"; shift 2; continue; | |
} | |
[[ "$1" == --request-cpu ]] && { | |
UPROC=`zenity --title "Set CPU Limit for process" --entry --text "How much should CPU usage (0-100) be limited by?" --entry-text "33" || echo quit`; | |
[[ $UPROC == quit ]] && exit 1; | |
shift; continue | |
} | |
[[ "$1" =~ ^-(-memory|m) ]] && { | |
UMEM="$2"; shift 2; continue; | |
} | |
[[ "$1" == --request-memory ]] && { | |
UMEM=`zenity --title "Set memory Limit for process" --entry --text "How many bytes should memory consumption be limited by?" --entry-text "480M" || echo quit`; | |
[[ $UMEM == quit ]] && exit 1; | |
shift; continue | |
} | |
[[ "$1" =~ ^-(-block-io|b) ]] && { | |
UBLKIO="$2"; shift 2; continue; | |
} | |
[[ "$1" == --request-block-io ]] && { | |
UBLKIO=`zenity --title "Set Block IO Limit for process" --entry --text "How many bytes-per-second should block-io be limited by?" --entry-text "480M" || echo quit`; | |
[[ $UBLKIO == quit ]] && exit 1; | |
shift; continue | |
} | |
[[ "$1" =~ ^-(-help|h) ]] && { | |
throttle.help; shift; exit 1; | |
} | |
# unknown argument: | |
break; | |
done; | |
# takes a bandwidth-measurement suffixed with: K, M, G, or T, the specified bandwidth is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes, respectively, to the base of 1000. | |
[[ -n $UBLKIO ]] && { | |
USER_BLOCK_SETTING=`ls /dev/disk/by-uuid/* | while read line; do echo "-p IOAccounting=true -p IOWriteBandwidthMax='$line $UBLKIO'"; done` | |
}; | |
# takes a percentage without the percent-sign. percentage-value applies to each processor-core. | |
[[ -n $UPROC ]] && { | |
CORES=`grep -c ^processor /proc/cpuinfo`; | |
USER_CPU_SETTING="-p CPUAccounting=true -p CPUQuota="`echo $CORES'*'$UPROC | bc`"%" | |
}; | |
# takes a memory-measurement suffixed with: K, M, G, or T, the specified memory is parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes, respectively, to the base of 1000. | |
[[ -n $UMEM ]] && { | |
USER_MEMORY_SETTING="-p MemoryAccounting=true -p MemoryHigh=$UMEM"; | |
}; | |
# this command is evaluated becuase BLKIO creates parameters with embedded spaces. | |
eval systemd-run -G --uid=$UID $USER_BLOCK_SETTING $USER_MEMORY_SETTING $USER_CPU_SETTING --scope "$@"; | |
exit $?; |
Final rant: they guy(s) who wrote systemd-run are morons for asking me to enter MY password to set process limits on a user-process. Also, option --no-ask-password is VOID. Another round of moron-mania... And the guys at ArchLinux are morons, because for whatever reason, I can't use the --user option. sudo throttle DELINQUENT, doesn't work either. "Can't find display" and all that non-sense. I think you have to write a service and a helper script to pipe commands you want to launch. Anyway, too much BS for control of my own processes: FROM THE BEGINNING.
Why is throttle.sh -b 1024 dd if=/dev/urandom of=/tmp/BIN bs=1M count=1 conv=fdatasync
not working?
PS : I share your angriness
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By the way, my system is running fairly snappy and happy! I do have to say this because its a fact: These software developers who make these misbehaving apps are morons.
I run android-studio at 60% cpu on an intel Intel(R) Pentium(R) CPU G620 @ 2.60GHz with 768MB of RAM-LIMIT, 480M BLKIO (usb 2.0 speed) and it runs faster than it does when you let it go all the way: frequently locking up the whole system.
For firefox 128M RAM, 30% CPU.
SHIT HAS NEVER BEEN SO FUCKING BREEZY.