diff --git a/master/api_service.go b/master/api_service.go index 8d302ac9d..d9848344e 100644 --- a/master/api_service.go +++ b/master/api_service.go @@ -2594,6 +2594,20 @@ func (m *Server) checkStorageClassForCreateVolReq(req *createVolReq) (err error) scope := "cluster" if req.zoneName != "" { scope = fmt.Sprintf("assigned zones(%v)", req.zoneName) + + notExistZones := make([]string, 0) + reqZoneList := strings.Split(req.zoneName, ",") + for _, reqZone := range reqZoneList { + if _, err = m.cluster.t.getZone(reqZone); err != nil { + notExistZones = append(notExistZones, reqZone) + } + } + + if len(notExistZones) != 0 { + err = fmt.Errorf("assigned zone name not exist: %v", notExistZones) + log.LogErrorf("[checkStorageClassForCreateVol] create vol(%v) err:%v", req.name, err.Error()) + return err + } } resourceChecker := NewStorageClassResourceChecker(m.cluster, req.zoneName) @@ -2602,7 +2616,7 @@ func (m *Server) checkStorageClassForCreateVolReq(req *createVolReq) (err error) // when volStorageClass not specified, try to set as replica with fastest mediaType if resource can support req.volStorageClass = m.cluster.GetFastestReplicaStorageClassInCluster(resourceChecker, req.zoneName) if req.volStorageClass == proto.StorageClass_Unspecified { - err = fmt.Errorf("volStorageClass not specified and %v has no resource to suppoort replca storageClass", scope) + err = fmt.Errorf("volStorageClass not specified and %v has no resource to auto choose replca storageClass", scope) log.LogErrorf("[checkStorageClassForCreateVol] create vol(%v) err:%v", req.name, err.Error()) return err } diff --git a/master/master_manager.go b/master/master_manager.go index 7e473a963..1e630a73f 100644 --- a/master/master_manager.go +++ b/master/master_manager.go @@ -184,9 +184,10 @@ func (m *Server) loadMetadata() { panic(err) } - if err, autoUpdatedZones = m.cluster.loadZoneValue(); err != nil { + if err = m.cluster.loadZoneValue(); err != nil { panic(err) } + autoUpdatedZones = m.cluster.checkSetMediaTypeForLegacyZones() if err, autoUpdatedLegacyVols = m.cluster.loadVols(); err != nil { panic(err) diff --git a/master/metadata_fsm_op.go b/master/metadata_fsm_op.go index b9844cdb8..679eb4884 100644 --- a/master/metadata_fsm_op.go +++ b/master/metadata_fsm_op.go @@ -1112,31 +1112,20 @@ func (c *Cluster) updateDecommissionDiskLimit(val uint32) { atomic.StoreUint32(&c.DecommissionDiskLimit, val) } -func (c *Cluster) loadZoneValue() (err error, updatedZones []*Zone) { +func (c *Cluster) loadZoneValue() (err error) { var ok bool - updatedZones = make([]*Zone, 0) - result, err := c.fsm.store.SeekForPrefix([]byte(zonePrefix)) if err != nil { err = fmt.Errorf("action[loadZoneValue],err:%v", err.Error()) return } - for _, value := range result { - var autoUpdated bool + for _, value := range result { cv := &zoneValue{} if err = json.Unmarshal(value, cv); err != nil { log.LogErrorf("action[loadZoneValue], unmarshal err:%v", err.Error()) continue } - if cv.DataMediaType == proto.MediaType_Unspecified { - // TODO:tangjingyu check zone's datanode count > 0 before set as legacyDataMediaType - cv.DataMediaType = c.server.config.legacyDataMediaType - autoUpdated = true - log.LogWarnf("legacy zone(%v), set mediaType(%v) by config legacyDataMediaType", - cv.Name, proto.MediaTypeString(cv.DataMediaType)) - } - var zoneInfo interface{} if zoneInfo, ok = c.t.zoneMap.Load(cv.Name); !ok { log.LogErrorf("action[loadZoneValue], zonename [%v] not found", cv.Name) @@ -1153,16 +1142,45 @@ func (c *Cluster) loadZoneValue() (err error, updatedZones []*Zone) { if zone.GetMetaNodesetSelector() != cv.MetaNodesetSelector { zone.metaNodesetSelector = NewNodesetSelector(cv.MetaNodesetSelector, MetaNodeType) } - log.LogInfof("action[loadZoneValue] load zoneName[%v] with limit [%v,%v,%v,%v], dataMediaType:%v", - zone.name, cv.QosFlowRLimit, cv.QosIopsWLimit, cv.QosFlowWLimit, cv.QosIopsRLimit, - proto.MediaTypeString(cv.DataMediaType)) - zone.loadDataNodeQosLimit() zone.SetDataMediaType(cv.DataMediaType) + log.LogInfof("action[loadZoneValue] load zoneName[%v] with limit [%v,%v,%v,%v], dataMediaType[%v]", + zone.name, cv.QosFlowRLimit, cv.QosIopsWLimit, cv.QosFlowWLimit, cv.QosIopsRLimit, + proto.MediaTypeString(zone.dataMediaType)) + zone.loadDataNodeQosLimit() + } - if autoUpdated { + return +} + +func (c *Cluster) checkSetMediaTypeForLegacyZones() (updatedZones []*Zone) { + updatedZones = make([]*Zone, 0) + + zonesHasDatanode := map[string]struct{}{} + c.dataNodes.Range(func(addr, node interface{}) bool { + dn := node.(*DataNode) + zonesHasDatanode[dn.ZoneName] = struct{}{} + return true + }) + + log.LogDebugf("[checkSetMediaTypeForLegacyZones] zone num: %v", c.t.getZoneLen()) + c.t.zoneMap.Range(func(key, value interface{}) bool { + zone := value.(*Zone) + + log.LogDebugf("[checkSetMediaTypeForLegacyZones] zone(%v) mediaType(%v)", + zone.name, proto.MediaTypeString(zone.dataMediaType)) + if zone.dataMediaType != proto.MediaType_Unspecified { + return true + } + + if _, exists := zonesHasDatanode[zone.name]; exists { + zone.SetDataMediaType(c.server.config.legacyDataMediaType) + log.LogWarnf("[checkSetMediaTypeForLegacyZones] set mediaType(%v) by config legacyDataMediaType for legacy zone(%v)", + proto.MediaTypeString(zone.dataMediaType), zone.name) updatedZones = append(updatedZones, zone) } - } + + return true + }) return }