|
|
@ -577,7 +577,8 @@ func (h *healSequence) queueHealTask(path string, healType madmin.HealItemType) |
|
|
|
func (h *healSequence) healItemsFromSourceCh() error { |
|
|
|
func (h *healSequence) healItemsFromSourceCh() error { |
|
|
|
h.lastHealActivity = UTCNow() |
|
|
|
h.lastHealActivity = UTCNow() |
|
|
|
|
|
|
|
|
|
|
|
if err := h.healItems(); err != nil { |
|
|
|
bucketsOnly := true // heal buckets only, not objects.
|
|
|
|
|
|
|
|
if err := h.healItems(bucketsOnly); err != nil { |
|
|
|
logger.LogIf(h.ctx, err) |
|
|
|
logger.LogIf(h.ctx, err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -615,7 +616,7 @@ func (h *healSequence) healFromSourceCh() { |
|
|
|
close(h.traverseAndHealDoneCh) |
|
|
|
close(h.traverseAndHealDoneCh) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (h *healSequence) healItems() error { |
|
|
|
func (h *healSequence) healItems(bucketsOnly bool) error { |
|
|
|
// Start with format healing
|
|
|
|
// Start with format healing
|
|
|
|
if err := h.healDiskFormat(); err != nil { |
|
|
|
if err := h.healDiskFormat(); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
@ -637,7 +638,7 @@ func (h *healSequence) healItems() error { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Heal buckets and objects
|
|
|
|
// Heal buckets and objects
|
|
|
|
return h.healBuckets() |
|
|
|
return h.healBuckets(bucketsOnly) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// traverseAndHeal - traverses on-disk data and performs healing
|
|
|
|
// traverseAndHeal - traverses on-disk data and performs healing
|
|
|
@ -648,7 +649,8 @@ func (h *healSequence) healItems() error { |
|
|
|
// has to wait until a safe point is reached, such as between scanning
|
|
|
|
// has to wait until a safe point is reached, such as between scanning
|
|
|
|
// two objects.
|
|
|
|
// two objects.
|
|
|
|
func (h *healSequence) traverseAndHeal() { |
|
|
|
func (h *healSequence) traverseAndHeal() { |
|
|
|
if err := h.healItems(); err != nil { |
|
|
|
bucketsOnly := false // Heals buckets and objects also.
|
|
|
|
|
|
|
|
if err := h.healItems(bucketsOnly); err != nil { |
|
|
|
if h.isQuitting() { |
|
|
|
if h.isQuitting() { |
|
|
|
err = errHealStopSignalled |
|
|
|
err = errHealStopSignalled |
|
|
|
} |
|
|
|
} |
|
|
@ -704,14 +706,14 @@ func (h *healSequence) healDiskFormat() error { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// healBuckets - check for all buckets heal or just particular bucket.
|
|
|
|
// healBuckets - check for all buckets heal or just particular bucket.
|
|
|
|
func (h *healSequence) healBuckets() error { |
|
|
|
func (h *healSequence) healBuckets(bucketsOnly bool) error { |
|
|
|
if h.isQuitting() { |
|
|
|
if h.isQuitting() { |
|
|
|
return errHealStopSignalled |
|
|
|
return errHealStopSignalled |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 1. If a bucket was specified, heal only the bucket.
|
|
|
|
// 1. If a bucket was specified, heal only the bucket.
|
|
|
|
if h.bucket != "" { |
|
|
|
if h.bucket != "" { |
|
|
|
return h.healBucket(h.bucket) |
|
|
|
return h.healBucket(h.bucket, bucketsOnly) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get current object layer instance.
|
|
|
|
// Get current object layer instance.
|
|
|
@ -726,7 +728,7 @@ func (h *healSequence) healBuckets() error { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, bucket := range buckets { |
|
|
|
for _, bucket := range buckets { |
|
|
|
if err = h.healBucket(bucket.Name); err != nil { |
|
|
|
if err = h.healBucket(bucket.Name, bucketsOnly); err != nil { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -735,7 +737,7 @@ func (h *healSequence) healBuckets() error { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// healBucket - traverses and heals given bucket
|
|
|
|
// healBucket - traverses and heals given bucket
|
|
|
|
func (h *healSequence) healBucket(bucket string) error { |
|
|
|
func (h *healSequence) healBucket(bucket string, bucketsOnly bool) error { |
|
|
|
// Get current object layer instance.
|
|
|
|
// Get current object layer instance.
|
|
|
|
objectAPI := newObjectLayerWithoutSafeModeFn() |
|
|
|
objectAPI := newObjectLayerWithoutSafeModeFn() |
|
|
|
if objectAPI == nil { |
|
|
|
if objectAPI == nil { |
|
|
@ -746,6 +748,10 @@ func (h *healSequence) healBucket(bucket string) error { |
|
|
|
return err |
|
|
|
return err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if bucketsOnly { |
|
|
|
|
|
|
|
return nil |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if !h.settings.Recursive { |
|
|
|
if !h.settings.Recursive { |
|
|
|
if h.objPrefix != "" { |
|
|
|
if h.objPrefix != "" { |
|
|
|
// Check if an object named as the objPrefix exists,
|
|
|
|
// Check if an object named as the objPrefix exists,
|
|
|
|