From 4da29d1fb32a77dd299e84a9ed3a11ddcaa31a3b Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Mon, 21 Dec 2020 17:38:00 +0100 Subject: Remove socket warnings from client adapters Change-Id: I5e72df39c0e4ba4f0a70d561d7f9b220b4e72a4c Signed-off-by: Ondrej Fabry --- adapter/socketclient/socketclient.go | 119 ++++++++++------------------------- adapter/statsclient/statsclient.go | 59 ++++++++--------- 2 files changed, 58 insertions(+), 120 deletions(-) diff --git a/adapter/socketclient/socketclient.go b/adapter/socketclient/socketclient.go index 4ee319b..4173d7e 100644 --- a/adapter/socketclient/socketclient.go +++ b/adapter/socketclient/socketclient.go @@ -73,29 +73,8 @@ func init() { log = logger.WithField("logger", "govpp/socketclient") } -const socketMissing = ` ------------------------------------------------------------- - No socket file found at: %s - VPP binary API socket file is missing! - - - is VPP running with socket for binapi enabled? - - is the correct socket name configured? - - To enable it add following section to your VPP config: - socksvr { - socket-name /run/vpp/api.sock - } ------------------------------------------------------------- -` - -var warnOnce sync.Once - -func (c *socketClient) printMissingSocketMsg() { - fmt.Fprintf(os.Stderr, socketMissing, c.sockAddr) -} - -type socketClient struct { - sockAddr string +type Client struct { + socketPath string clientName string conn *net.UnixConn @@ -117,12 +96,14 @@ type socketClient struct { wg sync.WaitGroup } -func NewVppClient(sockAddr string) *socketClient { - if sockAddr == "" { - sockAddr = DefaultSocketName +// NewVppClient returns a new Client using socket. +// If socket is empty string DefaultSocketName is used. +func NewVppClient(socket string) *Client { + if socket == "" { + socket = DefaultSocketName } - return &socketClient{ - sockAddr: sockAddr, + return &Client{ + socketPath: socket, clientName: DefaultClientName, connectTimeout: DefaultConnectTimeout, disconnectTimeout: DefaultDisconnectTimeout, @@ -136,61 +117,34 @@ func NewVppClient(sockAddr string) *socketClient { } // SetClientName sets a client name used for identification. -func (c *socketClient) SetClientName(name string) { +func (c *Client) SetClientName(name string) { c.clientName = name } // SetConnectTimeout sets timeout used during connecting. -func (c *socketClient) SetConnectTimeout(t time.Duration) { +func (c *Client) SetConnectTimeout(t time.Duration) { c.connectTimeout = t } // SetDisconnectTimeout sets timeout used during disconnecting. -func (c *socketClient) SetDisconnectTimeout(t time.Duration) { +func (c *Client) SetDisconnectTimeout(t time.Duration) { c.disconnectTimeout = t } -func (c *socketClient) SetMsgCallback(cb adapter.MsgCallback) { +func (c *Client) SetMsgCallback(cb adapter.MsgCallback) { log.Debug("SetMsgCallback") c.msgCallback = cb } -const legacySocketName = "/run/vpp-api.sock" - -func (c *socketClient) checkLegacySocket() bool { - if c.sockAddr == legacySocketName { - return false - } - log.Debugf("checking legacy socket: %s", legacySocketName) - // check if socket exists - if _, err := os.Stat(c.sockAddr); err == nil { - return false // socket exists - } else if !os.IsNotExist(err) { - return false // some other error occurred - } - // check if legacy socket exists - if _, err := os.Stat(legacySocketName); err == nil { - // legacy socket exists, update sockAddr - c.sockAddr = legacySocketName - return true - } - // no socket socket found - return false -} - // WaitReady checks socket file existence and waits for it if necessary -func (c *socketClient) WaitReady() error { +func (c *Client) WaitReady() error { // check if socket already exists - if _, err := os.Stat(c.sockAddr); err == nil { + if _, err := os.Stat(c.socketPath); err == nil { return nil // socket exists, we are ready } else if !os.IsNotExist(err) { return err // some other error occurred } - if c.checkLegacySocket() { - return nil - } - // socket does not exist, watch for it watcher, err := fsnotify.NewWatcher() if err != nil { @@ -203,7 +157,7 @@ func (c *socketClient) WaitReady() error { }() // start directory watcher - if err := watcher.Add(filepath.Dir(c.sockAddr)); err != nil { + if err := watcher.Add(filepath.Dir(c.socketPath)); err != nil { return err } @@ -211,17 +165,14 @@ func (c *socketClient) WaitReady() error { for { select { case <-timeout.C: - if c.checkLegacySocket() { - return nil - } - return fmt.Errorf("timeout waiting (%s) for socket file: %s", MaxWaitReady, c.sockAddr) + return fmt.Errorf("timeout waiting (%s) for socket file: %s", MaxWaitReady, c.socketPath) case e := <-watcher.Errors: return e case ev := <-watcher.Events: log.Debugf("watcher event: %+v", ev) - if ev.Name == c.sockAddr && (ev.Op&fsnotify.Create) == fsnotify.Create { + if ev.Name == c.socketPath && (ev.Op&fsnotify.Create) == fsnotify.Create { // socket created, we are ready return nil } @@ -229,18 +180,15 @@ func (c *socketClient) WaitReady() error { } } -func (c *socketClient) Connect() error { - c.checkLegacySocket() - +func (c *Client) Connect() error { // check if socket exists - if _, err := os.Stat(c.sockAddr); os.IsNotExist(err) { - warnOnce.Do(c.printMissingSocketMsg) - return fmt.Errorf("VPP API socket file %s does not exist", c.sockAddr) + if _, err := os.Stat(c.socketPath); os.IsNotExist(err) { + return fmt.Errorf("VPP API socket file %s does not exist", c.socketPath) } else if err != nil { return fmt.Errorf("VPP API socket error: %v", err) } - if err := c.connect(c.sockAddr); err != nil { + if err := c.connect(c.socketPath); err != nil { return err } @@ -256,7 +204,7 @@ func (c *socketClient) Connect() error { return nil } -func (c *socketClient) Disconnect() error { +func (c *Client) Disconnect() error { if c.conn == nil { return nil } @@ -273,7 +221,6 @@ func (c *socketClient) Disconnect() error { // Don't bother sending a vl_api_sockclnt_delete_t message, // just close the socket. - if err := c.disconnect(); err != nil { return err } @@ -283,10 +230,10 @@ func (c *socketClient) Disconnect() error { const defaultBufferSize = 4096 -func (c *socketClient) connect(sockAddr string) error { +func (c *Client) connect(sockAddr string) error { addr := &net.UnixAddr{Name: sockAddr, Net: "unix"} - log.Debugf("Connecting to: %v", c.sockAddr) + log.Debugf("Connecting to: %v", c.socketPath) conn, err := net.DialUnix("unix", nil, addr) if err != nil { @@ -311,7 +258,7 @@ func (c *socketClient) connect(sockAddr string) error { return nil } -func (c *socketClient) disconnect() error { +func (c *Client) disconnect() error { log.Debugf("Closing socket") if err := c.conn.Close(); err != nil { log.Debugln("Closing socket failed:", err) @@ -326,7 +273,7 @@ const ( deleteMsgContext = byte(124) ) -func (c *socketClient) open() error { +func (c *Client) open() error { var msgCodec = codec.DefaultCodec // Request socket client create @@ -379,7 +326,7 @@ func (c *socketClient) open() error { return nil } -func (c *socketClient) GetMsgID(msgName string, msgCrc string) (uint16, error) { +func (c *Client) GetMsgID(msgName string, msgCrc string) (uint16, error) { if msgID, ok := c.msgTable[msgName+"_"+msgCrc]; ok { return msgID, nil } @@ -389,7 +336,7 @@ func (c *socketClient) GetMsgID(msgName string, msgCrc string) (uint16, error) { } } -func (c *socketClient) SendMsg(context uint32, data []byte) error { +func (c *Client) SendMsg(context uint32, data []byte) error { if len(data) < 10 { return fmt.Errorf("invalid message data, length must be at least 10 bytes") } @@ -423,7 +370,7 @@ func setMsgRequestHeader(data []byte, clientIndex, context uint32) { binary.BigEndian.PutUint32(data[6:10], context) } -func (c *socketClient) writeMsg(msg []byte) error { +func (c *Client) writeMsg(msg []byte) error { // we lock to prevent mixing multiple message writes c.writeMu.Lock() defer c.writeMu.Unlock() @@ -482,7 +429,7 @@ func writeMsgData(w io.Writer, msg []byte, writerSize int) error { return nil } -func (c *socketClient) readerLoop() { +func (c *Client) readerLoop() { defer c.wg.Done() defer log.Debugf("reader loop done") @@ -528,7 +475,7 @@ func getMsgReplyHeader(msg []byte) (msgID uint16, context uint32) { return } -func (c *socketClient) readMsgTimeout(buf []byte, timeout time.Duration) ([]byte, error) { +func (c *Client) readMsgTimeout(buf []byte, timeout time.Duration) ([]byte, error) { // set read deadline readDeadline := time.Now().Add(timeout) if err := c.conn.SetReadDeadline(readDeadline); err != nil { @@ -549,7 +496,7 @@ func (c *socketClient) readMsgTimeout(buf []byte, timeout time.Duration) ([]byte return msgReply, nil } -func (c *socketClient) readMsg(buf []byte) ([]byte, error) { +func (c *Client) readMsg(buf []byte) ([]byte, error) { log.Debug("reading msg..") header := c.headerPool.Get().([]byte) diff --git a/adapter/statsclient/statsclient.go b/adapter/statsclient/statsclient.go index 8693410..9470275 100644 --- a/adapter/statsclient/statsclient.go +++ b/adapter/statsclient/statsclient.go @@ -24,10 +24,11 @@ import ( "syscall" "time" - "git.fd.io/govpp.git/adapter" "github.com/fsnotify/fsnotify" "github.com/ftrvxmtrx/fd" logger "github.com/sirupsen/logrus" + + "git.fd.io/govpp.git/adapter" ) const ( @@ -35,20 +36,6 @@ const ( DefaultSocketName = adapter.DefaultStatsSocket ) -const socketMissing = ` ------------------------------------------------------------- - VPP stats socket file %s is missing! - - - is VPP running with stats segment enabled? - - is the correct socket name configured? - - To enable it add following section to your VPP config: - statseg { - socket-name /run/vpp/stats.sock - } ------------------------------------------------------------- -` - var ( // Debug is global variable that determines debug mode Debug = os.Getenv("DEBUG_GOVPP_STATS") != "" @@ -77,7 +64,8 @@ var _ adapter.StatsAPI = (*StatsClient)(nil) // StatsClient is the pure Go implementation for VPP stats API. type StatsClient struct { - sockAddr string + socketPath string + headerData []byte isConnected bool @@ -87,13 +75,14 @@ type StatsClient struct { statSegment } -// NewStatsClient returns new VPP stats API client. -func NewStatsClient(sockAddr string) *StatsClient { - if sockAddr == "" { - sockAddr = DefaultSocketName +// NewStatsClient returns a new StatsClient using socket. +// If socket is empty string DefaultSocketName is used. +func NewStatsClient(socket string) *StatsClient { + if socket == "" { + socket = DefaultSocketName } return &StatsClient{ - sockAddr: sockAddr, + socketPath: socket, } } @@ -103,20 +92,25 @@ func (sc *StatsClient) Connect() (err error) { if sc.isConnected { return fmt.Errorf("already connected") } - if err := sc.validate(); err != nil { + if err := sc.checkSocketValid(); err != nil { return err } sc.done = make(chan struct{}) - sc.monitorSocket() if sc.statSegment, err = sc.connect(); err != nil { return err } + sc.monitorSocket() + sc.isConnected = true return nil } // Disconnect from the socket, unmap shared memory and terminate // socket monitor func (sc *StatsClient) Disconnect() error { + if !sc.isConnected { + return nil // not connected + } + sc.isConnected = false close(sc.done) return sc.disconnect() } @@ -287,11 +281,9 @@ func (sc *StatsClient) UpdateDir(dir *adapter.StatDir) (err error) { return nil } -// validate file presence by retrieving its file info -func (sc *StatsClient) validate() error { - if _, err := os.Stat(sc.sockAddr); os.IsNotExist(err) { - fmt.Fprintf(os.Stderr, socketMissing, sc.sockAddr) - return fmt.Errorf("stats socket file %s does not exist", sc.sockAddr) +func (sc *StatsClient) checkSocketValid() error { + if _, err := os.Stat(sc.socketPath); os.IsNotExist(err) { + return fmt.Errorf("stats socket file %s does not exist", sc.socketPath) } else if err != nil { return fmt.Errorf("stats socket error: %v", err) } @@ -303,7 +295,7 @@ func (sc *StatsClient) validate() error { func (sc *StatsClient) connect() (ss statSegment, err error) { addr := net.UnixAddr{ Net: "unixpacket", - Name: sc.sockAddr, + Name: sc.socketPath, } Log.Debugf("connecting to: %v", addr) @@ -357,7 +349,7 @@ func (sc *StatsClient) connect() (ss statSegment, err error) { return nil, fmt.Errorf("stat segment version is not supported: %v (min: %v, max: %v)", version, minVersion, maxVersion) } - sc.isConnected = true + return ss, nil } @@ -367,7 +359,7 @@ func (sc *StatsClient) reconnect() (err error) { if err = sc.disconnect(); err != nil { return fmt.Errorf("error disconnecting socket: %v", err) } - if err = sc.validate(); err != nil { + if err = sc.checkSocketValid(); err != nil { return fmt.Errorf("error validating socket: %v", err) } if sc.statSegment, err = sc.connect(); err != nil { @@ -378,7 +370,6 @@ func (sc *StatsClient) reconnect() (err error) { // disconnect unmaps socket data from the memory and resets the header func (sc *StatsClient) disconnect() error { - sc.isConnected = false if sc.headerData == nil { return nil } @@ -408,7 +399,7 @@ func (sc *StatsClient) monitorSocket() { Log.Errorf("error occurred during socket reconnect: %v", err) } // path must be re-added to the watcher - if err = watcher.Add(sc.sockAddr); err != nil { + if err = watcher.Add(sc.socketPath); err != nil { Log.Errorf("failed to add socket address to the watcher: %v", err) } } @@ -422,7 +413,7 @@ func (sc *StatsClient) monitorSocket() { } }() - if err := watcher.Add(sc.sockAddr); err != nil { + if err := watcher.Add(sc.socketPath); err != nil { Log.Errorf("failed to add socket address to the watcher: %v", err) } } -- cgit 1.2.3-korg