tangetools/iothrottle/iothrottle.in
2024-12-29 02:57:09 +01:00

175 lines
3.4 KiB
Bash
Executable file

#!/bin/bash
: <<=cut
=pod
=head1 NAME
iothrottle - Limit IO to a given speed
=head1 SYNOPSIS
B<iothrottle> [-i read-speed] [-o write-speed] I<command>
=head1 DESCRIPTION
B<iothrottle> limits B<read>(2) and B<write>(2) to a given speed.
=head1 OPTIONS
=over 4
=item B<-i> I<input-speed>
Throttle B<read>(2) to I<input-speed> bytes per second.
To I<input-speed> you can append k, K, m, M, g, G to multiply by 1000,
1024, 1000000, 1048576 respectively.
=item B<-o> I<output-speed>
Throttle B<write>(2) to I<output-speed> bytes per second.
To I<output-speed> you can append k, K, m, M, g, G to multiply by 1000,
1024, 1000000, 1048576 respectively.
=back
=head1 EXAMPLE
Copy mydir at 1MB/s:
iothrottle -i 1M cp -a mydir/ /other/filesystem/
=head1 BUGS
Not all program use B<read>(2) and B<write>(2) for I/O.
These all use other methods: cp (to same filesystem), seq
File a bug report when you find other programs:
https://git.data.coop/tange/tangetools/issues
=head1 ENVIRONMENT VARIABLES
=over 9
=item $IOTHROTTLE_DEBUG=1
Turn on debugging.
=back
=head1 AUTHOR
Copyright (C) 2024 Ole Tange,
http://ole.tange.dk and Free Software Foundation, Inc.
=head1 LICENSE
Copyright (C) 2012 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
at your option any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
=head1 DEPENDENCIES
B<iothrottle> uses B<bash>.
=head1 SEE ALSO
B<ionice>, B<bwlimit>
=cut
_hex() {
local hex=dummy
echo $hex
}
_iothrottle.so() {
local iothrottleso=$(mktemp)
_hex |
LC_ALL=C awk '{for (i=1; i<=length($0); i+=2) printf "%c", strtonum("0x" substr($0, i, 2))}' > "$iothrottleso"
echo "$iothrottleso"
}
# Default values for input and output limits
INPUT_LIMIT=""
OUTPUT_LIMIT=""
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-i)
INPUT_LIMIT="$2"
shift 2
;;
-o)
OUTPUT_LIMIT="$2"
shift 2
;;
*)
break
;;
esac
done
# Convert limits to bytes
convert_to_bytes() {
local value="$1"
if [[ "$value" =~ ^[0-9]+K$ ]]; then
value=$(( ${value%K*} * 1024 ))
fi
if [[ "$value" =~ ^[0-9]+k$ ]]; then
value=$(( ${value%k*} * 1000 ))
fi
if [[ "$value" =~ ^[0-9]+M$ ]]; then
value=$(( ${value%M*} * 1024 * 1024 ))
fi
if [[ "$value" =~ ^[0-9]+m$ ]]; then
value=$(( ${value%m*} * 1000 * 1000 ))
fi
echo "$value"
}
IOTHROTTLE_READ=$(convert_to_bytes "$INPUT_LIMIT")
IOTHROTTLE_WRITE=$(convert_to_bytes "$OUTPUT_LIMIT")
# Export environment variables
export IOTHROTTLE_READ=${IOTHROTTLE_READ:-0}
export IOTHROTTLE_WRITE=${IOTHROTTLE_WRITE:-0}
# Preload the library and execute the remaining command
_so=$(_iothrottle.so)
if [ IOTHROTTLE_DEBUG = 1 ] ; then
echo LD_PRELOAD=$_so
LD_PRELOAD=$_so "$@"
else
LD_PRELOAD=$_so "$@"
rm $_so
fi