mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
master:
1.add ump warn packet 2.partition has recover,but the status don't change 3.remove redundancy calling loadMetaData method 4.reload meta data when change leader metanode: 1. add totalMem in configFile 2.change not raft leader to tryOtherAddr error datanode: 1.when datapartition not exsit,tell client with proto.OptryAgain resultcode 2.change disk retrain default space to 20gb 3.heartbeat report add volname raft: 1.use raft.ErrNotLeader replace ErrNotLeader 2.raft became leader must apply from oldapplyid to commitid client: 1. create a dummy node instance if inode does not exist 2. add ump alarm for read/write/fsync errors log: 1. auto create subdir to logdir error: 1.delete juju error packet
This commit is contained in:
parent
88d2a1c87b
commit
36d97f1034
@ -179,7 +179,9 @@ func (d *Dir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.Lo
|
||||
inode, err := d.super.InodeGet(ino)
|
||||
if err != nil {
|
||||
log.LogErrorf("Lookup: parent(%v) name(%v) ino(%v) err(%v)", d.inode.ino, req.Name, ino, err)
|
||||
return nil, ParseError(err)
|
||||
dummyInode := &Inode{ino: ino}
|
||||
dummyChild := NewFile(d.super, dummyInode)
|
||||
return dummyChild, nil
|
||||
}
|
||||
mode := inode.mode
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"syscall"
|
||||
"time"
|
||||
@ -65,6 +66,10 @@ func (f *File) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||
inode, err := f.super.InodeGet(ino)
|
||||
if err != nil {
|
||||
log.LogErrorf("Attr: ino(%v) err(%v)", ino, err)
|
||||
if err == fuse.ENOENT {
|
||||
a.Inode = ino
|
||||
return nil
|
||||
}
|
||||
return ParseError(err)
|
||||
}
|
||||
|
||||
@ -140,16 +145,22 @@ func (f *File) Release(ctx context.Context, req *fuse.ReleaseRequest) (err error
|
||||
// Read handles the read request.
|
||||
func (f *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) (err error) {
|
||||
log.LogDebugf("TRACE Read enter: ino(%v) offset(%v) reqsize(%v) req(%v)", f.inode.ino, req.Offset, req.Size, req)
|
||||
|
||||
start := time.Now()
|
||||
|
||||
size, err := f.super.ec.Read(f.inode.ino, resp.Data[fuse.OutHeaderSize:], int(req.Offset), req.Size)
|
||||
if err != nil && err != io.EOF {
|
||||
log.LogErrorf("Read: ino(%v) req(%v) err(%v) size(%v)", f.inode.ino, req, err, size)
|
||||
msg := fmt.Sprintf("Read: ino(%v) req(%v) err(%v) size(%v)", f.inode.ino, req, err, size)
|
||||
f.super.handleError("Read", msg)
|
||||
return fuse.EIO
|
||||
}
|
||||
|
||||
if size > req.Size {
|
||||
log.LogErrorf("Read: ino(%v) req(%v) size(%v)", f.inode.ino, req, size)
|
||||
msg := fmt.Sprintf("Read: read size larger than request size, ino(%v) req(%v) size(%v)", f.inode.ino, req, size)
|
||||
f.super.handleError("Read", msg)
|
||||
return fuse.ERANGE
|
||||
}
|
||||
|
||||
if size > 0 {
|
||||
resp.Data = resp.Data[:size+fuse.OutHeaderSize]
|
||||
} else if size <= 0 {
|
||||
@ -192,11 +203,14 @@ func (f *File) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.Wri
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
size, err := f.super.ec.Write(ino, int(req.Offset), req.Data, enSyncWrite)
|
||||
if err != nil {
|
||||
log.LogErrorf("Write: ino(%v) offset(%v) len(%v) err(%v)", ino, req.Offset, reqlen, err)
|
||||
msg := fmt.Sprintf("Write: ino(%v) offset(%v) len(%v) err(%v)", ino, req.Offset, reqlen, err)
|
||||
f.super.handleError("Write", msg)
|
||||
return fuse.EIO
|
||||
}
|
||||
|
||||
resp.Size = size
|
||||
if size != reqlen {
|
||||
log.LogErrorf("Write: ino(%v) offset(%v) len(%v) size(%v)", ino, req.Offset, reqlen, size)
|
||||
@ -204,7 +218,8 @@ func (f *File) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.Wri
|
||||
|
||||
if waitForFlush {
|
||||
if err = f.super.ec.Flush(ino); err != nil {
|
||||
log.LogErrorf("Write: failed to wait for flush, ino(%v) offset(%v) len(%v) err(%v) req(%v)", ino, req.Offset, reqlen, err, req)
|
||||
msg := fmt.Sprintf("Write: failed to wait for flush, ino(%v) offset(%v) len(%v) err(%v) req(%v)", ino, req.Offset, reqlen, err, req)
|
||||
f.super.handleError("Wrtie", msg)
|
||||
return fuse.EIO
|
||||
}
|
||||
}
|
||||
@ -226,7 +241,8 @@ func (f *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) (err error) {
|
||||
start := time.Now()
|
||||
err = f.super.ec.Flush(f.inode.ino)
|
||||
if err != nil {
|
||||
log.LogErrorf("Fsync: ino(%v) err(%v)", f.inode.ino, err)
|
||||
msg := fmt.Sprintf("Fsync: ino(%v) err(%v)", f.inode.ino, err)
|
||||
f.super.handleError("Fsync", msg)
|
||||
return fuse.EIO
|
||||
}
|
||||
f.super.ic.Delete(f.inode.ino)
|
||||
|
||||
@ -16,7 +16,7 @@ package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"golang.org/x/net/context"
|
||||
"sync"
|
||||
"time"
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"github.com/chubaofs/chubaofs/sdk/data/stream"
|
||||
"github.com/chubaofs/chubaofs/sdk/meta"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/chubaofs/chubaofs/util/ump"
|
||||
)
|
||||
|
||||
// Super defines the struct of a super block.
|
||||
@ -54,12 +55,12 @@ func NewSuper(volname, owner, master string, icacheTimeout, lookupValid, attrVal
|
||||
s = new(Super)
|
||||
s.mw, err = meta.NewMetaWrapper(volname, owner, master)
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "NewMetaWrapper failed!")
|
||||
return nil, errors.Trace(err, "NewMetaWrapper failed!")
|
||||
}
|
||||
|
||||
s.ec, err = stream.NewExtentClient(volname, master, s.mw.AppendExtentKey, s.mw.GetExtents, s.mw.Truncate)
|
||||
if err != nil {
|
||||
return nil, errors.Annotate(err, "NewExtentClient failed!")
|
||||
return nil, errors.Trace(err, "NewExtentClient failed!")
|
||||
}
|
||||
|
||||
s.volname = volname
|
||||
@ -107,11 +108,20 @@ func (s *Super) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Super) exporterKey(act string) string {
|
||||
return fmt.Sprintf("%s_fuseclient_%s", s.cluster, act)
|
||||
}
|
||||
|
||||
// ClusterName returns the cluster name.
|
||||
func (s *Super) ClusterName() string {
|
||||
return s.cluster
|
||||
}
|
||||
|
||||
func (s *Super) exporterKey(act string) string {
|
||||
return fmt.Sprintf("%v_fuseclient_%v", s.cluster, act)
|
||||
}
|
||||
|
||||
func (s *Super) umpKey(act string) string {
|
||||
return fmt.Sprintf("%v_fuseclient_%v", s.cluster, act)
|
||||
}
|
||||
|
||||
func (s *Super) handleError(op, msg string) {
|
||||
log.LogError(msg)
|
||||
ump.Alarm(s.umpKey(op), msg)
|
||||
}
|
||||
|
||||
@ -23,11 +23,10 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -38,6 +37,7 @@ import (
|
||||
"github.com/chubaofs/chubaofs/util/config"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/chubaofs/chubaofs/util/ump"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -94,13 +94,14 @@ func Mount(cfg *config.Config) (err error) {
|
||||
attrValid := ParseConfigString(cfg, "attrValid")
|
||||
enSyncWrite := ParseConfigString(cfg, "enSyncWrite")
|
||||
autoInvalData := ParseConfigString(cfg, "autoInvalData")
|
||||
umpDatadir := cfg.GetString("warnLogDir")
|
||||
|
||||
if mnt == "" || volname == "" || owner == "" || master == "" {
|
||||
return errors.New(fmt.Sprintf("invalid config file: lack of mandatory fields, mountPoint(%v), volName(%v), owner(%v), masterAddr(%v)", mnt, volname, owner, master))
|
||||
}
|
||||
|
||||
level := ParseLogLevel(loglvl)
|
||||
_, err = log.InitLog(path.Join(logpath, LoggerDir), LoggerPrefix, level, nil)
|
||||
_, err = log.InitLog(logpath, LoggerPrefix, level, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -108,7 +109,7 @@ func Mount(cfg *config.Config) (err error) {
|
||||
|
||||
super, err := cfs.NewSuper(volname, owner, master, icacheTimeout, lookupValid, attrValid, enSyncWrite)
|
||||
if err != nil {
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -132,6 +133,7 @@ func Mount(cfg *config.Config) (err error) {
|
||||
fmt.Println(http.ListenAndServe(":"+profport, nil))
|
||||
}()
|
||||
|
||||
ump.InitUmp(fmt.Sprintf("%v_%v", super.ClusterName(), ModuleName), umpDatadir)
|
||||
exporter.Init(super.ClusterName(), ModuleName, cfg)
|
||||
|
||||
if err = fs.Serve(c, super); err != nil {
|
||||
|
||||
17
cmd/cmd.go
17
cmd/cmd.go
@ -25,6 +25,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/util/config"
|
||||
"github.com/chubaofs/chubaofs/util/ump"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
@ -38,11 +39,11 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
ConfigKeyRole = "role"
|
||||
ConfigKeyLogDir = "logDir"
|
||||
ConfigKeyLogLevel = "logLevel"
|
||||
ConfigKeyProfPort = "prof"
|
||||
ConfigKeyExporterPort = "exporterPort"
|
||||
ConfigKeyRole = "role"
|
||||
ConfigKeyLogDir = "logDir"
|
||||
ConfigKeyLogLevel = "logLevel"
|
||||
ConfigKeyProfPort = "prof"
|
||||
ConfigKeyWarnLogDir = "warnLogDir"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -118,7 +119,8 @@ func main() {
|
||||
|
||||
err := modifyOpenFiles()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
fmt.Println(fmt.Sprintf(err.Error()))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.LogInfof("Hello, ChubaoFS Storage, Current Version: %s", Version)
|
||||
@ -127,10 +129,11 @@ func main() {
|
||||
logDir := cfg.GetString(ConfigKeyLogDir)
|
||||
logLevel := cfg.GetString(ConfigKeyLogLevel)
|
||||
profPort := cfg.GetString(ConfigKeyProfPort)
|
||||
umpDatadir := cfg.GetString(ConfigKeyWarnLogDir)
|
||||
|
||||
//for multi-cpu scheduling
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
ump.InitUmp(role, umpDatadir)
|
||||
// Init server instance with specified role configuration.
|
||||
var (
|
||||
server Server
|
||||
|
||||
@ -24,8 +24,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
@ -89,7 +89,7 @@ func (dp *DataPartition) repair(extentType uint8) {
|
||||
err := dp.buildDataPartitionRepairTask(repairTasks, extentType, tinyExtents)
|
||||
|
||||
if err != nil {
|
||||
log.LogErrorf(errors.ErrorStack(err))
|
||||
log.LogErrorf(errors.Stack(err))
|
||||
log.LogErrorf("action[repair] partition(%v) err(%v).",
|
||||
dp.partitionID, err)
|
||||
dp.moveToBrokenTinyExtentC(extentType, tinyExtents)
|
||||
@ -105,7 +105,7 @@ func (dp *DataPartition) repair(extentType uint8) {
|
||||
dp.sendAllTinyExtentsToC(extentType, availableTinyExtents, brokenTinyExtents)
|
||||
log.LogErrorf("action[repair] partition(%v) err(%v).",
|
||||
dp.partitionID, err)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
return
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ func (dp *DataPartition) repair(extentType uint8) {
|
||||
dp.DoRepair(repairTasks)
|
||||
end := time.Now().UnixNano()
|
||||
|
||||
// every time we need to figure out which extents need to be repaired and which ones do not.
|
||||
// every time we need to figureAnnotatef out which extents need to be repaired and which ones do not.
|
||||
dp.sendAllTinyExtentsToC(extentType, availableTinyExtents, brokenTinyExtents)
|
||||
|
||||
// error check
|
||||
@ -162,17 +162,17 @@ func (dp *DataPartition) getLocalExtentInfo(extentType uint8, tinyExtents []uint
|
||||
localExtents, tinyDeleteRecordSize, err = dp.extentStore.GetAllWatermarks(storage.TinyExtentFilter(tinyExtents))
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
err = errors.Trace(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
return
|
||||
}
|
||||
data, err := json.Marshal(localExtents)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
err = errors.Trace(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(data, &extents); err != nil {
|
||||
err = errors.Annotatef(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
err = errors.Trace(err, "getLocalExtentInfo extent DataPartition(%v) GetAllWaterMark", dp.partitionID)
|
||||
}
|
||||
|
||||
return
|
||||
@ -185,7 +185,7 @@ func (dp *DataPartition) getRemoteExtentInfo(extentType uint8, tinyExtents []uin
|
||||
if extentType == proto.TinyExtentType {
|
||||
p.Data, err = json.Marshal(tinyExtents)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getRemoteExtentInfo DataPartition(%v) GetAllWatermarks", dp.partitionID)
|
||||
err = errors.Trace(err, "getRemoteExtentInfo DataPartition(%v) GetAllWatermarks", dp.partitionID)
|
||||
return
|
||||
}
|
||||
p.Size = uint32(len(p.Data))
|
||||
@ -193,24 +193,24 @@ func (dp *DataPartition) getRemoteExtentInfo(extentType uint8, tinyExtents []uin
|
||||
var conn *net.TCPConn
|
||||
conn, err = gConnPool.GetConnect(target) // get remote connection
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getRemoteExtentInfo DataPartition(%v) get host(%v) connect", dp.partitionID, target)
|
||||
err = errors.Trace(err, "getRemoteExtentInfo DataPartition(%v) get host(%v) connect", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
defer gConnPool.PutConnect(conn, true)
|
||||
err = p.WriteToConn(conn) // write command to the remote host
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getRemoteExtentInfo DataPartition(%v) write to host(%v)", dp.partitionID, target)
|
||||
err = errors.Trace(err, "getRemoteExtentInfo DataPartition(%v) write to host(%v)", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
reply := new(repl.Packet)
|
||||
err = reply.ReadFromConn(conn, proto.GetAllWatermarksDeadLineTime) // read the response
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getRemoteExtentInfo DataPartition(%v) read from host(%v)", dp.partitionID, target)
|
||||
err = errors.Trace(err, "getRemoteExtentInfo DataPartition(%v) read from host(%v)", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(reply.Data[:reply.Size], &extentFiles)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "getRemoteExtentInfo DataPartition(%v) unmarshal json(%v) from host(%v)",
|
||||
err = errors.Trace(err, "getRemoteExtentInfo DataPartition(%v) unmarshal json(%v) from host(%v)",
|
||||
dp.partitionID, string(reply.Data[:reply.Size]), target)
|
||||
return
|
||||
}
|
||||
@ -227,12 +227,12 @@ func (dp *DataPartition) DoRepair(repairTasks []*DataPartitionRepairTask) {
|
||||
for _, extentInfo := range repairTasks[0].ExtentsToBeRepaired {
|
||||
err := dp.streamRepairExtent(extentInfo)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "doStreamExtentFixRepair %v", dp.applyRepairKey(int(extentInfo.FileID)))
|
||||
err = errors.Trace(err, "doStreamExtentFixRepair %v", dp.applyRepairKey(int(extentInfo.FileID)))
|
||||
localExtentInfo, opErr := dp.ExtentStore().Watermark(uint64(extentInfo.FileID))
|
||||
if opErr != nil {
|
||||
err = errors.Annotatef(err, opErr.Error())
|
||||
err = errors.Trace(err, opErr.Error())
|
||||
}
|
||||
err = errors.Annotatef(err, "partition(%v) remote(%v) local(%v)",
|
||||
err = errors.Trace(err, "partition(%v) remote(%v) local(%v)",
|
||||
dp.partitionID, extentInfo, localExtentInfo)
|
||||
log.LogWarnf("action[doStreamExtentFixRepair] err(%v).", err)
|
||||
}
|
||||
@ -404,12 +404,12 @@ func (dp *DataPartition) doStreamExtentFixRepair(wg *sync.WaitGroup, remoteExten
|
||||
err := dp.streamRepairExtent(remoteExtentInfo)
|
||||
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "doStreamExtentFixRepair %v", dp.applyRepairKey(int(remoteExtentInfo.FileID)))
|
||||
err = errors.Trace(err, "doStreamExtentFixRepair %v", dp.applyRepairKey(int(remoteExtentInfo.FileID)))
|
||||
localExtentInfo, opErr := dp.ExtentStore().Watermark(uint64(remoteExtentInfo.FileID))
|
||||
if opErr != nil {
|
||||
err = errors.Annotatef(err, opErr.Error())
|
||||
err = errors.Trace(err, opErr.Error())
|
||||
}
|
||||
err = errors.Annotatef(err, "partition(%v) remote(%v) local(%v)",
|
||||
err = errors.Trace(err, "partition(%v) remote(%v) local(%v)",
|
||||
dp.partitionID, remoteExtentInfo, localExtentInfo)
|
||||
log.LogWarnf("action[doStreamExtentFixRepair] err(%v).", err)
|
||||
}
|
||||
@ -427,7 +427,7 @@ func (dp *DataPartition) streamRepairExtent(remoteExtentInfo *storage.ExtentInfo
|
||||
}
|
||||
localExtentInfo, err := store.Watermark(remoteExtentInfo.FileID)
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "streamRepairExtent Watermark error")
|
||||
return errors.Trace(err, "streamRepairExtent Watermark error")
|
||||
}
|
||||
|
||||
if localExtentInfo.Size >= remoteExtentInfo.Size {
|
||||
@ -439,12 +439,12 @@ func (dp *DataPartition) streamRepairExtent(remoteExtentInfo *storage.ExtentInfo
|
||||
var conn *net.TCPConn
|
||||
conn, err = gConnPool.GetConnect(remoteExtentInfo.Source)
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "streamRepairExtent get conn from host[%v] error", remoteExtentInfo.Source)
|
||||
return errors.Trace(err, "streamRepairExtent get conn from host[%v] error", remoteExtentInfo.Source)
|
||||
}
|
||||
defer gConnPool.PutConnect(conn, true)
|
||||
|
||||
if err = request.WriteToConn(conn); err != nil {
|
||||
err = errors.Annotatef(err, "streamRepairExtent send streamRead to host[%v] error", remoteExtentInfo.Source)
|
||||
err = errors.Trace(err, "streamRepairExtent send streamRead to host[%v] error", remoteExtentInfo.Source)
|
||||
log.LogWarnf("action[streamRepairExtent] err[%v].", err)
|
||||
return
|
||||
}
|
||||
@ -457,20 +457,20 @@ func (dp *DataPartition) streamRepairExtent(remoteExtentInfo *storage.ExtentInfo
|
||||
|
||||
// read 64k streaming repair packet
|
||||
if err = reply.ReadFromConn(conn, proto.ReadDeadlineTime); err != nil {
|
||||
err = errors.Annotatef(err, "streamRepairExtent receive data error")
|
||||
err = errors.Trace(err, "streamRepairExtent receive data error")
|
||||
log.LogErrorf("action[streamRepairExtent] err(%v).", err)
|
||||
return
|
||||
}
|
||||
|
||||
if reply.ResultCode != proto.OpOk {
|
||||
err = errors.Annotatef(fmt.Errorf("unknow result code"),
|
||||
err = errors.Trace(fmt.Errorf("unknow result code"),
|
||||
"streamRepairExtent receive opcode error(%v) ", string(reply.Data[:reply.Size]))
|
||||
return
|
||||
}
|
||||
|
||||
if reply.ReqID != request.ReqID || reply.PartitionID != request.PartitionID ||
|
||||
reply.ExtentID != request.ExtentID || reply.Size == 0 || reply.ExtentOffset != int64(currFixOffset) {
|
||||
err = errors.Annotatef(fmt.Errorf("unavali reply"), "streamRepairExtent receive unavalid "+
|
||||
err = errors.Trace(fmt.Errorf("unavali reply"), "streamRepairExtent receive unavalid "+
|
||||
"request(%v) reply(%v)", request.GetUniqueLogId(), reply.GetUniqueLogId())
|
||||
return
|
||||
}
|
||||
@ -483,13 +483,13 @@ func (dp *DataPartition) streamRepairExtent(remoteExtentInfo *storage.ExtentInfo
|
||||
err = fmt.Errorf("streamRepairExtent crc mismatch expectCrc(%v) actualCrc(%v) extent(%v_%v) start fix from (%v)"+
|
||||
" remoteSize(%v) localSize(%v) request(%v) reply(%v) ", reply.CRC, actualCrc, dp.partitionID, remoteExtentInfo.String(),
|
||||
remoteExtentInfo.Source, remoteExtentInfo.Size, currFixOffset, request.GetUniqueLogId(), reply.GetUniqueLogId())
|
||||
return errors.Annotatef(err, "streamRepairExtent receive data error")
|
||||
return errors.Trace(err, "streamRepairExtent receive data error")
|
||||
}
|
||||
|
||||
// write to the local extent file
|
||||
err = store.Write(uint64(localExtentInfo.FileID), int64(currFixOffset), int64(reply.Size), reply.Data, reply.CRC, UpdateSize, BufferWrite)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "streamRepairExtent repair data error")
|
||||
err = errors.Trace(err, "streamRepairExtent repair data error")
|
||||
return
|
||||
}
|
||||
currFixOffset += uint64(reply.Size)
|
||||
|
||||
@ -89,7 +89,6 @@ func (d *Disk) computeUsage() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO how about:
|
||||
// total := math.Max(0, int64(fs.Blocks*uint64(fs.Bsize) - d.ReservedSpace))
|
||||
total := int64(fs.Blocks*uint64(fs.Bsize) - d.ReservedSpace)
|
||||
if total < 0 {
|
||||
@ -97,7 +96,6 @@ func (d *Disk) computeUsage() (err error) {
|
||||
}
|
||||
d.Total = uint64(total)
|
||||
|
||||
// TODO how about:
|
||||
// available := math.Max(0, int64(fs.Bavail*uint64(fs.Bsize) - d.ReservedSpace))
|
||||
available := int64(fs.Bavail*uint64(fs.Bsize) - d.ReservedSpace)
|
||||
if available < 0 {
|
||||
@ -105,7 +103,6 @@ func (d *Disk) computeUsage() (err error) {
|
||||
}
|
||||
d.Available = uint64(available)
|
||||
|
||||
// TODO how about:
|
||||
// used := math.Max(0, int64(total - available))
|
||||
used := int64(total - available)
|
||||
if used < 0 {
|
||||
|
||||
@ -31,8 +31,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
raftProto "github.com/tiglabs/raft/proto"
|
||||
"hash/crc32"
|
||||
"net"
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/tiglabs/raft"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
)
|
||||
@ -159,9 +160,9 @@ func (dp *DataPartition) CheckLeader(request *repl.Packet, connect net.Conn) (er
|
||||
// and use another getRaftLeaderAddr() to return the actual address
|
||||
_, ok := dp.IsRaftLeader()
|
||||
if !ok {
|
||||
err = storage.NotALeaderError
|
||||
err = raft.ErrNotLeader
|
||||
logContent := fmt.Sprintf("action[ReadCheck] %v.", request.LogMessage(request.GetOpMsg(), connect.RemoteAddr().String(), request.StartT, err))
|
||||
log.LogInfof(logContent)
|
||||
log.LogWarnf(logContent)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -29,8 +29,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/util/config"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
raftproto "github.com/tiglabs/raft/proto"
|
||||
)
|
||||
|
||||
@ -158,7 +158,7 @@ func (dp *DataPartition) StartRaftLoggingSchedule() {
|
||||
|
||||
case <-storeAppliedIDTimer.C:
|
||||
if err := dp.storeAppliedID(dp.appliedID); err != nil {
|
||||
err = errors.Errorf("[startSchedule]: dump partition=%d: %v", dp.config.PartitionID, err.Error())
|
||||
err = errors.NewErrorf("[startSchedule]: dump partition=%d: %v", dp.config.PartitionID, err.Error())
|
||||
log.LogErrorf(err.Error())
|
||||
}
|
||||
storeAppliedIDTimer.Reset(time.Second * 10)
|
||||
@ -333,15 +333,15 @@ func (dp *DataPartition) LoadAppliedID() (err error) {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Errorf("[loadApplyIndex] OpenFile: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadApplyIndex] OpenFile: %s", err.Error())
|
||||
return
|
||||
}
|
||||
if len(data) == 0 {
|
||||
err = errors.Errorf("[loadApplyIndex]: ApplyIndex is empty")
|
||||
err = errors.NewErrorf("[loadApplyIndex]: ApplyIndex is empty")
|
||||
return
|
||||
}
|
||||
if _, err = fmt.Sscanf(string(data), "%d", &dp.appliedID); err != nil {
|
||||
err = errors.Errorf("[loadApplyID] ReadApplyID: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadApplyID] ReadApplyID: %s", err.Error())
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -375,7 +375,7 @@ func (s *DataNode) startRaftServer(cfg *config.Config) (err error) {
|
||||
|
||||
if _, err = os.Stat(s.raftDir); err != nil {
|
||||
if err = os.MkdirAll(s.raftDir, 0755); err != nil {
|
||||
err = errors.Errorf("create raft server dir: %s", err.Error())
|
||||
err = errors.NewErrorf("create raft server dir: %s", err.Error())
|
||||
log.LogErrorf("action[startRaftServer] cannot start raft server err[%v]", err)
|
||||
return
|
||||
}
|
||||
@ -402,7 +402,7 @@ func (s *DataNode) startRaftServer(cfg *config.Config) (err error) {
|
||||
}
|
||||
s.raftStore, err = raftstore.NewRaftStore(raftConf)
|
||||
if err != nil {
|
||||
err = errors.Errorf("new raftStore: %s", err.Error())
|
||||
err = errors.NewErrorf("new raftStore: %s", err.Error())
|
||||
log.LogErrorf("action[startRaftServer] cannot start raft server err[%v]", err)
|
||||
}
|
||||
|
||||
@ -481,18 +481,18 @@ func (dp *DataPartition) getPartitionSize() (size uint64, err error) {
|
||||
target := dp.replicas[0]
|
||||
conn, err = gConnPool.GetConnect(target) //get remote connect
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, " partition=%v get host[%v] connect", dp.partitionID, target)
|
||||
err = errors.Trace(err, " partition=%v get host[%v] connect", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
defer gConnPool.PutConnect(conn, true)
|
||||
err = p.WriteToConn(conn) // write command to the remote host
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "partition=%v write to host[%v]", dp.partitionID, target)
|
||||
err = errors.Trace(err, "partition=%v write to host[%v]", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
err = p.ReadFromConn(conn, 60)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "partition=%v read from host[%v]", dp.partitionID, target)
|
||||
err = errors.Trace(err, "partition=%v read from host[%v]", dp.partitionID, target)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -20,9 +20,9 @@ import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft"
|
||||
raftproto "github.com/tiglabs/raft/proto"
|
||||
)
|
||||
@ -37,7 +37,7 @@ func (dp *DataPartition) Apply(command []byte, index uint64) (resp interface{},
|
||||
if err != nil {
|
||||
key := fmt.Sprintf("%s_datapartition_apply_err", dp.clusterID)
|
||||
prefix := fmt.Sprintf("Datapartition(%v)_Extent(%v)", dp.partitionID, extentID)
|
||||
err = errors.Annotatef(err, prefix)
|
||||
err = errors.Trace(err, prefix)
|
||||
exporter.NewAlarm(key)
|
||||
resp = proto.OpExistErr
|
||||
dp.stopRaftC <- extentID
|
||||
|
||||
@ -50,11 +50,11 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultRackName = "chubaofs_rack1"
|
||||
DefaultRackName = "cfs_rack1"
|
||||
DefaultRaftDir = "raft"
|
||||
DefaultRaftLogsToRetain = 20000 // Count of raft logs per data partition
|
||||
DefaultRaftLogsToRetain = 2000 // Count of raft logs per data partition
|
||||
DefaultDiskMaxErr = 20
|
||||
DefaultDiskRetain = 30 * util.GB // GB
|
||||
DefaultDiskRetain = 20 * util.GB // GB
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -148,6 +148,7 @@ func (s *DataNode) getPartitionAPI(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
result := &struct {
|
||||
VolName string `json:volName`
|
||||
ID uint64 `json:"id"`
|
||||
Size int `json:"size"`
|
||||
Used int `json:"used"`
|
||||
@ -158,6 +159,7 @@ func (s *DataNode) getPartitionAPI(w http.ResponseWriter, r *http.Request) {
|
||||
Replicas []string `json:"replicas"`
|
||||
TinyDeleteRecordSize int64 `json:"tinyDeleteRecordSize"`
|
||||
}{
|
||||
VolName: partition.volumeID,
|
||||
ID: partition.partitionID,
|
||||
Size: partition.Size(),
|
||||
Used: partition.Used(),
|
||||
|
||||
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
)
|
||||
|
||||
@ -254,7 +255,7 @@ func (manager *SpaceManager) CreatePartition(request *proto.CreateDataPartitionR
|
||||
)
|
||||
for i := 0; i < len(manager.disks); i++ {
|
||||
disk = manager.minPartitionCnt()
|
||||
if disk.Available < uint64(dpCfg.PartitionSize) || disk.Status != proto.ReadWrite {
|
||||
if disk.Available < 5*util.GB || disk.Status != proto.ReadWrite {
|
||||
disk = nil
|
||||
continue
|
||||
}
|
||||
@ -305,6 +306,7 @@ func (s *DataNode) buildHeartBeatResponse(response *proto.DataNodeHeartbeatRespo
|
||||
space.RangePartitions(func(partition *DataPartition) bool {
|
||||
leaderAddr, isLeader := partition.IsRaftLeader()
|
||||
vr := &proto.PartitionReport{
|
||||
VolName: partition.volumeID,
|
||||
PartitionID: uint64(partition.partitionID),
|
||||
PartitionStatus: partition.Status(),
|
||||
Total: uint64(partition.Size()),
|
||||
|
||||
@ -23,18 +23,17 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft"
|
||||
raftProto "github.com/tiglabs/raft/proto"
|
||||
"hash/crc32"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (s *DataNode) OperatePacket(p *repl.Packet, c *net.TCPConn) (err error) {
|
||||
@ -56,7 +55,7 @@ func (s *DataNode) OperatePacket(p *repl.Packet, c *net.TCPConn) (err error) {
|
||||
case proto.OpStreamRead, proto.OpRead, proto.OpExtentRepairRead:
|
||||
case proto.OpReadTinyDelete:
|
||||
log.LogRead(logContent)
|
||||
case proto.OpWrite, proto.OpRandomWrite, proto.OpSyncRandomWrite, proto.OpSyncWrite:
|
||||
case proto.OpWrite, proto.OpRandomWrite, proto.OpSyncRandomWrite, proto.OpSyncWrite, proto.OpMarkDelete:
|
||||
log.LogWrite(logContent)
|
||||
default:
|
||||
log.LogInfo(logContent)
|
||||
@ -73,9 +72,9 @@ func (s *DataNode) OperatePacket(p *repl.Packet, c *net.TCPConn) (err error) {
|
||||
case proto.OpStreamRead:
|
||||
s.handleStreamReadPacket(p, c, StreamRead)
|
||||
case proto.OpExtentRepairRead:
|
||||
s.handleStreamReadPacket(p, c, RepairRead)
|
||||
s.handleExtentRepaiReadPacket(p, c, RepairRead)
|
||||
case proto.OpMarkDelete:
|
||||
s.handleMarkDeletePacket(p)
|
||||
s.handleMarkDeletePacket(p, c)
|
||||
case proto.OpRandomWrite, proto.OpSyncRandomWrite:
|
||||
s.handleRandomWritePacket(p)
|
||||
case proto.OpNotifyReplicasToRepair:
|
||||
@ -209,7 +208,7 @@ func (s *DataNode) handleHeartbeatPacket(p *repl.Packet) {
|
||||
}
|
||||
_, err = MasterHelper.Request("POST", proto.GetDataNodeTaskResponse, nil, data)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "heartbeat to master(%v) failed.", request.MasterAddr)
|
||||
err = errors.Trace(err, "heartbeat to master(%v) failed.", request.MasterAddr)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -252,7 +251,7 @@ func (s *DataNode) handlePacketToDeleteDataPartition(p *repl.Packet) {
|
||||
data, _ := json.Marshal(task)
|
||||
_, err = MasterHelper.Request("POST", proto.GetDataNodeTaskResponse, nil, data)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "delete DataPartition failed,partitionID(%v)", request.PartitionId)
|
||||
err = errors.Trace(err, "delete DataPartition failed,partitionID(%v)", request.PartitionId)
|
||||
log.LogErrorf("action[handlePacketToDeleteDataPartition] err(%v).", err)
|
||||
}
|
||||
log.LogInfof(fmt.Sprintf("action[handlePacketToDeleteDataPartition] %v error(%v)", request.PartitionId, string(data)))
|
||||
@ -262,7 +261,9 @@ func (s *DataNode) handlePacketToDeleteDataPartition(p *repl.Packet) {
|
||||
// Handle OpLoadDataPartition packet.
|
||||
func (s *DataNode) handlePacketToLoadDataPartition(p *repl.Packet) {
|
||||
task := &proto.AdminTask{}
|
||||
err := json.Unmarshal(p.Data, task)
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
p.PackErrorBody(ActionLoadDataPartition, err.Error())
|
||||
@ -270,13 +271,18 @@ func (s *DataNode) handlePacketToLoadDataPartition(p *repl.Packet) {
|
||||
p.PacketOkReply()
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(p.Data, task)
|
||||
p.PacketOkReply()
|
||||
go s.asyncLoadDataPartition(task)
|
||||
}
|
||||
|
||||
func (s *DataNode) asyncLoadDataPartition(task *proto.AdminTask) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
request := &proto.LoadDataPartitionRequest{}
|
||||
response := &proto.LoadDataPartitionResponse{}
|
||||
if task.OpCode == proto.OpLoadDataPartition {
|
||||
// TODO unhandled errors
|
||||
bytes, _ := json.Marshal(task.Request)
|
||||
json.Unmarshal(bytes, request)
|
||||
dp := s.space.Partition(request.PartitionId)
|
||||
@ -306,13 +312,13 @@ func (s *DataNode) handlePacketToLoadDataPartition(p *repl.Packet) {
|
||||
}
|
||||
_, err = MasterHelper.Request("POST", proto.GetDataNodeTaskResponse, nil, data)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "load DataPartition failed,partitionID(%v)", request.PartitionId)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
err = errors.Trace(err, "load DataPartition failed,partitionID(%v)", request.PartitionId)
|
||||
log.LogError(errors.Stack(err))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle OpMarkDelete packet.
|
||||
func (s *DataNode) handleMarkDeletePacket(p *repl.Packet) {
|
||||
func (s *DataNode) handleMarkDeletePacket(p *repl.Packet, c net.Conn) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
@ -390,12 +396,12 @@ func (s *DataNode) handleRandomWritePacket(p *repl.Packet) {
|
||||
partition := p.Object.(*DataPartition)
|
||||
_, isLeader := partition.IsRaftLeader()
|
||||
if !isLeader {
|
||||
err = storage.NotALeaderError
|
||||
err = raft.ErrNotLeader
|
||||
return
|
||||
}
|
||||
err = partition.RandomWriteSubmit(p)
|
||||
if err != nil && strings.Contains(err.Error(), raft.ErrNotLeader.Error()) {
|
||||
err = storage.NotALeaderError
|
||||
err = raft.ErrNotLeader
|
||||
return
|
||||
}
|
||||
|
||||
@ -409,37 +415,47 @@ func (s *DataNode) handleRandomWritePacket(p *repl.Packet) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle OpStreamRead packet.
|
||||
func (s *DataNode) handleStreamReadPacket(p *repl.Packet, connect net.Conn, isRepairRead bool) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logContent := fmt.Sprintf("action[OperatePacket] %v.",
|
||||
p.LogMessage(p.GetOpMsg(), connect.RemoteAddr().String(), p.StartT, err))
|
||||
log.LogError(logContent)
|
||||
p.PackErrorBody(ActionStreamRead, err.Error())
|
||||
p.WriteToConn(connect)
|
||||
}
|
||||
}()
|
||||
partition := p.Object.(*DataPartition)
|
||||
if !isRepairRead {
|
||||
err = partition.CheckLeader(p, connect)
|
||||
if err = partition.CheckLeader(p, connect); err != nil {
|
||||
return
|
||||
}
|
||||
s.handleExtentRepaiReadPacket(p, connect, isRepairRead)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DataNode) handleExtentRepaiReadPacket(p *repl.Packet, connect net.Conn, isRepairRead bool) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
p.PackErrorBody(ActionStreamRead, err.Error())
|
||||
p.WriteToConn(connect)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
partition := p.Object.(*DataPartition)
|
||||
needReplySize := p.Size
|
||||
offset := p.ExtentOffset
|
||||
store := partition.ExtentStore()
|
||||
reply := repl.NewStreamReadResponsePacket(p.ReqID, p.PartitionID, p.ExtentID)
|
||||
reply.StartT = time.Now().UnixNano()
|
||||
|
||||
for {
|
||||
if needReplySize <= 0 {
|
||||
break
|
||||
}
|
||||
err = nil
|
||||
reply := repl.NewStreamReadResponsePacket(p.ReqID, p.PartitionID, p.ExtentID)
|
||||
reply.StartT = p.StartT
|
||||
currReadSize := uint32(util.Min(int(needReplySize), util.ReadBlockSize))
|
||||
if currReadSize == util.ReadBlockSize {
|
||||
reply.Data, _ = proto.Buffers.Get(util.ReadBlockSize)
|
||||
@ -454,21 +470,12 @@ func (s *DataNode) handleStreamReadPacket(p *repl.Packet, connect net.Conn, isRe
|
||||
p.CRC = reply.CRC
|
||||
tpObject.Set()
|
||||
if err != nil {
|
||||
reply.PackErrorBody(ActionStreamRead, err.Error())
|
||||
p.PackErrorBody(ActionStreamRead, err.Error())
|
||||
if err = reply.WriteToConn(connect); err != nil {
|
||||
p.PackErrorBody(ActionStreamRead, err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
reply.Size = uint32(currReadSize)
|
||||
reply.ResultCode = proto.OpOk
|
||||
p.ResultCode = proto.OpOk
|
||||
logContent := fmt.Sprintf("action[OperatePacket] %v.",
|
||||
p.LogMessage(p.GetOpMsg(), connect.RemoteAddr().String(), p.StartT, err))
|
||||
log.LogRead(logContent)
|
||||
if err = reply.WriteToConn(connect); err != nil {
|
||||
p.PackErrorBody(ActionStreamRead, err.Error())
|
||||
return
|
||||
}
|
||||
needReplySize -= currReadSize
|
||||
@ -476,6 +483,9 @@ func (s *DataNode) handleStreamReadPacket(p *repl.Packet, connect net.Conn, isRe
|
||||
if currReadSize == util.ReadBlockSize {
|
||||
proto.Buffers.Put(reply.Data)
|
||||
}
|
||||
logContent := fmt.Sprintf("action[operatePacket] %v.",
|
||||
reply.LogMessage(reply.GetOpMsg(), connect.RemoteAddr().String(), reply.StartT, err))
|
||||
log.LogReadf(logContent)
|
||||
}
|
||||
p.PacketOkReply()
|
||||
|
||||
@ -652,7 +662,7 @@ func (s *DataNode) handlePacketToDecommissionDataPartition(p *repl.Packet) {
|
||||
Status: proto.TaskFailed,
|
||||
}
|
||||
if req.AddPeer.ID == req.RemovePeer.ID {
|
||||
err = errors.Errorf("[opOfflineDataPartition]: AddPeer[%v] same withRemovePeer[%v]", req.AddPeer, req.RemovePeer)
|
||||
err = errors.NewErrorf("[opOfflineDataPartition]: AddPeer[%v] same withRemovePeer[%v]", req.AddPeer, req.RemovePeer)
|
||||
resp.Result = err.Error()
|
||||
goto end
|
||||
}
|
||||
@ -677,8 +687,8 @@ end:
|
||||
data, _ := json.Marshal(adminTask)
|
||||
_, err = MasterHelper.Request("POST", proto.GetDataNodeTaskResponse, nil, data)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, "opOfflineDataPartition failed, partitionID(%v)", resp.PartitionId)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
err = errors.Trace(err, "opOfflineDataPartition failed, partitionID(%v)", resp.PartitionId)
|
||||
log.LogError(errors.Stack(err))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -23,14 +23,11 @@ import (
|
||||
|
||||
func (s *DataNode) Post(p *repl.Packet) error {
|
||||
if p.IsMasterCommand() {
|
||||
p.NeedReply = false
|
||||
p.NeedReply = true
|
||||
}
|
||||
if isReadExtentOperation(p) {
|
||||
p.NeedReply = false
|
||||
}
|
||||
if p.Opcode == proto.OpCreateDataPartition || p.Opcode == proto.OpDataNodeHeartbeat {
|
||||
p.NeedReply = true
|
||||
}
|
||||
s.cleanupPkt(p)
|
||||
s.addMetrics(p)
|
||||
return nil
|
||||
|
||||
@ -20,7 +20,6 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/repl"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/juju/errors"
|
||||
"hash/crc32"
|
||||
)
|
||||
|
||||
@ -75,7 +74,7 @@ func (s *DataNode) checkCrc(p *repl.Packet) (err error) {
|
||||
func (s *DataNode) checkPartition(p *repl.Packet) (err error) {
|
||||
dp := s.space.Partition(p.PartitionID)
|
||||
if dp == nil {
|
||||
err = errors.Errorf("partition %v is not exist", p.PartitionID)
|
||||
err = proto.ErrDataPartitionNotExists
|
||||
return
|
||||
}
|
||||
p.Object = dp
|
||||
|
||||
@ -48,10 +48,11 @@ Sample *master.json* is shown as follows,
|
||||
"id":"1",
|
||||
"peers": "1:192.168.31.173:80,2:192.168.31.141:80,3:192.168.30.200:80",
|
||||
"retainLogs":"20000",
|
||||
"logDir": "/export/Logs/cfs/master",
|
||||
"logDir": "/export/Logs/master",
|
||||
"logLevel":"info",
|
||||
"walDir":"/export/Logs/cfs/raft",
|
||||
"storeDir":"/export/cfs/rocksdbstore",
|
||||
"walDir":"/export/Data/master/raft",
|
||||
"storeDir":"/export/Data/master/rocksdbstore",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"exporterPort": 9510,
|
||||
"clusterName":"cfs"
|
||||
@ -76,11 +77,13 @@ Sample *meta.json is* shown as follows,
|
||||
"listen": "9021",
|
||||
"prof": "9092",
|
||||
"logLevel": "debug",
|
||||
"metaDir": "/export/cfs/metanode_meta",
|
||||
"logDir": "/export/Logs/cfs/metanode",
|
||||
"raftDir": "/export/cfs/metanode_raft",
|
||||
"metaDir": "/export/Data/metanode",
|
||||
"logDir": "/export/Logs/metanode",
|
||||
"raftDir": "/export/Data/metanode/raft",
|
||||
"raftHeartbeatPort": "9093",
|
||||
"raftReplicatePort": "9094",
|
||||
"totalMem": "17179869184",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"exporterPort": 9511,
|
||||
"masterAddrs": [
|
||||
@ -144,6 +147,7 @@ Start Datanode
|
||||
"logLevel": "info",
|
||||
"raftHeartbeat": "9095",
|
||||
"raftReplica": "9096",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"exporterPort": 9512,
|
||||
"masterAddr": [
|
||||
@ -153,7 +157,8 @@ Start Datanode
|
||||
],
|
||||
"rack": "",
|
||||
"disks": [
|
||||
"/data0:107374182400"
|
||||
"/data0:21474836480",
|
||||
"/data1:21474836480",
|
||||
]
|
||||
}
|
||||
|
||||
@ -186,7 +191,8 @@ Mount Client
|
||||
"volName": "test",
|
||||
"owner": "cfs",
|
||||
"masterAddr": "192.168.31.173:80,192.168.31.141:80,192.168.30.200:80",
|
||||
"logDir": "/export/Logs/cfs",
|
||||
"logDir": "/export/Logs/client",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"profPort": "10094",
|
||||
"logLevel": "info"
|
||||
}
|
||||
|
||||
@ -23,7 +23,8 @@ fuse.json
|
||||
"volName": "test",
|
||||
"owner": "cfs",
|
||||
"masterAddr": "192.168.31.173:80,192.168.31.141:80,192.168.30.200:80",
|
||||
"logDir": "/export/Logs/cfs",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"logDir": "/export/Logs/client",
|
||||
"logLevel": "info",
|
||||
"profPort": "10094"
|
||||
}
|
||||
@ -45,6 +46,7 @@ fuse.json
|
||||
"icacheTimeout", "string", "Inode cache valid duration in client", "No"
|
||||
"enSyncWrite", "string", "Enable DirectIO sync write, i.e. make sure data is fsynced in data node", "No"
|
||||
"autoInvalData", "string", "Use AutoInvalData FUSE mount option", "No"
|
||||
"warnLogDir","string","Warn message directory","No"
|
||||
|
||||
Mount
|
||||
-----
|
||||
|
||||
@ -31,6 +31,8 @@ Configurations
|
||||
"masterAddr", "string slice", "Addresses of master server", "Yes"
|
||||
"rack", "string", "Identity of rack", "No"
|
||||
"disks", "string slice", "PATH:MAX_ERRS:REST_SIZE", "Yes"
|
||||
"warnLogDir","string","Warn message directory","No"
|
||||
|
||||
|
||||
**Example:**
|
||||
|
||||
@ -43,8 +45,9 @@ Configurations
|
||||
"logDir": "/export/Logs/datanode",
|
||||
"logLevel": "debug",
|
||||
"raftHeartbeat": "9095",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"raftReplica": "9096",
|
||||
"raftDir": "/export/Logs/datanode/raft",
|
||||
"raftDir": "/export/Data/datanode/raft",
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"exporterPort": 9512,
|
||||
"masterAddr": [
|
||||
@ -54,8 +57,8 @@ Configurations
|
||||
],
|
||||
"rack": "main",
|
||||
"disks": [
|
||||
"/data0:107374182400",
|
||||
"/data1:107374182400"
|
||||
"/data0:21474836480",
|
||||
"/data1:21474836480"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,8 @@ ChubaoFS use **JSON** as configuration file format.
|
||||
"clusterName", "string", "The cluster identifier", "Yes"
|
||||
"exporterPort", "int", "The prometheus exporter port", "No"
|
||||
"consulAddr", "string", "The consul register addr for prometheus exporter", "No"
|
||||
"warnLogDir","string","Warn message directory","No"
|
||||
|
||||
|
||||
**Example:**
|
||||
|
||||
@ -45,11 +47,12 @@ ChubaoFS use **JSON** as configuration file format.
|
||||
"prof":"10088",
|
||||
"id":"1",
|
||||
"peers": "1:127.0.0.1:8080,1:127.0.0.1:8081,1:127.0.0.1:8082",
|
||||
"logDir": "/export/master",
|
||||
"logLevel":"DEBUG",
|
||||
"retainLogs":"2000",
|
||||
"walDir":"/export/raft",
|
||||
"storeDir":"/export/rocks",
|
||||
"retainLogs":"20000",
|
||||
"logDir": "/export/Logs/master",
|
||||
"logLevel":"info",
|
||||
"walDir":"/export/Data/master/raft",
|
||||
"storeDir":"/export/Data/master/rocksdbstore",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"exporterPort": 9510,
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"clusterName":"test"
|
||||
|
||||
@ -18,6 +18,9 @@ Metanode is the manager of meta partitions and replicated by MultiRaft. Each met
|
||||
"consulAddr", "string", "Addresses of monitor system", "No"
|
||||
"exporterPort", "string", "Port for monitor system", "No"
|
||||
"masterAddrs", "string", "Addresses of master server", "Yes"
|
||||
"warnLogDir","string","Warn message directory","No"
|
||||
"totalMem","string","max memory metadata used","No"
|
||||
|
||||
|
||||
|
||||
|
||||
@ -30,13 +33,15 @@ Example:
|
||||
"listen": "9021",
|
||||
"prof": "9092",
|
||||
"logLevel": "debug",
|
||||
"metadataDir": "/export/cfs/metanode_meta",
|
||||
"logDir": "/export/Logs/cfs/metanode",
|
||||
"raftDir": "/export/cfs/metanode_raft",
|
||||
"metaDir": "/export/Data/metanode",
|
||||
"logDir": "/export/Logs/metanode",
|
||||
"raftDir": "/export/Data/metanode/raft",
|
||||
"warnLogDir":"/export/home/tomcat/UMP-Monitor/logs/",
|
||||
"raftHeartbeatPort": "9093",
|
||||
"raftReplicaPort": "9094",
|
||||
"consulAddr": "http://consul.prometheus-cfs.local",
|
||||
"exporterPort": 9511,
|
||||
"exporterPort": 9511,
|
||||
"totalMem": "17179869184",
|
||||
"masterAddrs": [
|
||||
"192.168.31.173:80",
|
||||
"192.168.31.141:80",
|
||||
|
||||
@ -12,7 +12,7 @@ ChubaoFS use prometheus as metrics collector. It simply config as follow in mast
|
||||
|
||||
|
||||
* exporterPort:prometheus exporter Port. when set,can export prometheus metrics from URL(http://$hostip:$exporterPort/metrics). If not set, prometheus exporter will unavailable;
|
||||
* consulAddr: consul register address,it can work with prometheus to auto discover deployed cfs nodes, if not set, consul register will not work.
|
||||
* consulAddr: consul register address,it can work with prometheus to auto discover deployed chubaofs nodes, if not set, consul register will not work.
|
||||
|
||||
Using grafana as prometheus metrics web front:
|
||||
|
||||
|
||||
@ -22,8 +22,8 @@ import (
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
@ -117,14 +117,14 @@ func (sender *AdminTaskManager) sendTasks(tasks []*proto.AdminTask) {
|
||||
for _, task := range tasks {
|
||||
conn, err := sender.connPool.GetConnect(sender.targetAddr)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("clusterID[%v] get connection to %v,err,%v", sender.clusterID, sender.targetAddr, errors.ErrorStack(err))
|
||||
msg := fmt.Sprintf("clusterID[%v] get connection to %v,err,%v", sender.clusterID, sender.targetAddr, errors.Stack(err))
|
||||
WarnBySpecialKey(fmt.Sprintf("%v_%v_sendTask", sender.clusterID, ModuleName), msg)
|
||||
sender.connPool.PutConnect(conn, true)
|
||||
sender.updateTaskInfo(task, false)
|
||||
break
|
||||
}
|
||||
if err = sender.sendAdminTask(task, conn); err != nil {
|
||||
log.LogError(fmt.Sprintf("send task %v to %v,err,%v", task.ToString(), sender.targetAddr, errors.ErrorStack(err)))
|
||||
log.LogError(fmt.Sprintf("send task %v to %v,err,%v", task.ToString(), sender.targetAddr, errors.Stack(err)))
|
||||
sender.connPool.PutConnect(conn, true)
|
||||
sender.updateTaskInfo(task, true)
|
||||
continue
|
||||
@ -157,13 +157,13 @@ func (sender *AdminTaskManager) buildPacket(task *proto.AdminTask) (packet *prot
|
||||
func (sender *AdminTaskManager) sendAdminTask(task *proto.AdminTask, conn net.Conn) (err error) {
|
||||
packet, err := sender.buildPacket(task)
|
||||
if err != nil {
|
||||
return errors.Annotatef(err, "action[sendAdminTask build packet failed,task:%v]", task.ID)
|
||||
return errors.Trace(err, "action[sendAdminTask build packet failed,task:%v]", task.ID)
|
||||
}
|
||||
if err = packet.WriteToConn(conn); err != nil {
|
||||
return errors.Annotatef(err, "action[sendAdminTask],WriteToConn failed,task:%v", task.ID)
|
||||
return errors.Trace(err, "action[sendAdminTask],WriteToConn failed,task:%v", task.ID)
|
||||
}
|
||||
if err = packet.ReadFromConn(conn, proto.ReadDeadlineTime); err != nil {
|
||||
return errors.Annotatef(err, "action[sendAdminTask],ReadFromConn failed task:%v", task.ID)
|
||||
return errors.Trace(err, "action[sendAdminTask],ReadFromConn failed task:%v", task.ID)
|
||||
}
|
||||
log.LogDebugf(fmt.Sprintf("action[sendAdminTask] sender task:%v success", task.ToString()))
|
||||
sender.updateTaskInfo(task, true)
|
||||
@ -175,13 +175,13 @@ func (sender *AdminTaskManager) syncSendAdminTask(task *proto.AdminTask, conn ne
|
||||
log.LogInfof(fmt.Sprintf("action[syncSendAdminTask] sender task:%v begin", task.ToString()))
|
||||
packet, err := sender.buildPacket(task)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "action[syncSendAdminTask build packet failed,task:%v]", task.ID)
|
||||
return nil, errors.Trace(err, "action[syncSendAdminTask build packet failed,task:%v]", task.ID)
|
||||
}
|
||||
if err = packet.WriteToConn(conn); err != nil {
|
||||
return nil, errors.Annotatef(err, "action[syncSendAdminTask],WriteToConn failed,task:%v", task.ID)
|
||||
return nil, errors.Trace(err, "action[syncSendAdminTask],WriteToConn failed,task:%v", task.ID)
|
||||
}
|
||||
if err = packet.ReadFromConn(conn, proto.SyncSendTaskDeadlineTime); err != nil {
|
||||
return nil, errors.Annotatef(err, "action[syncSendAdminTask],ReadFromConn failed task:%v", task.ID)
|
||||
return nil, errors.Trace(err, "action[syncSendAdminTask],ReadFromConn failed task:%v", task.ID)
|
||||
}
|
||||
if packet.ResultCode != proto.OpOk {
|
||||
err = fmt.Errorf(string(packet.Data))
|
||||
|
||||
@ -23,8 +23,8 @@ import (
|
||||
"bytes"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -519,7 +519,6 @@ func (m *Server) decommissionDisk(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
rstMsg = fmt.Sprintf("recive decommissionDisk node[%v] disk[%v], badPartitionIds[%v] has offline successfully",
|
||||
node.Addr, diskPath, badPartitionIds)
|
||||
m.cluster.BadDataPartitionIds.Store(fmt.Sprintf("%s:%s", offLineAddr, diskPath), badPartitionIds)
|
||||
if err = m.cluster.decommissionDisk(node, diskPath, badPartitionIds); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
|
||||
@ -19,8 +19,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -290,7 +290,7 @@ func (c *Cluster) addMetaNode(nodeAddr string) (id uint64, err error) {
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[addMetaNode],clusterID[%v] metaNodeAddr:%v err:%v ",
|
||||
c.Name, nodeAddr, err.Error())
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -344,7 +344,7 @@ func (c *Cluster) addDataNode(nodeAddr string) (id uint64, err error) {
|
||||
return
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[addDataNode],clusterID[%v] dataNodeAddr:%v err:%v ", c.Name, nodeAddr, err.Error())
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -384,7 +384,7 @@ func (c *Cluster) getVol(volName string) (vol *Vol, err error) {
|
||||
defer c.volMutex.RUnlock()
|
||||
vol, ok := c.vols[volName]
|
||||
if !ok {
|
||||
err = errors.Annotatef(volNotFound(volName), "%v not found", volName)
|
||||
err = errors.Trace(volNotFound(volName), "%v not found", volName)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -491,7 +491,7 @@ func (c *Cluster) createDataPartition(volName string) (dp *DataPartition, err er
|
||||
return
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[createDataPartition],clusterID[%v] vol[%v] Err:%v ", c.Name, volName, err.Error())
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -545,22 +545,22 @@ func (c *Cluster) chooseTargetDataNodes(replicaNum int) (hosts []string, peers [
|
||||
peers = make([]proto.Peer, 0)
|
||||
ns, err := c.t.allocNodeSetForDataNode(uint8(replicaNum))
|
||||
if err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
if ns.isSingleRack() {
|
||||
var newHosts []string
|
||||
if rack, err = ns.getRack(ns.racks[0]); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
if newHosts, peers, err = rack.getAvailDataNodeHosts(hosts, replicaNum); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
hosts = newHosts
|
||||
return
|
||||
}
|
||||
|
||||
if racks, err = ns.allocRacks(replicaNum, nil); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
|
||||
if len(racks) == 2 {
|
||||
@ -569,12 +569,12 @@ func (c *Cluster) chooseTargetDataNodes(replicaNum int) (hosts []string, peers [
|
||||
masterReplicaNum := replicaNum/2 + 1
|
||||
slaveReplicaNum := replicaNum - masterReplicaNum
|
||||
if masterAddr, masterPeers, err = masterRack.getAvailDataNodeHosts(hosts, masterReplicaNum); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
hosts = append(hosts, masterAddr...)
|
||||
peers = append(peers, masterPeers...)
|
||||
if addrs, slavePeers, err = slaveRack.getAvailDataNodeHosts(hosts, slaveReplicaNum); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
hosts = append(hosts, addrs...)
|
||||
peers = append(peers, slavePeers...)
|
||||
@ -583,7 +583,7 @@ func (c *Cluster) chooseTargetDataNodes(replicaNum int) (hosts []string, peers [
|
||||
rack := racks[index]
|
||||
var selectPeers []proto.Peer
|
||||
if addrs, selectPeers, err = rack.getAvailDataNodeHosts(hosts, 1); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
hosts = append(hosts, addrs...)
|
||||
peers = append(peers, selectPeers...)
|
||||
@ -598,7 +598,7 @@ func (c *Cluster) chooseTargetDataNodes(replicaNum int) (hosts []string, peers [
|
||||
func (c *Cluster) dataNode(addr string) (dataNode *DataNode, err error) {
|
||||
value, ok := c.dataNodes.Load(addr)
|
||||
if !ok {
|
||||
err = errors.Annotatef(dataNodeNotFound(addr), "%v not found", addr)
|
||||
err = errors.Trace(dataNodeNotFound(addr), "%v not found", addr)
|
||||
return
|
||||
}
|
||||
dataNode = value.(*DataNode)
|
||||
@ -608,7 +608,7 @@ func (c *Cluster) dataNode(addr string) (dataNode *DataNode, err error) {
|
||||
func (c *Cluster) metaNode(addr string) (metaNode *MetaNode, err error) {
|
||||
value, ok := c.metaNodes.Load(addr)
|
||||
if !ok {
|
||||
err = errors.Annotatef(metaNodeNotFound(addr), "%v not found", addr)
|
||||
err = errors.Trace(metaNodeNotFound(addr), "%v not found", addr)
|
||||
return
|
||||
}
|
||||
metaNode = value.(*MetaNode)
|
||||
@ -669,8 +669,6 @@ func (c *Cluster) decommissionDataPartition(offlineAddr string, dp *DataPartitio
|
||||
removePeer proto.Peer
|
||||
replica *DataReplica
|
||||
)
|
||||
badPartitionIDs := make([]uint64, 0)
|
||||
badPartitionIDs = append(badPartitionIDs, dp.PartitionID)
|
||||
dp.Lock()
|
||||
defer dp.Unlock()
|
||||
if ok := dp.hasHost(offlineAddr); !ok {
|
||||
@ -681,10 +679,6 @@ func (c *Cluster) decommissionDataPartition(offlineAddr string, dp *DataPartitio
|
||||
goto errHandler
|
||||
}
|
||||
|
||||
if replica, err = dp.getReplica(offlineAddr); err != nil {
|
||||
goto errHandler
|
||||
}
|
||||
|
||||
if err = dp.hasMissingOneReplica(int(vol.dpReplicaNum)); err != nil {
|
||||
goto errHandler
|
||||
}
|
||||
@ -730,6 +724,7 @@ func (c *Cluster) decommissionDataPartition(offlineAddr string, dp *DataPartitio
|
||||
if err = dp.updateForOffline(offlineAddr, newAddr, dp.VolName, newPeers, c); err != nil {
|
||||
goto errHandler
|
||||
}
|
||||
replica, _ = dp.getReplica(offlineAddr)
|
||||
dp.removeReplicaByAddr(offlineAddr)
|
||||
dp.checkAndRemoveMissReplica(offlineAddr)
|
||||
tasks = make([]*proto.AdminTask, 0)
|
||||
@ -743,7 +738,7 @@ func (c *Cluster) decommissionDataPartition(offlineAddr string, dp *DataPartitio
|
||||
}
|
||||
dp.Status = proto.ReadOnly
|
||||
dp.isRecover = true
|
||||
c.BadDataPartitionIds.Store(fmt.Sprintf("%s:%s", offlineAddr, replica.DiskPath), badPartitionIDs)
|
||||
c.putBadDataPartitionIDs(replica, offlineAddr, dp.PartitionID)
|
||||
log.LogWarnf("clusterID[%v] partitionID:%v on Node:%v offline success,newHost[%v],PersistenceHosts:[%v]",
|
||||
c.Name, dp.PartitionID, offlineAddr, newAddr, dp.Hosts)
|
||||
return
|
||||
@ -757,6 +752,22 @@ errHandler:
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) putBadDataPartitionIDs(replica *DataReplica, offlineAddr string, partitionID uint64) {
|
||||
var key string
|
||||
newBadPartitionIDs := make([]uint64, 0)
|
||||
if replica != nil {
|
||||
key = fmt.Sprintf("%s:%s", offlineAddr, replica.DiskPath)
|
||||
} else {
|
||||
key = fmt.Sprintf("%s:%s", offlineAddr, "")
|
||||
}
|
||||
badPartitionIDs, ok := c.BadDataPartitionIds.Load(key)
|
||||
if ok {
|
||||
newBadPartitionIDs = badPartitionIDs.([]uint64)
|
||||
}
|
||||
newBadPartitionIDs = append(newBadPartitionIDs, partitionID)
|
||||
c.BadDataPartitionIds.Store(key, newBadPartitionIDs)
|
||||
}
|
||||
|
||||
func (c *Cluster) decommissionMetaNode(metaNode *MetaNode) {
|
||||
msg := fmt.Sprintf("action[decommissionMetaNode],clusterID[%v] Node[%v] OffLine", c.Name, metaNode.Addr)
|
||||
log.LogWarn(msg)
|
||||
@ -812,7 +823,7 @@ func (c *Cluster) updateVol(name, authKey string, capacity int) (err error) {
|
||||
return
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[updateVol], clusterID[%v] name:%v, err:%v ", c.Name, name, err.Error())
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -863,7 +874,7 @@ func (c *Cluster) createVol(name, owner string, size, capacity int) (vol *Vol, e
|
||||
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[createVol], clusterID[%v] name:%v, err:%v ", c.Name, name, err)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -881,7 +892,7 @@ func (c *Cluster) doCreateVol(name, owner string, dpSize, capacity uint64) (err
|
||||
return
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[doCreateVol], clusterID[%v] name:%v, err:%v ", c.Name, name, err.Error())
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
}
|
||||
@ -936,11 +947,11 @@ func (c *Cluster) createMetaPartition(volName string, start, end uint64) (err er
|
||||
errChannel := make(chan error, vol.mpReplicaNum)
|
||||
|
||||
if hosts, peers, err = c.chooseTargetMetaHosts(int(vol.mpReplicaNum)); err != nil {
|
||||
return errors.Trace(err)
|
||||
return errors.NewError(err)
|
||||
}
|
||||
log.LogInfof("target meta hosts:%v,peers:%v", hosts, peers)
|
||||
if partitionID, err = c.idAlloc.allocateMetaPartitionID(); err != nil {
|
||||
return errors.Trace(err)
|
||||
return errors.NewError(err)
|
||||
}
|
||||
mp = newMetaPartition(partitionID, start, end, vol.mpReplicaNum, volName, vol.ID)
|
||||
mp.setHosts(hosts)
|
||||
@ -981,12 +992,12 @@ func (c *Cluster) createMetaPartition(volName string, start, end uint64) (err er
|
||||
c.addMetaNodeTasks(tasks)
|
||||
}(host)
|
||||
}
|
||||
return errors.Trace(err)
|
||||
return errors.NewError(err)
|
||||
default:
|
||||
mp.Status = proto.ReadWrite
|
||||
}
|
||||
if err = c.syncAddMetaPartition(mp); err != nil {
|
||||
return errors.Trace(err)
|
||||
return errors.NewError(err)
|
||||
}
|
||||
vol.addMetaPartition(mp)
|
||||
log.LogInfof("action[createMetaPartition] success,volName[%v],partition[%v]", volName, partitionID)
|
||||
@ -1018,12 +1029,12 @@ func (c *Cluster) chooseTargetMetaHosts(replicaNum int) (hosts []string, peers [
|
||||
ns *nodeSet
|
||||
)
|
||||
if ns, err = c.t.allocNodeSetForMetaNode(uint8(replicaNum)); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
|
||||
hosts = make([]string, 0)
|
||||
if masterAddr, masterPeer, err = ns.getAvailMetaNodeHosts(hosts, 1); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
peers = append(peers, masterPeer...)
|
||||
hosts = append(hosts, masterAddr[0])
|
||||
@ -1032,7 +1043,7 @@ func (c *Cluster) chooseTargetMetaHosts(replicaNum int) (hosts []string, peers [
|
||||
return
|
||||
}
|
||||
if slaveAddrs, slavePeers, err = ns.getAvailMetaNodeHosts(hosts, otherReplica); err != nil {
|
||||
return nil, nil, errors.Trace(err)
|
||||
return nil, nil, errors.NewError(err)
|
||||
}
|
||||
hosts = append(hosts, slaveAddrs...)
|
||||
peers = append(peers, slavePeers...)
|
||||
@ -1175,3 +1186,9 @@ func (c *Cluster) setDisableAutoAllocate(disableAutoAllocate bool) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) clearVols() {
|
||||
c.volMutex.Lock()
|
||||
defer c.volMutex.Unlock()
|
||||
c.vols = make(map[string]*Vol, 0)
|
||||
}
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
@ -157,7 +157,7 @@ func (c *Cluster) decommissionMetaPartition(nodeAddr string, mp *MetaPartition)
|
||||
|
||||
errHandler:
|
||||
log.LogError(fmt.Sprintf("action[decommissionMetaPartition],volName: %v,partitionID: %v,err: %v",
|
||||
mp.volName, mp.PartitionID, errors.ErrorStack(err)))
|
||||
mp.volName, mp.PartitionID, errors.Stack(err)))
|
||||
Warn(c.Name, fmt.Sprintf("clusterID[%v] meta partition[%v] offline addr[%v] failed,err:%v",
|
||||
c.Name, mp.PartitionID, nodeAddr, err))
|
||||
return
|
||||
@ -401,7 +401,7 @@ func (c *Cluster) dealCreateMetaPartitionResp(nodeAddr string, resp *proto.Creat
|
||||
log.LogInfof("action[dealCreateMetaPartitionResp] process resp from nodeAddr[%v] pid[%v] success", nodeAddr, resp.PartitionID)
|
||||
return
|
||||
errHandler:
|
||||
log.LogErrorf(fmt.Sprintf("action[dealCreateMetaPartitionResp] %v", errors.ErrorStack(err)))
|
||||
log.LogErrorf(fmt.Sprintf("action[dealCreateMetaPartitionResp] %v", errors.Stack(err)))
|
||||
return
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ func (c *Cluster) dealMetaNodeHeartbeatResp(nodeAddr string, resp *proto.MetaNod
|
||||
log.LogInfof(logMsg)
|
||||
return
|
||||
errHandler:
|
||||
logMsg = fmt.Sprintf("nodeAddr %v heartbeat error :%v", nodeAddr, errors.ErrorStack(err))
|
||||
logMsg = fmt.Sprintf("nodeAddr %v heartbeat error :%v", nodeAddr, errors.Stack(err))
|
||||
log.LogError(logMsg)
|
||||
return
|
||||
}
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -235,7 +235,7 @@ func (partition *DataPartition) getReplica(addr string) (replica *DataReplica, e
|
||||
}
|
||||
log.LogErrorf("action[getReplica],partitionID:%v,locations:%v,err:%v",
|
||||
partition.PartitionID, addr, dataReplicaNotFound(addr))
|
||||
return nil, errors.Annotatef(dataReplicaNotFound(addr), "%v not found", addr)
|
||||
return nil, errors.Trace(dataReplicaNotFound(addr), "%v not found", addr)
|
||||
}
|
||||
|
||||
func (partition *DataPartition) convertToDataPartitionResponse() (dpr *proto.DataPartitionResponse) {
|
||||
@ -455,7 +455,7 @@ func (partition *DataPartition) getReplicaIndex(addr string) (index int, err err
|
||||
}
|
||||
log.LogErrorf("action[getReplicaIndex],partitionID:%v,location:%v,err:%v",
|
||||
partition.PartitionID, addr, dataReplicaNotFound(addr))
|
||||
return -1, errors.Annotatef(dataReplicaNotFound(addr), "%v not found ", addr)
|
||||
return -1, errors.Trace(dataReplicaNotFound(addr), "%v not found ", addr)
|
||||
}
|
||||
|
||||
func (partition *DataPartition) updateForOffline(offlineAddr, newAddr, volName string, newPeers []proto.Peer, c *Cluster) (err error) {
|
||||
@ -478,7 +478,7 @@ func (partition *DataPartition) updateForOffline(offlineAddr, newAddr, volName s
|
||||
if err = c.syncUpdateDataPartition(partition); err != nil {
|
||||
partition.Hosts = orgHosts
|
||||
partition.Peers = oldPeers
|
||||
return errors.Annotatef(err, "update partition[%v] failed", partition.PartitionID)
|
||||
return errors.Trace(err, "update partition[%v] failed", partition.PartitionID)
|
||||
}
|
||||
msg := fmt.Sprintf("action[updateForOffline] partitionID:%v offlineAddr:%v newAddr:%v"+
|
||||
"oldHosts:%v newHosts:%v,oldPees[%v],newPeers[%v]",
|
||||
|
||||
@ -209,7 +209,6 @@ func (partition *DataPartition) missingReplicaAddress(dataPartitionSize uint64)
|
||||
partition.PartitionID, addr))
|
||||
err = proto.ErrMissingReplica
|
||||
addr = addr
|
||||
partition.isRecover = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
@ -51,7 +51,7 @@ func (dpMap *DataPartitionMap) get(ID uint64) (*DataPartition, error) {
|
||||
if v, ok := dpMap.partitionMap[ID]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return nil, errors.Annotatef(dataPartitionNotFound(ID), "[%v] not found in [%v]", ID, dpMap.volName)
|
||||
return nil, errors.Trace(dataPartitionNotFound(ID), "[%v] not found in [%v]", ID, dpMap.volName)
|
||||
}
|
||||
|
||||
func (dpMap *DataPartitionMap) put(dp *DataPartition) {
|
||||
|
||||
@ -80,8 +80,14 @@ func (m *Server) handlerWithInterceptor() http.Handler {
|
||||
return http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if m.partition.IsRaftLeader() {
|
||||
m.ServeHTTP(w, r)
|
||||
return
|
||||
if m.metaReady {
|
||||
m.ServeHTTP(w, r)
|
||||
return
|
||||
} else {
|
||||
log.LogWarnf("action[handlerWithInterceptor] leader meta has not ready")
|
||||
http.Error(w, m.leaderInfo.addr, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
if m.leaderInfo.addr == "" {
|
||||
log.LogErrorf("action[handlerWithInterceptor] no leader,request[%v]", r.URL)
|
||||
|
||||
@ -35,12 +35,17 @@ func (m *Server) handleLeaderChange(leader uint64) {
|
||||
log.LogWarnf("action[handleLeaderChange] change leader to [%v] ", m.leaderInfo.addr)
|
||||
m.reverseProxy = m.newReverseProxy()
|
||||
|
||||
// once switching to the master, check the Heartbeat
|
||||
if m.id == leader {
|
||||
Warn(m.clusterName, fmt.Sprintf("clusterID[%v] leader is changed to %v",
|
||||
m.clusterName, m.leaderInfo.addr))
|
||||
m.cluster.checkMetaNodeHeartbeat()
|
||||
m.loadMetadata()
|
||||
m.metaReady = true
|
||||
m.cluster.checkDataNodeHeartbeat()
|
||||
m.cluster.checkMetaNodeHeartbeat()
|
||||
} else {
|
||||
Warn(m.clusterName, fmt.Sprintf("clusterID[%v] leader is changed to %v",
|
||||
m.clusterName, m.leaderInfo.addr))
|
||||
m.metaReady = false
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +87,9 @@ func (m *Server) restoreIDAlloc() {
|
||||
// Load stored metadata into the memory
|
||||
func (m *Server) loadMetadata() {
|
||||
log.LogInfo("action[loadMetadata] begin")
|
||||
m.clearMetadata()
|
||||
m.restoreIDAlloc()
|
||||
m.cluster.fsm.restore()
|
||||
var err error
|
||||
if err = m.cluster.loadClusterValue(); err != nil {
|
||||
panic(err)
|
||||
@ -112,3 +119,8 @@ func (m *Server) loadMetadata() {
|
||||
log.LogInfo("action[loadMetadata] end")
|
||||
|
||||
}
|
||||
|
||||
func (m *Server) clearMetadata() {
|
||||
m.cluster.clearVols()
|
||||
m.cluster.t = newTopology()
|
||||
}
|
||||
|
||||
@ -19,8 +19,8 @@ import (
|
||||
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -458,7 +458,7 @@ func (mp *MetaPartition) buildNewMetaPartitionTasks(specifyAddrs []string, peers
|
||||
func (mp *MetaPartition) createTaskToDecommissionReplica(volName string, removePeer proto.Peer, addPeer proto.Peer) (t *proto.AdminTask, err error) {
|
||||
mr, err := mp.getMetaReplicaLeader()
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
return nil, errors.NewError(err)
|
||||
}
|
||||
req := &proto.MetaPartitionDecommissionRequest{PartitionID: mp.PartitionID, VolName: volName, RemovePeer: removePeer, AddPeer: addPeer}
|
||||
t = proto.NewAdminTask(proto.OpDecommissionMetaPartition, mr.Addr, req)
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
bsProto "github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft/proto"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -20,9 +20,9 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/ump"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
@ -153,19 +153,19 @@ func Warn(clusterID, msg string) {
|
||||
// WarnBySpecialKey provides warnings when exits
|
||||
func WarnBySpecialKey(key, msg string) {
|
||||
log.LogWarn(msg)
|
||||
exporter.NewAlarm(key)
|
||||
ump.Alarm(key, msg)
|
||||
}
|
||||
|
||||
func keyNotFound(name string) (err error) {
|
||||
return errors.Errorf("parameter %v not found", name)
|
||||
return errors.NewErrorf("parameter %v not found", name)
|
||||
}
|
||||
|
||||
func unmatchedKey(name string) (err error) {
|
||||
return errors.Errorf("parameter %v not match", name)
|
||||
return errors.NewErrorf("parameter %v not match", name)
|
||||
}
|
||||
|
||||
func notFoundMsg(name string) (err error) {
|
||||
return errors.Errorf("%v not found", name)
|
||||
return errors.NewErrorf("%v not found", name)
|
||||
}
|
||||
|
||||
func metaPartitionNotFound(id uint64) (err error) {
|
||||
|
||||
@ -19,9 +19,9 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util/config"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"net/http/httputil"
|
||||
"strconv"
|
||||
"sync"
|
||||
@ -60,6 +60,7 @@ type Server struct {
|
||||
partition raftstore.Partition
|
||||
wg sync.WaitGroup
|
||||
reverseProxy *httputil.ReverseProxy
|
||||
metaReady bool
|
||||
}
|
||||
|
||||
// NewServer creates a new server
|
||||
@ -73,14 +74,14 @@ func (m *Server) Start(cfg *config.Config) (err error) {
|
||||
m.leaderInfo = &LeaderInfo{}
|
||||
m.reverseProxy = m.newReverseProxy()
|
||||
if err = m.checkConfig(cfg); err != nil {
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
return
|
||||
}
|
||||
m.rocksDBStore = raftstore.NewRocksDBStore(m.storeDir, LRUCacheSize, WriteBufferSize)
|
||||
m.initFsm()
|
||||
m.initCluster()
|
||||
if err = m.createRaftServer(); err != nil {
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
log.LogError(errors.Stack(err))
|
||||
return
|
||||
}
|
||||
m.cluster.partition = m.partition
|
||||
@ -175,7 +176,7 @@ func (m *Server) checkConfig(cfg *config.Config) (err error) {
|
||||
func (m *Server) createRaftServer() (err error) {
|
||||
raftCfg := &raftstore.Config{NodeID: m.id, RaftPath: m.walDir, NumOfLogsToRetain: m.retainLogs}
|
||||
if m.raftStore, err = raftstore.NewRaftStore(raftCfg); err != nil {
|
||||
return errors.Annotatef(err, "NewRaftStore failed! id[%v] walPath[%v]", m.id, m.walDir)
|
||||
return errors.Trace(err, "NewRaftStore failed! id[%v] walPath[%v]", m.id, m.walDir)
|
||||
}
|
||||
fmt.Println(m.config.peers)
|
||||
partitionCfg := &raftstore.PartitionConfig{
|
||||
@ -185,7 +186,7 @@ func (m *Server) createRaftServer() (err error) {
|
||||
SM: m.fsm,
|
||||
}
|
||||
if m.partition, err = m.raftStore.CreatePartition(partitionCfg); err != nil {
|
||||
return errors.Annotate(err, "CreatePartition failed")
|
||||
return errors.Trace(err, "CreatePartition failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -17,8 +17,8 @@ package master
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
@ -105,7 +105,7 @@ func (t *topology) deleteDataNode(dataNode *DataNode) {
|
||||
func (t *topology) getRack(dataNode *DataNode) (rack *Rack, err error) {
|
||||
topoNode, ok := t.dataNodes.Load(dataNode.Addr)
|
||||
if !ok {
|
||||
return nil, errors.Annotatef(dataNodeNotFound(dataNode.Addr), "%v not found", dataNode.Addr)
|
||||
return nil, errors.Trace(dataNodeNotFound(dataNode.Addr), "%v not found", dataNode.Addr)
|
||||
}
|
||||
node := topoNode.(*topoDataNode)
|
||||
ns, err := t.getNodeSet(node.setID)
|
||||
@ -189,7 +189,7 @@ func (t *topology) getNodeSet(setID uint64) (ns *nodeSet, err error) {
|
||||
defer t.nsLock.RUnlock()
|
||||
ns, ok := t.nodeSetMap[setID]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("set %v not found", setID)
|
||||
return nil, errors.NewErrorf("set %v not found", setID)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -363,7 +363,7 @@ func (ns *nodeSet) getRack(name string) (rack *Rack, err error) {
|
||||
defer ns.rackLock.RUnlock()
|
||||
rack, ok := ns.rackMap[name]
|
||||
if !ok {
|
||||
return nil, errors.Annotatef(rackNotFound(name), "%v not found", name)
|
||||
return nil, errors.Trace(rackNotFound(name), "%v not found", name)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -494,7 +494,7 @@ func (rack *Rack) putDataNode(dataNode *DataNode) {
|
||||
func (rack *Rack) getDataNode(addr string) (dataNode *DataNode, err error) {
|
||||
value, ok := rack.dataNodes.Load(addr)
|
||||
if !ok {
|
||||
return nil, errors.Annotatef(dataNodeNotFound(addr), "%v not found", addr)
|
||||
return nil, errors.Trace(dataNodeNotFound(addr), "%v not found", addr)
|
||||
}
|
||||
dataNode = value.(*DataNode)
|
||||
return
|
||||
|
||||
@ -16,7 +16,7 @@ package metanode
|
||||
|
||||
import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -129,6 +129,7 @@ const (
|
||||
cfgMasterAddrs = "masterAddrs"
|
||||
cfgRaftHeartbeatPort = "raftHeartbeatPort"
|
||||
cfgRaftReplicaPort = "raftReplicaPort"
|
||||
cfgTotalMem = "totalMem"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -30,9 +30,9 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
const partitionPrefix = "partition_"
|
||||
@ -116,13 +116,12 @@ func (m *metadataManager) HandleMetadataOperation(conn net.Conn, p *Packet,
|
||||
err = m.opDecommissionMetaPartition(conn, p, remoteAddr)
|
||||
case proto.OpMetaBatchInodeGet:
|
||||
err = m.opMetaBatchInodeGet(conn, p, remoteAddr)
|
||||
case proto.OpPing:
|
||||
default:
|
||||
err = fmt.Errorf("%s unknown Opcode: %d, reqId: %d", remoteAddr,
|
||||
p.Opcode, p.GetReqID())
|
||||
}
|
||||
if err != nil {
|
||||
err = errors.Errorf("%s [%s] req: %d - %s", remoteAddr, p.GetOpMsg(),
|
||||
err = errors.NewErrorf("%s [%s] req: %d - %s", remoteAddr, p.GetOpMsg(),
|
||||
p.GetReqID(), err.Error())
|
||||
}
|
||||
return
|
||||
@ -246,7 +245,7 @@ func (m *metadataManager) loadPartitions() (err error) {
|
||||
backupDir := path.Join(partitionConfig.RootDir, snapshotBackup)
|
||||
if _, err = os.Stat(backupDir); err == nil {
|
||||
if err = os.Rename(backupDir, snapshotDir); err != nil {
|
||||
err = errors.Annotate(err,
|
||||
err = errors.Trace(err,
|
||||
fmt.Sprintf(": fail recover backup snapshot %s",
|
||||
snapshotDir))
|
||||
return
|
||||
@ -293,7 +292,7 @@ func (m *metadataManager) createPartition(id uint64, volName string, start,
|
||||
end uint64, peers []proto.Peer) (err error) {
|
||||
// check partitions
|
||||
if _, err = m.getPartition(id); err == nil {
|
||||
err = errors.Errorf("create partition id=%d is exsited!", id)
|
||||
err = errors.NewErrorf("create partition id=%d is exsited!", id)
|
||||
return
|
||||
}
|
||||
err = nil
|
||||
@ -317,13 +316,13 @@ func (m *metadataManager) createPartition(id uint64, volName string, start,
|
||||
}
|
||||
partition := NewMetaPartition(mpc)
|
||||
if err = partition.PersistMetadata(); err != nil {
|
||||
err = errors.Errorf("[createPartition]->%s", err.Error())
|
||||
err = errors.NewErrorf("[createPartition]->%s", err.Error())
|
||||
return
|
||||
}
|
||||
if err = m.attachPartition(id, partition); err != nil {
|
||||
// TODO Unhandled errors
|
||||
os.RemoveAll(mpc.RootDir)
|
||||
err = errors.Errorf("[createPartition]->%s", err.Error())
|
||||
err = errors.NewErrorf("[createPartition]->%s", err.Error())
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
@ -22,8 +22,8 @@ import (
|
||||
"bytes"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
raftProto "github.com/tiglabs/raft/proto"
|
||||
)
|
||||
|
||||
@ -47,7 +47,8 @@ func (m *metadataManager) opMasterHeartbeat(conn net.Conn, p *Packet,
|
||||
}
|
||||
|
||||
// collect memory info
|
||||
resp.Total, resp.Used, err = util.GetMemInfo()
|
||||
resp.Total = configTotalMem
|
||||
resp.Used, err = util.GetProcessMemory(os.Getpid())
|
||||
if err != nil {
|
||||
adminTask.Status = proto.TaskFailed
|
||||
goto end
|
||||
@ -101,7 +102,7 @@ func (m *metadataManager) opCreateMetaPartition(conn net.Conn, p *Packet,
|
||||
decode := json.NewDecoder(bytes.NewBuffer(p.Data))
|
||||
decode.UseNumber()
|
||||
if err = decode.Decode(adminTask); err != nil {
|
||||
err = errors.Errorf("[opCreateMetaPartition]: Unmarshal AdminTask"+
|
||||
err = errors.NewErrorf("[opCreateMetaPartition]: Unmarshal AdminTask"+
|
||||
" struct: %s", err.Error())
|
||||
return
|
||||
}
|
||||
@ -110,7 +111,7 @@ func (m *metadataManager) opCreateMetaPartition(conn net.Conn, p *Packet,
|
||||
// create a new meta partition.
|
||||
if err = m.createPartition(req.PartitionID, req.VolName,
|
||||
req.Start, req.End, req.Members); err != nil {
|
||||
err = errors.Errorf("[opCreateMetaPartition]->%s; request message: %v",
|
||||
err = errors.NewErrorf("[opCreateMetaPartition]->%s; request message: %v",
|
||||
err.Error(), adminTask.Request)
|
||||
return
|
||||
}
|
||||
@ -314,14 +315,14 @@ func (m *metadataManager) opMetaInodeGet(conn net.Conn, p *Packet,
|
||||
if err = json.Unmarshal(p.Data, req); err != nil {
|
||||
p.PacketErrorWithBody(proto.OpErr, nil)
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opMetaInodeGet]: %s", err.Error())
|
||||
err = errors.NewErrorf("[opMetaInodeGet]: %s", err.Error())
|
||||
return
|
||||
}
|
||||
mp, err := m.getPartition(req.PartitionID)
|
||||
if err != nil {
|
||||
p.PacketErrorWithBody(proto.OpNotExistErr, nil)
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opMetaInodeGet] %s, req: %s", err.Error(),
|
||||
err = errors.NewErrorf("[opMetaInodeGet] %s, req: %s", err.Error(),
|
||||
string(p.Data))
|
||||
return
|
||||
}
|
||||
@ -329,7 +330,7 @@ func (m *metadataManager) opMetaInodeGet(conn net.Conn, p *Packet,
|
||||
return
|
||||
}
|
||||
if err = mp.InodeGet(req, p); err != nil {
|
||||
err = errors.Errorf("[opMetaInodeGet] %s, req: %s", err.Error(),
|
||||
err = errors.NewErrorf("[opMetaInodeGet] %s, req: %s", err.Error(),
|
||||
string(p.Data))
|
||||
}
|
||||
m.respondToClient(conn, p)
|
||||
@ -344,14 +345,14 @@ func (m *metadataManager) opMetaEvictInode(conn net.Conn, p *Packet,
|
||||
if err = json.Unmarshal(p.Data, req); err != nil {
|
||||
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opMetaEvictInode] request unmarshal: %v", err.Error())
|
||||
err = errors.NewErrorf("[opMetaEvictInode] request unmarshal: %v", err.Error())
|
||||
return
|
||||
}
|
||||
mp, err := m.getPartition(req.PartitionID)
|
||||
if err != nil {
|
||||
p.PacketErrorWithBody(proto.OpNotExistErr, nil)
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opMetaEvictInode] req: %s, resp: %v", req, err.Error())
|
||||
err = errors.NewErrorf("[opMetaEvictInode] req: %s, resp: %v", req, err.Error())
|
||||
return
|
||||
}
|
||||
if !m.serveProxy(conn, mp, p) {
|
||||
@ -359,7 +360,7 @@ func (m *metadataManager) opMetaEvictInode(conn net.Conn, p *Packet,
|
||||
}
|
||||
|
||||
if err = mp.EvictInode(req, p); err != nil {
|
||||
err = errors.Errorf("[opMetaEvictInode] req: %s, resp: %v", req, err.Error())
|
||||
err = errors.NewErrorf("[opMetaEvictInode] req: %s, resp: %v", req, err.Error())
|
||||
}
|
||||
m.respondToClient(conn, p)
|
||||
log.LogInfof("%s [opMetaEvictInode] req: %d - %v, resp: %v, body: %s",
|
||||
@ -373,7 +374,7 @@ func (m *metadataManager) opSetAttr(conn net.Conn, p *Packet,
|
||||
if err = json.Unmarshal(p.Data, req); err != nil {
|
||||
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opSetAttr] req: %v, error: %v", req, err.Error())
|
||||
err = errors.NewErrorf("[opSetAttr] req: %v, error: %v", req, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -381,7 +382,7 @@ func (m *metadataManager) opSetAttr(conn net.Conn, p *Packet,
|
||||
if err != nil {
|
||||
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("[opSetAttr] req: %v, error: %v", req, err.Error())
|
||||
err = errors.NewErrorf("[opSetAttr] req: %v, error: %v", req, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -389,7 +390,7 @@ func (m *metadataManager) opSetAttr(conn net.Conn, p *Packet,
|
||||
return
|
||||
}
|
||||
if err = mp.SetAttr(p.Data, p); err != nil {
|
||||
err = errors.Errorf("[opSetAttr] req: %v, error: %s", req, err.Error())
|
||||
err = errors.NewErrorf("[opSetAttr] req: %v, error: %s", req, err.Error())
|
||||
}
|
||||
m.respondToClient(conn, p)
|
||||
log.LogDebugf("%s [opSetAttr] req: %d - %v, resp: %v, body: %s", remoteAddr,
|
||||
@ -434,7 +435,7 @@ func (m *metadataManager) opMetaExtentsAdd(conn net.Conn, p *Packet,
|
||||
if err != nil {
|
||||
p.PacketErrorWithBody(proto.OpNotExistErr, nil)
|
||||
m.respondToClient(conn, p)
|
||||
err = errors.Errorf("%s, response to client: %s", err.Error(),
|
||||
err = errors.NewErrorf("%s, response to client: %s", err.Error(),
|
||||
p.GetResultMsg())
|
||||
return
|
||||
}
|
||||
@ -645,13 +646,13 @@ func (m *metadataManager) opDecommissionMetaPartition(conn net.Conn,
|
||||
Status: proto.TaskFailed,
|
||||
}
|
||||
if req.AddPeer.ID == req.RemovePeer.ID {
|
||||
err = errors.Errorf("[opDecommissionMetaPartition]: AddPeer[%v] same withRemovePeer[%v]", req.AddPeer, req.RemovePeer)
|
||||
err = errors.NewErrorf("[opDecommissionMetaPartition]: AddPeer[%v] same withRemovePeer[%v]", req.AddPeer, req.RemovePeer)
|
||||
resp.Result = err.Error()
|
||||
goto end
|
||||
}
|
||||
reqData, err = json.Marshal(req)
|
||||
if err != nil {
|
||||
err = errors.Errorf("[opDecommissionMetaPartition]: partitionID= %d, "+
|
||||
err = errors.NewErrorf("[opDecommissionMetaPartition]: partitionID= %d, "+
|
||||
"Marshal %s", req.PartitionID, err)
|
||||
resp.Result = err.Error()
|
||||
goto end
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -48,7 +48,7 @@ func (m *metadataManager) respondToMaster(data interface{}) (err error) {
|
||||
}
|
||||
_, err = masterHelper.Request("POST", masterResponsePath, nil, jsonBytes)
|
||||
if err != nil {
|
||||
err = errors.Annotate(err, "try respondToMaster failed")
|
||||
err = errors.Trace(err, "try respondToMaster failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -26,15 +26,16 @@ import (
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/config"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
clusterInfo *proto.ClusterInfo
|
||||
masterHelper util.MasterHelper
|
||||
clusterInfo *proto.ClusterInfo
|
||||
masterHelper util.MasterHelper
|
||||
configTotalMem uint64
|
||||
)
|
||||
|
||||
// The MetaNode manages the dentry and inode information of the meta partitions on a meta node.
|
||||
@ -135,6 +136,19 @@ func (m *MetaNode) parseConfig(cfg *config.Config) (err error) {
|
||||
m.raftDir = cfg.GetString(cfgRaftDir)
|
||||
m.raftHeartbeatPort = cfg.GetString(cfgRaftHeartbeatPort)
|
||||
m.raftReplicatePort = cfg.GetString(cfgRaftReplicaPort)
|
||||
configTotalMem, _ = strconv.ParseUint(cfg.GetString(cfgTotalMem), 10, 64)
|
||||
if configTotalMem != 0 && configTotalMem <= util.GB {
|
||||
configTotalMem = util.GB
|
||||
}
|
||||
|
||||
total, _, err := util.GetMemInfo()
|
||||
if err == nil && configTotalMem == 0 {
|
||||
configTotalMem = total
|
||||
}
|
||||
|
||||
if configTotalMem > total {
|
||||
configTotalMem = total
|
||||
}
|
||||
|
||||
log.LogInfof("[parseConfig] load localAddr[%v].", m.localAddr)
|
||||
log.LogInfof("[parseConfig] load listen[%v].", m.listen)
|
||||
|
||||
@ -25,8 +25,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
raftproto "github.com/tiglabs/raft/proto"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -77,21 +77,21 @@ type MetaPartitionConfig struct {
|
||||
|
||||
func (c *MetaPartitionConfig) checkMeta() (err error) {
|
||||
if c.PartitionId <= 0 {
|
||||
err = errors.Errorf("[checkMeta]: partition id at least 1, "+
|
||||
err = errors.NewErrorf("[checkMeta]: partition id at least 1, "+
|
||||
"now partition id is: %d", c.PartitionId)
|
||||
return
|
||||
}
|
||||
if c.Start < 0 {
|
||||
err = errors.Errorf("[checkMeta]: start at least 0")
|
||||
err = errors.NewErrorf("[checkMeta]: start at least 0")
|
||||
return
|
||||
}
|
||||
if c.End <= c.Start {
|
||||
err = errors.Errorf("[checkMeta]: end=%v, "+
|
||||
err = errors.NewErrorf("[checkMeta]: end=%v, "+
|
||||
"start=%v; end <= start", c.End, c.Start)
|
||||
return
|
||||
}
|
||||
if len(c.Peers) <= 0 {
|
||||
err = errors.Errorf("[checkMeta]: must have peers, now peers is 0")
|
||||
err = errors.NewErrorf("[checkMeta]: must have peers, now peers is 0")
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -198,7 +198,7 @@ func (mp *metaPartition) Start() (err error) {
|
||||
mp.config.BeforeStart()
|
||||
}
|
||||
if err = mp.onStart(); err != nil {
|
||||
err = errors.Errorf("[Start]->%s", err.Error())
|
||||
err = errors.NewErrorf("[Start]->%s", err.Error())
|
||||
return
|
||||
}
|
||||
if mp.config.AfterStart != nil {
|
||||
@ -232,18 +232,18 @@ func (mp *metaPartition) onStart() (err error) {
|
||||
mp.onStop()
|
||||
}()
|
||||
if err = mp.load(); err != nil {
|
||||
err = errors.Errorf("[onStart]:load partition id=%d: %s",
|
||||
err = errors.NewErrorf("[onStart]:load partition id=%d: %s",
|
||||
mp.config.PartitionId, err.Error())
|
||||
return
|
||||
}
|
||||
mp.startSchedule(mp.applyID)
|
||||
if err = mp.startFreeList(); err != nil {
|
||||
err = errors.Errorf("[onStart] start free list id=%d: %s",
|
||||
err = errors.NewErrorf("[onStart] start free list id=%d: %s",
|
||||
mp.config.PartitionId, err.Error())
|
||||
return
|
||||
}
|
||||
if err = mp.startRaft(); err != nil {
|
||||
err = errors.Errorf("[onStart]start raft id=%d: %s",
|
||||
err = errors.NewErrorf("[onStart]start raft id=%d: %s",
|
||||
mp.config.PartitionId, err.Error())
|
||||
return
|
||||
}
|
||||
@ -520,7 +520,7 @@ func (mp *metaPartition) UpdatePartition(req *UpdatePartitionReq,
|
||||
resp.Status = proto.TaskFailed
|
||||
p := &Packet{}
|
||||
p.ResultCode = status
|
||||
err = errors.Errorf("[UpdatePartition]: %s", p.GetResultMsg())
|
||||
err = errors.NewErrorf("[UpdatePartition]: %s", p.GetResultMsg())
|
||||
resp.Result = p.GetResultMsg()
|
||||
}
|
||||
resp.Status = proto.TaskSucceeds
|
||||
@ -542,7 +542,7 @@ func (mp *metaPartition) LoadSnapshotSign(p *Packet) (err error) {
|
||||
snapshotDir)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
err = errors.Annotate(err, "[LoadSnapshotSign] 1st check snapshot")
|
||||
err = errors.Trace(err, "[LoadSnapshotSign] 1st check snapshot")
|
||||
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
|
||||
return err
|
||||
}
|
||||
@ -551,7 +551,7 @@ func (mp *metaPartition) LoadSnapshotSign(p *Packet) (err error) {
|
||||
}
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
err = errors.Annotate(err,
|
||||
err = errors.Trace(err,
|
||||
"[LoadSnapshotSign] 2st check snapshot")
|
||||
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
|
||||
return
|
||||
@ -561,7 +561,7 @@ func (mp *metaPartition) LoadSnapshotSign(p *Packet) (err error) {
|
||||
}
|
||||
data, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
err = errors.Annotate(err, "[LoadSnapshotSign] marshal")
|
||||
err = errors.Trace(err, "[LoadSnapshotSign] marshal")
|
||||
return
|
||||
}
|
||||
p.PacketOkWithBody(data)
|
||||
|
||||
@ -18,8 +18,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
@ -73,7 +73,6 @@ func (mp *metaPartition) updateVolWorker() {
|
||||
break
|
||||
}
|
||||
mp.vol.UpdatePartitions(dataView)
|
||||
log.LogDebugf("[updateVol] %v", dataView)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +209,7 @@ func (mp *metaPartition) deleteMarkedInodes(inoSlice []*Inode) {
|
||||
for _, ino := range shouldCommit {
|
||||
mp.freeList.Push(ino)
|
||||
}
|
||||
log.LogWarnf("[deleteInodeTreeOnRaftPeers] syncToRaftFollowersFreeInode inode list: %v, "+
|
||||
log.LogWarnf("[deleteInodeTreeOnRaftPeers] raft commit inode list: %v, "+
|
||||
"response %s", shouldCommit, err.Error())
|
||||
}
|
||||
log.LogDebugf("[deleteInodeTree] inode list: %v", shouldCommit)
|
||||
@ -218,6 +217,10 @@ func (mp *metaPartition) deleteMarkedInodes(inoSlice []*Inode) {
|
||||
|
||||
}
|
||||
|
||||
func (mp *metaPartition) freeInodesOnRaftFollower(inodes []byte) {
|
||||
|
||||
}
|
||||
|
||||
func (mp *metaPartition) syncToRaftFollowersFreeInode(hasDeleteInodes []byte) (err error) {
|
||||
raftPeers := mp.GetPeers()
|
||||
raftPeersError := make([]error, len(raftPeers))
|
||||
@ -272,7 +275,7 @@ func (mp *metaPartition) doDeleteMarkedInodes(ext *proto.ExtentKey) (err error)
|
||||
// get the data node view
|
||||
dp := mp.vol.GetPartition(ext.PartitionId)
|
||||
if dp == nil {
|
||||
err = errors.Errorf("unknown dataPartitionID=%d in vol",
|
||||
err = errors.NewErrorf("unknown dataPartitionID=%d in vol",
|
||||
ext.PartitionId)
|
||||
return
|
||||
}
|
||||
@ -288,24 +291,24 @@ func (mp *metaPartition) doDeleteMarkedInodes(ext *proto.ExtentKey) (err error)
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
err = errors.Errorf("get conn from pool %s, "+
|
||||
err = errors.NewErrorf("get conn from pool %s, "+
|
||||
"extents partitionId=%d, extentId=%d",
|
||||
err.Error(), ext.PartitionId, ext.ExtentId)
|
||||
return
|
||||
}
|
||||
p := NewPacketToDeleteExtent(dp, ext)
|
||||
if err = p.WriteToConn(conn); err != nil {
|
||||
err = errors.Errorf("write to dataNode %s, %s", p.GetUniqueLogId(),
|
||||
err = errors.NewErrorf("write to dataNode %s, %s", p.GetUniqueLogId(),
|
||||
err.Error())
|
||||
return
|
||||
}
|
||||
if err = p.ReadFromConn(conn, proto.ReadDeadlineTime); err != nil {
|
||||
err = errors.Errorf("read response from dataNode %s, %s",
|
||||
err = errors.NewErrorf("read response from dataNode %s, %s",
|
||||
p.GetUniqueLogId(), err.Error())
|
||||
return
|
||||
}
|
||||
if p.ResultCode != proto.OpOk {
|
||||
err = errors.Errorf("[deleteMarkedInodes] %s response: %s", p.GetUniqueLogId(),
|
||||
err = errors.NewErrorf("[deleteMarkedInodes] %s response: %s", p.GetUniqueLogId(),
|
||||
p.GetResultMsg())
|
||||
}
|
||||
log.LogDebugf("[deleteMarkedInodes] %v", p.GetUniqueLogId())
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -44,19 +44,19 @@ func (mp *metaPartition) loadMetadata() (err error) {
|
||||
metaFile := path.Join(mp.config.RootDir, metadataFile)
|
||||
fp, err := os.OpenFile(metaFile, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
err = errors.Errorf("[loadMetadata]: OpenFile %s", err.Error())
|
||||
err = errors.NewErrorf("[loadMetadata]: OpenFile %s", err.Error())
|
||||
return
|
||||
}
|
||||
defer fp.Close()
|
||||
data, err := ioutil.ReadAll(fp)
|
||||
if err != nil || len(data) == 0 {
|
||||
err = errors.Errorf("[loadMetadata]: ReadFile %s, data: %s", err.Error(),
|
||||
err = errors.NewErrorf("[loadMetadata]: ReadFile %s, data: %s", err.Error(),
|
||||
string(data))
|
||||
return
|
||||
}
|
||||
mConf := &MetaPartitionConfig{}
|
||||
if err = json.Unmarshal(data, mConf); err != nil {
|
||||
err = errors.Errorf("[loadMetadata]: Unmarshal MetaPartitionConfig %s",
|
||||
err = errors.NewErrorf("[loadMetadata]: Unmarshal MetaPartitionConfig %s",
|
||||
err.Error())
|
||||
return
|
||||
}
|
||||
@ -81,7 +81,7 @@ func (mp *metaPartition) loadInode(rootDir string) (err error) {
|
||||
}
|
||||
fp, err := os.OpenFile(filename, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
err = errors.Errorf("[loadInode] OpenFile: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadInode] OpenFile: %s", err.Error())
|
||||
return
|
||||
}
|
||||
defer fp.Close()
|
||||
@ -96,7 +96,7 @@ func (mp *metaPartition) loadInode(rootDir string) (err error) {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Errorf("[loadInode] ReadHeader: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadInode] ReadHeader: %s", err.Error())
|
||||
return
|
||||
}
|
||||
length := binary.BigEndian.Uint32(inoBuf)
|
||||
@ -109,12 +109,12 @@ func (mp *metaPartition) loadInode(rootDir string) (err error) {
|
||||
}
|
||||
_, err = io.ReadFull(reader, inoBuf)
|
||||
if err != nil {
|
||||
err = errors.Errorf("[loadInode] ReadBody: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadInode] ReadBody: %s", err.Error())
|
||||
return
|
||||
}
|
||||
ino := NewInode(0, 0)
|
||||
if err = ino.Unmarshal(inoBuf); err != nil {
|
||||
err = errors.Errorf("[loadInode] Unmarshal: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadInode] Unmarshal: %s", err.Error())
|
||||
return
|
||||
}
|
||||
mp.fsmCreateInode(ino)
|
||||
@ -138,7 +138,7 @@ func (mp *metaPartition) loadDentry(rootDir string) (err error) {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Errorf("[loadDentry] OpenFile: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadDentry] OpenFile: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ func (mp *metaPartition) loadDentry(rootDir string) (err error) {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Errorf("[loadDentry] ReadHeader: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadDentry] ReadHeader: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -168,16 +168,16 @@ func (mp *metaPartition) loadDentry(rootDir string) (err error) {
|
||||
}
|
||||
_, err = io.ReadFull(reader, dentryBuf)
|
||||
if err != nil {
|
||||
err = errors.Errorf("[loadDentry]: ReadBody: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadDentry]: ReadBody: %s", err.Error())
|
||||
return
|
||||
}
|
||||
dentry := &Dentry{}
|
||||
if err = dentry.Unmarshal(dentryBuf); err != nil {
|
||||
err = errors.Errorf("[loadDentry] Unmarshal: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadDentry] Unmarshal: %s", err.Error())
|
||||
return
|
||||
}
|
||||
if status := mp.fsmCreateDentry(dentry, true); status != proto.OpOk {
|
||||
err = errors.Errorf("[loadDentry] createDentry dentry: %v, "+
|
||||
err = errors.NewErrorf("[loadDentry] createDentry dentry: %v, "+
|
||||
"resp code: %d", status)
|
||||
return
|
||||
}
|
||||
@ -196,15 +196,15 @@ func (mp *metaPartition) loadApplyID(rootDir string) (err error) {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
err = errors.Errorf("[loadApplyID] OpenFile: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadApplyID] OpenFile: %s", err.Error())
|
||||
return
|
||||
}
|
||||
if len(data) == 0 {
|
||||
err = errors.Errorf("[loadApplyID]: ApplyID is empty")
|
||||
err = errors.NewErrorf("[loadApplyID]: ApplyID is empty")
|
||||
return
|
||||
}
|
||||
if _, err = fmt.Sscanf(string(data), "%d", &mp.applyID); err != nil {
|
||||
err = errors.Errorf("[loadApplyID] ReadApplyID: %s", err.Error())
|
||||
err = errors.NewErrorf("[loadApplyID] ReadApplyID: %s", err.Error())
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -212,7 +212,7 @@ func (mp *metaPartition) loadApplyID(rootDir string) (err error) {
|
||||
|
||||
func (mp *metaPartition) persistMetadata() (err error) {
|
||||
if err = mp.config.checkMeta(); err != nil {
|
||||
err = errors.Errorf("[persistMetadata]->%s", err.Error())
|
||||
err = errors.NewErrorf("[persistMetadata]->%s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -17,9 +17,9 @@ package metanode
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
type storeMsg struct {
|
||||
@ -50,7 +50,7 @@ func (mp *metaPartition) startSchedule(curIndex uint64) {
|
||||
} else {
|
||||
// retry again
|
||||
mp.storeChan <- msg
|
||||
err = errors.Errorf("[startSchedule]: dump partition id=%d: %v",
|
||||
err = errors.NewErrorf("[startSchedule]: dump partition id=%d: %v",
|
||||
mp.config.PartitionId, err.Error())
|
||||
log.LogErrorf(err.Error())
|
||||
exporter.NewAlarm(exporterKey)
|
||||
|
||||
@ -19,14 +19,14 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/chubaofs/chubaofs/raftstore"
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
)
|
||||
|
||||
// StartRaftServer initializes the address resolver and the raftStore server instance.
|
||||
func (m *MetaNode) startRaftServer() (err error) {
|
||||
if _, err = os.Stat(m.raftDir); err != nil {
|
||||
if err = os.MkdirAll(m.raftDir, 0755); err != nil {
|
||||
err = errors.Errorf("create raft server dir: %s", err.Error())
|
||||
err = errors.NewErrorf("create raft server dir: %s", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -44,7 +44,7 @@ func (m *MetaNode) startRaftServer() (err error) {
|
||||
}
|
||||
m.raftStore, err = raftstore.NewRaftStore(raftConf)
|
||||
if err != nil {
|
||||
err = errors.Errorf("new raftStore: %s", err.Error())
|
||||
err = errors.NewErrorf("new raftStore: %s", err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -169,6 +169,7 @@ type HeartBeatRequest struct {
|
||||
|
||||
// PartitionReport defines the partition report.
|
||||
type PartitionReport struct {
|
||||
VolName string
|
||||
PartitionID uint64
|
||||
PartitionStatus int
|
||||
Total uint64
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
)
|
||||
|
||||
//err
|
||||
@ -30,8 +30,8 @@ var (
|
||||
ErrVolNotExists = errors.New("vol not exists")
|
||||
ErrMetaPartitionNotExists = errors.New("meta partition not exists")
|
||||
ErrDataPartitionNotExists = errors.New("data partition not exists")
|
||||
ErrDataNodeNotExists = errors.New("data partition not exists")
|
||||
ErrMetaNodeNotExists = errors.New("data partition not exists")
|
||||
ErrDataNodeNotExists = errors.New("data node not exists")
|
||||
ErrMetaNodeNotExists = errors.New("meta node not exists")
|
||||
ErrDuplicateVol = errors.New("duplicate vol")
|
||||
ErrActiveDataNodesTooLess = errors.New("no enough active data node")
|
||||
ErrActiveMetaNodesTooLess = errors.New("no enough active meta node")
|
||||
|
||||
@ -113,7 +113,7 @@ const (
|
||||
OpAgain uint8 = 0xF9
|
||||
OpExistErr uint8 = 0xFA
|
||||
OpInodeFullErr uint8 = 0xFB
|
||||
OpNotLeaderErr uint8 = 0xFC
|
||||
OpTryOtherAddr uint8 = 0xFC
|
||||
OpNotPerm uint8 = 0xFD
|
||||
OpNotEmtpy uint8 = 0xFE
|
||||
OpOk uint8 = 0xF0
|
||||
@ -153,6 +153,7 @@ type Packet struct {
|
||||
Arg []byte // for create or append ops, the data contains the address
|
||||
Data []byte
|
||||
StartT int64
|
||||
mesg string
|
||||
}
|
||||
|
||||
// NewPacket returns a new packet.
|
||||
@ -317,8 +318,8 @@ func (p *Packet) GetResultMsg() (m string) {
|
||||
m = "ArgUnmatchErr"
|
||||
case OpNotExistErr:
|
||||
m = "NotExistErr"
|
||||
case OpNotLeaderErr:
|
||||
m = "NotLeaderErr"
|
||||
case OpTryOtherAddr:
|
||||
m = "TryOtherAddr"
|
||||
case OpNotPerm:
|
||||
m = "NotPerm"
|
||||
case OpNotEmtpy:
|
||||
@ -503,26 +504,35 @@ func (p *Packet) PacketErrorWithBody(code uint8, reply []byte) {
|
||||
|
||||
// GetUniqueLogId returns the unique log ID.
|
||||
func (p *Packet) GetUniqueLogId() (m string) {
|
||||
defer func() {
|
||||
if p.mesg == "" {
|
||||
p.mesg = m
|
||||
}
|
||||
m = p.mesg + fmt.Sprintf("_ResultMesg(%v)", p.GetResultMsg())
|
||||
}()
|
||||
if p.mesg != "" {
|
||||
return
|
||||
}
|
||||
m = fmt.Sprintf("Req(%v)_Partition(%v)_", p.ReqID, p.PartitionID)
|
||||
if p.ExtentType == TinyExtentType && p.Opcode == OpMarkDelete && len(p.Data) > 0 {
|
||||
ext := new(TinyExtentDeleteRecord)
|
||||
err := json.Unmarshal(p.Data, ext)
|
||||
if err == nil {
|
||||
m += fmt.Sprintf("Extent(%v)_ExtentOffset(%v)_TinyDeleteFileOffset(%v)_Size(%v)_Opcode(%v)_ResultCode(%v)",
|
||||
ext.ExtentId, ext.ExtentOffset, ext.TinyDeleteFileOffset, ext.Size, p.Opcode, p.ResultCode)
|
||||
m += fmt.Sprintf("Extent(%v)_ExtentOffset(%v)_TinyDeleteFileOffset(%v)_Size(%v)_Opcode(%v)",
|
||||
ext.ExtentId, ext.ExtentOffset, ext.TinyDeleteFileOffset, ext.Size, p.Opcode)
|
||||
return m
|
||||
}
|
||||
} else if p.Opcode == OpReadTinyDelete {
|
||||
m += fmt.Sprintf("Opcode(%v)_ResultCode(%v)", p.GetOpMsg(), p.GetResultMsg())
|
||||
m += fmt.Sprintf("Opcode(%v)", p.GetOpMsg())
|
||||
return m
|
||||
} else if p.Opcode == OpNotifyReplicasToRepair {
|
||||
m += fmt.Sprintf("Opcode(%v)_ResultCode(%v)", p.GetOpMsg(), p.GetResultMsg())
|
||||
m += fmt.Sprintf("Opcode(%v)", p.GetOpMsg())
|
||||
return m
|
||||
}
|
||||
m = fmt.Sprintf("Req(%v)_Partition(%v)_Extent(%v)_ExtentOffset(%v)_KernelOffset(%v)_"+
|
||||
"Size(%v)_Opcode(%v)_ResultCode(%v)_CRC(%v)",
|
||||
"Size(%v)_Opcode(%v)_CRC(%v)",
|
||||
p.ReqID, p.PartitionID, p.ExtentID, p.ExtentOffset,
|
||||
p.KernelOffset, p.Size, p.GetOpMsg(), p.GetResultMsg(), p.CRC)
|
||||
p.KernelOffset, p.Size, p.GetOpMsg(), p.CRC)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -15,17 +15,11 @@
|
||||
package raftstore
|
||||
|
||||
import (
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft"
|
||||
"github.com/tiglabs/raft/proto"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Error definitions for raft store partition.
|
||||
var (
|
||||
ErrNotLeader = errors.New("not a raft leader")
|
||||
)
|
||||
|
||||
// PartitionStatus is a type alias of raft.Status
|
||||
type PartitionStatus = raft.Status
|
||||
|
||||
@ -85,7 +79,7 @@ type partition struct {
|
||||
func (p *partition) ChangeMember(changeType proto.ConfChangeType, peer proto.Peer, context []byte) (
|
||||
resp interface{}, err error) {
|
||||
if !p.IsRaftLeader() {
|
||||
err = ErrNotLeader
|
||||
err = raft.ErrNotLeader
|
||||
return
|
||||
}
|
||||
future := p.raft.ChangeMember(p.id, changeType, peer, context)
|
||||
@ -141,7 +135,7 @@ func (p *partition) CommittedIndex() (applied uint64) {
|
||||
// Submit submits command data to raft log.
|
||||
func (p *partition) Submit(cmd []byte) (resp interface{}, err error) {
|
||||
if !p.IsRaftLeader() {
|
||||
err = ErrNotLeader
|
||||
err = raft.ErrNotLeader
|
||||
return
|
||||
}
|
||||
future := p.raft.Submit(p.id, cmd)
|
||||
|
||||
@ -16,8 +16,8 @@ package raftstore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@ -26,7 +26,6 @@ const (
|
||||
ActionSendToFollowers = "ActionSendToFollowers"
|
||||
ActionReceiveFromFollower = "ActionReceiveFromFollower"
|
||||
ActionWriteToClient = "ActionWriteToClient"
|
||||
ActionCheckAndAddInfos = "ActionCheckAndAddInfos"
|
||||
ActionCheckReply = "ActionCheckReply"
|
||||
|
||||
ActionPreparePkt = "ActionPreparePkt"
|
||||
|
||||
@ -24,8 +24,9 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/storage"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
"github.com/juju/errors"
|
||||
"github.com/tiglabs/raft"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -230,14 +231,13 @@ var (
|
||||
|
||||
func (p *Packet) identificationErrorResultCode(errLog string, errMsg string) {
|
||||
if strings.Contains(errLog, ActionReceiveFromFollower) || strings.Contains(errLog, ActionSendToFollowers) ||
|
||||
strings.Contains(errLog, ConnIsNullErr) || strings.Contains(errLog, ActionCheckAndAddInfos) {
|
||||
strings.Contains(errLog, ConnIsNullErr) {
|
||||
p.ResultCode = proto.OpIntraGroupNetErr
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Contains(errMsg, storage.ParameterMismatchError.Error()) ||
|
||||
} else if strings.Contains(errMsg, storage.ParameterMismatchError.Error()) ||
|
||||
strings.Contains(errMsg, ErrorUnknownOp.Error()) {
|
||||
p.ResultCode = proto.OpArgMismatchErr
|
||||
} else if strings.Contains(errMsg, proto.ErrDataPartitionNotExists.Error()) {
|
||||
p.ResultCode = proto.OpTryOtherAddr
|
||||
} else if strings.Contains(errMsg, storage.ExtentNotFoundError.Error()) ||
|
||||
strings.Contains(errMsg, storage.ExtentHasBeenDeletedError.Error()) {
|
||||
p.ResultCode = proto.OpNotExistErr
|
||||
@ -245,14 +245,8 @@ func (p *Packet) identificationErrorResultCode(errLog string, errMsg string) {
|
||||
p.ResultCode = proto.OpDiskNoSpaceErr
|
||||
} else if strings.Contains(errMsg, storage.TryAgainError.Error()) {
|
||||
p.ResultCode = proto.OpAgain
|
||||
} else if strings.Contains(errMsg, storage.NotALeaderError.Error()) {
|
||||
p.ResultCode = proto.OpNotLeaderErr
|
||||
} else if strings.Contains(errMsg, storage.ExtentNotFoundError.Error()) {
|
||||
if p.Opcode != proto.OpWrite {
|
||||
p.ResultCode = proto.OpNotExistErr
|
||||
} else {
|
||||
p.ResultCode = proto.OpIntraGroupNetErr
|
||||
}
|
||||
} else if strings.Contains(errMsg, raft.ErrNotLeader.Error()) {
|
||||
p.ResultCode = proto.OpTryOtherAddr
|
||||
} else {
|
||||
p.ResultCode = proto.OpIntraGroupNetErr
|
||||
}
|
||||
@ -260,9 +254,6 @@ func (p *Packet) identificationErrorResultCode(errLog string, errMsg string) {
|
||||
|
||||
func (p *Packet) PackErrorBody(action, msg string) {
|
||||
p.identificationErrorResultCode(action, msg)
|
||||
if p.ResultCode == proto.OpDiskNoSpaceErr || p.ResultCode == proto.OpDiskErr {
|
||||
p.ResultCode = proto.OpIntraGroupNetErr
|
||||
}
|
||||
p.Size = uint32(len([]byte(action + "_" + msg)))
|
||||
p.Data = make([]byte, p.Size)
|
||||
copy(p.Data[:int(p.Size)], []byte(action+"_"+msg))
|
||||
|
||||
@ -22,8 +22,8 @@ import (
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
@ -286,7 +286,7 @@ func (rp *ReplProtocol) checkLocalResultAndReceiveFromFollower(request *Packet,
|
||||
reply.clean()
|
||||
}()
|
||||
if err = reply.ReadFromConn(request.followerConns[index], proto.ReadDeadlineTime); err != nil {
|
||||
err = errors.Annotatef(err, "local(%v) follower(%v)", request.followerConns[index].LocalAddr().String(),
|
||||
err = errors.Trace(err, "local(%v) follower(%v)", request.followerConns[index].LocalAddr().String(),
|
||||
request.followerConns[index].RemoteAddr().String())
|
||||
return
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/sdk/data/wrapper"
|
||||
@ -56,7 +56,7 @@ func NewExtentClient(volname, master string, appendExtentKey AppendExtentKeyFunc
|
||||
client = new(ExtentClient)
|
||||
gDataWrapper, err = wrapper.NewDataPartitionWrapper(volname, master)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Init dp wrapper failed!")
|
||||
return nil, errors.Trace(err, "Init dp wrapper failed!")
|
||||
}
|
||||
client.streamers = make(map[uint64]*Streamer)
|
||||
client.appendExtentKey = appendExtentKey
|
||||
@ -165,8 +165,8 @@ func (client *ExtentClient) Write(inode uint64, offset int, data []byte, direct
|
||||
|
||||
write, err = s.IssueWriteRequest(offset, data, direct)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, prefix)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
err = errors.Trace(err, prefix)
|
||||
log.LogError(errors.Stack(err))
|
||||
exporter.NewAlarm(gDataWrapper.WarningMsg())
|
||||
}
|
||||
return
|
||||
@ -181,8 +181,8 @@ func (client *ExtentClient) Truncate(inode uint64, size int) error {
|
||||
|
||||
err := s.IssueTruncRequest(size)
|
||||
if err != nil {
|
||||
err = errors.Annotatef(err, prefix)
|
||||
log.LogError(errors.ErrorStack(err))
|
||||
err = errors.Trace(err, prefix)
|
||||
log.LogError(errors.Stack(err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/sdk/data/wrapper"
|
||||
@ -516,7 +516,7 @@ func (eh *ExtentHandler) allocateExtent() (err error) {
|
||||
|
||||
errmsg := fmt.Sprintf("allocateExtent failed: hit max retry limit")
|
||||
if err != nil {
|
||||
err = errors.Annotate(err, errmsg)
|
||||
err = errors.Trace(err, errmsg)
|
||||
} else {
|
||||
err = errors.New(errmsg)
|
||||
}
|
||||
@ -539,7 +539,7 @@ func (eh *ExtentHandler) createExtent(dp *wrapper.DataPartition) (extID int, err
|
||||
conn, err := StreamConnPool.GetConnect(dp.Hosts[0])
|
||||
if err != nil {
|
||||
// TODO unhandled error
|
||||
errors.Annotatef(err, "createExtent: failed to create connection, eh(%v) datapartionHosts(%v)", eh, dp.Hosts[0])
|
||||
errors.Trace(err, "createExtent: failed to create connection, eh(%v) datapartionHosts(%v)", eh, dp.Hosts[0])
|
||||
return
|
||||
}
|
||||
// TODO unhandled error
|
||||
@ -554,12 +554,12 @@ func (eh *ExtentHandler) createExtent(dp *wrapper.DataPartition) (extID int, err
|
||||
p := NewCreateExtentPacket(dp, eh.inode)
|
||||
if err = p.WriteToConn(conn); err != nil {
|
||||
// TODO unhandled error
|
||||
errors.Annotatef(err, "createExtent: failed to WriteToConn, packet(%v) datapartionHosts(%v)", p, dp.Hosts[0])
|
||||
errors.Trace(err, "createExtent: failed to WriteToConn, packet(%v) datapartionHosts(%v)", p, dp.Hosts[0])
|
||||
return
|
||||
}
|
||||
|
||||
if err = p.ReadFromConn(conn, proto.ReadDeadlineTime*2); err != nil {
|
||||
err = errors.Annotatef(err, "createExtent: failed to ReadFromConn, packet(%v) datapartionHosts(%v)", p, dp.Hosts[0])
|
||||
err = errors.Trace(err, "createExtent: failed to ReadFromConn, packet(%v) datapartionHosts(%v)", p, dp.Hosts[0])
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/sdk/data/wrapper"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
"hash/crc32"
|
||||
"net"
|
||||
)
|
||||
@ -66,8 +66,8 @@ func (reader *ExtentReader) Read(req *ExtentRequest) (readBytes int, err error)
|
||||
e := replyPacket.readFromConn(conn, proto.ReadDeadlineTime)
|
||||
if e != nil {
|
||||
log.LogErrorf("Extent Reader Read: failed to read from connect, readBytes(%v) err(%v)", readBytes, e)
|
||||
// Upon receiving NotALeaderError, other hosts will be retried.
|
||||
return NotALeaderError, false
|
||||
// Upon receiving TryOtherAddrError, other hosts will be retried.
|
||||
return TryOtherAddrError, false
|
||||
}
|
||||
|
||||
//log.LogDebugf("ExtentReader Read: ResultCode(%v) req(%v) reply(%v) readBytes(%v)", replyPacket.GetResultMsg(), reqPacket, replyPacket, readBytes)
|
||||
@ -97,8 +97,8 @@ func (reader *ExtentReader) Read(req *ExtentRequest) (readBytes int, err error)
|
||||
}
|
||||
|
||||
func (reader *ExtentReader) checkStreamReply(request *Packet, reply *Packet) (err error) {
|
||||
if reply.ResultCode == proto.OpNotLeaderErr {
|
||||
return NotALeaderError
|
||||
if reply.ResultCode == proto.OpTryOtherAddr {
|
||||
return TryOtherAddrError
|
||||
}
|
||||
|
||||
if reply.ResultCode != proto.OpOk {
|
||||
|
||||
@ -21,12 +21,12 @@ import (
|
||||
|
||||
"github.com/chubaofs/chubaofs/sdk/data/wrapper"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
NotALeaderError = errors.New("NotALeaderError")
|
||||
TryOtherAddrError = errors.New("TryOtherAddrError")
|
||||
)
|
||||
|
||||
const (
|
||||
@ -83,7 +83,7 @@ func (sc *StreamConn) sendToPartition(req *Packet, getReply GetReplyFunc) (err e
|
||||
}
|
||||
log.LogWarnf("sendToPartition: curr addr failed, addr(%v) reqPacket(%v) err(%v)", sc.currAddr, req, err)
|
||||
StreamConnPool.PutConnect(conn, true)
|
||||
if err != NotALeaderError {
|
||||
if err != TryOtherAddrError {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ func (sc *StreamConn) sendToPartition(req *Packet, getReply GetReplyFunc) (err e
|
||||
return
|
||||
}
|
||||
StreamConnPool.PutConnect(conn, true)
|
||||
if err != NotALeaderError {
|
||||
if err != TryOtherAddrError {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,8 +25,8 @@ import (
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/sdk/data/wrapper"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"github.com/juju/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -312,7 +312,7 @@ func (s *Streamer) doOverwrite(req *ExtentRequest, direct bool) (total int, err
|
||||
|
||||
if dp, err = gDataWrapper.GetDataPartition(req.ExtentKey.PartitionId); err != nil {
|
||||
// TODO unhandled error
|
||||
errors.Annotatef(err, "doOverwrite: ino(%v) failed to get datapartition, ek(%v)", s.inode, req.ExtentKey)
|
||||
errors.Trace(err, "doOverwrite: ino(%v) failed to get datapartition, ek(%v)", s.inode, req.ExtentKey)
|
||||
return
|
||||
}
|
||||
|
||||
@ -333,16 +333,16 @@ func (s *Streamer) doOverwrite(req *ExtentRequest, direct bool) (total int, err
|
||||
e := replyPacket.ReadFromConn(conn, proto.ReadDeadlineTime)
|
||||
if e != nil {
|
||||
log.LogErrorf("Stream Writer doOverwrite: ino(%v) failed to read from connect, err(%v)", s.inode, e)
|
||||
// Upon receiving NotALeaderError, other hosts will be retried.
|
||||
return NotALeaderError, false
|
||||
// Upon receiving TryOtherAddrError, other hosts will be retried.
|
||||
return TryOtherAddrError, false
|
||||
}
|
||||
|
||||
if replyPacket.ResultCode == proto.OpAgain {
|
||||
return nil, true
|
||||
}
|
||||
|
||||
if replyPacket.ResultCode == proto.OpNotLeaderErr {
|
||||
e = NotALeaderError
|
||||
if replyPacket.ResultCode == proto.OpTryOtherAddr {
|
||||
e = TryOtherAddrError
|
||||
}
|
||||
return e, false
|
||||
})
|
||||
|
||||
@ -23,7 +23,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util"
|
||||
@ -65,11 +65,11 @@ func NewDataPartitionWrapper(volName, masterHosts string) (w *Wrapper, err error
|
||||
w.rwPartition = make([]*DataPartition, 0)
|
||||
w.partitions = make(map[uint64]*DataPartition)
|
||||
if err = w.updateClusterInfo(); err != nil {
|
||||
err = errors.Annotate(err, "NewDataPartitionWrapper:")
|
||||
err = errors.Trace(err, "NewDataPartitionWrapper:")
|
||||
return
|
||||
}
|
||||
if err = w.updateDataPartition(); err != nil {
|
||||
err = errors.Annotate(err, "NewDataPartitionWrapper:")
|
||||
err = errors.Trace(err, "NewDataPartitionWrapper:")
|
||||
return
|
||||
}
|
||||
go w.update()
|
||||
@ -117,14 +117,14 @@ func (w *Wrapper) updateDataPartition() error {
|
||||
paras["name"] = w.volName
|
||||
msg, err := MasterHelper.Request(http.MethodGet, proto.ClientDataPartitions, paras, nil)
|
||||
if err != nil {
|
||||
return errors.Annotate(err, "updateDataPartition: request to master failed!")
|
||||
return errors.Trace(err, "updateDataPartition: request to master failed!")
|
||||
}
|
||||
|
||||
log.LogInfof("updateDataPartition: start!")
|
||||
|
||||
view := &DataPartitionView{}
|
||||
if err = json.Unmarshal(msg, view); err != nil {
|
||||
return errors.Annotatef(err, "updateDataPartition: unmarshal failed, msg(%v)", msg)
|
||||
return errors.Trace(err, "updateDataPartition: unmarshal failed, msg(%v)", msg)
|
||||
}
|
||||
|
||||
rwPartitionGroups := make([]*DataPartition, 0)
|
||||
|
||||
@ -281,6 +281,8 @@ func (mw *MetaWrapper) Rename_ll(srcParentID uint64, srcName string, dstParentID
|
||||
return statusToErrno(status)
|
||||
}
|
||||
|
||||
mw.iunlink(srcMP, inode)
|
||||
|
||||
if oldInode != 0 {
|
||||
inodeMP := mw.getPartitionByInode(oldInode)
|
||||
if inodeMP != nil {
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
@ -120,12 +120,12 @@ out:
|
||||
func (mc *MetaConn) send(req *proto.Packet) (resp *proto.Packet, err error) {
|
||||
err = req.WriteToConn(mc.conn)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Failed to write to conn, req(%v)", req)
|
||||
return nil, errors.Trace(err, "Failed to write to conn, req(%v)", req)
|
||||
}
|
||||
resp = proto.NewPacket()
|
||||
err = resp.ReadFromConn(mc.conn, proto.ReadDeadlineTime)
|
||||
if err != nil {
|
||||
return nil, errors.Annotatef(err, "Failed to read from conn, req(%v)", req)
|
||||
return nil, errors.Trace(err, "Failed to read from conn, req(%v)", req)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/juju/errors"
|
||||
"github.com/chubaofs/chubaofs/util/errors"
|
||||
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/exporter"
|
||||
|
||||
@ -15,28 +15,21 @@
|
||||
package meta
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/juju/errors"
|
||||
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"github.com/chubaofs/chubaofs/proto"
|
||||
"github.com/chubaofs/chubaofs/util/log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxSendToMaster = 3
|
||||
)
|
||||
|
||||
var (
|
||||
NotLeader = errors.New("NotLeader")
|
||||
)
|
||||
|
||||
type VolumeView struct {
|
||||
VolName string
|
||||
MetaPartitions []*MetaPartition
|
||||
|
||||
@ -27,7 +27,6 @@ var (
|
||||
NoSpaceError = errors.New("no space left on the device")
|
||||
TryAgainError = errors.New("try again")
|
||||
CrcMismatchError = errors.New("packet Crc is incorrect")
|
||||
NotALeaderError = errors.New("not a raft leader")
|
||||
NoLeaderError = errors.New("no raft leader")
|
||||
ExtentNotFoundError = errors.New("extent does not exist")
|
||||
ExtentExistsError = errors.New("extent already exists")
|
||||
|
||||
88
util/errors/errors.go
Normal file
88
util/errors/errors.go
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2018 The Chubao Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ErrorTrace struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func New(msg string) error {
|
||||
return &ErrorTrace{msg: msg}
|
||||
}
|
||||
|
||||
func NewError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
_, fileName := path.Split(file)
|
||||
|
||||
return &ErrorTrace{
|
||||
msg: fmt.Sprintf("[%v %v] %v", fileName, line, err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
func NewErrorf(format string, a ...interface{}) error {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
_, fileName := path.Split(file)
|
||||
|
||||
return &ErrorTrace{
|
||||
msg: fmt.Sprintf("[%v %v] %v", fileName, line, msg),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *ErrorTrace) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func Trace(err error, format string, a ...interface{}) error {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
_, fileName := path.Split(file)
|
||||
|
||||
if err == nil {
|
||||
return &ErrorTrace{
|
||||
msg: fmt.Sprintf("[%v %v] %v", fileName, line, msg),
|
||||
}
|
||||
}
|
||||
|
||||
return &ErrorTrace{
|
||||
msg: fmt.Sprintf("[%v %v] %v :: %v", fileName, line, msg, err),
|
||||
}
|
||||
}
|
||||
|
||||
func Stack(err error) string {
|
||||
e, ok := err.(*ErrorTrace)
|
||||
if !ok {
|
||||
return err.Error()
|
||||
}
|
||||
|
||||
var msg string
|
||||
|
||||
stack := strings.Split(e.msg, "::")
|
||||
for _, s := range stack {
|
||||
msg = fmt.Sprintf("%v\n%v", msg, strings.TrimPrefix(s, " "))
|
||||
}
|
||||
return msg
|
||||
}
|
||||
35
util/errors/errors_test.go
Normal file
35
util/errors/errors_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
func TestError01(t *testing.T) {
|
||||
err := New("first")
|
||||
err = NewError(err)
|
||||
err = Trace(err, "second(%v %v)", 2, 3)
|
||||
err = Trace(err, "third(%v %v)", 4, 5)
|
||||
t.Log(err)
|
||||
t.Log(Stack(err))
|
||||
}
|
||||
|
||||
func TestError02(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = Trace(nil, "first(%v %v)", 2, 3)
|
||||
err = Trace(err, "second(%v %v)", 4, 5)
|
||||
t.Log(err)
|
||||
t.Log(Stack(err))
|
||||
}
|
||||
|
||||
func TestError03(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = Trace(nil, "first")
|
||||
err = Trace(err, "second(%v %v)", 4, 5)
|
||||
t.Log(err)
|
||||
t.Log(Stack(err))
|
||||
}
|
||||
@ -140,21 +140,20 @@ func (writer *asyncWriter) flushToFile() {
|
||||
writer.mu.Lock()
|
||||
writer.buffer, writer.flushTmp = writer.flushTmp, writer.buffer
|
||||
writer.mu.Unlock()
|
||||
isRotateDay := false // TODO rename?
|
||||
isRotateDay := false
|
||||
select {
|
||||
case <-writer.rotateDay:
|
||||
isRotateDay = true
|
||||
default:
|
||||
}
|
||||
flushLength := writer.flushTmp.Len()
|
||||
if (writer.logSize+int64(flushLength))/(1024*1024) >= writer.
|
||||
if (writer.logSize+int64(flushLength)) >= writer.
|
||||
rollingSize || isRotateDay {
|
||||
oldFile := writer.fileName + "." + time.Now().Format(
|
||||
FileNameDateFormat) + RolledExtension
|
||||
if _, err := os.Lstat(oldFile); err != nil {
|
||||
if err := writer.rename(oldFile); err == nil {
|
||||
if fp, err := os.OpenFile(writer.fileName, FileOpt, 0666); err == nil {
|
||||
// TODO Unhandled errors
|
||||
writer.file.Close()
|
||||
writer.file = fp
|
||||
writer.logSize = 0
|
||||
@ -225,7 +224,6 @@ func newLogObject(writer *asyncWriter, prefix string, flag int) *LogObject {
|
||||
// Log defines the log struct.
|
||||
type Log struct {
|
||||
dir string
|
||||
module string
|
||||
errorLogger *LogObject
|
||||
warnLogger *LogObject
|
||||
debugLogger *LogObject
|
||||
@ -252,12 +250,10 @@ var gLog *Log = nil
|
||||
// InitLog initializes the log.
|
||||
func InitLog(dir, module string, level Level, rotate *LogRotate) (*Log, error) {
|
||||
l := new(Log)
|
||||
dir = path.Join(dir, module)
|
||||
l.dir = dir
|
||||
l.module = module
|
||||
fi, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
// TODO unhandled errors
|
||||
// TODO there are many unhandled errors in this file.
|
||||
os.MkdirAll(dir, 0755)
|
||||
} else {
|
||||
if !fi.IsDir() {
|
||||
|
||||
@ -17,7 +17,7 @@ package log
|
||||
const (
|
||||
// DefaultRollingSize Specifies at what size to roll the output log at
|
||||
// Units: MB
|
||||
DefaultRollingSize = 10 * 1024
|
||||
DefaultRollingSize = 20 * 1024 * 1024 * 1024
|
||||
// DefaultHeadRoom The tolerance for the log space limit (in megabytes)
|
||||
DefaultHeadRoom = 50 * 1024
|
||||
// DefaultHeadRatio The disk reserve space ratio
|
||||
|
||||
33
util/mem.go
33
util/mem.go
@ -16,12 +16,16 @@ package util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const MEMINFO = "/proc/meminfo"
|
||||
const (
|
||||
MEMINFO = "/proc/meminfo"
|
||||
PRO_MEM = "/proc/%d/status"
|
||||
)
|
||||
|
||||
// GetMemInfo returns the memory information.
|
||||
func GetMemInfo() (total, used uint64, err error) {
|
||||
@ -65,3 +69,30 @@ func GetMemInfo() (total, used uint64, err error) {
|
||||
used = total - free - buffer - cached
|
||||
return
|
||||
}
|
||||
|
||||
func GetProcessMemory(pid int) (used uint64, err error) {
|
||||
proFileName := fmt.Sprintf(PRO_MEM, pid)
|
||||
fp, err := os.Open(proFileName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer fp.Close()
|
||||
scan := bufio.NewScanner(fp)
|
||||
for scan.Scan() {
|
||||
line := scan.Text()
|
||||
fields := strings.Split(line, ":")
|
||||
key := fields[0]
|
||||
if key != "VmRSS" {
|
||||
continue
|
||||
}
|
||||
value := strings.TrimSpace(fields[1])
|
||||
value = strings.Replace(value, " kB", "", -1)
|
||||
used, err = strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
used = used * KB
|
||||
break
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
127
util/ump/ump.go
Normal file
127
util/ump/ump.go
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright 2018 The ChubaoFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package ump
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TpObject struct {
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
UmpType interface{}
|
||||
}
|
||||
|
||||
func NewTpObject() (o *TpObject) {
|
||||
o = new(TpObject)
|
||||
o.StartTime = time.Now()
|
||||
return
|
||||
}
|
||||
|
||||
const (
|
||||
TpMethod = "TP"
|
||||
HeartbeatMethod = "Heartbeat"
|
||||
FunctionError = "FunctionError"
|
||||
)
|
||||
|
||||
var (
|
||||
HostName string
|
||||
LogTimeForMat = "20060102150405000"
|
||||
AlarmPool = &sync.Pool{New: func() interface{} {
|
||||
return new(BusinessAlarm)
|
||||
}}
|
||||
TpObjectPool = &sync.Pool{New: func() interface{} {
|
||||
return new(TpObject)
|
||||
}}
|
||||
SystemAlivePool = &sync.Pool{New: func() interface{} {
|
||||
return new(SystemAlive)
|
||||
}}
|
||||
FunctionTpPool = &sync.Pool{New: func() interface{} {
|
||||
return new(FunctionTp)
|
||||
}}
|
||||
)
|
||||
|
||||
func InitUmp(module, dataDir string) {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
if err := initLogName(module, dataDir); err != nil {
|
||||
panic("init UMP Monitor failed " + err.Error())
|
||||
}
|
||||
|
||||
backGroudWrite()
|
||||
}
|
||||
|
||||
func BeforeTP(key string) (o *TpObject) {
|
||||
o = TpObjectPool.Get().(*TpObject)
|
||||
o.StartTime = time.Now()
|
||||
tp := FunctionTpPool.Get().(*FunctionTp)
|
||||
tp.HostName = HostName
|
||||
tp.Time = time.Now().Format(LogTimeForMat)
|
||||
tp.Key = key
|
||||
tp.ProcessState = "0"
|
||||
o.UmpType = tp
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func AfterTP(o *TpObject, err error) {
|
||||
tp := o.UmpType.(*FunctionTp)
|
||||
tp.ElapsedTime = strconv.FormatInt((int64)(time.Since(o.StartTime)/1e6), 10)
|
||||
TpObjectPool.Put(o)
|
||||
tp.ProcessState = "0"
|
||||
if err != nil {
|
||||
tp.ProcessState = "1"
|
||||
}
|
||||
select {
|
||||
case FunctionTpLogWrite.logCh <- tp:
|
||||
default:
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func Alive(key string) {
|
||||
alive := SystemAlivePool.Get().(*SystemAlive)
|
||||
alive.HostName = HostName
|
||||
alive.Key = key
|
||||
alive.Time = time.Now().Format(LogTimeForMat)
|
||||
select {
|
||||
case SystemAliveLogWrite.logCh <- alive:
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Alarm(key, detail string) {
|
||||
alarm := AlarmPool.Get().(*BusinessAlarm)
|
||||
alarm.Time = time.Now().Format(LogTimeForMat)
|
||||
alarm.Key = key
|
||||
alarm.HostName = HostName
|
||||
alarm.BusinessType = "0"
|
||||
alarm.Value = "0"
|
||||
alarm.Detail = detail
|
||||
if len(alarm.Detail) > 512 {
|
||||
rs := []rune(detail)
|
||||
alarm.Detail = string(rs[0:510])
|
||||
}
|
||||
|
||||
select {
|
||||
case BusinessAlarmLogWrite.logCh <- alarm:
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
205
util/ump/ump_async_log.go
Normal file
205
util/ump/ump_async_log.go
Normal file
@ -0,0 +1,205 @@
|
||||
// Copyright 2018 The ChubaoFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package ump
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FunctionTp struct {
|
||||
Time string `json:"time"`
|
||||
Key string `json:"key"`
|
||||
HostName string `json:"hostname"`
|
||||
ProcessState string `json:"processState"`
|
||||
ElapsedTime string `json:"elapsedTime"`
|
||||
}
|
||||
|
||||
type SystemAlive struct {
|
||||
Key string `json:"key"`
|
||||
HostName string `json:"hostname"`
|
||||
Time string `json:"time"`
|
||||
}
|
||||
|
||||
type BusinessAlarm struct {
|
||||
Time string `json:"time"`
|
||||
Key string `json:"key"`
|
||||
HostName string `json:"hostname"`
|
||||
BusinessType string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Detail string `json:"detail"`
|
||||
}
|
||||
|
||||
const (
|
||||
FunctionTpSufixx = "tp.log"
|
||||
SystemAliveSufixx = "alive.log"
|
||||
BusinessAlarmSufixx = "business.log"
|
||||
LogFileOpt = os.O_RDWR | os.O_CREATE | os.O_APPEND
|
||||
ChSize = 102400
|
||||
BusinessAlarmType = "BusinessAlarm"
|
||||
SystemAliveType = "SystemAlive"
|
||||
FunctionTpType = "FunctionTp"
|
||||
HostNameFile = "/proc/sys/kernel/hostname"
|
||||
MaxLogSize = 1024 * 1024 * 10
|
||||
)
|
||||
|
||||
var (
|
||||
FunctionTpLogWrite = &LogWrite{logCh: make(chan interface{}, ChSize)}
|
||||
SystemAliveLogWrite = &LogWrite{logCh: make(chan interface{}, ChSize)}
|
||||
BusinessAlarmLogWrite = &LogWrite{logCh: make(chan interface{}, ChSize)}
|
||||
UmpDataDir = "/export/home/tomcat/UMP-Monitor/logs/"
|
||||
)
|
||||
|
||||
type LogWrite struct {
|
||||
logCh chan interface{}
|
||||
logName string
|
||||
logSize int64
|
||||
seq int
|
||||
logSufixx string
|
||||
logFp *os.File
|
||||
sigCh chan bool
|
||||
}
|
||||
|
||||
func (lw *LogWrite) initLogFp(sufixx string) (err error) {
|
||||
var fi os.FileInfo
|
||||
lw.seq = 0
|
||||
lw.sigCh = make(chan bool, 1)
|
||||
lw.logSufixx = sufixx
|
||||
lw.logName = fmt.Sprintf("%s%s%s", UmpDataDir, "ump_", lw.logSufixx)
|
||||
if lw.logFp, err = os.OpenFile(lw.logName, LogFileOpt, 0666); err != nil {
|
||||
return
|
||||
}
|
||||
if fi, err = lw.logFp.Stat(); err != nil {
|
||||
return
|
||||
}
|
||||
lw.logSize = fi.Size()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (lw *LogWrite) backGroundCheckFile() (err error) {
|
||||
if lw.logSize <= MaxLogSize {
|
||||
return
|
||||
}
|
||||
lw.logFp.Close()
|
||||
lw.seq++
|
||||
if lw.seq > 3 {
|
||||
lw.seq = 1
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s%s%s.%d", UmpDataDir, "ump_", lw.logSufixx, lw.seq)
|
||||
if _, err = os.Stat(name); err == nil {
|
||||
os.Remove(name)
|
||||
}
|
||||
os.Rename(lw.logName, name)
|
||||
|
||||
if lw.logFp, err = os.OpenFile(lw.logName, LogFileOpt, 0666); err != nil {
|
||||
lw.seq--
|
||||
return
|
||||
}
|
||||
if err = os.Truncate(lw.logName, 0); err != nil {
|
||||
lw.seq--
|
||||
return
|
||||
}
|
||||
lw.logSize = 0
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (lw *LogWrite) backGroundWrite(umpType string) {
|
||||
var (
|
||||
body []byte
|
||||
)
|
||||
|
||||
for {
|
||||
obj := <-lw.logCh
|
||||
switch umpType {
|
||||
case FunctionTpType:
|
||||
tp := obj.(*FunctionTp)
|
||||
body, _ = json.Marshal(tp)
|
||||
FunctionTpPool.Put(tp)
|
||||
case SystemAliveType:
|
||||
alive := obj.(*SystemAlive)
|
||||
body, _ = json.Marshal(alive)
|
||||
SystemAlivePool.Put(alive)
|
||||
case BusinessAlarmType:
|
||||
alarm := obj.(*BusinessAlarm)
|
||||
body, _ = json.Marshal(alarm)
|
||||
AlarmPool.Put(alarm)
|
||||
}
|
||||
if lw.backGroundCheckFile() != nil {
|
||||
continue
|
||||
}
|
||||
body = append(body, []byte("\n")...)
|
||||
lw.logFp.Write(body)
|
||||
lw.logSize += (int64)(len(body))
|
||||
}
|
||||
}
|
||||
|
||||
func initLogName(module, dataDir string) (err error) {
|
||||
if dataDir != "" {
|
||||
UmpDataDir = dataDir
|
||||
if !strings.HasSuffix(UmpDataDir, "/") {
|
||||
UmpDataDir += "/"
|
||||
}
|
||||
}
|
||||
if err = os.MkdirAll(UmpDataDir, 0666); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if HostName, err = GetLocalIpAddr(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = FunctionTpLogWrite.initLogFp(module + "_" + FunctionTpSufixx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = SystemAliveLogWrite.initLogFp(module + "_" + SystemAliveSufixx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = BusinessAlarmLogWrite.initLogFp(module + "_" + BusinessAlarmSufixx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func GetLocalIpAddr() (localAddr string, err error) {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if ipNet, isIpNet := addr.(*net.IPNet); isIpNet && !ipNet.IP.IsLoopback() {
|
||||
if ipv4 := ipNet.IP.To4(); ipv4 != nil {
|
||||
localAddr = ipv4.String()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("cannot get local ip")
|
||||
return
|
||||
}
|
||||
|
||||
func backGroudWrite() {
|
||||
go FunctionTpLogWrite.backGroundWrite(FunctionTpType)
|
||||
go SystemAliveLogWrite.backGroundWrite(SystemAliveType)
|
||||
go BusinessAlarmLogWrite.backGroundWrite(BusinessAlarmType)
|
||||
}
|
||||
23
vendor/github.com/juju/errors/.gitignore
generated
vendored
23
vendor/github.com/juju/errors/.gitignore
generated
vendored
@ -1,23 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
191
vendor/github.com/juju/errors/LICENSE
generated
vendored
191
vendor/github.com/juju/errors/LICENSE
generated
vendored
@ -1,191 +0,0 @@
|
||||
All files in this repository are licensed as follows. If you contribute
|
||||
to this repository, it is assumed that you license your contribution
|
||||
under the same license unless you state otherwise.
|
||||
|
||||
All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file.
|
||||
|
||||
This software is licensed under the LGPLv3, included below.
|
||||
|
||||
As a special exception to the GNU Lesser General Public License version 3
|
||||
("LGPL3"), the copyright holders of this Library give you permission to
|
||||
convey to a third party a Combined Work that links statically or dynamically
|
||||
to this Library without providing any Minimal Corresponding Source or
|
||||
Minimal Application Code as set out in 4d or providing the installation
|
||||
information set out in section 4e, provided that you comply with the other
|
||||
provisions of LGPL3 and provided that you meet, for the Application the
|
||||
terms and conditions of the license(s) which apply to the Application.
|
||||
|
||||
Except as stated in this special exception, the provisions of LGPL3 will
|
||||
continue to comply in full to this Library. If you modify this Library, you
|
||||
may apply this exception to your version of this Library, but you are not
|
||||
obliged to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version. This exception does not (and cannot) modify any
|
||||
license terms which apply to the Application, with which you must still
|
||||
comply.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
11
vendor/github.com/juju/errors/Makefile
generated
vendored
11
vendor/github.com/juju/errors/Makefile
generated
vendored
@ -1,11 +0,0 @@
|
||||
default: check
|
||||
|
||||
check:
|
||||
go test && go test -compiler gccgo
|
||||
|
||||
docs:
|
||||
godoc2md github.com/juju/errors > README.md
|
||||
sed -i 's|\[godoc-link-here\]|[](https://godoc.org/github.com/juju/errors)|' README.md
|
||||
|
||||
|
||||
.PHONY: default check docs
|
||||
543
vendor/github.com/juju/errors/README.md
generated
vendored
543
vendor/github.com/juju/errors/README.md
generated
vendored
@ -1,543 +0,0 @@
|
||||
|
||||
# errors
|
||||
import "github.com/juju/errors"
|
||||
|
||||
[](https://godoc.org/github.com/juju/errors)
|
||||
|
||||
The juju/errors provides an easy way to annotate errors without losing the
|
||||
orginal error context.
|
||||
|
||||
The exported `New` and `Errorf` functions are designed to replace the
|
||||
`errors.New` and `fmt.Errorf` functions respectively. The same underlying
|
||||
error is there, but the package also records the location at which the error
|
||||
was created.
|
||||
|
||||
A primary use case for this library is to add extra context any time an
|
||||
error is returned from a function.
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
This instead becomes:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
which just records the file and line number of the Trace call, or
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Annotate(err, "more context")
|
||||
}
|
||||
|
||||
which also adds an annotation to the error.
|
||||
|
||||
When you want to check to see if an error is of a particular type, a helper
|
||||
function is normally exported by the package that returned the error, like the
|
||||
`os` package does. The underlying cause of the error is available using the
|
||||
`Cause` function.
|
||||
|
||||
|
||||
os.IsNotExist(errors.Cause(err))
|
||||
|
||||
The result of the `Error()` call on an annotated error is the annotations joined
|
||||
with colons, then the result of the `Error()` method for the underlying error
|
||||
that was the cause.
|
||||
|
||||
|
||||
err := errors.Errorf("original")
|
||||
err = errors.Annotatef(err, "context")
|
||||
err = errors.Annotatef(err, "more context")
|
||||
err.Error() -> "more context: context: original"
|
||||
|
||||
Obviously recording the file, line and functions is not very useful if you
|
||||
cannot get them back out again.
|
||||
|
||||
|
||||
errors.ErrorStack(err)
|
||||
|
||||
will return something like:
|
||||
|
||||
|
||||
first error
|
||||
github.com/juju/errors/annotation_test.go:193:
|
||||
github.com/juju/errors/annotation_test.go:194: annotation
|
||||
github.com/juju/errors/annotation_test.go:195:
|
||||
github.com/juju/errors/annotation_test.go:196: more context
|
||||
github.com/juju/errors/annotation_test.go:197:
|
||||
|
||||
The first error was generated by an external system, so there was no location
|
||||
associated. The second, fourth, and last lines were generated with Trace calls,
|
||||
and the other two through Annotate.
|
||||
|
||||
Sometimes when responding to an error you want to return a more specific error
|
||||
for the situation.
|
||||
|
||||
|
||||
if err := FindField(field); err != nil {
|
||||
return errors.Wrap(err, errors.NotFoundf(field))
|
||||
}
|
||||
|
||||
This returns an error where the complete error stack is still available, and
|
||||
`errors.Cause()` will return the `NotFound` error.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## func AlreadyExistsf
|
||||
``` go
|
||||
func AlreadyExistsf(format string, args ...interface{}) error
|
||||
```
|
||||
AlreadyExistsf returns an error which satisfies IsAlreadyExists().
|
||||
|
||||
|
||||
## func Annotate
|
||||
``` go
|
||||
func Annotate(other error, message string) error
|
||||
```
|
||||
Annotate is used to add extra context to an existing error. The location of
|
||||
the Annotate call is recorded with the annotations. The file, line and
|
||||
function are also recorded.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Annotate(err, "failed to frombulate")
|
||||
}
|
||||
|
||||
|
||||
## func Annotatef
|
||||
``` go
|
||||
func Annotatef(other error, format string, args ...interface{}) error
|
||||
```
|
||||
Annotatef is used to add extra context to an existing error. The location of
|
||||
the Annotate call is recorded with the annotations. The file, line and
|
||||
function are also recorded.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Annotatef(err, "failed to frombulate the %s", arg)
|
||||
}
|
||||
|
||||
|
||||
## func Cause
|
||||
``` go
|
||||
func Cause(err error) error
|
||||
```
|
||||
Cause returns the cause of the given error. This will be either the
|
||||
original error, or the result of a Wrap or Mask call.
|
||||
|
||||
Cause is the usual way to diagnose errors that may have been wrapped by
|
||||
the other errors functions.
|
||||
|
||||
|
||||
## func DeferredAnnotatef
|
||||
``` go
|
||||
func DeferredAnnotatef(err *error, format string, args ...interface{})
|
||||
```
|
||||
DeferredAnnotatef annotates the given error (when it is not nil) with the given
|
||||
format string and arguments (like fmt.Sprintf). If *err is nil, DeferredAnnotatef
|
||||
does nothing. This method is used in a defer statement in order to annotate any
|
||||
resulting error with the same message.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
defer DeferredAnnotatef(&err, "failed to frombulate the %s", arg)
|
||||
|
||||
|
||||
## func Details
|
||||
``` go
|
||||
func Details(err error) string
|
||||
```
|
||||
Details returns information about the stack of errors wrapped by err, in
|
||||
the format:
|
||||
|
||||
|
||||
[{filename:99: error one} {otherfile:55: cause of error one}]
|
||||
|
||||
This is a terse alternative to ErrorStack as it returns a single line.
|
||||
|
||||
|
||||
## func ErrorStack
|
||||
``` go
|
||||
func ErrorStack(err error) string
|
||||
```
|
||||
ErrorStack returns a string representation of the annotated error. If the
|
||||
error passed as the parameter is not an annotated error, the result is
|
||||
simply the result of the Error() method on that error.
|
||||
|
||||
If the error is an annotated error, a multi-line string is returned where
|
||||
each line represents one entry in the annotation stack. The full filename
|
||||
from the call stack is used in the output.
|
||||
|
||||
|
||||
first error
|
||||
github.com/juju/errors/annotation_test.go:193:
|
||||
github.com/juju/errors/annotation_test.go:194: annotation
|
||||
github.com/juju/errors/annotation_test.go:195:
|
||||
github.com/juju/errors/annotation_test.go:196: more context
|
||||
github.com/juju/errors/annotation_test.go:197:
|
||||
|
||||
|
||||
## func Errorf
|
||||
``` go
|
||||
func Errorf(format string, args ...interface{}) error
|
||||
```
|
||||
Errorf creates a new annotated error and records the location that the
|
||||
error is created. This should be a drop in replacement for fmt.Errorf.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
return errors.Errorf("validation failed: %s", message)
|
||||
|
||||
|
||||
## func IsAlreadyExists
|
||||
``` go
|
||||
func IsAlreadyExists(err error) bool
|
||||
```
|
||||
IsAlreadyExists reports whether the error was created with
|
||||
AlreadyExistsf() or NewAlreadyExists().
|
||||
|
||||
|
||||
## func IsNotFound
|
||||
``` go
|
||||
func IsNotFound(err error) bool
|
||||
```
|
||||
IsNotFound reports whether err was created with NotFoundf() or
|
||||
NewNotFound().
|
||||
|
||||
|
||||
## func IsNotImplemented
|
||||
``` go
|
||||
func IsNotImplemented(err error) bool
|
||||
```
|
||||
IsNotImplemented reports whether err was created with
|
||||
NotImplementedf() or NewNotImplemented().
|
||||
|
||||
|
||||
## func IsNotSupported
|
||||
``` go
|
||||
func IsNotSupported(err error) bool
|
||||
```
|
||||
IsNotSupported reports whether the error was created with
|
||||
NotSupportedf() or NewNotSupported().
|
||||
|
||||
|
||||
## func IsNotValid
|
||||
``` go
|
||||
func IsNotValid(err error) bool
|
||||
```
|
||||
IsNotValid reports whether the error was created with NotValidf() or
|
||||
NewNotValid().
|
||||
|
||||
|
||||
## func IsUnauthorized
|
||||
``` go
|
||||
func IsUnauthorized(err error) bool
|
||||
```
|
||||
IsUnauthorized reports whether err was created with Unauthorizedf() or
|
||||
NewUnauthorized().
|
||||
|
||||
|
||||
## func Mask
|
||||
``` go
|
||||
func Mask(other error) error
|
||||
```
|
||||
Mask hides the underlying error type, and records the location of the masking.
|
||||
|
||||
|
||||
## func Maskf
|
||||
``` go
|
||||
func Maskf(other error, format string, args ...interface{}) error
|
||||
```
|
||||
Mask masks the given error with the given format string and arguments (like
|
||||
fmt.Sprintf), returning a new error that maintains the error stack, but
|
||||
hides the underlying error type. The error string still contains the full
|
||||
annotations. If you want to hide the annotations, call Wrap.
|
||||
|
||||
|
||||
## func New
|
||||
``` go
|
||||
func New(message string) error
|
||||
```
|
||||
New is a drop in replacement for the standard libary errors module that records
|
||||
the location that the error is created.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
return errors.New("validation failed")
|
||||
|
||||
|
||||
## func NewAlreadyExists
|
||||
``` go
|
||||
func NewAlreadyExists(err error, msg string) error
|
||||
```
|
||||
NewAlreadyExists returns an error which wraps err and satisfies
|
||||
IsAlreadyExists().
|
||||
|
||||
|
||||
## func NewNotFound
|
||||
``` go
|
||||
func NewNotFound(err error, msg string) error
|
||||
```
|
||||
NewNotFound returns an error which wraps err that satisfies
|
||||
IsNotFound().
|
||||
|
||||
|
||||
## func NewNotImplemented
|
||||
``` go
|
||||
func NewNotImplemented(err error, msg string) error
|
||||
```
|
||||
NewNotImplemented returns an error which wraps err and satisfies
|
||||
IsNotImplemented().
|
||||
|
||||
|
||||
## func NewNotSupported
|
||||
``` go
|
||||
func NewNotSupported(err error, msg string) error
|
||||
```
|
||||
NewNotSupported returns an error which wraps err and satisfies
|
||||
IsNotSupported().
|
||||
|
||||
|
||||
## func NewNotValid
|
||||
``` go
|
||||
func NewNotValid(err error, msg string) error
|
||||
```
|
||||
NewNotValid returns an error which wraps err and satisfies IsNotValid().
|
||||
|
||||
|
||||
## func NewUnauthorized
|
||||
``` go
|
||||
func NewUnauthorized(err error, msg string) error
|
||||
```
|
||||
NewUnauthorized returns an error which wraps err and satisfies
|
||||
IsUnauthorized().
|
||||
|
||||
|
||||
## func NotFoundf
|
||||
``` go
|
||||
func NotFoundf(format string, args ...interface{}) error
|
||||
```
|
||||
NotFoundf returns an error which satisfies IsNotFound().
|
||||
|
||||
|
||||
## func NotImplementedf
|
||||
``` go
|
||||
func NotImplementedf(format string, args ...interface{}) error
|
||||
```
|
||||
NotImplementedf returns an error which satisfies IsNotImplemented().
|
||||
|
||||
|
||||
## func NotSupportedf
|
||||
``` go
|
||||
func NotSupportedf(format string, args ...interface{}) error
|
||||
```
|
||||
NotSupportedf returns an error which satisfies IsNotSupported().
|
||||
|
||||
|
||||
## func NotValidf
|
||||
``` go
|
||||
func NotValidf(format string, args ...interface{}) error
|
||||
```
|
||||
NotValidf returns an error which satisfies IsNotValid().
|
||||
|
||||
|
||||
## func Trace
|
||||
``` go
|
||||
func Trace(other error) error
|
||||
```
|
||||
Trace adds the location of the Trace call to the stack. The Cause of the
|
||||
resulting error is the same as the error parameter. If the other error is
|
||||
nil, the result will be nil.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
|
||||
## func Unauthorizedf
|
||||
``` go
|
||||
func Unauthorizedf(format string, args ...interface{}) error
|
||||
```
|
||||
Unauthorizedf returns an error which satisfies IsUnauthorized().
|
||||
|
||||
|
||||
## func Forbiddenf
|
||||
``` go
|
||||
func Forbiddenf(format string, args ...interface{}) error
|
||||
```
|
||||
Forbiddenf returns an error which satisfies IsForbidden().
|
||||
|
||||
|
||||
## func Wrap
|
||||
``` go
|
||||
func Wrap(other, newDescriptive error) error
|
||||
```
|
||||
Wrap changes the Cause of the error. The location of the Wrap call is also
|
||||
stored in the error stack.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
newErr := &packageError{"more context", private_value}
|
||||
return errors.Wrap(err, newErr)
|
||||
}
|
||||
|
||||
|
||||
## func Wrapf
|
||||
``` go
|
||||
func Wrapf(other, newDescriptive error, format string, args ...interface{}) error
|
||||
```
|
||||
Wrapf changes the Cause of the error, and adds an annotation. The location
|
||||
of the Wrap call is also stored in the error stack.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Wrapf(err, simpleErrorType, "invalid value %q", value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
## type Err
|
||||
``` go
|
||||
type Err struct {
|
||||
// contains filtered or unexported fields
|
||||
}
|
||||
```
|
||||
Err holds a description of an error along with information about
|
||||
where the error was created.
|
||||
|
||||
It may be embedded in custom error types to add extra information that
|
||||
this errors package can understand.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### func NewErr
|
||||
``` go
|
||||
func NewErr(format string, args ...interface{}) Err
|
||||
```
|
||||
NewErr is used to return an Err for the purpose of embedding in other
|
||||
structures. The location is not specified, and needs to be set with a call
|
||||
to SetLocation.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
type FooError struct {
|
||||
errors.Err
|
||||
code int
|
||||
}
|
||||
|
||||
func NewFooError(code int) error {
|
||||
err := &FooError{errors.NewErr("foo"), code}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
### func (\*Err) Cause
|
||||
``` go
|
||||
func (e *Err) Cause() error
|
||||
```
|
||||
The Cause of an error is the most recent error in the error stack that
|
||||
meets one of these criteria: the original error that was raised; the new
|
||||
error that was passed into the Wrap function; the most recently masked
|
||||
error; or nil if the error itself is considered the Cause. Normally this
|
||||
method is not invoked directly, but instead through the Cause stand alone
|
||||
function.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) Error
|
||||
``` go
|
||||
func (e *Err) Error() string
|
||||
```
|
||||
Error implements error.Error.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) Location
|
||||
``` go
|
||||
func (e *Err) Location() (filename string, line int)
|
||||
```
|
||||
Location is the file and line of where the error was most recently
|
||||
created or annotated.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) Message
|
||||
``` go
|
||||
func (e *Err) Message() string
|
||||
```
|
||||
Message returns the message stored with the most recent location. This is
|
||||
the empty string if the most recent call was Trace, or the message stored
|
||||
with Annotate or Mask.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) SetLocation
|
||||
``` go
|
||||
func (e *Err) SetLocation(callDepth int)
|
||||
```
|
||||
SetLocation records the source location of the error at callDepth stack
|
||||
frames above the call.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) StackTrace
|
||||
``` go
|
||||
func (e *Err) StackTrace() []string
|
||||
```
|
||||
StackTrace returns one string for each location recorded in the stack of
|
||||
errors. The first value is the originating error, with a line for each
|
||||
other annotation or tracing of the error.
|
||||
|
||||
|
||||
|
||||
### func (\*Err) Underlying
|
||||
``` go
|
||||
func (e *Err) Underlying() error
|
||||
```
|
||||
Underlying returns the previous error in the error stack, if any. A client
|
||||
should not ever really call this method. It is used to build the error
|
||||
stack and should not be introspected by client calls. Or more
|
||||
specifically, clients should not depend on anything but the `Cause` of an
|
||||
error.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- - -
|
||||
Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
|
||||
81
vendor/github.com/juju/errors/doc.go
generated
vendored
81
vendor/github.com/juju/errors/doc.go
generated
vendored
@ -1,81 +0,0 @@
|
||||
// Copyright 2013, 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3, see LICENCE file for details.
|
||||
|
||||
/*
|
||||
[godoc-link-here]
|
||||
|
||||
The juju/errors provides an easy way to annotate errors without losing the
|
||||
orginal error context.
|
||||
|
||||
The exported `New` and `Errorf` functions are designed to replace the
|
||||
`errors.New` and `fmt.Errorf` functions respectively. The same underlying
|
||||
error is there, but the package also records the location at which the error
|
||||
was created.
|
||||
|
||||
A primary use case for this library is to add extra context any time an
|
||||
error is returned from a function.
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
This instead becomes:
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
which just records the file and line number of the Trace call, or
|
||||
|
||||
if err := SomeFunc(); err != nil {
|
||||
return errors.Annotate(err, "more context")
|
||||
}
|
||||
|
||||
which also adds an annotation to the error.
|
||||
|
||||
When you want to check to see if an error is of a particular type, a helper
|
||||
function is normally exported by the package that returned the error, like the
|
||||
`os` package does. The underlying cause of the error is available using the
|
||||
`Cause` function.
|
||||
|
||||
os.IsNotExist(errors.Cause(err))
|
||||
|
||||
The result of the `Error()` call on an annotated error is the annotations joined
|
||||
with colons, then the result of the `Error()` method for the underlying error
|
||||
that was the cause.
|
||||
|
||||
err := errors.Errorf("original")
|
||||
err = errors.Annotatef(err, "context")
|
||||
err = errors.Annotatef(err, "more context")
|
||||
err.Error() -> "more context: context: original"
|
||||
|
||||
Obviously recording the file, line and functions is not very useful if you
|
||||
cannot get them back out again.
|
||||
|
||||
errors.ErrorStack(err)
|
||||
|
||||
will return something like:
|
||||
|
||||
first error
|
||||
github.com/juju/errors/annotation_test.go:193:
|
||||
github.com/juju/errors/annotation_test.go:194: annotation
|
||||
github.com/juju/errors/annotation_test.go:195:
|
||||
github.com/juju/errors/annotation_test.go:196: more context
|
||||
github.com/juju/errors/annotation_test.go:197:
|
||||
|
||||
The first error was generated by an external system, so there was no location
|
||||
associated. The second, fourth, and last lines were generated with Trace calls,
|
||||
and the other two through Annotate.
|
||||
|
||||
Sometimes when responding to an error you want to return a more specific error
|
||||
for the situation.
|
||||
|
||||
if err := FindField(field); err != nil {
|
||||
return errors.Wrap(err, errors.NotFoundf(field))
|
||||
}
|
||||
|
||||
This returns an error where the complete error stack is still available, and
|
||||
`errors.Cause()` will return the `NotFound` error.
|
||||
|
||||
*/
|
||||
package errors
|
||||
172
vendor/github.com/juju/errors/error.go
generated
vendored
172
vendor/github.com/juju/errors/error.go
generated
vendored
@ -1,172 +0,0 @@
|
||||
// Copyright 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3, see LICENCE file for details.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Err holds a description of an error along with information about
|
||||
// where the error was created.
|
||||
//
|
||||
// It may be embedded in custom error types to add extra information that
|
||||
// this errors package can understand.
|
||||
type Err struct {
|
||||
// message holds an annotation of the error.
|
||||
message string
|
||||
|
||||
// cause holds the cause of the error as returned
|
||||
// by the Cause method.
|
||||
cause error
|
||||
|
||||
// previous holds the previous error in the error stack, if any.
|
||||
previous error
|
||||
|
||||
// file and line hold the source code location where the error was
|
||||
// created.
|
||||
file string
|
||||
line int
|
||||
}
|
||||
|
||||
// NewErr is used to return an Err for the purpose of embedding in other
|
||||
// structures. The location is not specified, and needs to be set with a call
|
||||
// to SetLocation.
|
||||
//
|
||||
// For example:
|
||||
// type FooError struct {
|
||||
// errors.Err
|
||||
// code int
|
||||
// }
|
||||
//
|
||||
// func NewFooError(code int) error {
|
||||
// err := &FooError{errors.NewErr("foo"), code}
|
||||
// err.SetLocation(1)
|
||||
// return err
|
||||
// }
|
||||
func NewErr(format string, args ...interface{}) Err {
|
||||
return Err{
|
||||
message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
|
||||
// NewErrWithCause is used to return an Err with case by other error for the purpose of embedding in other
|
||||
// structures. The location is not specified, and needs to be set with a call
|
||||
// to SetLocation.
|
||||
//
|
||||
// For example:
|
||||
// type FooError struct {
|
||||
// errors.Err
|
||||
// code int
|
||||
// }
|
||||
//
|
||||
// func (e *FooError) Annotate(format string, args ...interface{}) error {
|
||||
// err := &FooError{errors.NewErrWithCause(e.Err, format, args...), e.code}
|
||||
// err.SetLocation(1)
|
||||
// return err
|
||||
// })
|
||||
func NewErrWithCause(other error, format string, args ...interface{}) Err {
|
||||
return Err{
|
||||
message: fmt.Sprintf(format, args...),
|
||||
cause: Cause(other),
|
||||
previous: other,
|
||||
}
|
||||
}
|
||||
|
||||
// Location is the file and line of where the error was most recently
|
||||
// created or annotated.
|
||||
func (e *Err) Location() (filename string, line int) {
|
||||
return e.file, e.line
|
||||
}
|
||||
|
||||
// Underlying returns the previous error in the error stack, if any. A client
|
||||
// should not ever really call this method. It is used to build the error
|
||||
// stack and should not be introspected by client calls. Or more
|
||||
// specifically, clients should not depend on anything but the `Cause` of an
|
||||
// error.
|
||||
func (e *Err) Underlying() error {
|
||||
return e.previous
|
||||
}
|
||||
|
||||
// The Cause of an error is the most recent error in the error stack that
|
||||
// meets one of these criteria: the original error that was raised; the new
|
||||
// error that was passed into the Wrap function; the most recently masked
|
||||
// error; or nil if the error itself is considered the Cause. Normally this
|
||||
// method is not invoked directly, but instead through the Cause stand alone
|
||||
// function.
|
||||
func (e *Err) Cause() error {
|
||||
return e.cause
|
||||
}
|
||||
|
||||
// Message returns the message stored with the most recent location. This is
|
||||
// the empty string if the most recent call was Trace, or the message stored
|
||||
// with Annotate or Mask.
|
||||
func (e *Err) Message() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
// Error implements error.Error.
|
||||
func (e *Err) Error() string {
|
||||
// We want to walk up the stack of errors showing the annotations
|
||||
// as long as the cause is the same.
|
||||
err := e.previous
|
||||
if !sameError(Cause(err), e.cause) && e.cause != nil {
|
||||
err = e.cause
|
||||
}
|
||||
switch {
|
||||
case err == nil:
|
||||
return e.message
|
||||
case e.message == "":
|
||||
return err.Error()
|
||||
}
|
||||
return fmt.Sprintf("%s: %v", e.message, err)
|
||||
}
|
||||
|
||||
// Format implements fmt.Formatter
|
||||
// When printing errors with %+v it also prints the stack trace.
|
||||
// %#v unsurprisingly will print the real underlying type.
|
||||
func (e *Err) Format(s fmt.State, verb rune) {
|
||||
switch verb {
|
||||
case 'v':
|
||||
switch {
|
||||
case s.Flag('+'):
|
||||
fmt.Fprintf(s, "%s", ErrorStack(e))
|
||||
return
|
||||
case s.Flag('#'):
|
||||
// avoid infinite recursion by wrapping e into a type
|
||||
// that doesn't implement Formatter.
|
||||
fmt.Fprintf(s, "%#v", (*unformatter)(e))
|
||||
return
|
||||
}
|
||||
fallthrough
|
||||
case 's':
|
||||
fmt.Fprintf(s, "%s", e.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// helper for Format
|
||||
type unformatter Err
|
||||
|
||||
func (unformatter) Format() { /* break the fmt.Formatter interface */ }
|
||||
|
||||
// SetLocation records the source location of the error at callDepth stack
|
||||
// frames above the call.
|
||||
func (e *Err) SetLocation(callDepth int) {
|
||||
_, file, line, _ := runtime.Caller(callDepth + 1)
|
||||
e.file = trimGoPath(file)
|
||||
e.line = line
|
||||
}
|
||||
|
||||
// StackTrace returns one string for each location recorded in the stack of
|
||||
// errors. The first value is the originating error, with a line for each
|
||||
// other annotation or tracing of the error.
|
||||
func (e *Err) StackTrace() []string {
|
||||
return errorStack(e)
|
||||
}
|
||||
|
||||
// Ideally we'd have a way to check identity, but deep equals will do.
|
||||
func sameError(e1, e2 error) bool {
|
||||
return reflect.DeepEqual(e1, e2)
|
||||
}
|
||||
309
vendor/github.com/juju/errors/errortypes.go
generated
vendored
309
vendor/github.com/juju/errors/errortypes.go
generated
vendored
@ -1,309 +0,0 @@
|
||||
// Copyright 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3, see LICENCE file for details.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// wrap is a helper to construct an *wrapper.
|
||||
func wrap(err error, format, suffix string, args ...interface{}) Err {
|
||||
newErr := Err{
|
||||
message: fmt.Sprintf(format+suffix, args...),
|
||||
previous: err,
|
||||
}
|
||||
newErr.SetLocation(2)
|
||||
return newErr
|
||||
}
|
||||
|
||||
// notFound represents an error when something has not been found.
|
||||
type notFound struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotFoundf returns an error which satisfies IsNotFound().
|
||||
func NotFoundf(format string, args ...interface{}) error {
|
||||
return ¬Found{wrap(nil, format, " not found", args...)}
|
||||
}
|
||||
|
||||
// NewNotFound returns an error which wraps err that satisfies
|
||||
// IsNotFound().
|
||||
func NewNotFound(err error, msg string) error {
|
||||
return ¬Found{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotFound reports whether err was created with NotFoundf() or
|
||||
// NewNotFound().
|
||||
func IsNotFound(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
// userNotFound represents an error when an inexistent user is looked up.
|
||||
type userNotFound struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// UserNotFoundf returns an error which satisfies IsUserNotFound().
|
||||
func UserNotFoundf(format string, args ...interface{}) error {
|
||||
return &userNotFound{wrap(nil, format, " user not found", args...)}
|
||||
}
|
||||
|
||||
// NewUserNotFound returns an error which wraps err and satisfies
|
||||
// IsUserNotFound().
|
||||
func NewUserNotFound(err error, msg string) error {
|
||||
return &userNotFound{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsUserNotFound reports whether err was created with UserNotFoundf() or
|
||||
// NewUserNotFound().
|
||||
func IsUserNotFound(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*userNotFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
// unauthorized represents an error when an operation is unauthorized.
|
||||
type unauthorized struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// Unauthorizedf returns an error which satisfies IsUnauthorized().
|
||||
func Unauthorizedf(format string, args ...interface{}) error {
|
||||
return &unauthorized{wrap(nil, format, "", args...)}
|
||||
}
|
||||
|
||||
// NewUnauthorized returns an error which wraps err and satisfies
|
||||
// IsUnauthorized().
|
||||
func NewUnauthorized(err error, msg string) error {
|
||||
return &unauthorized{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsUnauthorized reports whether err was created with Unauthorizedf() or
|
||||
// NewUnauthorized().
|
||||
func IsUnauthorized(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*unauthorized)
|
||||
return ok
|
||||
}
|
||||
|
||||
// notImplemented represents an error when something is not
|
||||
// implemented.
|
||||
type notImplemented struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotImplementedf returns an error which satisfies IsNotImplemented().
|
||||
func NotImplementedf(format string, args ...interface{}) error {
|
||||
return ¬Implemented{wrap(nil, format, " not implemented", args...)}
|
||||
}
|
||||
|
||||
// NewNotImplemented returns an error which wraps err and satisfies
|
||||
// IsNotImplemented().
|
||||
func NewNotImplemented(err error, msg string) error {
|
||||
return ¬Implemented{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotImplemented reports whether err was created with
|
||||
// NotImplementedf() or NewNotImplemented().
|
||||
func IsNotImplemented(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notImplemented)
|
||||
return ok
|
||||
}
|
||||
|
||||
// alreadyExists represents and error when something already exists.
|
||||
type alreadyExists struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// AlreadyExistsf returns an error which satisfies IsAlreadyExists().
|
||||
func AlreadyExistsf(format string, args ...interface{}) error {
|
||||
return &alreadyExists{wrap(nil, format, " already exists", args...)}
|
||||
}
|
||||
|
||||
// NewAlreadyExists returns an error which wraps err and satisfies
|
||||
// IsAlreadyExists().
|
||||
func NewAlreadyExists(err error, msg string) error {
|
||||
return &alreadyExists{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsAlreadyExists reports whether the error was created with
|
||||
// AlreadyExistsf() or NewAlreadyExists().
|
||||
func IsAlreadyExists(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*alreadyExists)
|
||||
return ok
|
||||
}
|
||||
|
||||
// notSupported represents an error when something is not supported.
|
||||
type notSupported struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotSupportedf returns an error which satisfies IsNotSupported().
|
||||
func NotSupportedf(format string, args ...interface{}) error {
|
||||
return ¬Supported{wrap(nil, format, " not supported", args...)}
|
||||
}
|
||||
|
||||
// NewNotSupported returns an error which wraps err and satisfies
|
||||
// IsNotSupported().
|
||||
func NewNotSupported(err error, msg string) error {
|
||||
return ¬Supported{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotSupported reports whether the error was created with
|
||||
// NotSupportedf() or NewNotSupported().
|
||||
func IsNotSupported(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notSupported)
|
||||
return ok
|
||||
}
|
||||
|
||||
// notValid represents an error when something is not valid.
|
||||
type notValid struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotValidf returns an error which satisfies IsNotValid().
|
||||
func NotValidf(format string, args ...interface{}) error {
|
||||
return ¬Valid{wrap(nil, format, " not valid", args...)}
|
||||
}
|
||||
|
||||
// NewNotValid returns an error which wraps err and satisfies IsNotValid().
|
||||
func NewNotValid(err error, msg string) error {
|
||||
return ¬Valid{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotValid reports whether the error was created with NotValidf() or
|
||||
// NewNotValid().
|
||||
func IsNotValid(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notValid)
|
||||
return ok
|
||||
}
|
||||
|
||||
// notProvisioned represents an error when something is not yet provisioned.
|
||||
type notProvisioned struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotProvisionedf returns an error which satisfies IsNotProvisioned().
|
||||
func NotProvisionedf(format string, args ...interface{}) error {
|
||||
return ¬Provisioned{wrap(nil, format, " not provisioned", args...)}
|
||||
}
|
||||
|
||||
// NewNotProvisioned returns an error which wraps err that satisfies
|
||||
// IsNotProvisioned().
|
||||
func NewNotProvisioned(err error, msg string) error {
|
||||
return ¬Provisioned{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotProvisioned reports whether err was created with NotProvisionedf() or
|
||||
// NewNotProvisioned().
|
||||
func IsNotProvisioned(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notProvisioned)
|
||||
return ok
|
||||
}
|
||||
|
||||
// notAssigned represents an error when something is not yet assigned to
|
||||
// something else.
|
||||
type notAssigned struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// NotAssignedf returns an error which satisfies IsNotAssigned().
|
||||
func NotAssignedf(format string, args ...interface{}) error {
|
||||
return ¬Assigned{wrap(nil, format, " not assigned", args...)}
|
||||
}
|
||||
|
||||
// NewNotAssigned returns an error which wraps err that satisfies
|
||||
// IsNotAssigned().
|
||||
func NewNotAssigned(err error, msg string) error {
|
||||
return ¬Assigned{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsNotAssigned reports whether err was created with NotAssignedf() or
|
||||
// NewNotAssigned().
|
||||
func IsNotAssigned(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*notAssigned)
|
||||
return ok
|
||||
}
|
||||
|
||||
// badRequest represents an error when a request has bad parameters.
|
||||
type badRequest struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// BadRequestf returns an error which satisfies IsBadRequest().
|
||||
func BadRequestf(format string, args ...interface{}) error {
|
||||
return &badRequest{wrap(nil, format, "", args...)}
|
||||
}
|
||||
|
||||
// NewBadRequest returns an error which wraps err that satisfies
|
||||
// IsBadRequest().
|
||||
func NewBadRequest(err error, msg string) error {
|
||||
return &badRequest{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsBadRequest reports whether err was created with BadRequestf() or
|
||||
// NewBadRequest().
|
||||
func IsBadRequest(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*badRequest)
|
||||
return ok
|
||||
}
|
||||
|
||||
// methodNotAllowed represents an error when an HTTP request
|
||||
// is made with an inappropriate method.
|
||||
type methodNotAllowed struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// MethodNotAllowedf returns an error which satisfies IsMethodNotAllowed().
|
||||
func MethodNotAllowedf(format string, args ...interface{}) error {
|
||||
return &methodNotAllowed{wrap(nil, format, "", args...)}
|
||||
}
|
||||
|
||||
// NewMethodNotAllowed returns an error which wraps err that satisfies
|
||||
// IsMethodNotAllowed().
|
||||
func NewMethodNotAllowed(err error, msg string) error {
|
||||
return &methodNotAllowed{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsMethodNotAllowed reports whether err was created with MethodNotAllowedf() or
|
||||
// NewMethodNotAllowed().
|
||||
func IsMethodNotAllowed(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*methodNotAllowed)
|
||||
return ok
|
||||
}
|
||||
|
||||
// forbidden represents an error when a request cannot be completed because of
|
||||
// missing privileges
|
||||
type forbidden struct {
|
||||
Err
|
||||
}
|
||||
|
||||
// Forbiddenf returns an error which satistifes IsForbidden()
|
||||
func Forbiddenf(format string, args ...interface{}) error {
|
||||
return &forbidden{wrap(nil, format, "", args...)}
|
||||
}
|
||||
|
||||
// NewForbidden returns an error which wraps err that satisfies
|
||||
// IsForbidden().
|
||||
func NewForbidden(err error, msg string) error {
|
||||
return &forbidden{wrap(err, msg, "")}
|
||||
}
|
||||
|
||||
// IsForbidden reports whether err was created with Forbiddenf() or
|
||||
// NewForbidden().
|
||||
func IsForbidden(err error) bool {
|
||||
err = Cause(err)
|
||||
_, ok := err.(*forbidden)
|
||||
return ok
|
||||
}
|
||||
330
vendor/github.com/juju/errors/functions.go
generated
vendored
330
vendor/github.com/juju/errors/functions.go
generated
vendored
@ -1,330 +0,0 @@
|
||||
// Copyright 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3, see LICENCE file for details.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// New is a drop in replacement for the standard library errors module that records
|
||||
// the location that the error is created.
|
||||
//
|
||||
// For example:
|
||||
// return errors.New("validation failed")
|
||||
//
|
||||
func New(message string) error {
|
||||
err := &Err{message: message}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Errorf creates a new annotated error and records the location that the
|
||||
// error is created. This should be a drop in replacement for fmt.Errorf.
|
||||
//
|
||||
// For example:
|
||||
// return errors.Errorf("validation failed: %s", message)
|
||||
//
|
||||
func Errorf(format string, args ...interface{}) error {
|
||||
err := &Err{message: fmt.Sprintf(format, args...)}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Trace adds the location of the Trace call to the stack. The Cause of the
|
||||
// resulting error is the same as the error parameter. If the other error is
|
||||
// nil, the result will be nil.
|
||||
//
|
||||
// For example:
|
||||
// if err := SomeFunc(); err != nil {
|
||||
// return errors.Trace(err)
|
||||
// }
|
||||
//
|
||||
func Trace(other error) error {
|
||||
if other == nil {
|
||||
return nil
|
||||
}
|
||||
err := &Err{previous: other, cause: Cause(other)}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Annotate is used to add extra context to an existing error. The location of
|
||||
// the Annotate call is recorded with the annotations. The file, line and
|
||||
// function are also recorded.
|
||||
//
|
||||
// For example:
|
||||
// if err := SomeFunc(); err != nil {
|
||||
// return errors.Annotate(err, "failed to frombulate")
|
||||
// }
|
||||
//
|
||||
func Annotate(other error, message string) error {
|
||||
if other == nil {
|
||||
return nil
|
||||
}
|
||||
err := &Err{
|
||||
previous: other,
|
||||
cause: Cause(other),
|
||||
message: message,
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Annotatef is used to add extra context to an existing error. The location of
|
||||
// the Annotate call is recorded with the annotations. The file, line and
|
||||
// function are also recorded.
|
||||
//
|
||||
// For example:
|
||||
// if err := SomeFunc(); err != nil {
|
||||
// return errors.Annotatef(err, "failed to frombulate the %s", arg)
|
||||
// }
|
||||
//
|
||||
func Annotatef(other error, format string, args ...interface{}) error {
|
||||
if other == nil {
|
||||
return nil
|
||||
}
|
||||
err := &Err{
|
||||
previous: other,
|
||||
cause: Cause(other),
|
||||
message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeferredAnnotatef annotates the given error (when it is not nil) with the given
|
||||
// format string and arguments (like fmt.Sprintf). If *err is nil, DeferredAnnotatef
|
||||
// does nothing. This method is used in a defer statement in order to annotate any
|
||||
// resulting error with the same message.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// defer DeferredAnnotatef(&err, "failed to frombulate the %s", arg)
|
||||
//
|
||||
func DeferredAnnotatef(err *error, format string, args ...interface{}) {
|
||||
if *err == nil {
|
||||
return
|
||||
}
|
||||
newErr := &Err{
|
||||
message: fmt.Sprintf(format, args...),
|
||||
cause: Cause(*err),
|
||||
previous: *err,
|
||||
}
|
||||
newErr.SetLocation(1)
|
||||
*err = newErr
|
||||
}
|
||||
|
||||
// Wrap changes the Cause of the error. The location of the Wrap call is also
|
||||
// stored in the error stack.
|
||||
//
|
||||
// For example:
|
||||
// if err := SomeFunc(); err != nil {
|
||||
// newErr := &packageError{"more context", private_value}
|
||||
// return errors.Wrap(err, newErr)
|
||||
// }
|
||||
//
|
||||
func Wrap(other, newDescriptive error) error {
|
||||
err := &Err{
|
||||
previous: other,
|
||||
cause: newDescriptive,
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wrapf changes the Cause of the error, and adds an annotation. The location
|
||||
// of the Wrap call is also stored in the error stack.
|
||||
//
|
||||
// For example:
|
||||
// if err := SomeFunc(); err != nil {
|
||||
// return errors.Wrapf(err, simpleErrorType, "invalid value %q", value)
|
||||
// }
|
||||
//
|
||||
func Wrapf(other, newDescriptive error, format string, args ...interface{}) error {
|
||||
err := &Err{
|
||||
message: fmt.Sprintf(format, args...),
|
||||
previous: other,
|
||||
cause: newDescriptive,
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Mask masks the given error with the given format string and arguments (like
|
||||
// fmt.Sprintf), returning a new error that maintains the error stack, but
|
||||
// hides the underlying error type. The error string still contains the full
|
||||
// annotations. If you want to hide the annotations, call Wrap.
|
||||
func Maskf(other error, format string, args ...interface{}) error {
|
||||
if other == nil {
|
||||
return nil
|
||||
}
|
||||
err := &Err{
|
||||
message: fmt.Sprintf(format, args...),
|
||||
previous: other,
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Mask hides the underlying error type, and records the location of the masking.
|
||||
func Mask(other error) error {
|
||||
if other == nil {
|
||||
return nil
|
||||
}
|
||||
err := &Err{
|
||||
previous: other,
|
||||
}
|
||||
err.SetLocation(1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Cause returns the cause of the given error. This will be either the
|
||||
// original error, or the result of a Wrap or Mask call.
|
||||
//
|
||||
// Cause is the usual way to diagnose errors that may have been wrapped by
|
||||
// the other errors functions.
|
||||
func Cause(err error) error {
|
||||
var diag error
|
||||
if err, ok := err.(causer); ok {
|
||||
diag = err.Cause()
|
||||
}
|
||||
if diag != nil {
|
||||
return diag
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
type causer interface {
|
||||
Cause() error
|
||||
}
|
||||
|
||||
type wrapper interface {
|
||||
// Message returns the top level error message,
|
||||
// not including the message from the Previous
|
||||
// error.
|
||||
Message() string
|
||||
|
||||
// Underlying returns the Previous error, or nil
|
||||
// if there is none.
|
||||
Underlying() error
|
||||
}
|
||||
|
||||
type locationer interface {
|
||||
Location() (string, int)
|
||||
}
|
||||
|
||||
var (
|
||||
_ wrapper = (*Err)(nil)
|
||||
_ locationer = (*Err)(nil)
|
||||
_ causer = (*Err)(nil)
|
||||
)
|
||||
|
||||
// Details returns information about the stack of errors wrapped by err, in
|
||||
// the format:
|
||||
//
|
||||
// [{filename:99: error one} {otherfile:55: cause of error one}]
|
||||
//
|
||||
// This is a terse alternative to ErrorStack as it returns a single line.
|
||||
func Details(err error) string {
|
||||
if err == nil {
|
||||
return "[]"
|
||||
}
|
||||
var s []byte
|
||||
s = append(s, '[')
|
||||
for {
|
||||
s = append(s, '{')
|
||||
if err, ok := err.(locationer); ok {
|
||||
file, line := err.Location()
|
||||
if file != "" {
|
||||
s = append(s, fmt.Sprintf("%s:%d", file, line)...)
|
||||
s = append(s, ": "...)
|
||||
}
|
||||
}
|
||||
if cerr, ok := err.(wrapper); ok {
|
||||
s = append(s, cerr.Message()...)
|
||||
err = cerr.Underlying()
|
||||
} else {
|
||||
s = append(s, err.Error()...)
|
||||
err = nil
|
||||
}
|
||||
s = append(s, '}')
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
s = append(s, ' ')
|
||||
}
|
||||
s = append(s, ']')
|
||||
return string(s)
|
||||
}
|
||||
|
||||
// ErrorStack returns a string representation of the annotated error. If the
|
||||
// error passed as the parameter is not an annotated error, the result is
|
||||
// simply the result of the Error() method on that error.
|
||||
//
|
||||
// If the error is an annotated error, a multi-line string is returned where
|
||||
// each line represents one entry in the annotation stack. The full filename
|
||||
// from the call stack is used in the output.
|
||||
//
|
||||
// first error
|
||||
// github.com/juju/errors/annotation_test.go:193:
|
||||
// github.com/juju/errors/annotation_test.go:194: annotation
|
||||
// github.com/juju/errors/annotation_test.go:195:
|
||||
// github.com/juju/errors/annotation_test.go:196: more context
|
||||
// github.com/juju/errors/annotation_test.go:197:
|
||||
func ErrorStack(err error) string {
|
||||
return strings.Join(errorStack(err), "\n")
|
||||
}
|
||||
|
||||
func errorStack(err error) []string {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// We want the first error first
|
||||
var lines []string
|
||||
for {
|
||||
var buff []byte
|
||||
if err, ok := err.(locationer); ok {
|
||||
file, line := err.Location()
|
||||
// Strip off the leading GOPATH/src path elements.
|
||||
file = trimGoPath(file)
|
||||
if file != "" {
|
||||
buff = append(buff, fmt.Sprintf("%s:%d", file, line)...)
|
||||
buff = append(buff, ": "...)
|
||||
}
|
||||
}
|
||||
if cerr, ok := err.(wrapper); ok {
|
||||
message := cerr.Message()
|
||||
buff = append(buff, message...)
|
||||
// If there is a cause for this error, and it is different to the cause
|
||||
// of the underlying error, then output the error string in the stack trace.
|
||||
var cause error
|
||||
if err1, ok := err.(causer); ok {
|
||||
cause = err1.Cause()
|
||||
}
|
||||
err = cerr.Underlying()
|
||||
if cause != nil && !sameError(Cause(err), cause) {
|
||||
if message != "" {
|
||||
buff = append(buff, ": "...)
|
||||
}
|
||||
buff = append(buff, cause.Error()...)
|
||||
}
|
||||
} else {
|
||||
buff = append(buff, err.Error()...)
|
||||
err = nil
|
||||
}
|
||||
lines = append(lines, string(buff))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
// reverse the lines to get the original error, which was at the end of
|
||||
// the list, back to the start.
|
||||
var result []string
|
||||
for i := len(lines); i > 0; i-- {
|
||||
result = append(result, lines[i-1])
|
||||
}
|
||||
return result
|
||||
}
|
||||
38
vendor/github.com/juju/errors/path.go
generated
vendored
38
vendor/github.com/juju/errors/path.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
// Copyright 2013, 2014 Canonical Ltd.
|
||||
// Licensed under the LGPLv3, see LICENCE file for details.
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// prefixSize is used internally to trim the user specific path from the
|
||||
// front of the returned filenames from the runtime call stack.
|
||||
var prefixSize int
|
||||
|
||||
// goPath is the deduced path based on the location of this file as compiled.
|
||||
var goPath string
|
||||
|
||||
func init() {
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if file == "?" {
|
||||
return
|
||||
}
|
||||
if ok {
|
||||
// We know that the end of the file should be:
|
||||
// github.com/juju/errors/path.go
|
||||
size := len(file)
|
||||
suffix := len("github.com/juju/errors/path.go")
|
||||
goPath = file[:size-suffix]
|
||||
prefixSize = len(goPath)
|
||||
}
|
||||
}
|
||||
|
||||
func trimGoPath(filename string) string {
|
||||
if strings.HasPrefix(filename, goPath) {
|
||||
return filename[prefixSize:]
|
||||
}
|
||||
return filename
|
||||
}
|
||||
6
vendor/github.com/tiglabs/raft/proto/proto.go
generated
vendored
6
vendor/github.com/tiglabs/raft/proto/proto.go
generated
vendored
@ -115,6 +115,12 @@ type Message struct {
|
||||
Snapshot Snapshot // No need for codec
|
||||
}
|
||||
|
||||
func (m *Message) ToString() (mesg string) {
|
||||
return fmt.Sprintf("Mesg:[%v] type(%v) ForceVote(%v) Reject(%v) RejectIndex(%v) "+
|
||||
"From(%v) To(%v) Term(%v) LogTrem(%v) Index(%v) Commit(%v)", m.ID, m.Type.String(), m.ForceVote,
|
||||
m.Reject, m.RejectIndex, m.From, m.To, m.Term, m.LogTerm, m.Index, m.Commit)
|
||||
}
|
||||
|
||||
type ConfChange struct {
|
||||
Type ConfChangeType
|
||||
Peer Peer
|
||||
|
||||
7
vendor/github.com/tiglabs/raft/raft.go
generated
vendored
7
vendor/github.com/tiglabs/raft/raft.go
generated
vendored
@ -447,6 +447,7 @@ func (s *raft) reciveMessage(m *proto.Message) {
|
||||
case <-s.stopc:
|
||||
case s.recvc <- m:
|
||||
default:
|
||||
logger.Warn(fmt.Sprintf("raft[%v] discard message(%v)", s.raftConfig.ID, m.ToString()))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -538,12 +539,6 @@ func (s *raft) sendMessage(m *proto.Message) {
|
||||
|
||||
func (s *raft) maybeChange(respErr bool) {
|
||||
updated := false
|
||||
if s.prevSoftSt.term != s.raftFsm.term && s.raftFsm.leader == s.config.NodeID &&
|
||||
s.curApplied.Get() < s.raftFsm.raftLog.committed {
|
||||
logger.Warn("raft:[%v] changed leader wait applied. curApplied %v committed %v at term %d.",
|
||||
s.raftFsm.id, s.curApplied.Get(), s.raftFsm.raftLog.committed, s.raftFsm.term)
|
||||
return
|
||||
}
|
||||
if s.prevSoftSt.term != s.raftFsm.term {
|
||||
updated = true
|
||||
s.prevSoftSt.term = s.raftFsm.term
|
||||
|
||||
17
vendor/github.com/tiglabs/raft/raft_fsm.go
generated
vendored
17
vendor/github.com/tiglabs/raft/raft_fsm.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
||||
|
||||
"github.com/tiglabs/raft/logger"
|
||||
"github.com/tiglabs/raft/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NoLeader is a placeholder nodeID used when there is no leader.
|
||||
@ -131,9 +132,20 @@ func newRaftFsm(config *Config, raftConfig *RaftConfig) (*raftFsm, error) {
|
||||
logger.Debug("newRaft[%v] [peers: [%s], term: %d, commit: %d, applied: %d, lastindex: %d, lastterm: %d]",
|
||||
r.id, strings.Join(peerStrs, ","), r.term, r.raftLog.committed, r.raftLog.applied, r.raftLog.lastIndex(), r.raftLog.lastTerm())
|
||||
}
|
||||
go r.doRandomSeed()
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (r *raftFsm) doRandomSeed() {
|
||||
ticker := time.Tick(time.Duration(rand.Intn(10)) * time.Second)
|
||||
for {
|
||||
select {
|
||||
case <-ticker:
|
||||
r.rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// raft main method
|
||||
func (r *raftFsm) Step(m *proto.Message) {
|
||||
if m.Type == proto.LocalMsgHup {
|
||||
@ -338,7 +350,10 @@ func (r *raftFsm) reset(term, lasti uint64, isLeader bool) {
|
||||
}
|
||||
|
||||
func (r *raftFsm) resetRandomizedElectionTimeout() {
|
||||
r.randElectionTick = r.config.ElectionTick + r.rand.Intn(r.config.ElectionTick)
|
||||
randTick := r.rand.Intn(r.config.ElectionTick)
|
||||
r.randElectionTick = r.config.ElectionTick + randTick
|
||||
logger.Debug("raft[%v] random election timeout randElectionTick=%v, config.ElectionTick=%v, randTick=%v", r.id,
|
||||
r.randElectionTick, r.config.ElectionTick, randTick)
|
||||
}
|
||||
|
||||
func (r *raftFsm) pastElectionTimeout() bool {
|
||||
|
||||
2
vendor/github.com/tiglabs/raft/raft_fsm_leader.go
generated
vendored
2
vendor/github.com/tiglabs/raft/raft_fsm_leader.go
generated
vendored
@ -29,7 +29,7 @@ func (r *raftFsm) becomeLeader() {
|
||||
if r.state == stateFollower {
|
||||
panic(AppPanicError(fmt.Sprintf("[raft->becomeLeader][%v] invalid transition [follower -> leader].", r.id)))
|
||||
}
|
||||
|
||||
r.recoverCommit()
|
||||
lasti := r.raftLog.lastIndex()
|
||||
r.step = stepLeader
|
||||
r.reset(r.term, lasti, true)
|
||||
|
||||
3
vendor/github.com/tiglabs/raft/transport_heartbeat.go
generated
vendored
3
vendor/github.com/tiglabs/raft/transport_heartbeat.go
generated
vendored
@ -18,6 +18,8 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
//"fmt"
|
||||
//"github.com/tiglabs/raft/logger"
|
||||
"github.com/tiglabs/raft/proto"
|
||||
"github.com/tiglabs/raft/util"
|
||||
)
|
||||
@ -96,6 +98,7 @@ func (t *heartbeatTransport) handleConn(conn *util.ConnTimeout) {
|
||||
if msg, err := reciveMessage(bufRd); err != nil {
|
||||
return
|
||||
} else {
|
||||
//logger.Debug(fmt.Sprintf("Recive %v from (%v)", msg.ToString(), conn.RemoteAddr()))
|
||||
t.raftServer.reciveMessage(msg)
|
||||
}
|
||||
}
|
||||
|
||||
1
vendor/github.com/tiglabs/raft/transport_replicate.go
generated
vendored
1
vendor/github.com/tiglabs/raft/transport_replicate.go
generated
vendored
@ -219,6 +219,7 @@ func (t *replicateTransport) handleConn(conn *util.ConnTimeout) {
|
||||
if msg, err := reciveMessage(bufRd); err != nil {
|
||||
return
|
||||
} else {
|
||||
//logger.Debug(fmt.Sprintf("Recive %v from (%v)", msg.ToString(), conn.RemoteAddr()))
|
||||
if msg.Type == proto.ReqMsgSnapShot {
|
||||
if err := t.handleSnapshot(msg, conn, bufRd); err != nil {
|
||||
return
|
||||
|
||||
2
vendor/github.com/tiglabs/raft/transport_sender.go
generated
vendored
2
vendor/github.com/tiglabs/raft/transport_sender.go
generated
vendored
@ -19,6 +19,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
//"fmt"
|
||||
"github.com/tiglabs/raft/logger"
|
||||
"github.com/tiglabs/raft/proto"
|
||||
"github.com/tiglabs/raft/util"
|
||||
@ -138,6 +139,7 @@ func (s *transportSender) loopSend(recvc chan *proto.Message) {
|
||||
select {
|
||||
case msg := <-recvc:
|
||||
err = msg.Encode(bufWr)
|
||||
//logger.Debug(fmt.Sprintf("SendMesg %v to (%v) ", msg.ToString(), conn.RemoteAddr()))
|
||||
proto.ReturnMessage(msg)
|
||||
if err != nil {
|
||||
goto flush
|
||||
|
||||
Loading…
Reference in New Issue
Block a user