mirror of https://github.com/minio/minio.git
				
				
				
			fix: report correct pool/set/disk indexes for offline disks (#17695)
This commit is contained in:
		
							parent
							
								
									bddd53d6d2
								
							
						
					
					
						commit
						756d6aa729
					
				| 
						 | 
					@ -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,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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")},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue