Skip to content

Commit

Permalink
Merge pull request #2135 from ctelfer/xtables-filter
Browse files Browse the repository at this point in the history
filter xtables lock warnings when firewalld is active
  • Loading branch information
Flavio Crisciani authored Apr 25, 2018
2 parents b1c7fd5 + 2fb05a3 commit eee3e06
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"
"strings"
"sync"
"time"

"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -45,7 +46,7 @@ var (
iptablesPath string
supportsXlock = false
supportsCOpt = false
xLockWaitMsg = "Another app is currently holding the xtables lock; waiting"
xLockWaitMsg = "Another app is currently holding the xtables lock"
// used to lock iptables commands if xtables lock is not supported
bestEffortLock sync.Mutex
// ErrIptablesNotFound is returned when the rule is not found.
Expand Down Expand Up @@ -423,12 +424,31 @@ func existsRaw(table Table, chain string, rule ...string) bool {
return strings.Contains(string(existingRules), ruleString)
}

// Maximum duration that an iptables operation can take
// before flagging a warning.
const opWarnTime = 2 * time.Second

func filterOutput(start time.Time, output []byte, args ...string) []byte {
// Flag operations that have taken a long time to complete
if time.Since(start) > opWarnTime {
logrus.Warnf("xtables contention detected while running [%s]: %q", strings.Join(args, " "), string(output))
}
// ignore iptables' message about xtables lock:
// it is a warning, not an error.
if strings.Contains(string(output), xLockWaitMsg) {
output = []byte("")
}
// Put further filters here if desired
return output
}

// Raw calls 'iptables' system command, passing supplied arguments.
func Raw(args ...string) ([]byte, error) {
if firewalldRunning {
startTime := time.Now()
output, err := Passthrough(Iptables, args...)
if err == nil || !strings.Contains(err.Error(), "was not provided by any .service files") {
return output, err
return filterOutput(startTime, output, args...), err
}
}
return raw(args...)
Expand All @@ -447,17 +467,13 @@ func raw(args ...string) ([]byte, error) {

logrus.Debugf("%s, %v", iptablesPath, args)

startTime := time.Now()
output, err := exec.Command(iptablesPath, args...).CombinedOutput()
if err != nil {
return nil, fmt.Errorf("iptables failed: iptables %v: %s (%s)", strings.Join(args, " "), output, err)
}

// ignore iptables' message about xtables lock
if strings.Contains(string(output), xLockWaitMsg) {
output = []byte("")
}

return output, err
return filterOutput(startTime, output, args...), err
}

// RawCombinedOutput inernally calls the Raw function and returns a non nil
Expand Down

0 comments on commit eee3e06

Please sign in to comment.