If you provide space for customer's data you probably get request from management to provide info about usable and allocated disk/storage space.
Usable is what you provide to customer (if you have two mirrored 300G disks, you provide 300G or something less, since some space goes for metadata).
Allocated is what is used at the moment and this is actually what you charge (billable storage).
Since I had variety of configurations and storages, like internal disks, DAS (directly attached storage), and SAN (storage area network), it was convenient for me to write script that easily generates storage report.
I had UFS/ZFS file systems. The UFS was on the top of SVM (Solaris Volume Manager).
I also had different file systems within one device, so script has to sum them and report one disk size as total for that system.
The idea was to have a configuration file with HOSTNAME:METADEVICE_OR_ZFS:DESC:UFS/ZFS and to have script that reads configuration file and generate the report.
# HOSTNAME:METADEVICE_OR_ZFS:DESC:UFS/ZFS #------------------------------------- # --------- sds1 StorEdge 6120 kingkong:t1_sds1-s0:sds1:zfs # --------- sds2 StorEdge 6120 trex:fc.san.hrc.r10.sds2-s1:sds2:zfs # --------- sds3 StorEdge 6120 trex:fc.san.hrc.r10.sds3-s0:sds3:zfs # --------- sds4 StorEdge 6120 kingkong:sds4-s1:sds4:zfs # --------- sds5 StorEdge 6120 kingkong:sds5-s0:sds5:zfs snake:sds5-1:sds5:zfs # --------- sds6 StorEdge 6120 trex:sds6-s2:sds6:zfs # --------- sds7 StorEdge 6120 kingkong:sds7-s0:sds7:zfs # --------- sds8 StorEdge 6120 kingkong:space:sds8:zfs # ---------- tip-0 StorEdge 3510 gorilla:d100:tip-0:ufs # ---------- tip-1 StorEdge 3510 gorilla:d200:tip-1:ufs # --------- gorilla-internal SunFire X4200 gorilla:ora01:gorilla-internal:zfs # ---------- winston StorEdge 6130 unicorn:d100:winston:ufs # ---------- lucky StorEdge 6130 unicorn:d200:lucky:ufs # --------- unicorn-internal SunFire X4200 unicorn:ora01:unicorn-internal:zfs # --------- monkey SunFire X4500 monkey:pool.0:monkey:zfs monkey:pool.1:monkey:zfs monkey:pool.2:monkey:zfs |
The script is
# cat reportstorage.sh
#!/bin/sh
#set -x
# -----------------------------------------------
# Gets storage report for manager's name
# -----------------------------------------------
# configuration file
global_infile=storage.conf
# prepare input file, ignore comments and blank lines, uniq (maybe duplicated entries), sort
cat ${global_infile} | sed -e '/^#/d' -e '/^$/d' | sort | uniq > ${global_infile}.$$
# separate input temporary file for ufs/zfs
ufs_infile=ufs_infile.$$
zfs_infile=zfs_infile.$$
cat ${global_infile}.$$ | awk -F: '$4=="ufs"' > ${ufs_infile}
cat ${global_infile}.$$ | awk -F: '$4=="zfs"' > ${zfs_infile}
# ---------------------------------
# functions
# -------------------------------
# --- FUNCTION: process hosts with ufs/metadevices
process_ufs() {
# get list of hosts that has metadevices
ufs_hostlist=`cat ${ufs_infile} | awk -F: '{print $1}' | sort | uniq`
# process host
for ufs_host in ${ufs_hostlist}
do
fping -q ${ufs_host} #-q=quite
if [ $? -eq 0 ]
then
# for system in the loop, get mount point of metadevice, from ${ufs_infile}
metadevice=`cat ${ufs_infile} | awk -F: '$1=="'${ufs_host}'" {print $2}'`
# process all metadevices in a system
for md in ${metadevice}
do
# find mount point of metadevice
mount=`ssh ${ufs_host} mount | gegrep -w "/dev/md/dsk/${md}" | awk '{print $1}'`
# find total size of md
usable=`ssh ${ufs_host} df -k ${mount} | gegrep -v "^Filesystem" | awk '{print $2}'` # total
# find used size of md
alocated=`ssh ${ufs_host} df -k ${mount} | gegrep -v "^Filesystem" | awk '{print $3}'` #used
# from ${ufs_infile} get description of metadevice
ufs_desc=`cat ${ufs_infile} | awk -F: '$1=="'${ufs_host}'" && $2=="'${md}'" {print $3}'`
# screen output FYI
printf "%-20s %-20s %-20s %-20s %-20s \n" \
"Host:${ufs_host}" "Mount:${mount}" " Desc:${ufs_desc}" \
"Total[KB]=${usable}" "Used[KB]=${alocated}"
# feed tmp file for further processing
echo ${ufs_desc} >> ufs_desc.$$
echo "${ufs_desc} ${usable} ${alocated}" >> ufs_of.$$
done
else
echo "Host ${ufs_host} is not reachable."
fi
done
}
# --- FUNCTION: process hosts with zfs
process_zfs() {
# get list of hosts that has zfs
zfs_hostlist=`cat ${zfs_infile} | awk -F: '{print $1}' | sort | uniq`
# process host
for zfs_host in ${zfs_hostlist}
do
fping -q ${zfs_host} #-q=quite
if [ $? -eq 0 ]
then
# for system in the loop, get zfs, from ${zfs_infile}
zetafs=`cat ${zfs_infile} | awk -F: '$1=="'${zfs_host}'" {print $2}'`
# process all zfs in a system
for zfs in ${zetafs}
do
# find used, avail, total size of zfs
used=`ssh ${zfs_host} zfs get -H -p used ${zfs} | awk '{print $3}'` # allocated in bytes
avail=`ssh ${zfs_host} zfs get -H -p avail ${zfs} | awk '{print $3}'` # free in bytes
total=`(echo "${used}+${avail}" | bc -l)` # total in bytes
# from ${zfs_infile} get description of zfs
zfs_desc=`cat ${zfs_infile} | awk -F: '$1=="'${zfs_host}'" && $2=="'${zfs}'" {print $3}'`
# screen output FYI
printf "%-20s %-20s %-20s %-20s %-20s \n" \
"Host:${zfs_host}" "ZFS:${zfs}" " Desc:${zfs_desc}" "Total[B]:${total}" "Used[B]:${used}"
# feed tmp file for further processing
echo ${zfs_desc} >> zfs_desc.$$
echo "${zfs_desc} ${total} ${used}" >> zfs_of.$$
done
else
echo "Host ${zfs_host} is not reachable."
fi
done
}
# --- FUNCTION: clean temp files
tmp_file_cleaning() {
[ -f ${global_infile}.$$ ] && rm ${global_infile}.$$
[ -f ${ufs_infile} ] && rm ${ufs_infile}
[ -f ufs_desc.$$ ] && rm ufs_desc.$$
[ -f ufs_of.$$ ] && rm ufs_of.$$
[ -f ${zfs_infile} ] && rm ${zfs_infile}
[ -f zfs_desc.$$ ] && rm zfs_desc.$$
[ -f zfs_of.$$ ] && rm zfs_of.$$
}
# --- cleaning in case of script termination and regular exit
trap tmp_file_cleaning HUP INT QUIT ABRT EXIT
# Process UFS and ZFS
process_ufs ; process_zfs
# ----- LOOK FOR SAME DESCRIPTION AND SUM THEIR VALUES
# remove duplicated description from tmp file
cat ufs_desc.$$ | sort| uniq > ufs_desc.$$.tmp ; mv ufs_desc.$$.tmp ufs_desc.$$
cat zfs_desc.$$ | sort| uniq > zfs_desc.$$.tmp ; mv zfs_desc.$$.tmp zfs_desc.$$
# print title on screen FYI
printf "------------------------------------------------------------------------- \n"
printf "%-15s %15s %15s \n" "Description" "Usable/Total[GB]" "Allocated/Used[GB]"
printf "------------------------------------------------------------------------- \n"
# for each description, calculate sum values, print on screen
# UFS - received in KB
for description in `cat ufs_desc.$$`
do
cat ufs_of.$$ | \
awk '$1=="'${description}'" {sumusable+=$2; sumalocated+=$3} \
END {printf "%-15s %11.0f %15.0f \n", "'${description}'", sumusable/1024/1024, sumalocated/1024/1024, "\n" }'
done
# ZFS - received in B
for description in `cat zfs_desc.$$`
do
cat zfs_of.$$ | \
awk '$1=="'${description}'" {sumusable+=$2; sumalocated+=$3} \
END {printf "%-15s %11.0f %15.0f \n", "'${description}'", sumusable/1024/1024/1024, sumalocated/1024/1024/1024, "\n" }'
done
exit 0
|
Output during processing is like:
# sh reportstorage.sh Host:gorilla Mount:/ora02 Desc:tip-0 Total[KB]=351683990 Used[KB]=51386171 Host:gorilla Mount:/ora03 Desc:tip-1 Total[KB]=351683990 Used[KB]=104905219 Host:tiger Mount:/.0 Desc:tiger-internal Total[KB]=10326524 Used[KB]=1580099 Host:tiger Mount:/shipping Desc:tiger-internal Total[KB]=10326524 Used[KB]=10307 Host:tiger Mount:/viewstore Desc:tiger-internal Total[KB]=103269854 Used[KB]=66251208 Host:tiger Mount:/buildstore Desc:tiger-internal Total[KB]=103269854 Used[KB]=14611264 Host:tiger Mount:/ccase_rls Desc:tiger-internal Total[KB]=20653809 Used[KB]=13518282 Host:tiger Mount:/vobstore Desc:tiger-internal Total[KB]=359090412 Used[KB]=263585448 Host:unicorn Mount:/.100 Desc:winston Total[KB]=207028354 Used[KB]=139473176 Host:unicorn Mount:/.200 Desc:lucky Total[KB]=207028354 Used[KB]=59108156 Host:trex ZFS:fc.san.hrc.r10.sds2-s1 Desc:sds2 Total[B]:930128855040 Used[B]:745045099008 Host:trex ZFS:fc.san.hrc.r10.sds3-s0 Desc:sds3 Total[B]:930128855040 Used[B]:871588045824 Host:trex ZFS:scsi.das.zfs.r60.d1-12 Desc:trex-das Total[B]:2342762053632 Used[B]:1355473254762 Host:trex ZFS:scsi.int.zpool.r1.d2d3 Desc:trex-internal Total[B]:71873593344 Used[B]:599597056 Host:trex ZFS:sds6-s2 Desc:sds6 Total[B]:1910992011264 Used[B]:1310114274816 Host:pigeon ZFS:pool.0 Desc:pigeon Total[B]:14571842568192 Used[B]:6553773370872 Host:borax ZFS:bob.0 Desc:bob0-4.div.w.5 Total[B]:1175344644096 Used[B]:722208151552 Host:borax ZFS:space.1 Desc:borax-das-1 Total[B]:1752909742080 Used[B]:1562364591690 Host:borax ZFS:space.2 Desc:borax-das-2 Total[B]:1752909742080 Used[B]:1286738422500 Host:clearvoice ZFS:space0 Desc:clearvoice-internal Total[B]:293836161024 Used[B]:270715788800 |
The result on the screen is like:
---------------------------------------------------- Description Usable/Total[GB] Allocated/Used[GB] ---------------------------------------------------- tiger-internal 579 343 lucky 197 56 tip-0 335 49 tip-1 335 100 winston 197 133 trex-das 2182 1262 trex-internal 67 1 pigeon 13571 6104 |