Created
November 1, 2015 21:05
-
-
Save iMartyn/015ff0f1ea20d5fa9b8f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
usage() { | |
echo "Find the true writable size of a device in mb. Useful for cheap/fake" | |
echo "SD Cards, mp3 players etc. that have been missold." | |
echo "NOTE: the data on the device WILL be destroyed" | |
echo "" | |
echo "Options:" | |
echo "" | |
echo " -h|-?|--help Show this help text" | |
echo " -d /dev/something Destination device" | |
echo " -v Be verbose about what is currently being done" | |
echo " -f /some/file Use this source file (1M file) instead of random data" | |
echo " -m maxsize Specify the max size (e.g. -m 48) that you want to test to" | |
echo " otherwise, size of device reported is assumed" | |
echo " -s startsize Specify where you want to start (e.g. -m 129) in meg" | |
echo " -p Print chars whilst working. W=write, R=read, .=comparing, -=no error." | |
echo " -2 Spot check at 1M, 2M, 4M, 8M, 16M etc." | |
echo " Recommendation, do this and then rerun starting from half of" | |
echo " where it reached, i.e. if it says it's a 32M device," | |
echo " rerun with -s16 without the -2 or try -s30 in case it's close." | |
exit 1 | |
} | |
verbecho() { | |
if [ "${verbose}" != "0" ]; then | |
echo $* | |
fi | |
} | |
verbose=0 | |
verbout=/dev/null | |
sourcefile="" | |
device="" | |
force=0 | |
maxsize=0 | |
startsize=0 | |
semiverbose=0 | |
spotcheck=0 | |
OPTIND=1 | |
while getopts "h?pv2d:f:-:m:s:" opt; do | |
case "${opt}" in | |
-) case "${OPTARG}" in | |
help) | |
usage | |
exit 0 | |
;; | |
force) | |
force=1 | |
;; | |
*) | |
echo "Could not parse long arg --${OPTARG}" | |
exit 1 | |
;; | |
esac;; | |
h|\?) | |
usage | |
exit 0 | |
;; | |
v) echo verbose mode set | |
verbose=1 | |
verbout=`tty` | |
;; | |
f) sourcefile=$OPTARG | |
;; | |
d) devicefile=$OPTARG | |
;; | |
m) maxsize=$OPTARG | |
;; | |
s) startsize=$OPTARG | |
;; | |
p) semiverbose=1 | |
;; | |
2) spotcheck=1 | |
;; | |
esac | |
done | |
if [ "${devicefile}" == "" ]; then | |
echo "" | |
echo "" | |
echo "Find the real space of WHAT?!" | |
echo "" | |
echo "USAGE:" | |
usage | |
exit 0 | |
fi | |
shift $((OPTIND-1)) | |
[ "$1" = "--" ] && shift | |
if [ "`whoami`" != "root" ]; then | |
echo "You need to be root for this script to work." | |
exit 3 | |
fi | |
if grep "^$devicefile" /proc/mounts > /dev/null 2>&1; then | |
echo "Device is mounted. Won't continue." | |
exit 4 | |
fi | |
createsourcefile() { | |
if [ "$1" == "" ]; then | |
sourcesource=/dev/urandom | |
else | |
sourcesource=$1 | |
fi | |
pushd /tmp/ 2>&1 > /dev/null | |
sourcefile=/tmp/`mktemp realsize.XXXXXXXX` | |
popd 2>&1 > /dev/null | |
dd if=$sourcesource of=$sourcefile bs=1M count=1 >$verbout 2>&1 | |
sourcefilecreated=1 | |
} | |
sourcefilecreated=0 | |
if [ "${sourcefile}" == "" ]; then | |
verbecho "Source file not set, creating.." | |
createsourcefile | |
fi | |
# Check the file exists and is the right size | |
if [ ! -f $sourcefile ]; then | |
echo "File $sourcefile does not exist, bailing." | |
exit 5 | |
fi | |
sourcefilesize=`stat ${sourcefile} | grep Size | cut -f4 -d" "` | |
if [ $sourcefilesize -lt 1048576 ]; then | |
echo "Cannot work with a file of less than 1M (1048576 bytes)" | |
exit 6 | |
fi | |
if [ $sourcefilesize -gt 1048576 ]; then | |
echo "WARN: you have passed a file greater than 1M, I would have to create a 1M file from your file" | |
if [ "${force}" == "0" ]; then | |
echo "Bailing because you didn't give a good file -- did you get source and dest the wrong way round?" | |
echo " use --force if you are certain." | |
exit 7 | |
fi | |
echo "WARN: you used force, so I'm going to beleive you and create a 1M file of the source file you passed." | |
originalsource=$sourcefile | |
createsourcefile $originalsource | |
fi | |
if [ $maxsize -lt 1 ]; then | |
maxsizebytes=`blockdev --getsize64 ${devicefile}` | |
if [ $? -ne 0 ]; then | |
echo "Could not determine size of destination ${devicefile}" | |
exit 8 | |
fi | |
maxsize=`expr $maxsizebytes / 1024 / 1024` | |
fi | |
if [ $maxsize -lt $startsize ]; then | |
echo "Max size of ${maxsize} is less than Start size of ${startsize}. I can't help you here!" | |
exit 9 | |
fi | |
currentmeg=$startsize | |
megforfailure=-1 | |
writeameg() { | |
dd if=$sourcefile of=$devicefile bs=1M count=1 seek=$1 >$verbout 2>&1 | |
} | |
readameg() { | |
# should only be used from /tmp | |
thismeg=`mktemp realsize-block.XXXXXXXX` | |
if [ $semiverbose -gt 0 ]; then | |
echo -n -e "\bR" | |
fi | |
dd if=$devicefile bs=1M skip=$1 count=1 of=$thismeg >$verbout 2>&1 | |
verbecho "dd if=$devicefile bs=1M skip=$1 count=1 of=$thismeg >$verbout 2>&1" | |
if [ $semiverbose -gt 0 ]; then | |
echo -n -e "\b." | |
fi | |
diff $thismeg $sourcefile >$verbout 2>&1 | |
if [ $? -gt 0 ]; then | |
verbecho "We found a block that didn't match!" | |
megforfailure=$currentmeg | |
if [ $semiverbose -gt 0 ]; then | |
echo -n -e "\bX" | |
fi | |
else | |
if [ $semiverbose -gt 0 ]; then | |
echo -n -e "\b-" | |
fi | |
fi | |
rm $thismeg | |
} | |
pushd /tmp > /dev/null 2>&1 | |
while [ $megforfailure -lt 0 ]; do | |
if [ $semiverbose -gt 0 ]; then | |
echo -n "W" | |
fi | |
writeameg $currentmeg | |
readameg $currentmeg | |
if [ $megforfailure -gt 0 ]; then | |
popd > /dev/null 2>&1 | |
if [ $semiverbose -gt 0 ]; then | |
echo "" | |
fi | |
echo "Size of device found : ${megforfailure}M"; | |
cleanup | |
exit 99 | |
fi | |
if [ $spotcheck -gt 0 ]; then | |
if [ $currentmeg -eq 0 ]; then | |
currentmeg=1 | |
fi | |
currentmeg=`expr $currentmeg \* 2` | |
echo "now at $currentmeg" | |
else | |
currentmeg=`expr $currentmeg + 1` | |
fi | |
if [ $currentmeg -eq $maxsize ]; then | |
break; | |
fi | |
done | |
popd > /dev/null 2>&1 | |
if [ $semiverbose -gt 0 ]; then | |
echo "" | |
fi | |
echo "Looks to be the same size as reported to the kernel, or bigger than you specified we should test to." | |
cleanup(){ | |
if [ "${sourcefilecreated}" != "0" ]; then | |
rm ${sourcefile} | |
fi | |
} | |
cleanup |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment