[sheepdog] [PATCH] recovery: fix incomplete recovery because of faulty oid scheduling

MORITA Kazutaka morita.kazutaka at gmail.com
Mon Apr 29 08:59:03 CEST 2013


At Mon, 29 Apr 2013 13:15:55 +0800,
Liu Yuan wrote:
> 
> On 04/29/2013 07:15 AM, MORITA Kazutaka wrote:
> > When auto-recovery is disabled, sheep recovers the objects only in
> > prio_oids and shouldn't reach here if the oid is in recovery, no?
> 
> No, this is why I saw bugs. I saw it happens only when two read on the same oid in the recovery process. The first one will trigger the oid scheduling(prepare/finish) and then the second one will also trigger it(prepare/finish) and result in faulty bug. The oids in rw->oids will be '7c2b2500000003,7c2b2500000003,7c2b2500000006', 7c2b2500000007 was ejected out.
> 
> Following is the error log when bug is reproduced by tests/010.
> 
> Apr 29 13:01:23 [main] queue_request(353) READ_OBJ, 1
> Apr 29 13:01:23 [main] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [main] finish_schedule_oids(405) nr_recovered 0, nr_prio_oids 1, count 3 = new 3
> Apr 29 13:01:23 [main] prepare_schedule_oid(252) 7c2b2500000003 nr_prio_oids 0
> Apr 29 13:01:23 [main] request_in_recovery(200) 7c2b2500000003 wait on oid
> Apr 29 13:01:23 [rw 4870] recover_object_work(205) done:0 count:3, oid:7c2b2500000003
> Apr 29 13:01:23 [rw 4870] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [rw 4870] do_recover_object(147) try recover object 7c2b2500000003 from epoch 8
> Apr 29 13:01:23 [rw 4870] sockfd_cache_get(387) 127.0.0.1:7007, idx 0
> Apr 29 13:01:23 [main] client_handler(808) 1, rx 0, tx 3
> Apr 29 13:01:23 [main] finish_rx(612) 27, 127.0.0.1:56182
> Apr 29 13:01:23 [main] queue_request(353) READ_PEER, 1
> Apr 29 13:01:23 [main] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [main] prepare_schedule_oid(252) 7c2b2500000003 nr_prio_oids 1
> Apr 29 13:01:23 [io 4869] do_process_work(1359) a4, 7c2b2500000003, 8
> Apr 29 13:01:23 [io 4869] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [io 4869] err_to_sderr(65) /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [io 4869] err_to_sderr(72) object 007c2b2500000003 not found locally
> Apr 29 13:01:23 [io 4869] do_process_work(1366) failed: a4, 7c2b2500000003 , 8, 2
> Apr 29 13:01:23 [main] io_op_done(67) unhandled error 2
> Apr 29 13:01:23 [main] client_handler(808) 4, rx 0, tx 3
> Apr 29 13:01:23 [main] finish_tx(699) connection from: 27, 127.0.0.1:56182
> Apr 29 13:01:23 [rw 4870] sheep_exec_req(526) failed 2
> Apr 29 13:01:23 [rw 4870] sockfd_cache_put(422) 127.0.0.1:7007 idx 0
> Apr 29 13:01:23 [rw 4870] sockfd_cache_get(387) 127.0.0.1:7002, idx 0
> Apr 29 13:01:23 [rw 4870] sockfd_cache_put(422) 127.0.0.1:7002 idx 0
> Apr 29 13:01:23 [rw 4870] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [rw 4870] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [rw 4870] default_create_and_write(343) 7c2b2500000003
> Apr 29 13:01:23 [rw 4870] recover_object_from_replica(111) recovered oid 7c2b2500000003 from 8 to epoch 8
> Apr 29 13:01:23 [main] wakeup_requests_on_oid(255) retry 7c2b2500000003
> Apr 29 13:01:23 [main] queue_request(353) READ_OBJ, 1
> Apr 29 13:01:23 [main] get_object_path(351) 0, /tmp/sheepdog/7/obj
> Apr 29 13:01:23 [main] oid_in_recovery(264) the object 7c2b2500000003 is already recoverd
> Apr 29 13:01:23 [main] finish_schedule_oids(405) WARN: nr_recovered 1, nr_prio_oids 1, count 3 = new 4
> 

Thanks, I understood what's going on from your log.

The problem is that scheduled oids can be re-scheduled again.  I think
the following is a better fix because it also omits redundant
scheduling even when auto-recovery is enabled.

---- >8 ---- >8 ---- >8 ----
diff --git a/sheep/recovery.c b/sheep/recovery.c
index 23babe0..e9cfc02 100644
--- a/sheep/recovery.c
+++ b/sheep/recovery.c
@@ -238,11 +238,15 @@ static inline void prepare_schedule_oid(uint64_t oid)
 			return;
 		}
 	/*
-	 * When auto recovery is enabled, the oid is currently being
-	 * recovered
+	 * rw->oids[rw->done..rw->nr_scheduled_prio_oids - 1] are
+	 * already scheduled ones.
 	 */
-	if (!sys->disable_recovery && rw->oids[rw->done] == oid)
-		return;
+	for (i = rw->done; i < rw->nr_scheduled_prio_oids; i++)
+		if (rw->oids[i] == oid) {
+			sd_dprintf("oid %" PRIx64 " is already scheduled", oid);
+			return;
+		}
+
 	rw->nr_prio_oids++;
 	rw->prio_oids = xrealloc(rw->prio_oids,
 				 rw->nr_prio_oids * sizeof(uint64_t));



More information about the sheepdog mailing list