summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Fabry <ofabry@cisco.com>2019-04-05 10:18:33 +0200
committerOndrej Fabry <ofabry@cisco.com>2019-04-05 10:18:33 +0200
commitf40a43b1a99f488da1400c74482b9c97eaf08515 (patch)
treed256d1f3e3a6a394849c4f53dabbdaee1b8925af
parente6cca4bfd215aba51d58bf0bb046c16c081e42a3 (diff)
Fix WaitReady for VPP client adapters
Change-Id: I57d29a819132d4894691e1131b7d79e19c90456e Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
-rw-r--r--adapter/socketclient/socketclient.go31
-rw-r--r--adapter/vppapiclient/vppapiclient.go31
2 files changed, 43 insertions, 19 deletions
diff --git a/adapter/socketclient/socketclient.go b/adapter/socketclient/socketclient.go
index f281955..4c576c3 100644
--- a/adapter/socketclient/socketclient.go
+++ b/adapter/socketclient/socketclient.go
@@ -4,7 +4,6 @@ import (
"bufio"
"bytes"
"fmt"
- "github.com/fsnotify/fsnotify"
"io"
"net"
"os"
@@ -13,6 +12,8 @@ import (
"sync"
"time"
+ "github.com/fsnotify/fsnotify"
+
"github.com/lunixbochs/struc"
logger "github.com/sirupsen/logrus"
@@ -33,6 +34,10 @@ var (
ConnectTimeout = time.Second * 3
DisconnectTimeout = time.Second
+ // MaxWaitReady defines maximum duration before waiting for socket file
+ // times out
+ MaxWaitReady = time.Second * 15
+
Debug = os.Getenv("DEBUG_GOVPP_SOCK") != ""
DebugMsgIds = os.Getenv("DEBUG_GOVPP_SOCKMSG") != ""
@@ -76,7 +81,7 @@ func nilCallback(msgID uint16, data []byte) {
// WaitReady checks socket file existence and waits for it if necessary
func (c *vppClient) WaitReady() error {
- // verify file existence
+ // check if file at the path already exists
if _, err := os.Stat(c.sockAddr); err == nil {
return nil
} else if os.IsExist(err) {
@@ -93,17 +98,25 @@ func (c *vppClient) WaitReady() error {
Log.Errorf("failed to close file watcher: %v", err)
}
}()
- path := filepath.Dir(c.sockAddr)
- if err := watcher.Add(path); err != nil {
+
+ // start watching directory
+ if err := watcher.Add(filepath.Dir(c.sockAddr)); err != nil {
return err
}
for {
- ev := <-watcher.Events
- if ev.Name == path {
- if (ev.Op & fsnotify.Create) == fsnotify.Create {
- // socket ready
- return nil
+ select {
+ case <-time.After(MaxWaitReady):
+ return fmt.Errorf("waiting for socket file timed out (%s)", MaxWaitReady)
+ case e := <-watcher.Errors:
+ return e
+ case ev := <-watcher.Events:
+ Log.Debugf("watcher event: %+v", ev)
+ if ev.Name == c.sockAddr {
+ if (ev.Op & fsnotify.Create) == fsnotify.Create {
+ // socket was created, we are ready
+ return nil
+ }
}
}
}
diff --git a/adapter/vppapiclient/vppapiclient.go b/adapter/vppapiclient/vppapiclient.go
index d43c832..037d3ac 100644
--- a/adapter/vppapiclient/vppapiclient.go
+++ b/adapter/vppapiclient/vppapiclient.go
@@ -78,12 +78,19 @@ import (
"os"
"path/filepath"
"reflect"
+ "time"
"unsafe"
"git.fd.io/govpp.git/adapter"
"github.com/fsnotify/fsnotify"
)
+var (
+ // MaxWaitReady defines maximum duration before waiting for shared memory
+ // segment times out
+ MaxWaitReady = time.Second * 15
+)
+
const (
// shmDir is a directory where shared memory is supposed to be created.
shmDir = "/dev/shm/"
@@ -173,16 +180,15 @@ func (a *vppClient) SetMsgCallback(cb adapter.MsgCallback) {
// WaitReady blocks until shared memory for sending
// binary api calls is present on the file system.
func (a *vppClient) WaitReady() error {
- var path string
-
// join the path to the shared memory segment
+ var path string
if a.shmPrefix == "" {
path = filepath.Join(shmDir, vppShmFile)
} else {
path = filepath.Join(shmDir, a.shmPrefix+"-"+vppShmFile)
}
- // check if file at the path exists
+ // check if file at the path already exists
if _, err := os.Stat(path); err == nil {
// file exists, we are ready
return nil
@@ -197,21 +203,26 @@ func (a *vppClient) WaitReady() error {
}
defer watcher.Close()
+ // start watching directory
if err := watcher.Add(shmDir); err != nil {
return err
}
for {
- ev := <-watcher.Events
- if ev.Name == path {
- if (ev.Op & fsnotify.Create) == fsnotify.Create {
- // file was created, we are ready
- break
+ select {
+ case <-time.After(MaxWaitReady):
+ return fmt.Errorf("waiting for shared memory segment timed out (%s)", MaxWaitReady)
+ case e := <-watcher.Errors:
+ return e
+ case ev := <-watcher.Events:
+ if ev.Name == path {
+ if (ev.Op & fsnotify.Create) == fsnotify.Create {
+ // file was created, we are ready
+ return nil
+ }
}
}
}
-
- return nil
}
//export go_msg_callback