Skip to content

Commit f7f5c2d

Browse files
authored
DAOS-18470 rebuild: re-schedule rebuild task after stopped (#17492)
* DAOS-18470 rebuild: re-schedule rebuild task after stopped To fix some rebuild stop sequence problem for example - 1. kill rank 5, trigger rebuild task A 2. dmg pool rebuild stop 3. kill rank 6 trigger rebuild task B After 3's rebuild done, rank 5 status keeps as DOWN, but rank 6 is DOWNOUT. The problem is due to in rebuild task B it actually rebuilt both rank 5 and rank 6, but when it completes it only sets rank 5's status to DOWNOUT because rebuild B's task->dst_tgts only with rank 6. This patch take a temporarily simple method that - After the rebuild stopped, reschedule original rebuild task with delay -1, so following's rebuild can be merge with that to a new rebuild with merged task->dst_tgts (which include both rank 5 and 6 in that case). In future can consider to refine rebuild task management further. Signed-off-by: Xuezhao Liu <xuezhao.liu@hpe.com>
1 parent df7854a commit f7f5c2d

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

src/rebuild/srv.c

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,12 @@ rebuild_try_merge_tgts(struct ds_pool *pool, uint32_t map_ver,
16051605
if (delay_sec != (uint64_t)(-1))
16061606
merge_task->dst_schedule_time = daos_gettime_coarse() + delay_sec;
16071607
}
1608+
/* For the case of new rebuild task in queue, and then rebuild stop's fail reclaim
1609+
* complete and re-scheduled the original rebuild task with delay -1.
1610+
*/
1611+
if (merge_pre_task->dst_schedule_time != (uint64_t)(-1) &&
1612+
delay_sec == (uint64_t)(-1))
1613+
merge_task = merge_pre_task;
16081614
} else if (merge_post_task != NULL && merge_post_task->dst_rebuild_op == rebuild_op) {
16091615
if ((merge_post_task->dst_schedule_time == (uint64_t)(-1) &&
16101616
delay_sec == (uint64_t)(-1)) ||
@@ -1854,6 +1860,25 @@ rebuild_task_complete_schedule(struct rebuild_task *task, struct ds_pool *pool,
18541860
* fails, it will be used to discard all of the previous rebuild data
18551861
* (reclaim - 1 see obj_reclaim()), but keep the in-flight I/O data.
18561862
*/
1863+
if (rgt->rgt_stop_admin) {
1864+
rc = ds_rebuild_schedule(
1865+
pool, task->dst_reclaim_ver - 1 /* map_ver */,
1866+
rgt->rgt_stable_epoch, task->dst_new_layout_version,
1867+
&task->dst_tgts, RB_OP_FAIL_RECLAIM,
1868+
task->dst_rebuild_op /* retry_rebuild_op */,
1869+
task->dst_map_ver /* retry_map_ver */, rgt->rgt_stop_admin,
1870+
task, delay_sec);
1871+
DL_CDEBUG(rc, DLOG_ERR, DLOG_INFO, rc,
1872+
DF_RB ": errno " DF_RC ", schedule %u(%s)",
1873+
DP_RB_RGT(rgt), DP_RC(rgt->rgt_status.rs_errno),
1874+
RB_OP_FAIL_RECLAIM, RB_OP_STR(RB_OP_FAIL_RECLAIM));
1875+
D_GOTO(complete, rc);
1876+
}
1877+
1878+
/* revert pool map and defer scheduling a retry until Fail_reclaim is done
1879+
*/
1880+
retry_rebuild_task(task, rgt, &retry_opc);
1881+
18571882
rc = ds_rebuild_schedule(
18581883
pool, task->dst_reclaim_ver - 1 /* map_ver */, rgt->rgt_stable_epoch,
18591884
task->dst_new_layout_version, &task->dst_tgts, RB_OP_FAIL_RECLAIM,
@@ -1863,10 +1888,6 @@ rebuild_task_complete_schedule(struct rebuild_task *task, struct ds_pool *pool,
18631888
DF_RB ": errno " DF_RC ", schedule %u(%s)", DP_RB_RGT(rgt),
18641889
DP_RC(rgt->rgt_status.rs_errno), RB_OP_FAIL_RECLAIM,
18651890
RB_OP_STR(RB_OP_FAIL_RECLAIM));
1866-
1867-
/* revert pool map and defer scheduling a retry until Fail_reclaim is done
1868-
*/
1869-
retry_rebuild_task(task, rgt, &retry_opc);
18701891
D_GOTO(complete, rc);
18711892
}
18721893

@@ -1926,6 +1947,23 @@ rebuild_task_complete_schedule(struct rebuild_task *task, struct ds_pool *pool,
19261947
DL_CDEBUG(rc1, DLOG_ERR, DLOG_INFO, rc1, DF_RB ": updated, state %d errno " DF_RC,
19271948
DP_RB_RGT(rgt), rgt->rgt_status.rs_state,
19281949
DP_RC(rgt->rgt_status.rs_errno));
1950+
1951+
/* re-schedule the stopped original rebuild task with delay -1, to be merged with
1952+
* following rebuild task, to avoid losing the task->dst_tgts.
1953+
*/
1954+
if (task->dst_retry_rebuild_op == RB_OP_REBUILD) {
1955+
rc = ds_rebuild_schedule(
1956+
pool, task->dst_retry_map_ver, rgt->rgt_reclaim_epoch,
1957+
task->dst_new_layout_version, &task->dst_tgts,
1958+
task->dst_retry_rebuild_op, RB_OP_NONE /* retry_rebuild_op */,
1959+
0 /* retry_map_ver */, false /* stop_admin */, task,
1960+
-1 /* delay_sec */);
1961+
DL_CDEBUG(rc, DLOG_ERR, DLOG_INFO, rc,
1962+
DF_RB ": errno " DF_RC ", schedule retry %u(%s) with delay -1",
1963+
DP_RB_RGT(rgt), DP_RC(rgt->rgt_status.rs_errno),
1964+
task->dst_retry_rebuild_op,
1965+
RB_OP_STR(task->dst_retry_rebuild_op));
1966+
}
19291967
} else if ((task->dst_rebuild_op == RB_OP_FAIL_RECLAIM) &&
19301968
(task->dst_retry_rebuild_op != RB_OP_NONE)) {
19311969
/* Fail_reclaim done (and a stop command wasn't received during) - retry rebuild. */

0 commit comments

Comments
 (0)