remove bad nodes from originalNodes list when repairing (#597)

* remove bad nodes from list

* create slice for healthy nodes

* add contains helper, clean up loop
This commit is contained in:
Cameron 2018-11-12 11:10:44 -05:00 committed by GitHub
parent 5dd41f0050
commit ace82bc834
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -314,18 +314,23 @@ func (s *segmentStore) Repair(ctx context.Context, path storj.Path, lostPieces [
// count the number of nil nodes thats needs to be repaired // count the number of nil nodes thats needs to be repaired
totalNilNodes := 0 totalNilNodes := 0
for j, v := range originalNodes {
if v != nil { healthyNodes := make([]*pb.Node, len(originalNodes))
excludeNodeIDs = append(excludeNodeIDs, node.IDFromString(v.GetId()))
} else { // populate healthyNodes with all nodes from originalNodes except those correlating to indices in lostPieces
for i, v := range originalNodes {
if v == nil {
totalNilNodes++ totalNilNodes++
continue
} }
//remove all lost pieces from the list to have only healthy pieces excludeNodeIDs = append(excludeNodeIDs, node.IDFromString(v.GetId()))
for i := range lostPieces {
if j == int(lostPieces[i]) { // If node index exists in lostPieces, skip adding it to healthyNodes
totalNilNodes++ if contains(lostPieces, i) {
} totalNilNodes++
} else {
healthyNodes[i] = v
} }
} }
@ -336,12 +341,21 @@ func (s *segmentStore) Repair(ctx context.Context, path storj.Path, lostPieces [
return err return err
} }
if totalNilNodes != len(newNodes) {
return Error.New("Number of new nodes from overlay (%d) does not equal total nil nodes (%d)", len(newNodes), totalNilNodes)
}
totalRepairCount := len(newNodes) totalRepairCount := len(newNodes)
//make a repair nodes list just with new unique ids //make a repair nodes list just with new unique ids
repairNodesList := make([]*pb.Node, len(originalNodes)) repairNodesList := make([]*pb.Node, len(healthyNodes))
for j, vr := range originalNodes { for j, vr := range healthyNodes {
// find the nil in the original node list // check that totalRepairCount is non-negative
if totalRepairCount < 0 {
return Error.New("Total repair count (%d) less than zero", totalRepairCount)
}
// find the nil in the node list
if vr == nil { if vr == nil {
// replace the location with the newNode Node info // replace the location with the newNode Node info
totalRepairCount-- totalRepairCount--
@ -349,6 +363,11 @@ func (s *segmentStore) Repair(ctx context.Context, path storj.Path, lostPieces [
} }
} }
// check that all nil nodes have a replacement prepared
if totalRepairCount != 0 {
return Error.New("Failed to replace all nil nodes (%d). (%d) new nodes not inserted", len(newNodes), totalRepairCount)
}
es, err := makeErasureScheme(pr.GetRemote().GetRedundancy()) es, err := makeErasureScheme(pr.GetRemote().GetRedundancy())
if err != nil { if err != nil {
return Error.Wrap(err) return Error.Wrap(err)
@ -358,7 +377,7 @@ func (s *segmentStore) Repair(ctx context.Context, path storj.Path, lostPieces [
pba := s.pdb.PayerBandwidthAllocation() pba := s.pdb.PayerBandwidthAllocation()
// download the segment using the nodes just with healthy nodes // download the segment using the nodes just with healthy nodes
rr, err := s.ec.Get(ctx, originalNodes, es, pid, pr.GetSize(), pba, signedMessage) rr, err := s.ec.Get(ctx, healthyNodes, es, pid, pr.GetSize(), pba, signedMessage)
if err != nil { if err != nil {
return Error.Wrap(err) return Error.Wrap(err)
} }
@ -378,16 +397,16 @@ func (s *segmentStore) Repair(ctx context.Context, path storj.Path, lostPieces [
return Error.Wrap(err) return Error.Wrap(err)
} }
// merge the successful nodes list into the originalNodes list // merge the successful nodes list into the healthy nodes list
for i, v := range originalNodes { for i, v := range healthyNodes {
if v == nil { if v == nil {
// copy the successfuNode info // copy the successfuNode info
originalNodes[i] = successfulNodes[i] healthyNodes[i] = successfulNodes[i]
} }
} }
metadata := pr.GetMetadata() metadata := pr.GetMetadata()
pointer, err := s.makeRemotePointer(originalNodes, pid, rr.Size(), exp, metadata) pointer, err := s.makeRemotePointer(healthyNodes, pid, rr.Size(), exp, metadata)
if err != nil { if err != nil {
return err return err
} }
@ -438,6 +457,16 @@ func (s *segmentStore) List(ctx context.Context, prefix, startAfter, endBefore s
return items, more, nil return items, more, nil
} }
// contains checks if n exists in list
func contains(list []int32, n int) bool {
for i := range list {
if n == int(list[i]) {
return true
}
}
return false
}
// convertMeta converts pointer to segment metadata // convertMeta converts pointer to segment metadata
func convertMeta(pr *pb.Pointer) Meta { func convertMeta(pr *pb.Pointer) Meta {
return Meta{ return Meta{