diff options
author | Ondrej Fabry <ofabry@cisco.com> | 2019-06-20 18:52:30 +0200 |
---|---|---|
committer | Ondrej Fabry <ofabry@cisco.com> | 2019-06-20 18:52:30 +0200 |
commit | da15c397b3dbbba07d159b3af767aa13d443cfd6 (patch) | |
tree | 284e4207377df3c0952656d4f75459a96d0ecb36 /vendor | |
parent | 682250e328472e855a4c59e9e5f004473b6af0d3 (diff) |
Add statsclient - pure Go implementation for stats API
Change-Id: Ia5bab652c6089378697459f477f9060dc7a53e90
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
Diffstat (limited to 'vendor')
-rw-r--r-- | vendor/github.com/ftrvxmtrx/fd/LICENSE.MIT | 18 | ||||
-rw-r--r-- | vendor/github.com/ftrvxmtrx/fd/README.md | 25 | ||||
-rw-r--r-- | vendor/github.com/ftrvxmtrx/fd/fd.go | 104 |
3 files changed, 147 insertions, 0 deletions
diff --git a/vendor/github.com/ftrvxmtrx/fd/LICENSE.MIT b/vendor/github.com/ftrvxmtrx/fd/LICENSE.MIT new file mode 100644 index 0000000..136e69e --- /dev/null +++ b/vendor/github.com/ftrvxmtrx/fd/LICENSE.MIT @@ -0,0 +1,18 @@ +Copyright © 2012 Serge Zirukin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/ftrvxmtrx/fd/README.md b/vendor/github.com/ftrvxmtrx/fd/README.md new file mode 100644 index 0000000..7a8a239 --- /dev/null +++ b/vendor/github.com/ftrvxmtrx/fd/README.md @@ -0,0 +1,25 @@ +# fd + +Package fd provides a simple API to pass file descriptors +between different OS processes. + +It can be useful if you want to inherit network connections +from another process without closing them. + +Example scenario: + + * Running server receives a "let's upgrade" message + * Server opens a Unix domain socket for the "upgrade" + * Server starts a new copy of itself and passes Unix domain + socket name + * New copy starts reading data from the socket + * Server sends its state over the socket, also sending the number + of network connections to inherit, then it sends those connections + using fd.Put() + * New server copy reads the state and inherits connections using fd.Get(), + checks that everything is OK and writes an "OK" message to the socket + * Server receives "OK" message and kills itself + +## Documentation + +[fd on godoc.org](http://godoc.org/github.com/ftrvxmtrx/fd) diff --git a/vendor/github.com/ftrvxmtrx/fd/fd.go b/vendor/github.com/ftrvxmtrx/fd/fd.go new file mode 100644 index 0000000..a5a4d48 --- /dev/null +++ b/vendor/github.com/ftrvxmtrx/fd/fd.go @@ -0,0 +1,104 @@ +// Package fd provides a simple API to pass file descriptors +// between different OS processes. +// +// It can be useful if you want to inherit network connections +// from another process without closing them. +// +// Example scenario: +// +// 1) Running server receives a "let's upgrade" message +// 2) Server opens a Unix domain socket for the "upgrade" +// 3) Server starts a new copy of itself and passes Unix domain socket name +// 4) New copy starts reading for the socket +// 5) Server sends its state over the socket, also sending the number +// of network connections to inherit, then it sends those connections +// using fd.Put() +// 6) New copy reads the state and inherits connections using fd.Get(), +// checks that everything is OK and sends the "OK" message to the socket +// 7) Server receives "OK" message and kills itself +package fd + +import ( + "net" + "os" + "syscall" +) + +// Get receives file descriptors from a Unix domain socket. +// +// Num specifies the expected number of file descriptors in one message. +// Internal files' names to be assigned are specified via optional filenames +// argument. +// +// You need to close all files in the returned slice. The slice can be +// non-empty even if this function returns an error. +// +// Use net.FileConn() if you're receiving a network connection. +func Get(via *net.UnixConn, num int, filenames []string) ([]*os.File, error) { + if num < 1 { + return nil, nil + } + + // get the underlying socket + viaf, err := via.File() + if err != nil { + return nil, err + } + socket := int(viaf.Fd()) + defer viaf.Close() + + // recvmsg + buf := make([]byte, syscall.CmsgSpace(num*4)) + _, _, _, _, err = syscall.Recvmsg(socket, nil, buf, 0) + if err != nil { + return nil, err + } + + // parse control msgs + var msgs []syscall.SocketControlMessage + msgs, err = syscall.ParseSocketControlMessage(buf) + + // convert fds to files + res := make([]*os.File, 0, len(msgs)) + for i := 0; i < len(msgs) && err == nil; i++ { + var fds []int + fds, err = syscall.ParseUnixRights(&msgs[i]) + + for fi, fd := range fds { + var filename string + if fi < len(filenames) { + filename = filenames[fi] + } + + res = append(res, os.NewFile(uintptr(fd), filename)) + } + } + + return res, err +} + +// Put sends file descriptors to Unix domain socket. +// +// Please note that the number of descriptors in one message is limited +// and is rather small. +// Use conn.File() to get a file if you want to put a network connection. +func Put(via *net.UnixConn, files ...*os.File) error { + if len(files) == 0 { + return nil + } + + viaf, err := via.File() + if err != nil { + return err + } + socket := int(viaf.Fd()) + defer viaf.Close() + + fds := make([]int, len(files)) + for i := range files { + fds[i] = int(files[i].Fd()) + } + + rights := syscall.UnixRights(fds...) + return syscall.Sendmsg(socket, nil, rights, nil, 0) +} |