in internal/proxy/proxy_other.go [103:164]
func (c *Client) Lookup(_ context.Context, instance string, _ *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
ctx := context.Background()
if instance == "README" {
return c.NewInode(ctx, &readme{}, fs.StableAttr{}), fs.OK
}
if _, err := parseConnName(instance); err != nil {
c.logger.Debugf("could not parse instance connection name for %q: %v", instance, err)
return nil, syscall.ENOENT
}
c.fuseMu.Lock()
defer c.fuseMu.Unlock()
if l, ok := c.fuseSockets[instance]; ok {
c.logger.Debugf("found existing socket for instance %q", instance)
return l.symlink.EmbeddedInode(), fs.OK
}
c.logger.Debugf("creating new socket for instance %q", instance)
s, err := c.newSocketMount(
ctx, withUnixSocket(*c.conf, c.fuseTempDir),
nil, InstanceConnConfig{Name: instance},
)
if err != nil {
c.logger.Errorf("could not create socket for %q: %v", instance, err)
return nil, syscall.ENOENT
}
c.fuseWg.Add(1)
go func() {
defer c.fuseWg.Done()
sErr := c.serveSocketMount(ctx, s)
if sErr != nil {
c.logger.Debugf("could not serve socket for instance %q: %v", instance, sErr)
c.fuseMu.Lock()
defer c.fuseMu.Unlock()
delete(c.fuseSockets, instance)
select {
// Best effort attempt to send error.
// If this send fails, it means the reading goroutine has
// already pulled a value out of the channel and is no longer
// reading any more values. In other words, we report only the
// first error.
case c.fuseExitCh <- sErr:
default:
return
}
}
}()
// Return a symlink that points to the actual Unix socket within the
// temporary directory. For Postgres, return a symlink that points to the
// directory which holds the ".s.PGSQL.5432" Unix socket.
sl := &symlink{path: filepath.Join(c.fuseTempDir, instance)}
c.fuseSockets[instance] = socketSymlink{
socket: s,
symlink: sl,
}
return c.NewInode(ctx, sl, fs.StableAttr{
Mode: 0777 | fuse.S_IFLNK},
), fs.OK
}