util/iptables: fix cross-build failures due to syscall.Flock()

Fixes: https://github.com/kubernetes/kubernetes/issues/45554
This commit is contained in:
Dan Williams
2017-05-10 11:10:56 -05:00
parent 48caf95a6c
commit a4624a0e75
5 changed files with 136 additions and 74 deletions

View File

@@ -19,18 +19,13 @@ package iptables
import (
"bytes"
"fmt"
"net"
"os"
"regexp"
"strings"
"sync"
"syscall"
"time"
godbus "github.com/godbus/dbus"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
utildbus "k8s.io/kubernetes/pkg/util/dbus"
utilexec "k8s.io/kubernetes/pkg/util/exec"
utilversion "k8s.io/kubernetes/pkg/util/version"
@@ -346,69 +341,8 @@ func (runner *runner) RestoreAll(data []byte, flush FlushFlag, counters RestoreC
return runner.restoreInternal(args, data, flush, counters)
}
type locker struct {
lock16 *os.File
lock14 *net.UnixListener
}
func (l *locker) Close() {
if l.lock16 != nil {
l.lock16.Close()
}
if l.lock14 != nil {
l.lock14.Close()
}
}
func (runner *runner) grabIptablesLocks() (*locker, error) {
var err error
var success bool
l := &locker{}
defer func(l *locker) {
// Clean up immediately on failure
if !success {
l.Close()
}
}(l)
if len(runner.restoreWaitFlag) > 0 {
// iptables-restore supports --wait; no need to grab locks
return l, nil
}
// Grab both 1.6.x and 1.4.x-style locks; we don't know what the
// iptables-restore version is if it doesn't support --wait, so we
// can't assume which lock method it'll use.
// Roughly duplicate iptables 1.6.x xtables_lock() function.
l.lock16, err = os.OpenFile(runner.lockfilePath, os.O_CREATE, 0600)
if err != nil {
return nil, fmt.Errorf("failed to open iptables lock %s: %v", runner.lockfilePath, err)
}
if err := wait.PollImmediate(200*time.Millisecond, 2*time.Second, func() (bool, error) {
if err := syscall.Flock(int(l.lock16.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
return false, nil
}
return true, nil
}); err != nil {
return nil, fmt.Errorf("failed to acquire new iptables lock: %v", err)
}
// Roughly duplicate iptables 1.4.x xtables_lock() function.
if err := wait.PollImmediate(200*time.Millisecond, 2*time.Second, func() (bool, error) {
l.lock14, err = net.ListenUnix("unix", &net.UnixAddr{Name: "@xtables", Net: "unix"})
if err != nil {
return false, nil
}
return true, nil
}); err != nil {
return nil, fmt.Errorf("failed to acquire old iptables lock: %v", err)
}
success = true
return l, nil
type iptablesLocker interface {
Close()
}
// restoreInternal is the shared part of Restore/RestoreAll
@@ -426,11 +360,13 @@ func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFla
// Grab the iptables lock to prevent iptables-restore and iptables
// from stepping on each other. iptables-restore 1.6.2 will have
// a --wait option like iptables itself, but that's not widely deployed.
locker, err := runner.grabIptablesLocks()
if err != nil {
return err
if len(runner.restoreWaitFlag) == 0 {
locker, err := grabIptablesLocks(runner.lockfilePath)
if err != nil {
return err
}
defer locker.Close()
}
defer locker.Close()
// run the command and return the output or an error including the output and error
fullArgs := append(runner.restoreWaitFlag, args...)