int META_CHUNK::recovery_action(double now) { unsigned int i; int retval; if (data_now_present) { status = PRESENT; } if (debug_status) { printf(" meta chunk %s: status %s have_unrec_children %d\n", name, status_str(status), have_unrecoverable_children ); } for (i=0; i<children.size(); i++) { DATA_UNIT* c = children[i]; if (debug_status) { printf(" child %s status %s in rec set %d\n", c->name, status_str(c->status), c->in_recovery_set ); } switch (status) { case PRESENT: if (c->status == UNRECOVERABLE) { c->data_now_present = true; } break; case RECOVERABLE: if (c->in_recovery_set && have_unrecoverable_children) { c->data_needed = true; } break; case UNRECOVERABLE: break; } retval = c->recovery_action(now); if (retval) return retval; } return 0; }
void META_CHUNK::recovery_action() { unsigned int i; if (data_now_present) { status = PRESENT; } #ifdef DEBUG_RECOVERY printf("meta chunk action %s state %s unrec children %d\n", name, status_str(status), have_unrecoverable_children ); #endif for (i=0; i<children.size(); i++) { DATA_UNIT* c = children[i]; #ifdef DEBUG_RECOVERY printf(" child %s status %s in rec set %d\n", c->name, status_str(c->status), c->in_recovery_set ); #endif switch (status) { case PRESENT: if (c->status == UNRECOVERABLE) { c->data_now_present = true; } break; case RECOVERABLE: if (c->in_recovery_set && have_unrecoverable_children) { c->data_needed = true; } break; case UNRECOVERABLE: break; } c->recovery_action(); } // because of recovery action, some of our children may have changed // status and fault tolerance, source may have changed too. // Recompute them. // vector<DATA_UNIT*> recoverable; vector<DATA_UNIT*> present; for (i=0; i<children.size(); i++) { DATA_UNIT* c = children[i]; switch (c->status) { case PRESENT: present.push_back(c); break; case RECOVERABLE: recoverable.push_back(c); break; } } if ((int)(present.size()) >= coding.n) { status = PRESENT; min_failures = INT_MAX; } else if ((int)(present.size() + recoverable.size()) >= coding.n) { status = RECOVERABLE; // our min_failures is the least X such that some X host failures // would make this node unrecoverable // sort(recoverable.begin(), recoverable.end(), compare_min_failures); min_failures = 0; unsigned int k = coding.n - present.size(); // we'd need to recover K recoverable children unsigned int j = recoverable.size() - k + 1; // a loss of J recoverable children would make this impossible // the loss of J recoverable children would make us unrecoverable // Sum the min_failures of the J children with smallest min_failures // for (i=0; i<j; i++) { DATA_UNIT* c = recoverable[i]; printf(" Min failures of %s: %d\n", c->name, c->min_failures); min_failures += c->min_failures; } printf(" our min failures: %d\n", min_failures); } }