Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gnmi_dump tool for debug and unit test #60

Merged
merged 8 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ ifeq ($(CROSS_BUILD_ENVIRON),y)
$(GO) build -o ${GOBIN}/gnmi_set -mod=vendor github.com/jipanyang/gnxi/gnmi_set
$(GO) build -o ${GOBIN}/gnmi_cli -mod=vendor github.com/openconfig/gnmi/cmd/gnmi_cli
$(GO) build -o ${GOBIN}/gnoi_client -mod=vendor github.com/sonic-net/sonic-gnmi/gnoi_client
$(GO) build -o ${GOBIN}/gnmi_dump -mod=vendor github.com/sonic-net/sonic-gnmi/gnmi_dump
else
$(GO) install -mod=vendor $(BLD_FLAGS) github.com/sonic-net/sonic-gnmi/telemetry
$(GO) install -mod=vendor $(BLD_FLAGS) github.com/sonic-net/sonic-gnmi/dialout/dialout_client_cli
$(GO) install -mod=vendor github.com/jipanyang/gnxi/gnmi_get
$(GO) install -mod=vendor github.com/jipanyang/gnxi/gnmi_set
$(GO) install -mod=vendor github.com/openconfig/gnmi/cmd/gnmi_cli
$(GO) install -mod=vendor github.com/sonic-net/sonic-gnmi/gnoi_client
$(GO) install -mod=vendor github.com/sonic-net/sonic-gnmi/gnmi_dump
endif

check_gotest:
Expand Down Expand Up @@ -99,6 +101,7 @@ install:
$(INSTALL) -D $(BUILD_DIR)/gnmi_set $(DESTDIR)/usr/sbin/gnmi_set
$(INSTALL) -D $(BUILD_DIR)/gnmi_cli $(DESTDIR)/usr/sbin/gnmi_cli
$(INSTALL) -D $(BUILD_DIR)/gnoi_client $(DESTDIR)/usr/sbin/gnoi_client
$(INSTALL) -D $(BUILD_DIR)/gnmi_dump $(DESTDIR)/usr/sbin/gnmi_dump


deinstall:
Expand All @@ -107,5 +110,6 @@ deinstall:
rm $(DESTDIR)/usr/sbin/gnmi_get
rm $(DESTDIR)/usr/sbin/gnmi_set
rm $(DESTDIR)/usr/sbin/gnoi_client
rm $(DESTDIR)/usr/sbin/gnmi_dump


45 changes: 42 additions & 3 deletions common_utils/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ const requestContextKey contextkey = 0
// Request Id generator
var requestCounter uint64

type CounterType int
const (
GNMI_GET CounterType = iota
GNMI_GET_FAIL
GNMI_SET
GNMI_SET_FAIL
COUNTER_SIZE
)

func (c CounterType) String() string {
switch c {
case GNMI_GET:
return "GNMI get"
case GNMI_GET_FAIL:
return "GNMI get fail"
case GNMI_SET:
return "GNMI set"
case GNMI_SET_FAIL:
return "GNMI set fail"
default:
return ""
}
}

var globalCounters [COUNTER_SIZE]uint64


// GetContext function returns the RequestContext object for a
// gRPC request. RequestContext is maintained as a context value of
// the request. Creates a new RequestContext object is not already
Expand All @@ -55,8 +82,20 @@ func GetContext(ctx context.Context) (*RequestContext, context.Context) {

func GetUsername(ctx context.Context, username *string) {
rc, _ := GetContext(ctx)
if rc != nil {
*username = rc.Auth.User
}
if rc != nil {
*username = rc.Auth.User
}
}

func InitCounters() {
for i := 0; i < int(COUNTER_SIZE); i++ {
globalCounters[i] = 0
}
SetMemCounters(&globalCounters)
}

func IncCounter(cnt CounterType) {
atomic.AddUint64(&globalCounters[cnt], 1)
SetMemCounters(&globalCounters)
}

64 changes: 64 additions & 0 deletions common_utils/shareMem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package common_utils

import (
"fmt"
"syscall"
"unsafe"
)

// Use share memory to dump GNMI internal counters,
// GNMI server and gnmi_dump should use memKey to access the share memory,
// memSize is 1024 bytes, so we can support 128 counters
// memMode is 0x380, this value is O_RDWR|IPC_CREAT,
// O_RDWR means: Owner can write and read the file, everyone else can't.
// IPC_CREAT means: Create a shared memory segment if a shared memory identifier does not exist for memKey.
var (
memKey = 7749
memSize = 1024
memMode = 0x380
)

func SetMemCounters(counters *[int(COUNTER_SIZE)]uint64) error {
shmid, _, err := syscall.Syscall(syscall.SYS_SHMGET, uintptr(memKey), uintptr(memSize), uintptr(memMode))
if int(shmid) == -1 {
return fmt.Errorf("syscall error, err: %v\n", err)
}

shmaddr, _, err := syscall.Syscall(syscall.SYS_SHMAT, shmid, 0, 0)
if int(shmaddr) == -1 {
return fmt.Errorf("syscall error, err: %v\n", err)
}
defer syscall.Syscall(syscall.SYS_SHMDT, shmaddr, 0, 0)

const size = unsafe.Sizeof(uint64(0))
addr := uintptr(unsafe.Pointer(shmaddr))

for i := 0; i < len(counters); i++ {
*(*uint64)(unsafe.Pointer(addr)) = counters[i]
addr += size
}
return nil
}

func GetMemCounters(counters *[int(COUNTER_SIZE)]uint64) error {
shmid, _, err := syscall.Syscall(syscall.SYS_SHMGET, uintptr(memKey), uintptr(memSize), uintptr(memMode))
if int(shmid) == -1 {
return fmt.Errorf("syscall error, err: %v\n", err)
}

shmaddr, _, err := syscall.Syscall(syscall.SYS_SHMAT, shmid, 0, 0)
if int(shmaddr) == -1 {
return fmt.Errorf("syscall error, err: %v\n", err)
}
defer syscall.Syscall(syscall.SYS_SHMDT, shmaddr, 0, 0)

const size = unsafe.Sizeof(uint64(0))
addr := uintptr(unsafe.Pointer(shmaddr))

for i := 0; i < len(counters); i++ {
counters[i] = *(*uint64)(unsafe.Pointer(addr))
addr += size
}
return nil
}

30 changes: 30 additions & 0 deletions gnmi_dump/gnmi_dump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"flag"
"fmt"
"github.com/sonic-net/sonic-gnmi/common_utils"
)

