github.com/minio/mc@v0.0.0-20240507152021-646712d5e5fb/cmd/admin-heal-result-item.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "fmt" 22 23 "github.com/minio/madmin-go/v3" 24 ) 25 26 type hri struct { 27 *madmin.HealResultItem 28 } 29 30 func newHRI(i *madmin.HealResultItem) *hri { 31 return &hri{i} 32 } 33 34 // getObjectHCCChange - returns before and after color change for 35 // objects 36 func (h hri) getObjectHCCChange() (b, a col, err error) { 37 parityShards := h.ParityBlocks 38 dataShards := h.DataBlocks 39 40 onlineBefore, onlineAfter := h.GetOnlineCounts() 41 surplusShardsBeforeHeal := onlineBefore - dataShards 42 surplusShardsAfterHeal := onlineAfter - dataShards 43 44 b, err = getHColCode(surplusShardsBeforeHeal, parityShards) 45 if err != nil { 46 err = fmt.Errorf("%w: surplusShardsBeforeHeal: %d, parityShards: %d", 47 err, surplusShardsBeforeHeal, parityShards) 48 return 49 } 50 a, err = getHColCode(surplusShardsAfterHeal, parityShards) 51 if err != nil { 52 err = fmt.Errorf("%w: surplusShardsBeforeHeal: %d, parityShards: %d", 53 err, surplusShardsAfterHeal, parityShards) 54 } 55 return 56 } 57 58 // getReplicatedFileHCCChange - fetches health color code for metadata 59 // files that are replicated. 60 func (h hri) getReplicatedFileHCCChange() (b, a col, err error) { 61 getColCode := func(numAvail int) (c col, err error) { 62 // calculate color code for replicated object similar 63 // to erasure coded objects 64 var quorum, surplus, parity int 65 if h.SetCount > 0 { 66 quorum = h.DiskCount/h.SetCount/2 + 1 67 surplus = numAvail/h.SetCount - quorum 68 parity = h.DiskCount/h.SetCount - quorum 69 } else { 70 // in case of bucket healing, disk count is for the node 71 // also explicitly set count would be set to invalid value of -1 72 quorum = h.DiskCount/2 + 1 73 surplus = numAvail - quorum 74 parity = h.DiskCount - quorum 75 } 76 c, err = getHColCode(surplus, parity) 77 return 78 } 79 80 onlineBefore, onlineAfter := h.GetOnlineCounts() 81 b, err = getColCode(onlineBefore) 82 if err != nil { 83 return 84 } 85 a, err = getColCode(onlineAfter) 86 return 87 } 88 89 func (h hri) makeHealEntityString() string { 90 switch h.Type { 91 case madmin.HealItemObject: 92 return h.Bucket + "/" + h.Object 93 case madmin.HealItemBucket: 94 return h.Bucket 95 case madmin.HealItemMetadata: 96 return "[disk-format]" 97 case madmin.HealItemBucketMetadata: 98 return fmt.Sprintf("[bucket-metadata]%s/%s", h.Bucket, h.Object) 99 } 100 return "** unexpected **" 101 } 102 103 func (h hri) getHRTypeAndName() (typ, name string) { 104 name = fmt.Sprintf("%s/%s", h.Bucket, h.Object) 105 switch h.Type { 106 case madmin.HealItemMetadata: 107 typ = "system" 108 name = h.Detail 109 case madmin.HealItemBucketMetadata: 110 typ = "system" 111 name = "bucket-metadata:" + name 112 case madmin.HealItemBucket: 113 typ = "bucket" 114 case madmin.HealItemObject: 115 typ = "object" 116 default: 117 typ = fmt.Sprintf("!! Unknown heal result record %#v !!", h) 118 name = typ 119 } 120 return 121 } 122 123 func (h hri) getHealResultStr() string { 124 typ, name := h.getHRTypeAndName() 125 126 switch h.Type { 127 case madmin.HealItemMetadata, madmin.HealItemBucketMetadata: 128 return typ + ":" + name 129 default: 130 return name 131 } 132 }