Drop drift detection; host tuning is one-shot system startup
This commit is contained in:
@@ -382,7 +382,7 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
tcfg := tuneConfig{
|
tcfg := systemConfig{
|
||||||
governor: *governor,
|
governor: *governor,
|
||||||
rxUsecs: uint32(*coalesce),
|
rxUsecs: uint32(*coalesce),
|
||||||
txUsecs: uint32(*coalesce),
|
txUsecs: uint32(*coalesce),
|
||||||
@@ -399,7 +399,7 @@ func main() {
|
|||||||
|
|
||||||
func run(aName, bName, sizesArg, patArg, fanout, txCPUsArg, rxCPUsArg string,
|
func run(aName, bName, sizesArg, patArg, fanout, txCPUsArg, rxCPUsArg string,
|
||||||
duration, interval, drain time.Duration, txN, rxN, batch, sndbuf, rcvbuf int,
|
duration, interval, drain time.Duration, txN, rxN, batch, sndbuf, rcvbuf int,
|
||||||
verify, duplex bool, tcfg tuneConfig) error {
|
verify, duplex bool, tcfg systemConfig) error {
|
||||||
|
|
||||||
if aName == "" || bName == "" {
|
if aName == "" || bName == "" {
|
||||||
return fmt.Errorf("both -a and -b are required")
|
return fmt.Errorf("both -a and -b are required")
|
||||||
@@ -441,7 +441,7 @@ func run(aName, bName, sizesArg, patArg, fanout, txCPUsArg, rxCPUsArg string,
|
|||||||
|
|
||||||
var fatal []string
|
var fatal []string
|
||||||
var tuneRows [][]string
|
var tuneRows [][]string
|
||||||
for _, r := range applyTuning(tcfg, ifnames) {
|
for _, r := range configureSystem(tcfg, ifnames) {
|
||||||
tuneRows = append(tuneRows, []string{r.item, r.status(), r.detail()})
|
tuneRows = append(tuneRows, []string{r.item, r.status(), r.detail()})
|
||||||
if r.fatal {
|
if r.fatal {
|
||||||
fatal = append(fatal, r.item)
|
fatal = append(fatal, r.item)
|
||||||
@@ -567,10 +567,6 @@ loop:
|
|||||||
secs := now.Sub(last).Seconds()
|
secs := now.Sub(last).Seconds()
|
||||||
last = now
|
last = now
|
||||||
elapsed := now.Sub(start).Seconds()
|
elapsed := now.Sub(start).Seconds()
|
||||||
for _, r := range verifyTuning(tcfg, ifnames) {
|
|
||||||
fmt.Printf(" %s host config drifted: %s — %s\n",
|
|
||||||
paint("!", cYellow), r.item, r.detail())
|
|
||||||
}
|
|
||||||
for _, d := range dirs {
|
for _, d := range dirs {
|
||||||
for _, line := range stats.emit(d.intervalRow(elapsed, secs, target)) {
|
for _, line := range stats.emit(d.intervalRow(elapsed, secs, target)) {
|
||||||
fmt.Println(line)
|
fmt.Println(line)
|
||||||
|
|||||||
+21
-45
@@ -62,7 +62,7 @@ type ethtoolCoalesce struct {
|
|||||||
rateSampleInterval uint32
|
rateSampleInterval uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type tuneConfig struct {
|
type systemConfig struct {
|
||||||
governor string
|
governor string
|
||||||
rxUsecs uint32
|
rxUsecs uint32
|
||||||
txUsecs uint32
|
txUsecs uint32
|
||||||
@@ -70,7 +70,7 @@ type tuneConfig struct {
|
|||||||
txRing uint32
|
txRing uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type tuneResult struct {
|
type checkResult struct {
|
||||||
item string
|
item string
|
||||||
state string
|
state string
|
||||||
fixed bool
|
fixed bool
|
||||||
@@ -78,7 +78,7 @@ type tuneResult struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r tuneResult) status() string {
|
func (r checkResult) status() string {
|
||||||
switch {
|
switch {
|
||||||
case r.err != nil:
|
case r.err != nil:
|
||||||
return paint("FAIL", cRed)
|
return paint("FAIL", cRed)
|
||||||
@@ -89,7 +89,7 @@ func (r tuneResult) status() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r tuneResult) detail() string {
|
func (r checkResult) detail() string {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
if r.state == "" {
|
if r.state == "" {
|
||||||
return r.err.Error()
|
return r.err.Error()
|
||||||
@@ -126,8 +126,8 @@ func getCoalesce(fd int, ifname string) (ethtoolCoalesce, error) {
|
|||||||
return ec, err
|
return ec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkGovernor(want string) tuneResult {
|
func checkGovernor(want string) checkResult {
|
||||||
res := tuneResult{item: "cpu governor"}
|
res := checkResult{item: "cpu governor"}
|
||||||
paths, err := filepath.Glob("/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor")
|
paths, err := filepath.Glob("/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor")
|
||||||
if err != nil || len(paths) == 0 {
|
if err != nil || len(paths) == 0 {
|
||||||
res.err = fmt.Errorf("no cpufreq governors found")
|
res.err = fmt.Errorf("no cpufreq governors found")
|
||||||
@@ -167,8 +167,8 @@ func checkGovernor(want string) tuneResult {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLinkUp(fd int, ifname string) tuneResult {
|
func checkLinkUp(fd int, ifname string) checkResult {
|
||||||
res := tuneResult{item: ifname + " link up"}
|
res := checkResult{item: ifname + " link up"}
|
||||||
var ifr flagsIfreq
|
var ifr flagsIfreq
|
||||||
copy(ifr.name[:], ifname)
|
copy(ifr.name[:], ifname)
|
||||||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd),
|
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(fd),
|
||||||
@@ -196,8 +196,8 @@ func checkLinkUp(fd int, ifname string) tuneResult {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkCarrier(ifname string, wait time.Duration) tuneResult {
|
func checkCarrier(ifname string, wait time.Duration) checkResult {
|
||||||
res := tuneResult{item: ifname + " carrier"}
|
res := checkResult{item: ifname + " carrier"}
|
||||||
deadline := time.Now().Add(wait)
|
deadline := time.Now().Add(wait)
|
||||||
for {
|
for {
|
||||||
v, ok := readUint("/sys/class/net/" + ifname + "/carrier")
|
v, ok := readUint("/sys/class/net/" + ifname + "/carrier")
|
||||||
@@ -214,8 +214,8 @@ func checkCarrier(ifname string, wait time.Duration) tuneResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkCoalesce(fd int, ifname string, rxUsecs, txUsecs uint32) tuneResult {
|
func checkCoalesce(fd int, ifname string, rxUsecs, txUsecs uint32) checkResult {
|
||||||
res := tuneResult{item: ifname + " coalesce"}
|
res := checkResult{item: ifname + " coalesce"}
|
||||||
ec, err := getCoalesce(fd, ifname)
|
ec, err := getCoalesce(fd, ifname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.err = err
|
res.err = err
|
||||||
@@ -246,8 +246,8 @@ func checkCoalesce(fd int, ifname string, rxUsecs, txUsecs uint32) tuneResult {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRings(fd int, ifname string, rxWant, txWant uint32) (tuneResult, bool) {
|
func checkRings(fd int, ifname string, rxWant, txWant uint32) (checkResult, bool) {
|
||||||
res := tuneResult{item: ifname + " rings"}
|
res := checkResult{item: ifname + " rings"}
|
||||||
rp, err := getRings(fd, ifname)
|
rp, err := getRings(fd, ifname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.err = err
|
res.err = err
|
||||||
@@ -273,8 +273,8 @@ func checkRings(fd int, ifname string, rxWant, txWant uint32) (tuneResult, bool)
|
|||||||
return res, true
|
return res, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNoAddrs(ifname string) tuneResult {
|
func checkNoAddrs(ifname string) checkResult {
|
||||||
res := tuneResult{item: ifname + " unmanaged"}
|
res := checkResult{item: ifname + " unmanaged"}
|
||||||
ifi, err := net.InterfaceByName(ifname)
|
ifi, err := net.InterfaceByName(ifname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.err = err
|
res.err = err
|
||||||
@@ -302,18 +302,18 @@ func checkNoAddrs(ifname string) tuneResult {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func withIoctlSocket(fn func(fd int) []tuneResult) []tuneResult {
|
func withIoctlSocket(fn func(fd int) []checkResult) []checkResult {
|
||||||
fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0)
|
fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []tuneResult{{item: "ioctl socket", err: err, fatal: true}}
|
return []checkResult{{item: "ioctl socket", err: err, fatal: true}}
|
||||||
}
|
}
|
||||||
defer unix.Close(fd)
|
defer unix.Close(fd)
|
||||||
return fn(fd)
|
return fn(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyTuning(cfg tuneConfig, ifnames []string) []tuneResult {
|
func configureSystem(cfg systemConfig, ifnames []string) []checkResult {
|
||||||
return withIoctlSocket(func(fd int) []tuneResult {
|
return withIoctlSocket(func(fd int) []checkResult {
|
||||||
out := []tuneResult{checkGovernor(cfg.governor)}
|
out := []checkResult{checkGovernor(cfg.governor)}
|
||||||
for _, ifname := range ifnames {
|
for _, ifname := range ifnames {
|
||||||
out = append(out, checkLinkUp(fd, ifname))
|
out = append(out, checkLinkUp(fd, ifname))
|
||||||
out = append(out, checkCoalesce(fd, ifname, cfg.rxUsecs, cfg.txUsecs))
|
out = append(out, checkCoalesce(fd, ifname, cfg.rxUsecs, cfg.txUsecs))
|
||||||
@@ -330,27 +330,3 @@ func applyTuning(cfg tuneConfig, ifnames []string) []tuneResult {
|
|||||||
return out
|
return out
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyTuning(cfg tuneConfig, ifnames []string) []tuneResult {
|
|
||||||
return withIoctlSocket(func(fd int) []tuneResult {
|
|
||||||
var drifted []tuneResult
|
|
||||||
if r := checkGovernor(cfg.governor); r.fixed || r.err != nil {
|
|
||||||
drifted = append(drifted, r)
|
|
||||||
}
|
|
||||||
for _, ifname := range ifnames {
|
|
||||||
if r := checkCoalesce(fd, ifname, cfg.rxUsecs, cfg.txUsecs); r.fixed || r.err != nil {
|
|
||||||
drifted = append(drifted, r)
|
|
||||||
}
|
|
||||||
r, reset := checkRings(fd, ifname, cfg.rxRing, cfg.txRing)
|
|
||||||
if r.fixed || r.err != nil {
|
|
||||||
drifted = append(drifted, r)
|
|
||||||
}
|
|
||||||
if reset {
|
|
||||||
if c := checkCarrier(ifname, 10*time.Second); c.err != nil {
|
|
||||||
drifted = append(drifted, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return drifted
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user