Repository: minio/minio (language: go)

Issue:
Unable to start decommissioning 

<!--- Provide a general summary of the issue in the Title above -->

## Expected Behavior
decommissioning started successfully 

## Current Behavior
```
root@araid060 ~]# mc admin decommission start  myminio http://araid0{63...64}.niz/store/{1...4}
mc: <ERROR> Unable to start decommission on the specified pool. Decommission cannot be started, rebalance is already in progress.
[root@araid060 ~]# 
```

## Possible Solution
Unknown 

## Steps to Reproduce (for bugs)

* setup minio with 2 pools
* add data over 500K objects
* start rebalance
* stop rebalance
```
./mc admin rebalance stop myminio
Rebalance stopped for myminio
```
* start decommissioning
```
root@araid060 ~]# mc admin decommission start  myminio http://araid0{63...64}.niz/store/{1...4}
mc: <ERROR> Unable to start decommission on the specified pool. Decommission cannot be started, rebalance is already in progress.
```

## Context
cannot replace/remove pool with the old hardware 

## Regression
unable to start decommission 

## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* mc version RELEASE.2022-12-24T15-21-38Z (commit-id=176072dee43de613569aaa56061eba9d6d550290)
Runtime: go1.19.4 linux/amd64
Copyright (c) 2015-2022 MinIO, Inc.




Discussion / hints:
@arm2arm why are you wasting time doing rebalancing when you want to decommission? 
this was a wrong decision, we had 2 pools with different ages, successfully added 3-rd (new) pool.
removed faulty pool. so got 2 pools left 1 middle-aged and 1 brand new hardware.
started rebalance and later realized the middle aged hardware became unstable, overheating hba controllers.
I investigated this, but couldn't find the place where rebalance marks itself as finished - maybe I am missing something, but unless the operation is completely removed once it completes it seems that the state will "stick around".
I found the problem @klauspost sending a fix. 

Fix patch:
diff --git a/cmd/erasure-server-pool-rebalance.go b/cmd/erasure-server-pool-rebalance.go
index d4f57b0083aef..c23c10d835bc7 100644
--- a/cmd/erasure-server-pool-rebalance.go
+++ b/cmd/erasure-server-pool-rebalance.go
@@ -353,6 +353,7 @@ func (z *erasureServerPools) rebalanceBuckets(ctx context.Context, poolIdx int)
 				z.rebalMu.Lock()
 				z.rebalMeta.PoolStats[poolIdx].Info.Status = rebalStopped
 				z.rebalMeta.PoolStats[poolIdx].Info.EndTime = now
+				z.rebalMeta.cancel = nil // remove the already used context.CancelFunc
 				z.rebalMu.Unlock()
 
 				rebalDone = true
diff --git a/cmd/notification.go b/cmd/notification.go
index 93db127ba79b3..8be8557f5ca9d 100644
--- a/cmd/notification.go
+++ b/cmd/notification.go
@@ -649,6 +649,15 @@ func (sys *NotificationSys) StopRebalance(ctx context.Context) {
 			logger.LogIf(logger.SetReqInfo(ctx, reqInfo), nErr.Err)
 		}
 	}
+
+	objAPI := newObjectLayerFn()
+	if objAPI == nil {
+		logger.LogIf(ctx, errServerNotInitialized)
+		return
+	}
+	if pools, ok := objAPI.(*erasureServerPools); ok {
+		pools.StopRebalance()
+	}
 }
 
 // LoadRebalanceMeta notifies all peers to load rebalance.bin from object layer.


Test patch: