support for shm prefixes 07/12307/1
authorVladimir Lavor <vlavor@cisco.com>
Wed, 2 May 2018 07:47:44 +0000 (09:47 +0200)
committerVladimir Lavor <vlavor@cisco.com>
Wed, 2 May 2018 07:47:44 +0000 (09:47 +0200)
Change-Id: I279653deb9911862d29143269aea5dffbd564478
Signed-off-by: Vladimir Lavor <vlavor@cisco.com>
adapter/vppapiclient/vppapiclient_adapter.go
examples/cmd/perf-bench/perf-bench.go
examples/cmd/simple-client/simple_client.go
examples/cmd/stats-client/stats_client.go
govpp.go

index e9948e8..5a05a58 100644 (file)
@@ -49,9 +49,9 @@ govpp_msg_callback (unsigned char *data, int size)
 }
 
 static int
-govpp_connect()
+govpp_connect (char *shm)
 {
-    return vac_connect("govpp", NULL, govpp_msg_callback, 32);
+    return vac_connect("govpp", shm, govpp_msg_callback, 32);
 }
 
 static int
@@ -90,27 +90,36 @@ const (
        // watchedFolder is a folder where vpp's shared memory is supposed to be created.
        // File system events are monitored in this folder.
        watchedFolder = "/dev/shm/"
-       // watchedFile is a name of the file in the watchedFolder. Once the file is present
+       // watchedFile is a default name of the file in the watchedFolder. Once the file is present,
        // the vpp is ready to accept a new connection.
-       watchedFile = watchedFolder + "vpe-api"
+       watchedFile = "vpe-api"
 )
 
 // vppAPIClientAdapter is the opaque context of the adapter.
 type vppAPIClientAdapter struct {
-       callback func(context uint32, msgId uint16, data []byte)
+       shmPrefix string
+       callback  func(context uint32, msgId uint16, data []byte)
 }
 
 var vppClient *vppAPIClientAdapter // global vpp API client adapter context
 
 // NewVppAdapter returns a new vpp API client adapter.
