mirror of
https://github.com/minio/minio.git
synced 2024-12-25 06:35:56 -05:00
fix: protect ReplicationStats against concurrent map iteration and write crash (#17403)
This commit is contained in:
parent
bb24346e04
commit
6f2406b0b6
@ -373,7 +373,7 @@ func (f *folderScanner) sendUpdate() {
|
|||||||
}
|
}
|
||||||
if flat := f.updateCache.sizeRecursive(f.newCache.Info.Name); flat != nil {
|
if flat := f.updateCache.sizeRecursive(f.newCache.Info.Name); flat != nil {
|
||||||
select {
|
select {
|
||||||
case f.updates <- *flat:
|
case f.updates <- flat.clone():
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
f.lastUpdate = time.Now()
|
f.lastUpdate = time.Now()
|
||||||
|
@ -88,6 +88,20 @@ func (ats *allTierStats) merge(other *allTierStats) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ats *allTierStats) clone() *allTierStats {
|
||||||
|
if ats == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dst := *ats
|
||||||
|
if dst.Tiers != nil {
|
||||||
|
dst.Tiers = make(map[string]tierStats, len(dst.Tiers))
|
||||||
|
for tier, st := range dst.Tiers {
|
||||||
|
dst.Tiers[tier] = st
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &dst
|
||||||
|
}
|
||||||
|
|
||||||
func (ats *allTierStats) adminStats(stats map[string]madmin.TierStats) map[string]madmin.TierStats {
|
func (ats *allTierStats) adminStats(stats map[string]madmin.TierStats) map[string]madmin.TierStats {
|
||||||
if ats == nil {
|
if ats == nil {
|
||||||
return stats
|
return stats
|
||||||
@ -168,6 +182,25 @@ type replicationAllStatsV1 struct {
|
|||||||
ReplicaSize uint64 `msg:"ReplicaSize,omitempty"`
|
ReplicaSize uint64 `msg:"ReplicaSize,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone creates a deep-copy clone.
|
||||||
|
func (r *replicationAllStats) clone() *replicationAllStats {
|
||||||
|
if r == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shallow copy
|
||||||
|
dst := *r
|
||||||
|
|
||||||
|
// Copy individual targets.
|
||||||
|
if dst.Targets != nil {
|
||||||
|
dst.Targets = make(map[string]replicationStats, len(dst.Targets))
|
||||||
|
for k, v := range r.Targets {
|
||||||
|
dst.Targets[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &dst
|
||||||
|
}
|
||||||
|
|
||||||
//msgp:encode ignore dataUsageEntryV2 dataUsageEntryV3 dataUsageEntryV4 dataUsageEntryV5 dataUsageEntryV6
|
//msgp:encode ignore dataUsageEntryV2 dataUsageEntryV3 dataUsageEntryV4 dataUsageEntryV5 dataUsageEntryV6
|
||||||
//msgp:marshal ignore dataUsageEntryV2 dataUsageEntryV3 dataUsageEntryV4 dataUsageEntryV5 dataUsageEntryV6
|
//msgp:marshal ignore dataUsageEntryV2 dataUsageEntryV3 dataUsageEntryV4 dataUsageEntryV5 dataUsageEntryV6
|
||||||
|
|
||||||
@ -413,14 +446,11 @@ func (e dataUsageEntry) clone() dataUsageEntry {
|
|||||||
e.Children = ch
|
e.Children = ch
|
||||||
}
|
}
|
||||||
if e.ReplicationStats != nil {
|
if e.ReplicationStats != nil {
|
||||||
// Copy to new struct
|
// Clone ReplicationStats
|
||||||
r := *e.ReplicationStats
|
e.ReplicationStats = e.ReplicationStats.clone()
|
||||||
e.ReplicationStats = &r
|
|
||||||
}
|
}
|
||||||
if e.AllTierStats != nil {
|
if e.AllTierStats != nil {
|
||||||
ats := newAllTierStats()
|
e.AllTierStats = e.AllTierStats.clone()
|
||||||
ats.merge(e.AllTierStats)
|
|
||||||
e.AllTierStats = ats
|
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user