fix: report correct pool/set/disk indexes for offline disks (#17695)

This commit is contained in:
Anis Eleuch 2023-07-20 15:48:21 +01:00 committed by GitHub
parent bddd53d6d2
commit 756d6aa729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 46 deletions

View File

@ -360,7 +360,7 @@ func createServerEndpoints(serverAddr string, args ...string) (
return nil, -1, err return nil, -1, err
} }
for i := range endpointList { for i := range endpointList {
endpointList[i].SetPool(0) endpointList[i].SetPoolIndex(0)
} }
endpointServerPools = append(endpointServerPools, PoolEndpoints{ endpointServerPools = append(endpointServerPools, PoolEndpoints{
Legacy: true, Legacy: true,

View File

@ -69,8 +69,9 @@ type Node struct {
// Endpoint - any type of endpoint. // Endpoint - any type of endpoint.
type Endpoint struct { type Endpoint struct {
*url.URL *url.URL
Pool int
IsLocal bool IsLocal bool
PoolIdx, SetIdx, DiskIdx int
} }
func (endpoint Endpoint) String() string { func (endpoint Endpoint) String() string {
@ -106,9 +107,19 @@ func (endpoint *Endpoint) UpdateIsLocal() (err error) {
return nil return nil
} }
// SetPool sets a specific pool number to this node // SetPoolIndex sets a specific pool number to this node
func (endpoint *Endpoint) SetPool(i int) { func (endpoint *Endpoint) SetPoolIndex(i int) {
endpoint.Pool = i endpoint.PoolIdx = i
}
// SetSetIndex sets a specific set number to this node
func (endpoint *Endpoint) SetSetIndex(i int) {
endpoint.SetIdx = i
}
// SetDiskIndex sets a specific disk number to this node
func (endpoint *Endpoint) SetDiskIndex(i int) {
endpoint.DiskIdx = i
} }
// NewEndpoint - returns new endpoint based on given arguments. // NewEndpoint - returns new endpoint based on given arguments.
@ -205,6 +216,9 @@ func NewEndpoint(arg string) (ep Endpoint, e error) {
return Endpoint{ return Endpoint{
URL: u, URL: u,
IsLocal: isLocal, IsLocal: isLocal,
PoolIdx: -1,
SetIdx: -1,
DiskIdx: -1,
}, nil }, nil
} }
@ -236,8 +250,8 @@ func (l EndpointServerPools) GetNodes() (nodes []Node) {
Host: ep.Host, Host: ep.Host,
} }
} }
if !slices.Contains(node.Pools, ep.Pool) { if !slices.Contains(node.Pools, ep.PoolIdx) {
node.Pools = append(node.Pools, ep.Pool) node.Pools = append(node.Pools, ep.PoolIdx)
} }
nodesMap[ep.Host] = node nodesMap[ep.Host] = node
} }
@ -811,7 +825,9 @@ func CreatePoolEndpoints(serverAddr string, poolArgs ...[][]string) ([]Endpoints
return nil, setupType, config.ErrInvalidEndpoint(nil).Msg("use path style endpoint for single node setup") return nil, setupType, config.ErrInvalidEndpoint(nil).Msg("use path style endpoint for single node setup")
} }
endpoint.SetPool(0) endpoint.SetPoolIndex(0)
endpoint.SetSetIndex(0)
endpoint.SetDiskIndex(0)
var endpoints Endpoints var endpoints Endpoints
endpoints = append(endpoints, endpoint) endpoints = append(endpoints, endpoint)
@ -828,7 +844,7 @@ func CreatePoolEndpoints(serverAddr string, poolArgs ...[][]string) ([]Endpoints
for poolIdx, args := range poolArgs { for poolIdx, args := range poolArgs {
var endpoints Endpoints var endpoints Endpoints
for _, iargs := range args { for setIdx, iargs := range args {
// Convert args to endpoints // Convert args to endpoints
eps, err := NewEndpoints(iargs...) eps, err := NewEndpoints(iargs...)
if err != nil { if err != nil {
@ -840,8 +856,10 @@ func CreatePoolEndpoints(serverAddr string, poolArgs ...[][]string) ([]Endpoints
return nil, setupType, config.ErrInvalidErasureEndpoints(nil).Msg(err.Error()) return nil, setupType, config.ErrInvalidErasureEndpoints(nil).Msg(err.Error())
} }
for i := range eps { for diskIdx := range eps {
eps[i].SetPool(poolIdx) eps[diskIdx].SetPoolIndex(poolIdx)
eps[diskIdx].SetSetIndex(setIdx)
eps[diskIdx].SetDiskIndex(diskIdx)
} }
endpoints = append(endpoints, eps...) endpoints = append(endpoints, eps...)
@ -1022,6 +1040,11 @@ func CreateEndpoints(serverAddr string, args ...[]string) (Endpoints, SetupType,
if endpoint.Type() != PathEndpointType { if endpoint.Type() != PathEndpointType {
return endpoints, setupType, config.ErrInvalidEndpoint(nil).Msg("use path style endpoint for single node setup") return endpoints, setupType, config.ErrInvalidEndpoint(nil).Msg("use path style endpoint for single node setup")
} }
endpoint.SetPoolIndex(0)
endpoint.SetSetIndex(0)
endpoint.SetDiskIndex(0)
endpoints = append(endpoints, endpoint) endpoints = append(endpoints, endpoint)
setupType = ErasureSDSetupType setupType = ErasureSDSetupType
@ -1033,7 +1056,7 @@ func CreateEndpoints(serverAddr string, args ...[]string) (Endpoints, SetupType,
return endpoints, setupType, nil return endpoints, setupType, nil
} }
for _, iargs := range args { for setIdx, iargs := range args {
// Convert args to endpoints // Convert args to endpoints
eps, err := NewEndpoints(iargs...) eps, err := NewEndpoints(iargs...)
if err != nil { if err != nil {
@ -1045,6 +1068,11 @@ func CreateEndpoints(serverAddr string, args ...[]string) (Endpoints, SetupType,
return endpoints, setupType, config.ErrInvalidErasureEndpoints(nil).Msg(err.Error()) return endpoints, setupType, config.ErrInvalidErasureEndpoints(nil).Msg(err.Error())
} }
for diskIdx := range eps {
eps[diskIdx].SetSetIndex(setIdx)
eps[diskIdx].SetDiskIndex(diskIdx)
}
endpoints = append(endpoints, eps...) endpoints = append(endpoints, eps...)
} }

View File

@ -37,9 +37,9 @@ func TestNewEndpoint(t *testing.T) {
expectedType EndpointType expectedType EndpointType
expectedErr error expectedErr error
}{ }{
{"/foo", Endpoint{URL: &url.URL{Path: rootSlashFoo}, IsLocal: true}, PathEndpointType, nil}, {"/foo", Endpoint{&url.URL{Path: rootSlashFoo}, true, -1, -1, -1}, PathEndpointType, nil},
{"https://example.org/path", Endpoint{URL: u2, IsLocal: false}, URLEndpointType, nil}, {"https://example.org/path", Endpoint{u2, false, -1, -1, -1}, URLEndpointType, nil},
{"http://192.168.253.200/path", Endpoint{URL: u4, IsLocal: false}, URLEndpointType, nil}, {"http://192.168.253.200/path", Endpoint{u4, false, -1, -1, -1}, URLEndpointType, nil},
{"", Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, {"", Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")},
{SlashSeparator, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, {SlashSeparator, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")},
{`\`, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")}, {`\`, Endpoint{}, -1, fmt.Errorf("empty or root endpoint is not supported")},

View File

@ -173,7 +173,7 @@ func TestNewErasureSets(t *testing.T) {
defer os.RemoveAll(disk) defer os.RemoveAll(disk)
} }
endpoints := mustGetNewEndpoints(0, erasureDisks...) endpoints := mustGetNewEndpoints(0, 16, erasureDisks...)
_, _, err := waitForFormatErasure(true, endpoints, 1, 0, 16, "", "") _, _, err := waitForFormatErasure(true, endpoints, 1, 0, 16, "", "")
if err != errInvalidArgument { if err != errInvalidArgument {
t.Fatalf("Expecting error, got %s", err) t.Fatalf("Expecting error, got %s", err)

View File

@ -174,33 +174,32 @@ func getDisksInfo(disks []StorageAPI, endpoints []Endpoint) (disksInfo []madmin.
for index := range disks { for index := range disks {
index := index index := index
g.Go(func() error { g.Go(func() error {
diskEndpoint := endpoints[index].String() di := madmin.Disk{
Endpoint: endpoints[index].String(),
PoolIndex: endpoints[index].PoolIdx,
SetIndex: endpoints[index].SetIdx,
DiskIndex: endpoints[index].DiskIdx,
}
if disks[index] == OfflineDisk { if disks[index] == OfflineDisk {
logger.LogOnceIf(GlobalContext, fmt.Errorf("%s: %s", errDiskNotFound, endpoints[index]), "get-disks-info-offline-"+diskEndpoint) logger.LogOnceIf(GlobalContext, fmt.Errorf("%s: %s", errDiskNotFound, endpoints[index]), "get-disks-info-offline-"+di.Endpoint)
disksInfo[index] = madmin.Disk{ di.State = diskErrToDriveState(errDiskNotFound)
State: diskErrToDriveState(errDiskNotFound), disksInfo[index] = di
Endpoint: diskEndpoint,
}
return nil return nil
} }
info, err := disks[index].DiskInfo(context.TODO()) info, err := disks[index].DiskInfo(context.TODO())
di := madmin.Disk{ di.DrivePath = info.MountPath
Endpoint: diskEndpoint, di.TotalSpace = info.Total
DrivePath: info.MountPath, di.UsedSpace = info.Used
TotalSpace: info.Total, di.AvailableSpace = info.Free
UsedSpace: info.Used, di.UUID = info.ID
AvailableSpace: info.Free, di.Major = info.Major
UUID: info.ID, di.Minor = info.Minor
Major: info.Major, di.RootDisk = info.RootDisk
Minor: info.Minor, di.Healing = info.Healing
RootDisk: info.RootDisk, di.Scanning = info.Scanning
Healing: info.Healing, di.State = diskErrToDriveState(err)
Scanning: info.Scanning, di.FreeInodes = info.FreeInodes
State: diskErrToDriveState(err), di.UsedInodes = info.UsedInodes
FreeInodes: info.FreeInodes,
UsedInodes: info.UsedInodes,
}
di.PoolIndex, di.SetIndex, di.DiskIndex = disks[index].GetDiskLoc()
if info.Healing { if info.Healing {
if hi := disks[index].Healing(); hi != nil { if hi := disks[index].Healing(); hi != nil {
hd := hi.toHealingDisk() hd := hi.toHealingDisk()

View File

@ -36,7 +36,7 @@ func TestFixFormatV3(t *testing.T) {
for _, erasureDir := range erasureDirs { for _, erasureDir := range erasureDirs {
defer os.RemoveAll(erasureDir) defer os.RemoveAll(erasureDir)
} }
endpoints := mustGetNewEndpoints(0, erasureDirs...) endpoints := mustGetNewEndpoints(0, 8, erasureDirs...)
storageDisks, errs := initStorageDisksWithErrors(endpoints, false) storageDisks, errs := initStorageDisksWithErrors(endpoints, false)
for _, err := range errs { for _, err := range errs {
@ -555,7 +555,8 @@ func benchmarkInitStorageDisksN(b *testing.B, nDisks int) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
endpoints := mustGetNewEndpoints(0, fsDirs...)
endpoints := mustGetNewEndpoints(0, 16, fsDirs...)
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
endpoints := endpoints endpoints := endpoints
for pb.Next() { for pb.Next() {

View File

@ -2173,13 +2173,13 @@ func generateTLSCertKey(host string) ([]byte, []byte, error) {
} }
func mustGetPoolEndpoints(poolIdx int, args ...string) EndpointServerPools { func mustGetPoolEndpoints(poolIdx int, args ...string) EndpointServerPools {
endpoints := mustGetNewEndpoints(poolIdx, args...)
drivesPerSet := len(args) drivesPerSet := len(args)
setCount := 1 setCount := 1
if len(args) >= 16 { if len(args) >= 16 {
drivesPerSet = 16 drivesPerSet = 16
setCount = len(args) / 16 setCount = len(args) / 16
} }
endpoints := mustGetNewEndpoints(poolIdx, drivesPerSet, args...)
return []PoolEndpoints{{ return []PoolEndpoints{{
SetCount: setCount, SetCount: setCount,
DrivesPerSet: drivesPerSet, DrivesPerSet: drivesPerSet,
@ -2188,12 +2188,16 @@ func mustGetPoolEndpoints(poolIdx int, args ...string) EndpointServerPools {
}} }}
} }
func mustGetNewEndpoints(poolIdx int, args ...string) (endpoints Endpoints) { func mustGetNewEndpoints(poolIdx int, drivesPerSet int, args ...string) (endpoints Endpoints) {
endpoints, err := NewEndpoints(args...) endpoints, err := NewEndpoints(args...)
for i := range endpoints { if err != nil {
endpoints[i].Pool = poolIdx panic(err)
}
for i := range endpoints {
endpoints[i].SetPoolIndex(poolIdx)
endpoints[i].SetSetIndex(i / drivesPerSet)
endpoints[i].SetDiskIndex(i % drivesPerSet)
} }
logger.FatalIf(err, "unable to create new endpoint list")
return endpoints return endpoints
} }