Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save g-ramirez/62e59d2354aa0a334eb619ee17e2e0c0 to your computer and use it in GitHub Desktop.
Save g-ramirez/62e59d2354aa0a334eb619ee17e2e0c0 to your computer and use it in GitHub Desktop.
#!/bin/bash -eu
#
# Origin: https://gist.github.com/dosaboy/c04fce37b99990bd1994da90e8e72e7e
#
# Authors:
# - edward.hope-morley@canonical.com
# - opentastic@gmail.com
#
# This must be executed on a node that has access to the Openstack apis.
#
# You must source your credentials before running this script.
#
# Returns average read and write iops used by the vm during the period
# specified.
script_name=/tmp/virsh_domain_iops_throttling.sh
cat << 'EOF' > $script_name
#!/bin/bash -eu
statspath=/tmp/virsh-blkdev-settings
mkdir -p $statspath
# Required deps
dpkg -s jq| grep -q "Status: install ok installed" || sudo apt install -y jq
save ()
{
domain=$1
device=$2
(($#>1)) || { echo "ERROR: not enough args"; return 1; }
results=$statspath/$domain
mkdir -p $results
for key in read_iops_sec write_iops_sec; do
results_key=$results/${device}_$key
if [ -r "$results_key" ]; then
echo "Domain $results_key already saved."
else
val=`virsh blkdeviotune $domain $device| sed -r "s/^$key\s*:\s*(.+)/\1/g;t;d"`
[ -n "$val" ] || { echo "ERROR: no value found for $domain $device $key"; continue; }
echo "$val" > $results_key
echo "Domain $results_key saved."
fi
done
}
apply ()
{
domain=$1
device=$2
iops_rd=$3
iops_wr=$4
(($#>3)) || { echo "ERROR: not enough args"; return 1; }
echo "Setting domain '$domain' --read-iops-sec $iops_rd --write-iops-sec $iops_wr"
read -p "OK? Hit [ENTER] to continue"
virsh blkdeviotune $domain $device --read-iops-sec $iops_rd --write-iops-sec $iops_wr
echo "Done."
}
restore ()
{
domain=$1
device=$2
(($#>1)) || { echo "ERROR: not enough args"; return 1; }
declare -A lookup=(
["read_iops_sec"]="--read-iops-sec"
["write_iops_sec"]="--write-iops-sec"
)
results=$statspath/$domain
args=()
for key in read_iops_sec write_iops_sec; do
results_key=$results/${device}_$key
if [ -r "$results_key" ]; then
val=`cat $results_key`
[ -n "$val" ] || echo "ERROR: $results_key has no value"
args+=( "${lookup[$key]} $val" )
else
echo "No saved settings for domain '$domain' dev $device"
break
fi
done
((${#args[@]}>0)) || continue
echo "Restoring domain '$domain' ${args[@]} "
virsh blkdeviotune $domain $device ${args[@]}
echo "Done."
}
EOF
chmod +x $script_name
# The following will ssh into the compute host as non-root user.
# You can then execute the script. You must first load the functions:
#
# . ./$script_name
#
# Then create a backup of all existing settings:
#
# save <domain> <device>
#
# Then you can go ahead and apply the new settings to all vms on this host:
#
# apply <domain> <device> <rd_iops_max> <wr_iops_max>
#
# If you need to restore settings you can do:
#
# restore <domain> <device>
#
readarray -t machines<<<"`juju status --format=json nova-compute| jq -r '.machines[]| .\"dns-name\"'`"
echo "Copying script '$script_name' to compute hosts: ${machines[@]}"
for m in "${machines[@]}"; do
juju scp $script_name $m: &
done
wait
echo "You can now log into any compute host and execute commands by doing:'"
echo -e "\n. ./`basename $script_name`; [save <domain> <dev>|apply <domain> <dev>|restore <domain> <dev>]\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment