mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Port netstack, hostinet, and netlink sockets to VFS2.
All three follow the same pattern: 1. Refactor VFS1 sockets into socketOpsCommon, so that most of the methods can be shared with VFS2. 2. Create a FileDescriptionImpl with the corresponding socket operations, rewriting the few that cannot be shared with VFS1. 3. Set up a VFS2 socket provider that creates a socket by setting up a dentry in the global Kernel.socketMount and connecting it with a new FileDescription. This mostly completes the work for porting sockets to VFS2, and many syscall tests can be enabled as a result. There are several networking-related syscall tests that are still not passing: 1. net gofer tests 2. socketpair gofer tests 2. sendfile tests (splice is not implemented in VFS2 yet) Updates #1478, #1484, #1485 PiperOrigin-RevId: 309457331
This commit is contained in:
@@ -411,7 +411,7 @@ func (i *inode) open(ctx context.Context, d *vfs.Dentry, mnt *vfs.Mount) (*vfs.F
|
||||
return nil, syserror.ENOTTY
|
||||
}
|
||||
|
||||
ep, err := newEndpoint(ctx, i.hostFD)
|
||||
ep, err := newEndpoint(ctx, i.hostFD, &i.queue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -34,17 +34,16 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
// Create a new host-backed endpoint from the given fd.
|
||||
func newEndpoint(ctx context.Context, hostFD int) (transport.Endpoint, error) {
|
||||
// Create a new host-backed endpoint from the given fd and its corresponding
|
||||
// notification queue.
|
||||
func newEndpoint(ctx context.Context, hostFD int, queue *waiter.Queue) (transport.Endpoint, error) {
|
||||
// Set up an external transport.Endpoint using the host fd.
|
||||
addr := fmt.Sprintf("hostfd:[%d]", hostFD)
|
||||
var q waiter.Queue
|
||||
e, err := NewConnectedEndpoint(ctx, hostFD, &q, addr, true /* saveable */)
|
||||
e, err := NewConnectedEndpoint(ctx, hostFD, addr, true /* saveable */)
|
||||
if err != nil {
|
||||
return nil, err.ToError()
|
||||
}
|
||||
e.Init()
|
||||
ep := transport.NewExternal(ctx, e.stype, uniqueid.GlobalProviderFromContext(ctx), &q, e, e)
|
||||
ep := transport.NewExternal(ctx, e.stype, uniqueid.GlobalProviderFromContext(ctx), queue, e, e)
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
@@ -77,8 +76,6 @@ type ConnectedEndpoint struct {
|
||||
// addr is the address at which this endpoint is bound.
|
||||
addr string
|
||||
|
||||
queue *waiter.Queue
|
||||
|
||||
// sndbuf is the size of the send buffer.
|
||||
//
|
||||
// N.B. When this is smaller than the host size, we present it via
|
||||
@@ -134,11 +131,10 @@ func (c *ConnectedEndpoint) init() *syserr.Error {
|
||||
// The caller is responsible for calling Init(). Additionaly, Release needs to
|
||||
// be called twice because ConnectedEndpoint is both a transport.Receiver and
|
||||
// transport.ConnectedEndpoint.
|
||||
func NewConnectedEndpoint(ctx context.Context, hostFD int, queue *waiter.Queue, addr string, saveable bool) (*ConnectedEndpoint, *syserr.Error) {
|
||||
func NewConnectedEndpoint(ctx context.Context, hostFD int, addr string, saveable bool) (*ConnectedEndpoint, *syserr.Error) {
|
||||
e := ConnectedEndpoint{
|
||||
fd: hostFD,
|
||||
addr: addr,
|
||||
queue: queue,
|
||||
fd: hostFD,
|
||||
addr: addr,
|
||||
}
|
||||
|
||||
if err := e.init(); err != nil {
|
||||
@@ -151,13 +147,6 @@ func NewConnectedEndpoint(ctx context.Context, hostFD int, queue *waiter.Queue,
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
// Init will do the initialization required without holding other locks.
|
||||
func (c *ConnectedEndpoint) Init() {
|
||||
if err := fdnotifier.AddFD(int32(c.fd), c.queue); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Send implements transport.ConnectedEndpoint.Send.
|
||||
func (c *ConnectedEndpoint) Send(data [][]byte, controlMessages transport.ControlMessages, from tcpip.FullAddress) (int64, bool, *syserr.Error) {
|
||||
c.mu.RLock()
|
||||
@@ -332,7 +321,6 @@ func (c *ConnectedEndpoint) RecvMaxQueueSize() int64 {
|
||||
}
|
||||
|
||||
func (c *ConnectedEndpoint) destroyLocked() {
|
||||
fdnotifier.RemoveFD(int32(c.fd))
|
||||
c.fd = -1
|
||||
}
|
||||
|
||||
@@ -350,14 +338,20 @@ func (c *ConnectedEndpoint) Release() {
|
||||
func (c *ConnectedEndpoint) CloseUnread() {}
|
||||
|
||||
// SCMConnectedEndpoint represents an endpoint backed by a host fd that was
|
||||
// passed through a gofer Unix socket. It is almost the same as
|
||||
// ConnectedEndpoint, with the following differences:
|
||||
// passed through a gofer Unix socket. It resembles ConnectedEndpoint, with the
|
||||
// following differences:
|
||||
// - SCMConnectedEndpoint is not saveable, because the host cannot guarantee
|
||||
// the same descriptor number across S/R.
|
||||
// - SCMConnectedEndpoint holds ownership of its fd and is responsible for
|
||||
// closing it.
|
||||
// - SCMConnectedEndpoint holds ownership of its fd and notification queue.
|
||||
type SCMConnectedEndpoint struct {
|
||||
ConnectedEndpoint
|
||||
|
||||
queue *waiter.Queue
|
||||
}
|
||||
|
||||
// Init will do the initialization required without holding other locks.
|
||||
func (e *SCMConnectedEndpoint) Init() error {
|
||||
return fdnotifier.AddFD(int32(e.fd), e.queue)
|
||||
}
|
||||
|
||||
// Release implements transport.ConnectedEndpoint.Release and
|
||||
@@ -368,6 +362,7 @@ func (e *SCMConnectedEndpoint) Release() {
|
||||
if err := syscall.Close(e.fd); err != nil {
|
||||
log.Warningf("Failed to close host fd %d: %v", err)
|
||||
}
|
||||
fdnotifier.RemoveFD(int32(e.fd))
|
||||
e.destroyLocked()
|
||||
e.mu.Unlock()
|
||||
})
|
||||
@@ -380,11 +375,13 @@ func (e *SCMConnectedEndpoint) Release() {
|
||||
// be called twice because ConnectedEndpoint is both a transport.Receiver and
|
||||
// transport.ConnectedEndpoint.
|
||||
func NewSCMEndpoint(ctx context.Context, hostFD int, queue *waiter.Queue, addr string) (*SCMConnectedEndpoint, *syserr.Error) {
|
||||
e := SCMConnectedEndpoint{ConnectedEndpoint{
|
||||
fd: hostFD,
|
||||
addr: addr,
|
||||
e := SCMConnectedEndpoint{
|
||||
ConnectedEndpoint: ConnectedEndpoint{
|
||||
fd: hostFD,
|
||||
addr: addr,
|
||||
},
|
||||
queue: queue,
|
||||
}}
|
||||
}
|
||||
|
||||
if err := e.init(); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user