--- /dev/null
+#!/bin/bash
+#
+# dmdedup-info script
+#
+# Copyright (c) 2012 Gary Lent
+# Copyright (c) 2012 File Systems and Storage Lab
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation
+#
+# This file contains a shell script to take the output of the
+# `dmsetup status` command, perform all necessary processing,
+# and output information about any deduplication devices in a
+# human-readable format.
+#
+
+# Converts between G, M, K, B, and blocks. Takes the number to convert,
+# the conversion between blocks and bytes, and the target unit
+# (options are G, M, K, B, or anything else). Echoes the result, but does
+# not return it.
+convert_unit()
+{
+ number=$1
+ conversion=$2
+ target=$3
+ case "${3}" in
+ G) div=`expr 1024 \* 1024 \* 1024`;;
+ M) div=`expr 1024 \* 1024`;;
+ K) div=1024;;
+ B) div=1;;
+ *) div=1
+ conversion=1
+ ;;
+ esac
+ val=`expr $number \* $conversion / $div`
+ echo $val
+}
+
+# Triggers the status method of the dmdedup target to get the necessary statistics
+# info and prints in the required format
+pull_status()
+{
+ uflag=$1;
+ dmsetup status | while read name start end type dtotal dfree dused dactual\
+ dblock ddisk mddisk writes uniqwrites dupwrites readonwrites\
+ overwrites newwrites
+ do
+ if [ $type == "dedup" ] ; then
+ # Use I/O redirection to avoid subshell problem with |
+ # Dig through /proc/diskstats to match up device major/minor
+ # numbers with device paths.
+ exec 3<> /proc/diskstats
+ while read d1 d2 d3 d4 <&3
+ do
+ if [[ $d1 == ${ddisk%:*} ]] && [[ $d2 == ${ddisk#*:} ]] ; then
+ datadisk="/dev/"$d3
+ elif [[ $d1 == ${mddisk%:*} ]] && [[ $d2 == ${mddisk#*:} ]] ; then
+ metadisk="/dev/"$d3
+ fi
+ done
+ exec 3>&-
+ #If you've not used the device, ratios are set to 1
+ if [ $dused == 0 ] || [ $dactual == 0 ] ; then
+ dratio="n/a"
+ else
+ # Just data ratio: bytes in / bytes out
+ # -> 3 decimal places
+ dratio=`echo "scale=3;($dactual*$dblock)/"\
+ "($dused*$dblock)" | bc`
+ # Ratio with metadata: bytes in / (bytes out + bytes of
+ # metadata space taken up) -> 3 decimal places
+ fi
+ if [ "$uflag" -ne "1" ] ; then
+ dunits=$dblock"B blocks"
+ fi
+ # Strip the ':' from the end of the device name
+ echo " ******************dmdedup device info****************"
+ echo $name | sed 's/.$//'
+ echo -e " Start sector:" $start "\n End sector:" $end
+ # Converting each number to the right units makes it easy
+ # to change / add units
+
+ echo -e " Data ("$datadisk"):" \
+ `convert_unit $dtotal $dblock $dunits` \
+ "total($dunits),\n " \
+ `convert_unit $dfree $dblock $dunits` "free," \
+ `convert_unit $dused $dblock $dunits` "physical," \
+ `convert_unit $dactual $dblock $dunits` "logical"
+
+ echo " Writes: $writes"
+ echo " Unique Writes: $uniqwrites"
+ echo " Duplicate Writes: $dupwrites"
+ echo " Read-on-Writes: $readonwrites"
+ echo " Overwrites: $overwrites"
+ echo " New writes: $newwrites"
+
+ echo " Dedup ratio without metadata: "$dratio
+ echo -e " "
+ echo " ******************dm_bufio parameters****************"
+ echo -e " Max_cache size bytes:" \
+ `cat /sys/module/dm_bufio/parameters/max_cache_size_bytes`
+ echo -e " Current_allocated bytes:" \
+ `cat /sys/module/dm_bufio/parameters/current_allocated_bytes`
+ echo -e " Allocated(free_pages) bytes:" \
+ `cat /sys/module/dm_bufio/parameters/allocated_get_free_pages_bytes`
+ echo -e " Allocated(kmem_cache) bytes:" \
+ `cat /sys/module/dm_bufio/parameters/allocated_kmem_cache_bytes`
+ echo -e " Allocated(vmalloc) bytes:" \
+ `cat /sys/module/dm_bufio/parameters/allocated_vmalloc_bytes`
+ echo -e " Peak_allocated bytes:" \
+ `cat /sys/module/dm_bufio/parameters/peak_allocated_bytes`
+ echo -e " Max_age seconds:" \
+ `cat /sys/module/dm_bufio/parameters/max_age_seconds`
+ fi
+ done
+}
+
+# Check if 'bc' is installed
+command -v bc >/dev/null ||
+ { echo "Please install 'bc' to use this script"; exit 1; }
+
+# Flags used for checking correctness of the options
+sflag=0;
+uflag=0;
+
+while getopts “t:gmkbBh” OPTION; do
+ case $OPTION in
+ t)
+ sleepTime=$OPTARG
+ sflag=$(($sflag+1))
+ ;;
+ g) dunits="G"
+ mdunits="G"
+ uflag=$(($uflag+1))
+ ;;
+ m) dunits="M"
+ mdunits="M"
+ uflag=$(($uflag+1))
+ ;;
+ k) dunits="K"
+ mdunits="K"
+ uflag=$(($uflag+1))
+ ;;
+ b) dunits="B"
+ mdunits="B"
+ uflag=$(($uflag+1))
+ ;;
+ B) dunits=$dblock"B blocks"
+ mdunits=$mdblock"B blocks"
+ uflag=$(($uflag+1))
+ ;;
+ h) echo -e "Flag options:"
+ echo -e "\t-t [sleepTime in seconds] For printing dmdedup system
+ info after every [sleepTime] seconds"
+ echo -e "\t-B\tDisplay in blocks (default)"
+ echo -e "\t-g\tDisplay in gigabytes"
+ echo -e "\t-m\tDisplay in megabytes"
+ echo -e "\t-k\tDisplay in kilobytes"
+ echo -e "\t-b\tDisplay in bytes"
+ echo -e "\t-h\tPrint flag options"
+ exit 0
+ ;;
+ \?) exit 1
+ ;;
+ esac
+done
+
+#
+# At any point only one unit of conversion is valid and only one
+# sleep time is valid
+#
+if [ "$sflag" -gt "1" ] || [ "$uflag" -gt "1" ]; then
+ echo "Specify only one unit of conversion or only one timeunit for sleep"
+ exit 1;
+fi
+
+# When '-t' option not set, the process doesn't sleep
+if [ "$sflag" -eq "0" ]; then
+ sleepTime=-1;
+fi
+
+# Main loop
+while :
+do
+ pull_status $uflag;
+ if [ "$sleepTime" -lt "0" ]; then
+ exit 0;
+ fi
+ sleep $sleepTime;
+done