Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' into update-build-scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
kshlm authored Jan 12, 2018
2 parents afcb0c5 + 9cc929f commit 8568a60
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 10 deletions.
19 changes: 14 additions & 5 deletions glusterd2/servers/sunrpc/dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import (
| count | key len | val len | key \0 | value |
------------------------------------------------------
4 4 4 <key len> <value len>
NOTE: The "key len" computed does not include the NULL character at the end.
All values are serialized to strings and "val len" takes the NULL
character into consideration.
*/

const (
Expand Down Expand Up @@ -57,7 +61,7 @@ func DictUnserialize(buf []byte) (map[string]string, error) {
reader.Read(value)

// Strings aren't NULL terminated in Go
newDict[string(key[:len(key)-1])] = string(value)
newDict[string(key[:len(key)-1])] = string(value[:len(value)-1])
}

return newDict, nil
Expand Down Expand Up @@ -97,7 +101,7 @@ func DictSerialize(dict map[string]string) ([]byte, error) {
totalBytesWritten += bytesWritten

// write value length
binary.BigEndian.PutUint32(tmpHeader, uint32(len(value)))
binary.BigEndian.PutUint32(tmpHeader, uint32(len(value)+1))
bytesWritten, err = buffer.Write(tmpHeader)
if err != nil {
return nil, err
Expand All @@ -116,13 +120,18 @@ func DictSerialize(dict map[string]string) ([]byte, error) {
}
totalBytesWritten += bytesWritten

// write value
// write value + '\0'
// Values are serialized to strings and strings in C are NULL terminated.
bytesWritten, err = buffer.Write([]byte(value))
if err != nil {
return nil, err
}
totalBytesWritten += bytesWritten

bytesWritten, err = buffer.Write([]byte("\x00"))
if err != nil {
return nil, err
}
totalBytesWritten += bytesWritten
}

if dictSerializedSize != totalBytesWritten {
Expand All @@ -142,7 +151,7 @@ func getSerializedDictLen(dict map[string]string) (int, error) {
for key, value := range dict {
// Key length and value length
totalSize += dictHeaderLen + dictHeaderLen
totalSize += (len(key) + 1) + len(value)
totalSize += (len(key) + 1) + (len(value) + 1)
}

return totalSize, nil
Expand Down
101 changes: 96 additions & 5 deletions glusterd2/servers/sunrpc/handshake_prog.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package sunrpc

import (
"context"
"errors"
"strconv"
"strings"
"syscall"

"github.com/gluster/glusterd2/glusterd2/store"
"github.com/gluster/glusterd2/glusterd2/volume"

"github.com/prashanthpai/sunrpc"
log "github.com/sirupsen/logrus"
Expand All @@ -16,7 +20,9 @@ const (
)

const (
gfHndskGetSpec = 2 // GF_HNDSK_GETSPEC
gfHndskGetSpec = 2 // GF_HNDSK_GETSPEC
gfHndskGetVolumeInfo = 6 // GF_HNDSK_GET_VOLUME_INFO

)

var volfilePrefix = "volfiles/"
Expand All @@ -31,9 +37,10 @@ func newGfHandshake() *GfHandshake {
progNum: hndskProgNum,
progVersion: hndskProgVersion,
procedures: []sunrpc.Procedure{
{
sunrpc.ProcedureID{ProgramNumber: hndskProgNum, ProgramVersion: hndskProgVersion,
ProcedureNumber: gfHndskGetSpec}, "ServerGetspec"},
{sunrpc.ProcedureID{ProgramNumber: hndskProgNum, ProgramVersion: hndskProgVersion,
ProcedureNumber: gfHndskGetSpec}, "ServerGetspec"},
{sunrpc.ProcedureID{ProgramNumber: hndskProgNum, ProgramVersion: hndskProgVersion,
ProcedureNumber: gfHndskGetVolumeInfo}, "ServerGetVolumeInfo"},
},
}
}
Expand Down Expand Up @@ -95,7 +102,8 @@ func (p *GfHandshake) ServerGetspec(args *GfGetspecReq, reply *GfGetspecRsp) err
}

if resp.Count != 1 {
log.WithField("volfile", args.Key).Error("ServerGetspec(): volfile not found in store")
err = errors.New("volfile not found in store")
log.WithField("volfile", args.Key).Error(err.Error())
goto Out
}

Expand All @@ -113,3 +121,86 @@ Out:

return nil
}

// GfGetVolumeInfoReq is a request sent by glusterfs client. It contains a dict
// which contains information about the volume information requested by the
// client.
type GfGetVolumeInfoReq struct {
Dict []byte
}

// GfGetVolumeInfoResp is response sent to glusterfs client in response to a
// GfGetVolumeInfoReq request. The dict shall contain actual information
// requested by the client.
type GfGetVolumeInfoResp struct {
OpRet int
OpErrno int
OpErrstr string
Dict []byte
}

const gfGetVolumeUUID = 1

// ServerGetVolumeInfo returns requested information about the volume to the
// client.
func (p *GfHandshake) ServerGetVolumeInfo(args *GfGetVolumeInfoReq, reply *GfGetVolumeInfoResp) error {

var (
// pre-declared variables are required for goto statements
err error
ok bool
volname string
flagsStr string
flags int
volinfo *volume.Volinfo
)
respDict := make(map[string]string)

reqDict, err := DictUnserialize(args.Dict)
if err != nil {
log.WithError(err).Error("DictUnserialize() failed")
goto Out
}

flagsStr, ok = reqDict["flags"]
if !ok {
err = errors.New("flags key not found")
goto Out
}
flags, err = strconv.Atoi(flagsStr)
if err != nil {
log.WithError(err).Error("failed to convert flags from string to int")
goto Out
}

volname, ok = reqDict["volname"]
if !ok {
log.WithError(err).WithField("volume", volname).Error("volume name not found in request dict")
reply.OpRet = -1
reply.OpErrno = int(syscall.EINVAL)
goto Out
}

if (flags & gfGetVolumeUUID) != 0 {
volinfo, err = volume.GetVolume(volname)
if err != nil {
log.WithError(err).WithField("volume", volname).Error("volume not found in store")
reply.OpErrno = int(syscall.EINVAL)
goto Out
}
respDict["volume_id"] = volinfo.ID.String()
}

reply.Dict, err = DictSerialize(respDict)
if err != nil {
log.WithError(err).Error("failed to serialize dict")
}

Out:
if err != nil {
reply.OpRet = -1
reply.OpErrstr = err.Error()
}

return nil
}

0 comments on commit 8568a60

Please sign in to comment.