Automatically compute drive stat file path
This commit is contained in:
@@ -116,12 +116,11 @@ As an example, the command line below will instruct HDD Fan control to:
|
|||||||
* consider the fans will stop with PWM value 75
|
* consider the fans will stop with PWM value 75
|
||||||
* never run the fans below 10% of their maximum speed
|
* never run the fans below 10% of their maximum speed
|
||||||
* check temperature at least every minute
|
* check temperature at least every minute
|
||||||
* monitor drive activity using special files `/sys/block/sda/stat` and `/sys/block/sdb/stat`
|
|
||||||
* automatically spin down drives if they are inactive for 2 hours (7200 seconds)
|
* automatically spin down drives if they are inactive for 2 hours (7200 seconds)
|
||||||
* run in daemon mode
|
* run in daemon mode
|
||||||
* log what is going on to `/var/log/hddfancontrol.log`
|
* log what is going on to `/var/log/hddfancontrol.log`
|
||||||
|
|
||||||
`hddfancontrol -d /dev/sda /dev/sdb -p /sys/class/hwmon/hwmon1/device/pwm2 /sys/class/hwmon/hwmon1/device/pwm3 --pwm-start-value 200 200 --pwm-stop-value 75 75 --min-fan-speed-prct 10 -i 60 --stat-files /sys/block/sda/stat /sys/block/sdb/stat --spin-down-time 7200 -b -l /var/log/hddfancontrol.log`
|
`hddfancontrol -d /dev/sda /dev/sdb -p /sys/class/hwmon/hwmon1/device/pwm2 /sys/class/hwmon/hwmon1/device/pwm3 --pwm-start-value 200 200 --pwm-stop-value 75 75 --min-fan-speed-prct 10 -i 60 --spin-down-time 7200 -b -l /var/log/hddfancontrol.log`
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ class Drive:
|
|||||||
HDPARM_GET_TEMP_HITACHI_REGEX = re.compile("drive temperature \(celsius\) is:\s*([0-9]*)")
|
HDPARM_GET_TEMP_HITACHI_REGEX = re.compile("drive temperature \(celsius\) is:\s*([0-9]*)")
|
||||||
HDPARM_GET_MODEL_REGEX = re.compile("Model Number:\s*(.*)")
|
HDPARM_GET_MODEL_REGEX = re.compile("Model Number:\s*(.*)")
|
||||||
|
|
||||||
def __init__(self, device_filepath, stat_filepath, hddtemp_daemon_port):
|
def __init__(self, device_filepath, hddtemp_daemon_port):
|
||||||
assert(stat.S_ISBLK(os.stat(device_filepath).st_mode))
|
assert(stat.S_ISBLK(os.stat(device_filepath).st_mode))
|
||||||
self.device_filepath = __class__.normalizeDrivePath(device_filepath)
|
self.device_filepath = __class__.normalizeDrivePath(device_filepath)
|
||||||
self.stat_filepath = stat_filepath
|
self.stat_filepath = "/sys/block/%s/stat" % (os.path.basename(self.device_filepath))
|
||||||
self.hddtemp_daemon_port = hddtemp_daemon_port
|
self.hddtemp_daemon_port = hddtemp_daemon_port
|
||||||
self.pretty_name = self.getPrettyName()
|
self.pretty_name = self.getPrettyName()
|
||||||
self.logger = logging.getLogger(str(self))
|
self.logger = logging.getLogger(str(self))
|
||||||
@@ -456,12 +456,9 @@ class TestHardware:
|
|||||||
print(("[ %s ]" % ("OK" if ok else "KO")).rjust(shutil.get_terminal_size()[0] - len(desc) - 1))
|
print(("[ %s ]" % ("OK" if ok else "KO")).rjust(shutil.get_terminal_size()[0] - len(desc) - 1))
|
||||||
|
|
||||||
|
|
||||||
def test(drive_filepaths, fan_pwm_filepaths, stat_filepaths, hddtemp_daemon_port):
|
def test(drive_filepaths, fan_pwm_filepaths, hddtemp_daemon_port):
|
||||||
fans = [Fan(i, fan_pwm_filepath, 0, 0) for i, fan_pwm_filepath in enumerate(fan_pwm_filepaths, 1)]
|
fans = [Fan(i, fan_pwm_filepath, 0, 0) for i, fan_pwm_filepath in enumerate(fan_pwm_filepaths, 1)]
|
||||||
drives = [Drive(drive_filepath,
|
drives = [Drive(drive_filepath, hddtemp_daemon_port) for drive_filepath in drive_filepaths]
|
||||||
stat_filepath,
|
|
||||||
hddtemp_daemon_port) for drive_filepath, stat_filepath in zip(drive_filepaths,
|
|
||||||
stat_filepaths)]
|
|
||||||
|
|
||||||
tester = TestHardware(drives, fans)
|
tester = TestHardware(drives, fans)
|
||||||
tester.run()
|
tester.run()
|
||||||
@@ -474,7 +471,7 @@ def signal_handler(sig, frame):
|
|||||||
|
|
||||||
|
|
||||||
def main(drive_filepaths, fan_pwm_filepaths, fan_start_values, fan_stop_values, min_fan_speed_prct, min_temp, max_temp,
|
def main(drive_filepaths, fan_pwm_filepaths, fan_start_values, fan_stop_values, min_fan_speed_prct, min_temp, max_temp,
|
||||||
interval_s, spin_down_time_s, stat_filepaths, hddtemp_daemon_port):
|
interval_s, spin_down_time_s, hddtemp_daemon_port):
|
||||||
logger = logging.getLogger("Main")
|
logger = logging.getLogger("Main")
|
||||||
|
|
||||||
fans = []
|
fans = []
|
||||||
@@ -507,10 +504,7 @@ def main(drive_filepaths, fan_pwm_filepaths, fan_start_values, fan_stop_values,
|
|||||||
fan_start_values,
|
fan_start_values,
|
||||||
fan_stop_values),
|
fan_stop_values),
|
||||||
1)]
|
1)]
|
||||||
drives = [Drive(drive_filepath,
|
drives = [Drive(drive_filepath, hddtemp_daemon_port) for drive_filepath in drive_filepaths]
|
||||||
stat_filepath,
|
|
||||||
hddtemp_daemon_port) for drive_filepath, stat_filepath in zip(drive_filepaths,
|
|
||||||
stat_filepaths)]
|
|
||||||
|
|
||||||
drives_startup_time = time.time()
|
drives_startup_time = time.time()
|
||||||
|
|
||||||
@@ -636,11 +630,6 @@ def cl_main():
|
|||||||
default=60,
|
default=60,
|
||||||
dest="interval_s",
|
dest="interval_s",
|
||||||
help="Interval in seconds to check temperature and adjust fan speed.")
|
help="Interval in seconds to check temperature and adjust fan speed.")
|
||||||
arg_parser.add_argument("--stat-files",
|
|
||||||
required=True,
|
|
||||||
nargs="+",
|
|
||||||
dest="stat_filepaths",
|
|
||||||
help="Filepath of drive stats file (ie. /sys/block/sdX/stat)")
|
|
||||||
arg_parser.add_argument("--spin-down-time",
|
arg_parser.add_argument("--spin-down-time",
|
||||||
type=int,
|
type=int,
|
||||||
default=None,
|
default=None,
|
||||||
@@ -684,8 +673,7 @@ def cl_main():
|
|||||||
dest="hddtemp_daemon_port",
|
dest="hddtemp_daemon_port",
|
||||||
help="hddtemp daemon port if option --hddtemp-daemon is used")
|
help="hddtemp daemon port if option --hddtemp-daemon is used")
|
||||||
args = arg_parser.parse_args()
|
args = arg_parser.parse_args()
|
||||||
if ((len(args.drive_filepaths) != len(args.stat_filepaths)) or
|
if (((args.fan_start_value is not None) and (len(args.fan_pwm_filepath) != len(args.fan_start_value))) or
|
||||||
((args.fan_start_value is not None) and (len(args.fan_pwm_filepath) != len(args.fan_start_value))) or
|
|
||||||
((args.fan_stop_value is not None) and (len(args.fan_pwm_filepath) != len(args.fan_stop_value)))):
|
((args.fan_stop_value is not None) and (len(args.fan_pwm_filepath) != len(args.fan_stop_value)))):
|
||||||
print("Invalid parameter count")
|
print("Invalid parameter count")
|
||||||
exit(1)
|
exit(1)
|
||||||
@@ -721,7 +709,6 @@ def cl_main():
|
|||||||
logging.getLogger("Startup").warning("Missing --pwm-start-value or --pwm-stop-value argument, running hardware test to find values")
|
logging.getLogger("Startup").warning("Missing --pwm-start-value or --pwm-stop-value argument, running hardware test to find values")
|
||||||
test(args.drive_filepaths,
|
test(args.drive_filepaths,
|
||||||
args.fan_pwm_filepath,
|
args.fan_pwm_filepath,
|
||||||
args.stat_filepaths,
|
|
||||||
args.hddtemp_daemon_port if args.hddtemp_daemon else None)
|
args.hddtemp_daemon_port if args.hddtemp_daemon else None)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -749,7 +736,6 @@ def cl_main():
|
|||||||
args.max_temp,
|
args.max_temp,
|
||||||
args.interval_s,
|
args.interval_s,
|
||||||
args.spin_down_time_s,
|
args.spin_down_time_s,
|
||||||
args.stat_filepaths,
|
|
||||||
args.hddtemp_daemon_port if args.hddtemp_daemon else None)
|
args.hddtemp_daemon_port if args.hddtemp_daemon else None)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ class TestDrive(unittest.TestCase):
|
|||||||
stat_mock.stat.S_IFBLK.return_value = True
|
stat_mock.stat.S_IFBLK.return_value = True
|
||||||
subprocess_check_call_mock.side_effect = subprocess.CalledProcessError(0, "")
|
subprocess_check_call_mock.side_effect = subprocess.CalledProcessError(0, "")
|
||||||
drive_getPrettyName.return_value = "drive_name"
|
drive_getPrettyName.return_value = "drive_name"
|
||||||
self.drive = hddfancontrol.Drive("/dev/sdz", "/dummy", None)
|
self.drive = hddfancontrol.Drive("/dev/sdz", None)
|
||||||
self.hddtemp_daemon = None
|
self.hddtemp_daemon = None
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user