const help = `
gnmi_dump is used to dump internal counters for debugging purpose,
including GNMI request counter, GNOI request counter and DBUS request counter.
`

func main() {
flag.Usage = func() {
fmt.Print(help)
}
flag.Parse()
var counters [common_utils.COUNTER_SIZE]uint64
err := common_utils.GetMemCounters(&counters)
if err != nil {
fmt.Printf("Error: Fail to read counters, %v", err)
return
}
fmt.Printf("Dump GNMI counters\n")
for i := 0; i < int(common_utils.COUNTER_SIZE); i++ {
cnt := common_utils.CounterType(i)
fmt.Printf("%v---%v\n", cnt.String(), counters[i])
}
}
24 changes: 19 additions & 5 deletions gnmi_server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ func NewServer(config *Config, opts []grpc.ServerOption) (*Server, error) {
return nil, errors.New("config not provided")
}

common_utils.InitCounters()

s := grpc.NewServer(opts...)
reflection.Register(s)

Expand Down Expand Up @@ -274,26 +276,32 @@ func (s *Server) checkEncodingAndModel(encoding gnmipb.Encoding, models []*gnmip

// Get implements the Get RPC in gNMI spec.
func (s *Server) Get(ctx context.Context, req *gnmipb.GetRequest) (*gnmipb.GetResponse, error) {
common_utils.IncCounter(common_utils.GNMI_GET)
ctx, err := authenticate(s.config.UserAuth, ctx)
if err != nil {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, err
}

if req.GetType() != gnmipb.GetRequest_ALL {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Errorf(codes.Unimplemented, "unsupported request type: %s", gnmipb.GetRequest_DataType_name[int32(req.GetType())])
}

if err = s.checkEncodingAndModel(req.GetEncoding(), req.GetUseModels()); err != nil {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Error(codes.Unimplemented, err.Error())
}

var target string
prefix := req.GetPrefix()
if prefix == nil {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Error(codes.Unimplemented, "No target specified in prefix")
} else {
target = prefix.GetTarget()
if target == "" {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Error(codes.Unimplemented, "Empty target data not supported yet")
}
}
Expand All @@ -315,11 +323,13 @@ func (s *Server) Get(ctx context.Context, req *gnmipb.GetRequest) (*gnmipb.GetRe
}

if err != nil {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Error(codes.NotFound, err.Error())
}
notifications := make([]*gnmipb.Notification, len(paths))
spbValues, err := dc.Get(nil)
if err != nil {
common_utils.IncCounter(common_utils.GNMI_GET_FAIL)
return nil, status.Error(codes.NotFound, err.Error())
}

Expand All @@ -339,8 +349,14 @@ func (s *Server) Get(ctx context.Context, req *gnmipb.GetRequest) (*gnmipb.GetRe
}

func (s *Server) Set(ctx context.Context, req *gnmipb.SetRequest) (*gnmipb.SetResponse, error) {
common_utils.IncCounter(common_utils.GNMI_SET)
if s.config.EnableTranslibWrite == false {
common_utils.IncCounter(common_utils.GNMI_SET_FAIL)
return nil, grpc.Errorf(codes.Unimplemented, "GNMI is in read-only mode")
}
ctx, err := authenticate(s.config.UserAuth, ctx)
if err != nil {
common_utils.IncCounter(common_utils.GNMI_SET_FAIL)
return nil, err
}
var results []*gnmipb.UpdateResult
Expand Down Expand Up @@ -388,13 +404,11 @@ func (s *Server) Set(ctx context.Context, req *gnmipb.SetRequest) (*gnmipb.SetRe
/* Add to Set response results. */
results = append(results, &res)
}
if s.config.EnableTranslibWrite {
Copy link
Collaborator

@qiluo-msft qiluo-msft Nov 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnableTranslibWrite

Why removing this check? If this is significant change, add some PR description, even add it into PR title. #Closed

Copy link
Contributor Author

@ganglyu ganglyu Nov 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I move the check to line 353 to simplify logic for set fail, when EnableTranslibWrite is false, no need to authenticate and no need to update result.

err = dc.Set(req.GetDelete(), req.GetReplace(), req.GetUpdate())
} else {
return nil, grpc.Errorf(codes.Unimplemented, "Telemetry is in read-only mode")
err = dc.Set(req.GetDelete(), req.GetReplace(), req.GetUpdate())
if err != nil {
common_utils.IncCounter(common_utils.GNMI_SET_FAIL)
}


return &gnmipb.SetResponse{
Prefix: req.GetPrefix(),
Response: results,
Expand Down
Loading