util/iptables: fix cross-build failures due to syscall.Flock()
Fixes: https://github.com/kubernetes/kubernetes/issues/45554
This commit is contained in:
@@ -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...)
|
||||
|
Reference in New Issue
Block a user