controller: replica controller should enqueue all rebuilding replicas when there is a rebuilding complete/failed
Longhorn 2460
@@ -110,7 +110,15 @@ func NewReplicaController(
replicaInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: rc.enqueueReplica,
- UpdateFunc: func(old, cur interface{}) { rc.enqueueReplica(cur) },
+ UpdateFunc: func(old, cur interface{}) {
+ rc.enqueueReplica(cur)
+
+ oldR := old.(*longhorn.Replica)
+ curR := cur.(*longhorn.Replica)
+ if IsRebuildingReplica(oldR) && !IsRebuildingReplica(curR) {
+ rc.enqueueAllRebuildingReplicaOnCurrentNode()
+ }
+ },
DeleteFunc: rc.enqueueReplica,
})
@@ -393,7 +401,7 @@ func (rc *ReplicaController) CreateInstance(obj interface{}) (*types.InstancePro
}
}
- if r.Spec.RebuildRetryCount != 0 {
+ if IsRebuildingReplica(r) {
canStart, err := rc.CanStartRebuildingReplica(r)
if err != nil {
return nil, err
@@ -452,6 +460,10 @@ func (rc *ReplicaController) GetBackingImagePathForReplicaStarting(r *longhorn.R
return types.GetBackingImagePathForReplicaManagerContainer(r.Spec.DiskPath, r.Spec.BackingImage, bi.Status.UUID), nil
}
+func IsRebuildingReplica(r *longhorn.Replica) bool {
+ return r.Spec.RebuildRetryCount != 0 && r.Spec.HealthyAt == "" && r.Spec.FailedAt == ""
+}
+
func (rc *ReplicaController) CanStartRebuildingReplica(r *longhorn.Replica) (bool, error) {
log := getLoggerForReplica(rc.logger, r)
@@ -769,17 +781,23 @@ func (rc *ReplicaController) enqueueSettingChange(obj interface{}) {
return
}
+ rc.enqueueAllRebuildingReplicaOnCurrentNode()
+
+ return
+}
+
+func (rc *ReplicaController) enqueueAllRebuildingReplicaOnCurrentNode() {
replicas, err := rc.ds.ListReplicasByNodeRO(rc.controllerID)
if err != nil {
- utilruntime.HandleError(fmt.Errorf("failed to list replicas on current node %v for setting %v: %v",
- rc.controllerID, types.SettingNameConcurrentReplicaRebuildPerNodeLimit, err))
+ utilruntime.HandleError(fmt.Errorf("failed to list rebuilding replicas on current node %v: %v",
+ rc.controllerID, err))
return
}
for _, r := range replicas {
+ if IsRebuildingReplica(r) {
rc.enqueueReplica(r)
}
-
- return
+ }
}
func (rc *ReplicaController) isResponsibleFor(r *longhorn.Replica) bool {
