99 lines
2.3 KiB
Go
99 lines
2.3 KiB
Go
package consumer
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"amuz.es/src/infra/cpu_ctrl/util"
|
|
"time"
|
|
"amuz.es/src/infra/cpu_ctrl/processor"
|
|
"amuz.es/src/infra/cpu_ctrl/logger"
|
|
"bytes"
|
|
)
|
|
|
|
var (
|
|
log = logger.NewLogger("consumer")
|
|
)
|
|
|
|
type fanControl struct {
|
|
processorCount int
|
|
handler util.Handler
|
|
fanSpeedConsumer chan processor.FanspeedInfo
|
|
sampleDuration time.Duration
|
|
}
|
|
|
|
type FanControl interface {
|
|
Consumer() chan<- processor.FanspeedInfo
|
|
StartControl()
|
|
}
|
|
|
|
func NewFanControl(processorCount int, sampleDuration time.Duration, handler util.Handler) FanControl {
|
|
return &fanControl{
|
|
processorCount: processorCount,
|
|
handler: handler,
|
|
fanSpeedConsumer: make(chan processor.FanspeedInfo, processorCount),
|
|
sampleDuration: sampleDuration,
|
|
}
|
|
}
|
|
|
|
func (c *fanControl) Consumer() chan<- processor.FanspeedInfo { return c.fanSpeedConsumer }
|
|
|
|
func (c *fanControl) StartControl() {
|
|
defer c.handler.DecreaseWait()
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
c.handler.NotifyError(err.(error))
|
|
}
|
|
}()
|
|
defer close(c.fanSpeedConsumer)
|
|
log.Info("Fan control started")
|
|
|
|
ticker := time.Tick(c.sampleDuration)
|
|
fanSpeedList := make([]int, c.processorCount)
|
|
|
|
for {
|
|
newFanSpeedList := make([]int, c.processorCount)
|
|
checker:
|
|
for {
|
|
select {
|
|
case <-ticker:
|
|
break checker
|
|
case changedSpeed := <-c.fanSpeedConsumer:
|
|
newFanSpeedList[changedSpeed.Id] = changedSpeed.FanSpeed
|
|
case <-c.handler.Done():
|
|
return
|
|
}
|
|
}
|
|
if (!compareFanSpeed(fanSpeedList, newFanSpeedList)) {
|
|
copy(fanSpeedList, newFanSpeedList)
|
|
args := make([]string, 0)
|
|
args = append(args, "raw", "0x3a", "0x01", )
|
|
for _, item := range fanSpeedList {
|
|
args = append(args, fmt.Sprintf("0x%x", item))
|
|
}
|
|
args = append(args,
|
|
"0x0", "0x0", "0x0", "0x0", "0x0", "0x0",
|
|
)
|
|
cmd := exec.Command("ipmitool", args...)
|
|
if err := cmd.Run(); err != nil {
|
|
c.handler.NotifyError(err)
|
|
return
|
|
}
|
|
buf := bytes.NewBufferString("")
|
|
for _, item := range newFanSpeedList {
|
|
buf.WriteString(fmt.Sprintf("0x%x", item))
|
|
buf.WriteRune(' ')
|
|
}
|
|
log.Infof("Commit fan speed with %s", buf.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
func compareFanSpeed(old, new []int) bool {
|
|
for i, v := range old {
|
|
if v != new[i] { // here is no bounds checking for b[i]
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|