Update vendoring (#801)

* Update vendor github.com/godbus/dbus@v4.1.0

* Update vendor github.com/golang/protobuf/proto

* Update vendor github.com/mdlayher/netlink/...

* Update vendor github.com/prometheus/client_golang/prometheus/...

* Update vendor github.com/prometheus/client_model/go

* Update vendor github.com/prometheus/common/...

* Update vendor github.com/prometheus/procfs/...

* Update vendor github.com/sirupsen/logrus@v1.0.4

* Update vendor golang.org/x/...

* Update vendor gopkg.in/alecthomas/kingpin.v2

* Remove obsolete vendor github.com/mdlayher/netlink/genetlink
This commit is contained in:
Ben Kochie 2018-01-25 18:20:39 +01:00 committed by GitHub
commit f9e91156d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
172 changed files with 6865 additions and 1599 deletions

View file

@ -27,6 +27,10 @@ var (
// A Conn is a connection to netlink. A Conn can be used to send and
// receives messages to and from netlink.
//
// A Conn is safe for concurrent use, but to avoid contention in
// high-throughput applications, the caller should almost certainly create a
// pool of Conns and distribute them among workers.
type Conn struct {
// sock is the operating system-specific implementation of
// a netlink sockets connection.
@ -330,4 +334,14 @@ type Config struct {
// Groups is a bitmask which specifies multicast groups. If set to 0,
// no multicast group subscriptions will be made.
Groups uint32
// Experimental: do not lock the internal system call handling goroutine
// to its OS thread. This may result in a speed-up of system call handling,
// but may cause unexpected behavior when sending and receiving a large number
// of messages.
//
// This should almost certainly be set to false, but if you come up with a
// valid reason for using this, please file an issue at
// https://github.com/mdlayher/netlink to discuss your thoughts.
NoLockThread bool
}

View file

@ -5,6 +5,8 @@ package netlink
import (
"errors"
"os"
"runtime"
"sync"
"syscall"
"unsafe"
@ -39,16 +41,23 @@ type socket interface {
// dial is the entry point for Dial. dial opens a netlink socket using
// system calls, and returns its PID.
func dial(family int, config *Config) (*conn, uint32, error) {
fd, err := unix.Socket(
unix.AF_NETLINK,
unix.SOCK_RAW,
family,
)
if err != nil {
// Prepare sysSocket's internal loop and create the socket.
//
// The conditional is inverted because a zero value of false is desired
// if no config, but it's easier to interpret within this code when the
// value is inverted.
if config == nil {
config = &Config{}
}
lockThread := !config.NoLockThread
sock := newSysSocket(lockThread)
if err := sock.Socket(family); err != nil {
return nil, 0, err
}
return bind(&sysSocket{fd: fd}, config)
return bind(sock, config)
}
// bind binds a connection to netlink using the input socket, which may be
@ -213,18 +222,144 @@ var _ socket = &sysSocket{}
// A sysSocket is a socket which uses system calls for socket operations.
type sysSocket struct {
fd int
wg *sync.WaitGroup
funcC chan<- func()
}
func (s *sysSocket) Bind(sa unix.Sockaddr) error { return unix.Bind(s.fd, sa) }
func (s *sysSocket) Close() error { return unix.Close(s.fd) }
func (s *sysSocket) FD() int { return s.fd }
func (s *sysSocket) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(s.fd) }
// newSysSocket creates a sysSocket that optionally locks its internal goroutine
// to a single thread.
func newSysSocket(lockThread bool) *sysSocket {
var wg sync.WaitGroup
wg.Add(1)
// This system call loop strategy was inspired by:
// https://github.com/golang/go/wiki/LockOSThread. Thanks to squeed on
// Gophers Slack for providing this useful link.
funcC := make(chan func())
go func() {
// It is important to lock this goroutine to its OS thread for the duration
// of the netlink socket being used, or else the kernel may end up routing
// messages to the wrong places.
// See: http://lists.infradead.org/pipermail/libnl/2017-February/002293.html.
//
// But since this is very experimental, we'll leave it as a configurable at
// this point.
if lockThread {
// Never unlock the OS thread, so that the thread will terminate when
// the goroutine exits starting in Go 1.10:
// https://go-review.googlesource.com/c/go/+/46038.
runtime.LockOSThread()
}
defer wg.Done()
for f := range funcC {
f()
}
}()
return &sysSocket{
wg: &wg,
funcC: funcC,
}
}
// do runs f in a worker goroutine which can be locked to one thread.
func (s *sysSocket) do(f func()) {
done := make(chan bool, 1)
s.funcC <- func() {
f()
done <- true
}
<-done
}
func (s *sysSocket) Socket(family int) error {
var (
fd int
err error
)
s.do(func() {
fd, err = unix.Socket(
unix.AF_NETLINK,
unix.SOCK_RAW,
family,
)
})
if err != nil {
return err
}
s.fd = fd
return nil
}
func (s *sysSocket) Bind(sa unix.Sockaddr) error {
var err error
s.do(func() {
err = unix.Bind(s.fd, sa)
})
return err
}
func (s *sysSocket) Close() error {
var err error
s.do(func() {
err = unix.Close(s.fd)
})
close(s.funcC)
s.wg.Wait()
return err
}
func (s *sysSocket) FD() int { return s.fd }
func (s *sysSocket) Getsockname() (unix.Sockaddr, error) {
var (
sa unix.Sockaddr
err error
)
s.do(func() {
sa, err = unix.Getsockname(s.fd)
})
return sa, err
}
func (s *sysSocket) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
return unix.Recvmsg(s.fd, p, oob, flags)
var (
n, oobn, recvflags int
from unix.Sockaddr
err error
)
s.do(func() {
n, oobn, recvflags, from, err = unix.Recvmsg(s.fd, p, oob, flags)
})
return n, oobn, recvflags, from, err
}
func (s *sysSocket) Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error {
return unix.Sendmsg(s.fd, p, oob, to, flags)
var err error
s.do(func() {
err = unix.Sendmsg(s.fd, p, oob, to, flags)
})
return err
}
func (s *sysSocket) SetSockopt(level, name int, v unsafe.Pointer, l uint32) error {
return setsockopt(s.fd, level, name, v, l)
var err error
s.do(func() {
err = setsockopt(s.fd, level, name, v, l)
})
return err
}

View file

@ -62,6 +62,20 @@ const (
// HeaderFlagsDump requests that netlink return a complete list of
// all entries.
HeaderFlagsDump HeaderFlags = HeaderFlagsRoot | HeaderFlagsMatch
// Flags used to create objects.
// HeaderFlagsReplace indicates request replaces an existing matching object.
HeaderFlagsReplace HeaderFlags = 0x100
// HeaderFlagsExcl indicates request does not replace the object if it already exists.
HeaderFlagsExcl HeaderFlags = 0x200
// HeaderFlagsCreate indicates request creates an object if it doesn't already exist.
HeaderFlagsCreate HeaderFlags = 0x400
// HeaderFlagsAppend indicates request adds to the end of the object list.
HeaderFlagsAppend HeaderFlags = 0x800
)
// String returns the string representation of a HeaderFlags.
@ -73,14 +87,12 @@ func (f HeaderFlags) String() string {
"echo",
"dumpinterrupted",
"dumpfiltered",
"1<<6",
"1<<7",
"root",
"match",
"atomic",
}
var s string
left := uint(f)
for i, name := range names {
if f&(1<<uint(i)) != 0 {
if s != "" {
@ -88,13 +100,22 @@ func (f HeaderFlags) String() string {
}
s += name
left ^= (1 << uint(i))
}
}
if s == "" {
if s == "" && left == 0 {
s = "0"
}
if left > 0 {
if s != "" {
s += "|"
}
s += fmt.Sprintf("%#x", left)
}
return s
}
@ -212,8 +233,17 @@ func (m *Message) UnmarshalBinary(b []byte) error {
func checkMessage(m Message) error {
const success = 0
// HeaderTypeError may indicate an error code, or success
if m.Header.Type != HeaderTypeError {
// Both "done" and "error" can contain error codes.
isDone := m.Header.Type == HeaderTypeDone
isError := m.Header.Type == HeaderTypeError
switch {
// "done" with no data means success.
case isDone && len(m.Data) == 0:
return nil
case isError, isDone:
break
default:
return nil
}