From 3da2b73ec5ce77abf796ebeae6dfc149c8d3c698 Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Wed, 2 May 2018 09:47:44 +0200 Subject: [PATCH] support for shm prefixes Change-Id: I279653deb9911862d29143269aea5dffbd564478 Signed-off-by: Vladimir Lavor --- adapter/vppapiclient/vppapiclient_adapter.go | 39 +++++++++++++++++++--------- examples/cmd/perf-bench/perf-bench.go | 6 ++--- examples/cmd/simple-client/simple_client.go | 4 +-- examples/cmd/stats-client/stats_client.go | 4 +-- govpp.go | 10 +++---- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/adapter/vppapiclient/vppapiclient_adapter.go b/adapter/vppapiclient/vppapiclient_adapter.go index e9948e8..5a05a58 100644 --- a/adapter/vppapiclient/vppapiclient_adapter.go +++ b/adapter/vppapiclient/vppapiclient_adapter.go @@ -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 diff --git a/examples/cmd/perf-bench/perf-bench.go b/examples/cmd/perf-bench/perf-bench.go index ca74df6..f3ff752 100644 --- a/examples/cmd/perf-bench/perf-bench.go +++ b/examples/cmd/perf-bench/perf-bench.go @@ -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 diff --git a/examples/cmd/simple-client/simple_client.go b/examples/cmd/simple-client/simple_client.go index 8f10360..67dc14b 100644 --- a/examples/cmd/simple-client/simple_client.go +++ b/examples/cmd/simple-client/simple_client.go @@ -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 diff --git a/examples/cmd/stats-client/stats_client.go b/examples/cmd/stats-client/stats_client.go index 458da21..17c7956 100644 --- a/examples/cmd/stats-client/stats_client.go +++ b/examples/cmd/stats-client/stats_client.go @@ -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 diff --git a/govpp.go b/govpp.go index 6f0cc2e..ff45b78 100644 --- 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 -- 2.16.6