-func NewVppAdapter() adapter.VppAdapter {
-       return &vppAPIClientAdapter{}
+func NewVppAdapter(shmPrefix string) adapter.VppAdapter {
+       return &vppAPIClientAdapter{
+               shmPrefix: shmPrefix,
+       }
 }
 
 // Connect connects the process to VPP.
 func (a *vppAPIClientAdapter) Connect() error {
        vppClient = a
-       rc := C.govpp_connect()
+       var rc _Ctype_int
+       if a.shmPrefix == "" {
+               rc = C.govpp_connect(nil)
+       } else {
+               shm := C.CString(a.shmPrefix)
+               rc = C.govpp_connect(shm)
+       }
        if rc != 0 {
                return fmt.Errorf("unable to connect to VPP (error=%d)", rc)
        }
@@ -162,14 +171,20 @@ func (a *vppAPIClientAdapter) WaitReady() error {
        if err != nil {
                return err
        }
-
-       if fileExists(watchedFile) {
+       // Path to the shared memory segment with prefix, if set
+       var path string
+       if a.shmPrefix == "" {
+               path = watchedFolder + watchedFile
+       } else {
+               path = watchedFolder + a.shmPrefix + "-" + watchedFile
+       }
+       if fileExists(path) {
                return nil
        }
 
        for {
                ev := <-watcher.Events
-               if ev.Name == watchedFile && (ev.Op&fsnotify.Create) == fsnotify.Create {
+               if ev.Name == path && (ev.Op&fsnotify.Create) == fsnotify.Create {
                        break
                }
        }
@@ -192,4 +207,4 @@ func go_msg_callback(msgID C.uint16_t, context C.uint32_t, data unsafe.Pointer,
        byteArr := *(*[]byte)(unsafe.Pointer(slice))
 
        vppClient.callback(uint32(context), uint16(msgID), byteArr)
-}
+}
\ No newline at end of file
index ca74df6..f3ff752 100644 (file)
@@ -24,8 +24,8 @@ import (
        "sync"
        "time"
 
-       "github.com/sirupsen/logrus"
        "github.com/pkg/profile"
+       "github.com/sirupsen/logrus"
 
        "git.fd.io/govpp.git"
        "git.fd.io/govpp.git/api"
@@ -64,7 +64,7 @@ func main() {
        core.SetLogger(&logrus.Logger{Level: logrus.ErrorLevel})
 
        // connect to VPP
-       conn, err := govpp.Connect()
+       conn, err := govpp.Connect("")
        if err != nil {
                log.Println("Error:", err)
                os.Exit(1)
@@ -159,4 +159,4 @@ func readAsyncReplies(ch *api.Channel, expectedCnt int, wg *sync.WaitGroup) {
                        return
                }
        }
-}
+}
\ No newline at end of file
index 8f10360..67dc14b 100644 (file)
@@ -35,7 +35,7 @@ func main() {
        fmt.Println("Starting simple VPP client...")
 
        // connect to VPP
-       conn, err := govpp.Connect()
+       conn, err := govpp.Connect("")
        if err != nil {
                fmt.Println("Error:", err)
                os.Exit(1)
@@ -218,4 +218,4 @@ func interfaceNotifications(ch *api.Channel) {
 
        // unsubscribe from delivery of the notifications
        ch.UnsubscribeNotification(subs)
-}
+}
\ No newline at end of file
index 458da21..17c7956 100644 (file)
@@ -35,7 +35,7 @@ func main() {
        fmt.Println("Starting stats VPP client...")
 
        // async connect to VPP
-       conn, statCh, err := govpp.AsyncConnect()
+       conn, statCh, err := govpp.AsyncConnect("")
        if err != nil {
                fmt.Println("Error:", err)
                os.Exit(1)
@@ -141,4 +141,4 @@ func processCombinedCounters(counters *interfaces.VnetInterfaceCombinedCounters)
                        counters.FirstSwIfIndex+i, counterNames[counters.VnetCounterType], counters.Data[i].Packets,
                        counterNames[counters.VnetCounterType], counters.Data[i].Bytes)
        }
-}
+}
\ No newline at end of file
index 6f0cc2e..ff45b78 100644 (file)
--- a/govpp.go
+++ b/govpp.go
@@ -25,9 +25,9 @@ var vppAdapter adapter.VppAdapter // VPP Adapter that will be used in the subseq
 // Connect connects the govpp core to VPP either using the default VPP Adapter, or using the adapter previously
 // set by SetAdapter (useful mostly just for unit/integration tests with mocked VPP adapter).
 // This call blocks until VPP is connected, or an error occurs. Only one connection attempt will be performed.
-func Connect() (*core.Connection, error) {
+func Connect(shm string) (*core.Connection, error) {
        if vppAdapter == nil {
-               vppAdapter = vppapiclient.NewVppAdapter()
+               vppAdapter = vppapiclient.NewVppAdapter(shm)
        }
        return core.Connect(vppAdapter)
 }
@@ -37,9 +37,9 @@ func Connect() (*core.Connection, error) {
 // This call does not block until connection is established, it returns immediately. The caller is
 // supposed to watch the returned ConnectionState channel for Connected/Disconnected events.
 // In case of disconnect, the library will asynchronously try to reconnect.
-func AsyncConnect() (*core.Connection, chan core.ConnectionEvent, error) {
+func AsyncConnect(shm string) (*core.Connection, chan core.ConnectionEvent, error) {
        if vppAdapter == nil {
-               vppAdapter = vppapiclient.NewVppAdapter()
+               vppAdapter = vppapiclient.NewVppAdapter(shm)
        }
        return core.AsyncConnect(vppAdapter)
 }
@@ -47,4 +47,4 @@ func AsyncConnect() (*core.Connection, chan core.ConnectionEvent, error) {
 // SetAdapter sets the adapter that will be used for connections to VPP in the subsequent `Connect` calls.
 func SetAdapter(ad adapter.VppAdapter) {
        vppAdapter = ad
-}
+}
\ No newline at end of file