Skip to content

Instantly share code, notes, and snippets.

@ward
Last active September 7, 2019 13:42
Show Gist options
  • Save ward/cd8fc50eb395acb4a036fa49b789302d to your computer and use it in GitHub Desktop.
Save ward/cd8fc50eb395acb4a036fa49b789302d to your computer and use it in GitHub Desktop.
qnap nas hard drive spinning issues
#!/bin/bash
#================================================================
# Copyright (C) 2008 QNAP Systems, 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 2
# 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.
#----------------------------------------------------------------
#
# blkdevMonitor_v2.sh
#
# Abstract:
# A program of testing purpose on monitor block device
#
# HISTORY:
# 2013/05/15 - Created - Kent
# 2019-09-07 - Some cleanup Ward Muylaert
#
#================================================================
# This version downloaded through https://drive.google.com/file/d/0B8u8qWRYVhv0S1ozWFRjazFEX1E/view?usp=sharing
# Refers to itself as 20151225.
MD_DEVIVES="md9 md13 md0 md1 md2 md3 md4 md5 md6 md7 md8"
SD_DEVIVES="sda sdb sdc sdd sde sdf sdg sdh sdi sdj"
Do_Log=0
MAXRUN=10
FORCE_STANDBY=0
BLKDEV_LOG=/root/blkdevMonitor_v2.log
MAX_DM_NUMBER=256
analyse_kmsg()
{
_klog=/.klog
/bin/touch $_klog
_standby=1
# read /proc/kmsg
while [ 1 ]; do
/bin/dd if=/proc/kmsg of=$_klog bs=1 count=10240 2>/dev/null 1>/dev/null
for ((i = 0; i < $MAX_DM_NUMBER; i++))
do
/bin/cat $_klog | /bin/grep "dm-$i" | /bin/grep "dirtied inode"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep "dm-$i" | /bin/grep "dirtied inode" >> $BLKDEV_LOG
_standby=0
fi
/bin/cat $_klog | /bin/grep "dm-$i" | /bin/grep "block"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep "dm-$i" | /bin/grep "block" >> $BLKDEV_LOG
_standby=0
fi
done
for i in $MD_DEVIVES; do
/bin/cat $_klog | /bin/grep $i | /bin/grep "dirtied inode"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep $i | /bin/grep "dirtied inode" >> $BLKDEV_LOG
_standby=0
fi
/bin/cat $_klog | /bin/grep $i | /bin/grep "block"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep $i | /bin/grep "block" >> $BLKDEV_LOG
_standby=0
fi
done
for i in $SD_DEVIVES; do
/bin/cat $_klog | /bin/grep $i | /bin/grep "dirtied inode"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep $i | /bin/grep "dirtied inode" >> $BLKDEV_LOG
_standby=0
fi
/bin/cat $_klog | /bin/grep $i | /bin/grep "block"
if [ $? = 0 ]; then
/bin/cat $_klog | /bin/grep $i | /bin/grep "block" >> $BLKDEV_LOG
_standby=0
fi
done
if [ $_standby = 0 ]; then
return 1
fi
done
}
# Syncs cached writes to storage, counts down from given number to 0
# (exclusive)
_countdown()
{
/bin/sync;/bin/sync
/bin/echo -n "Countdown: "
cntdown=$1
while [ ${cntdown} -gt 0 ]; do
/bin/sleep 1
/bin/echo -n "${cntdown} "
cntdown=$[$cntdown-1]
done
echo
}
# Checks the /dev/sd? devices to see if any are active. Returns 1 if so, 0
# otherwise.
_check_standby()
{
for i in $SD_DEVIVES; do
/sbin/hdparm -C /dev/${i} 2>>/dev/null | /bin/grep active
if [ $? -eq 0 ]; then
echo /dev/${i}
echo "Some process has woken up the drive..."
return 1 # HDD is active
fi
done
return 0
}
# Prints usage information and exits without an error code
_print_help()
{
/bin/echo "blkdevmonitor.sh helps you find out which processes may be waking up your"
/bin/echo "harddrives. Originally written by QNAP for their NAS devices."
/bin/echo "Usage:"
/bin/echo " $0 [N]"
/bin/echo " Monitor block devices N times, generating N log files. (default N = 100)"
exit 0
}
# Check whether the user is asking for help
case "$1" in
"-h")
_print_help
;;
"--help")
_print_help
;;
esac
/bin/echo "===== Welcome to blkdevmonitor on `/bin/date` ====="
/bin/echo -n "Stop klogd.sh daemon... "
/sbin/daemon_mgr klogd.sh stop "/etc/init.d/klogd.sh start"
sleep 1
/bin/ps | /bin/grep klogd.sh | /bin/grep -v grep 1>/dev/null 2>/dev/null
if [ $? = 0 ]; then
/bin/echo "Failed"
exit 1
else
echo "Done"
/bin/rm -f /var/lock/subsys/klogd.sh
/usr/bin/killall dd 2>/dev/null 1>/dev/null
fi
/bin/echo "Turn off/on VM block_dump & Clean dmesg"
/bin/echo 0 > /proc/sys/vm/block_dump
/bin/dmesg -c 2>/dev/null 1>/dev/null
/bin/dmesg -c 2>/dev/null 1>/dev/null
/bin/dmesg -c 2>/dev/null 1>/dev/null
_cnt=20
while [ ${_cnt} -gt 0 ]; do
/bin/sync
/bin/dmesg -c 2>/dev/null 1>/dev/null
_cnt=$[$_cnt-1]
done
/bin/echo 1 > /proc/sys/vm/block_dump
/bin/date > /dev/null
_countdown 3
# ignore 10240 bytes
/bin/dd if=/proc/kmsg of=/dev/null bs=1 count=10240 2>/dev/null 1>/dev/null
/bin/echo "Start..."
[ "x$1" != "x" ] && MAXRUN=$1
_cnt=0
# remove log
/bin/rm -f $BLKDEV_LOG
while [ ${_cnt} -lt ${MAXRUN} ]; do
echo "============= $_cnt/$MAXRUN test, `/bin/date` ==============="
echo "============= $_cnt/$MAXRUN test, `/bin/date` ===============" >> $BLKDEV_LOG
if [ $FORCE_STANDBY = 1 ]; then
_check_standby
if [ $? != 0 ]; then
for i in $SD_DEVIVES; do
# force standby
/sbin/hdparm -y /dev/${i} 2>/dev/null 1>/dev/null
if [ $? = 0 ]; then
echo "Issuing standby command in /dev/${i}"
else
echo "/dev/${i} not found"
fi
done
fi
/bin/sleep 20
fi
analyse_kmsg
_cnt=$[$_cnt+1]
echo
echo >> $BLKDEV_LOG
done
/bin/echo "Turn off block_dump"
/bin/echo 0 > /proc/sys/vm/block_dump
/bin/echo "Start klogd.sh daemon"
/sbin/daemon_mgr klogd.sh start "/etc/init.d/klogd.sh start &"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment