diff --git a/metanode/api_handler.go b/metanode/api_handler.go index cd7c6b3d8..4dced4a7f 100644 --- a/metanode/api_handler.go +++ b/metanode/api_handler.go @@ -19,6 +19,7 @@ import ( "encoding/json" "fmt" "io" + "io/ioutil" "math" "net/http" "os" @@ -81,7 +82,9 @@ func (m *MetaNode) registerAPIHandler() (err error) { http.HandleFunc("/getTx", m.getTxHandler) http.HandleFunc("/getInodeAccessTime", m.getInodeAccessTimeHandler) http.HandleFunc("/getInodeWithExtentKey", m.getInodeWithExtentKeyHandler) - http.HandleFunc("/setInodeCreateTime", m.setInodeCreateTimeHandler) + http.HandleFunc("/setInodeCreateTime", m.setInodeCreateTimeHandler) //for debug + http.HandleFunc("/deleteMigrateExtentKey", m.deleteMigrateExtentKeyHandler) //for debug + http.HandleFunc("/updateExtentKeyAfterMigration", m.updateExtentKeyAfterMigrationHandler) //for debug return } @@ -961,7 +964,7 @@ func (m *MetaNode) setInodeCreateTimeHandler(w http.ResponseWriter, r *http.Requ defer func() { data, _ := resp.Marshal() if _, err := w.Write(data); err != nil { - log.LogErrorf("[setInodeCreateTimeHandler] response %s", err) + log.LogErrorf("[setInodeCreateTimeHandler] response %s", err.Error()) } }() @@ -1018,7 +1021,7 @@ func (m *MetaNode) setInodeCreateTimeHandler(w http.ResponseWriter, r *http.Requ } if err = mp.SetCreateTime(req, p.Data, p); err != nil { - err = errors.NewErrorf("[setInodeCreateTimeHandler] req: %v, error: %s", req, err.Error()) + log.LogErrorf("[setInodeCreateTimeHandler] req: %v, error: %s", req, err.Error()) resp.Msg = err.Error() return } @@ -1030,3 +1033,132 @@ func (m *MetaNode) setInodeCreateTimeHandler(w http.ResponseWriter, r *http.Requ pid, id, dateTimeStr, createTime) return } + +func (m *MetaNode) deleteMigrateExtentKeyHandler(w http.ResponseWriter, r *http.Request) { + var err error + + r.ParseForm() + resp := NewAPIResponse(http.StatusBadRequest, "") + defer func() { + data, _ := resp.Marshal() + if _, err := w.Write(data); err != nil { + log.LogErrorf("[deleteMigrateExtentKeyHandler] response %s", err.Error()) + } + }() + + mpId, err := strconv.ParseUint(r.FormValue("pid"), 10, 64) + if err != nil { + resp.Msg = err.Error() + return + } + + inoId, err := strconv.ParseUint(r.FormValue("ino"), 10, 64) + if err != nil { + resp.Msg = err.Error() + return + } + + log.LogInfof("[deleteMigrateExtentKeyHandler] mpId(%v) ino(%v) run", mpId, inoId) + + mp, err := m.metadataManager.GetPartition(mpId) + if err != nil { + log.LogErrorf("[deleteMigrateExtentKeyHandler] mpId(%v) ino(%v), get mp err: %v", mpId, inoId, err.Error()) + resp.Code = http.StatusNotFound + resp.Msg = err.Error() + return + } + + if leaderAddr, ok := mp.IsLeader(); !ok { + resp.Code = http.StatusSeeOther + err = fmt.Errorf("not mp leader, leader is %v", leaderAddr) + log.LogErrorf("[deleteMigrateExtentKeyHandler] mpId(%v) ino(%v), err: %v", mpId, inoId, err.Error()) + resp.Msg = err.Error() + return + } + + req := &DeleteMigrationExtentKeyRequest{ + PartitionID: mpId, + Inode: inoId, + } + + p := &Packet{} + p.Opcode = proto.OpDeleteMigrationExtentKey + req.FullPaths = []string{"N/A"} + err = p.MarshalData(req) + if err != nil { + resp.Msg = err.Error() + return + } + + remoteInfo := "httpFrom" + r.RemoteAddr + if err = mp.DeleteMigrationExtentKey(req, p, remoteInfo); err != nil { + log.LogErrorf("[deleteMigrateExtentKeyHandler] req: %v, error: %s", req, err.Error()) + resp.Msg = err.Error() + return + } + + resp.Code = http.StatusOK + resp.Msg = p.GetResultMsg() + + log.LogInfof("[deleteMigrateExtentKeyHandler] mpId(%v) ino(%v) success", mpId, inoId) + return +} + +func (m *MetaNode) updateExtentKeyAfterMigrationHandler(w http.ResponseWriter, r *http.Request) { + var err error + var bytes []byte + + resp := NewAPIResponse(http.StatusBadRequest, "") + defer func() { + data, _ := resp.Marshal() + if _, err := w.Write(data); err != nil { + log.LogErrorf("[updateExtentKeyAfterMigrationHandler] response %s", err.Error()) + } + }() + + if bytes, err = ioutil.ReadAll(r.Body); err != nil { + resp.Code = http.StatusBadRequest + resp.Msg = err.Error() + log.LogErrorf("[updateExtentKeyAfterMigrationHandler] read request data body err:%s", err) + return + } + var req = &proto.UpdateExtentKeyAfterMigrationRequest{} + if err = json.Unmarshal(bytes, req); err != nil { + resp.Code = http.StatusBadRequest + resp.Msg = err.Error() + log.LogErrorf("[updateExtentKeyAfterMigrationHandler] Unmarshal request data body err:%s", err) + return + } + log.LogInfof("[updateExtentKeyAfterMigrationHandler] req: %v", req) + + mp, err := m.metadataManager.GetPartition(req.PartitionID) + if err != nil { + log.LogErrorf("[updateExtentKeyAfterMigrationHandler] mpId(%v) ino(%v), get mp err: %v", + req.PartitionID, req.Inode, err.Error()) + resp.Code = http.StatusNotFound + resp.Msg = err.Error() + return + } + + p := &Packet{} + p.Opcode = proto.OpMetaUpdateExtentKeyAfterMigration + req.FullPaths = []string{"N/A"} + err = p.MarshalData(req) + if err != nil { + resp.Msg = err.Error() + return + } + + remoteInfo := "httpFrom" + r.RemoteAddr + if err = mp.UpdateExtentKeyAfterMigration(req, p, remoteInfo); err != nil { + log.LogErrorf("[updateExtentKeyAfterMigrationHandler] req: %v, error: %s", req, err.Error()) + resp.Msg = err.Error() + return + } + + resp.Code = http.StatusOK + resp.Msg = p.GetResultMsg() + + log.LogInfof("[updateExtentKeyAfterMigrationHandler] mpId(%v) ino(%v) success", req.PartitionID, req.Inode) + return +} diff --git a/metanode/partition_fsmop_inode.go b/metanode/partition_fsmop_inode.go index 2a1059224..bbc5df2e5 100644 --- a/metanode/partition_fsmop_inode.go +++ b/metanode/partition_fsmop_inode.go @@ -1064,6 +1064,14 @@ func (mp *metaPartition) fsmUpdateExtentKeyAfterMigration(inoParam *Inode) (resp return } i := item.(*Inode) + + if i.StorageClass == inoParam.HybridCouldExtentsMigration.storageClass { + log.LogWarnf("[fsmUpdateExtentKeyAfterMigration] inode(%v) storageClass(%v) is already the same with req storageClass", + i.Inode, i.StorageClass) + resp.Status = proto.OpNotPerm + return + } + // store old storage ek in HybridCouldExtentsMigration i.HybridCouldExtentsMigration.storageClass = inoParam.StorageClass i.HybridCouldExtentsMigration.sortedEks = inoParam.HybridCouldExtents.sortedEks diff --git a/metanode/partition_op_inode.go b/metanode/partition_op_inode.go index 31ee9163b..f6a837fc6 100644 --- a/metanode/partition_op_inode.go +++ b/metanode/partition_op_inode.go @@ -1150,6 +1150,14 @@ func (mp *metaPartition) UpdateExtentKeyAfterMigration(req *proto.UpdateExtentKe } }() + if ino.StorageClass == req.StorageClass { + err = fmt.Errorf("inode(%v) storageClass(%v) is already the same with request storageClass", + ino.Inode, ino.StorageClass) + log.LogWarnf("[UpdateExtentKeyAfterMigration] %v", err.Error()) + p.PacketErrorWithBody(proto.OpErr, []byte(err.Error())) + return + } + if atomic.LoadUint32(&ino.ForbiddenMigration) == ForbiddenToMigration { err = fmt.Errorf("mp %v inode %v is forbidden to migration", mp.config.PartitionId, ino.Inode) log.LogErrorf("action[UpdateExtentKeyAfterMigration] %v", err) @@ -1194,7 +1202,7 @@ func (mp *metaPartition) UpdateExtentKeyAfterMigration(req *proto.UpdateExtentKe } val, err := ino.Marshal() if err != nil { - log.LogErrorf("action[UpdateExtentKeyAfterMigration] ino %v marshall failed %v", ino.Inode, err) + log.LogErrorf("action[UpdateExtentKeyAfterMigration] ino %v marshall failed %v", ino.Inode, err.Error()) p.PacketErrorWithBody(proto.OpErr, []byte(err.Error())) return } @@ -1203,6 +1211,15 @@ func (mp *metaPartition) UpdateExtentKeyAfterMigration(req *proto.UpdateExtentKe p.PacketErrorWithBody(proto.OpAgain, []byte(err.Error())) return } + fsmRespStatus := resp.(*InodeResponse).Status + if fsmRespStatus != proto.OpOk { + err = fmt.Errorf("fsm resp err status(%v)", fsmRespStatus) + log.LogErrorf("action[UpdateExtentKeyAfterMigration] ino(%v) storageClass(%v) req(%v), fsm return err:%v", + ino.Inode, ino.StorageClass, req, err.Error()) + p.PacketErrorWithBody(proto.OpErr, []byte(err.Error())) + return + } + msg := resp.(*InodeResponse) p.PacketErrorWithBody(msg.Status, nil) return