Skip to content

Commit

Permalink
allow more than one method to check disk power status
Browse files Browse the repository at this point in the history
  • Loading branch information
creativeprojects committed May 18, 2023
1 parent 8a2d41e commit 262018b
Show file tree
Hide file tree
Showing 23 changed files with 209 additions and 117 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go_version: ['1.18']
go_version: ['1.19', '1.20']
os: [ubuntu-latest]

steps:

- name: Set up Go ${{ matrix.go_version }}
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go_version }}

- name: Check out code into the Go module directory
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Get dependencies
run: |
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
-
name: Unshallow
run: git fetch --prune --unshallow
-
name: Set up Go
uses: actions/setup-go@v1
uses: actions/setup-go@v3
with:
go-version: 1.18.x
go-version: 1.20.x
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v1
uses: goreleaser/goreleaser-action@v4
with:
version: latest
args: release --rm-dist
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20 changes: 11 additions & 9 deletions cfg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ import (

// Config from the file
type Config struct {
Simulation bool `yaml:"simulation"`
DiskPowerStatus DiskPowerStatus `yaml:"disk_power_status"`
Sensors map[string]Task `yaml:"sensors"`
DiskPools map[string][]string `yaml:"disk_pools"`
Disks map[string]Disk `yaml:"disks"`
Templates map[string]Template `yaml:"templates"`
Tasks map[string]Task `yaml:"tasks"`
Schedule map[string]Schedule `yaml:"schedule"`
FanControl FanControl `yaml:"fan_control"`
Simulation bool `yaml:"simulation"`
DiskPowerStatus map[string]DiskPowerStatus `yaml:"disk_power_status"`
Sensors map[string]Task `yaml:"sensors"`
DiskPools map[string][]string `yaml:"disk_pools"`
Disks map[string]Disk `yaml:"disks"`
Templates map[string]Template `yaml:"templates"`
Tasks map[string]Task `yaml:"tasks"`
Schedule map[string]Schedule `yaml:"schedule"`
FanControl FanControl `yaml:"fan_control"`
}

type DiskPowerStatus struct {
File string `yaml:"file"`
CheckCommand string `yaml:"check_command"`
Active string `yaml:"active"`
Standby string `yaml:"standby"`
Expand All @@ -37,6 +38,7 @@ type Disk struct {
MonitorTemperature string `yaml:"monitor_temperature"`
LastActive string `yaml:"last_active"`
StandbyAfter string `yaml:"standby_after"`
PowerStatus string `yaml:"power_status"`
}

type Template struct {
Expand Down
30 changes: 17 additions & 13 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ sensors:
pch:
file: "/sys/class/thermal/thermal_zone1/temp"
divider: 1000
drivetemp:
satatemp:
file: "/sys/block/${DEVICE_NAME}/device/hwmon/hwmon*/temp1_input"
divider: 1000
nvmetemp:
file: "/sys/block/${DEVICE_NAME}/device/hwmon*/temp1_input"
divider: 1000

fan_control:
# set fan mode to full
Expand Down Expand Up @@ -111,12 +114,13 @@ fan_control:
to: 100

disk_power_status:
check_command: "/sbin/hdparm -C ${DEVICE}"
active: "active/idle"
standby: "standby"
sleeping: "sleeping"
standby_command: "/sbin/hdparm -y ${DEVICE}"
timeout: 5s
hdparm:
check_command: "/sbin/hdparm -C ${DEVICE}"
active: "active/idle"
standby: "standby"
sleeping: "sleeping"
standby_command: "/sbin/hdparm -y ${DEVICE}"
timeout: 5s

disk_pools:
rpool:
Expand All @@ -131,33 +135,33 @@ disk_pools:
disks:
rpool1:
device: "/dev/disk/by-id/ata-SAMSUNG_SSD_first"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: always
rpool2:
device: "/dev/disk/by-id/ata-SAMSUNG_SSD_second"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: always
datapool1:
device: "/dev/disk/by-id/ata-ST2000DM001-first"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: when_active
last_active: 50m
standby_after: 1h
datapool2:
device: "/dev/disk/by-id/ata-ST2000DM001-second"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: when_active
last_active: 50m
standby_after: 1h
datapool3:
device: "/dev/disk/by-id/ata-ST2000DM001-third"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: when_active
last_active: 50m
standby_after: 1h
datapool4:
device: "/dev/disk/by-id/ata-ST2000DM001-fourth"
temperature_sensor: drivetemp
temperature_sensor: satatemp
monitor_temperature: when_active
last_active: 50m
standby_after: 1h
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
module github.com/creativeprojects/hardware-events

go 1.18
go 1.19

require (
github.com/coreos/go-systemd/v22 v22.3.2
github.com/creativeprojects/clog v0.11.1
github.com/stretchr/testify v1.7.5
github.com/coreos/go-systemd/v22 v22.5.0
github.com/creativeprojects/clog v0.13.0
github.com/stretchr/testify v1.8.2
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
golang.org/x/sys v0.5.0 // indirect
)
38 changes: 18 additions & 20 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creativeprojects/clog v0.11.1 h1:p285AvArKocGzyzlSsFvzw5Lp1ryU8m5A+ZNBC0CIHo=
github.com/creativeprojects/clog v0.11.1/go.mod h1:JmsbtbGXiZ/4muT/39UUZXWbI9sW6fNCY0DhyY6xqHQ=
github.com/creativeprojects/clog v0.13.0 h1:QVWO65Za2/XfCQeNnDvO4td9i7fwV2xuv8V5jzFIONk=
github.com/creativeprojects/clog v0.13.0/go.mod h1:4CBBbXkwjxTSIE/OyrC77aTrEEHj6daYGFEDrNjfOkU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
Expand All @@ -16,12 +16,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -30,15 +29,14 @@ github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XF
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
Expand Down
1 change: 1 addition & 0 deletions hardware-events.service
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[Unit]
Description=Hardware Events Dispatcher
After=network.target

[Service]
Type=notify
Expand Down
67 changes: 41 additions & 26 deletions lib/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,43 @@ import (

// Disk activity and status
type Disk struct {
global *Global
config cfg.Disk
Name string
Device string
active *cache.CacheValue[int]
temperature *cache.CacheValue[int]
lastActivity time.Time
activityMutex sync.Mutex
stats *Diskstats
idleAfter time.Duration
standbyAfter time.Duration
diskStatusCommand DiskStatuser
global *Global
config cfg.Disk
Name string
Device string
active *cache.CacheValue[int]
temperature *cache.CacheValue[int]
lastActivity time.Time
activityMutex sync.Mutex
stats *Diskstats
idleAfter time.Duration
standbyAfter time.Duration
diskStatus DiskStatuser
}

// NewDisk creates a new disk activity and status monitor
func NewDisk(global *Global, name string, config cfg.Disk, diskStatusCommand DiskStatuser) (*Disk, error) {
func NewDisk(global *Global, name string, config cfg.Disk, diskStatuses map[string]DiskStatuser) (*Disk, error) {
device := config.Device
fi, err := os.Lstat(device)
if err != nil {
return nil, err
}

var diskStatus DiskStatuser
if config.PowerStatus != "" {
diskStatus = diskStatuses[config.PowerStatus]
}
if diskStatus == nil && len(diskStatuses) == 1 {
// load the only one instead
for _, value := range diskStatuses {
diskStatus = value
break
}
}
if diskStatus == nil {
clog.Warningf("disk %q has no power status available", name)
}

if fi.Mode()&os.ModeSymlink != 0 {
// resolve symlink into kernel device name
dest, err := os.Readlink(device)
Expand Down Expand Up @@ -67,27 +82,27 @@ func NewDisk(global *Global, name string, config cfg.Disk, diskStatusCommand Dis

clog.Debugf("device %s: %s", name, device)
return &Disk{
global: global,
config: config,
Name: name,
Device: device,
active: cache.NewCacheValue[int](1 * time.Minute),
temperature: cache.NewCacheValue[int](1 * time.Minute),
idleAfter: idleAfter,
standbyAfter: standbyAfter,
diskStatusCommand: diskStatusCommand,
activityMutex: sync.Mutex{},
global: global,
config: config,
Name: name,
Device: device,
active: cache.NewCacheValue[int](1 * time.Minute),
temperature: cache.NewCacheValue[int](1 * time.Minute),
idleAfter: idleAfter,
standbyAfter: standbyAfter,
diskStatus: diskStatus,
activityMutex: sync.Mutex{},
}, nil
}

// IsActive returns true when the disk is not in standby or sleep mode
func (d *Disk) IsActive() bool {
if d.diskStatusCommand == nil {
if d.diskStatus == nil {
// shouldn't happen?
return false
}
output, err := d.active.Get(func() (int, error) {
return int(d.diskStatusCommand.Get(d.expandEnv)), nil
return int(d.diskStatus.Get(d.expandEnv)), nil
})
if err != nil {
return false
Expand Down Expand Up @@ -191,7 +206,7 @@ func (d *Disk) StartStandbyWatch() {
if d.IsActive() {
if d.LastActivity().Add(d.standbyAfter).Before(time.Now()) {
// time to put the disk to sleep
d.diskStatusCommand.Standby(d.expandEnv)
d.diskStatus.Standby(d.expandEnv)
d.active.Set(int(enum.DiskStatusActive))
}
}
Expand Down
Loading

0 comments on commit 262018b

Please sign in to comment.