Skip to content

Instantly share code, notes, and snippets.

@hypersoft
Last active May 27, 2020 08:12
Show Gist options
  • Save hypersoft/b8d45379c43b0d0e2fa0c7bfc7f57669 to your computer and use it in GitHub Desktop.
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.
#!/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 $?;
@tbarbette
Copy link

tbarbette commented Aug 21, 2019

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