BUG/MINOR: peers: empty chunks after a resync.
After pushing the last update related to a resync process, the teacher resets the re-connection's origin to the saved one (pointer position when he receive the resync request). But the last acknowledgement overwrites this pointer to an inconsistent value. In peersv2, it results with empty table chunks regularly pushed. The fix consist to move the confirm code to assure that the confirm message is always sent after the last acknowledgement related to the resync. And to reset the re-connection's origin to the saved one when a confirm message is received. This bug affects versions 1.6 and superior. For older versions (peersv1), this inconsistent state should not generate side effects because chunks are not used and a next acknowlegement message resets the pointer in a valid state.
This commit is contained in:
parent
30fcd39f35
commit
597b26e432
45
src/peers.c
45
src/peers.c
|
@ -886,6 +886,7 @@ static void peer_io_handler(struct appctx *appctx)
|
|||
curpeer->confirm++;
|
||||
}
|
||||
else if (msg_head[1] == PEER_MSG_CTRL_RESYNCCONFIRM) {
|
||||
struct shared_table *st;
|
||||
|
||||
/* If stopping state */
|
||||
if (stopping) {
|
||||
|
@ -894,6 +895,10 @@ static void peer_io_handler(struct appctx *appctx)
|
|||
appctx->st0 = PEER_SESS_ST_END;
|
||||
goto switchstate;
|
||||
}
|
||||
for (st = curpeer->tables; st; st = st->next) {
|
||||
st->update = st->last_pushed = st->teaching_origin;
|
||||
st->flags = 0;
|
||||
}
|
||||
|
||||
/* reset teaching flags to 0 */
|
||||
curpeer->flags &= PEER_TEACH_RESET;
|
||||
|
@ -1224,25 +1229,6 @@ static void peer_io_handler(struct appctx *appctx)
|
|||
}
|
||||
|
||||
|
||||
/* Confirm finished or partial messages */
|
||||
while (curpeer->confirm) {
|
||||
unsigned char msg[2];
|
||||
|
||||
/* There is a confirm messages to send */
|
||||
msg[0] = PEER_MSG_CLASS_CONTROL;
|
||||
msg[1] = PEER_MSG_CTRL_RESYNCCONFIRM;
|
||||
|
||||
/* message to buffer */
|
||||
repl = bi_putblk(si_ic(si), (char *)msg, sizeof(msg));
|
||||
if (repl <= 0) {
|
||||
/* no more write possible */
|
||||
if (repl == -1)
|
||||
goto full;
|
||||
appctx->st0 = PEER_SESS_ST_END;
|
||||
goto switchstate;
|
||||
}
|
||||
curpeer->confirm--;
|
||||
}
|
||||
|
||||
|
||||
/* Need to request a resync */
|
||||
|
@ -1491,7 +1477,6 @@ static void peer_io_handler(struct appctx *appctx)
|
|||
/* push local updates */
|
||||
if (!eb || eb->key > st->teaching_origin) {
|
||||
st->flags |= SHTABLE_F_TEACH_STAGE2;
|
||||
st->last_pushed = st->teaching_origin;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1548,6 +1533,26 @@ static void peer_io_handler(struct appctx *appctx)
|
|||
curpeer->flags |= PEER_F_TEACH_FINISHED;
|
||||
}
|
||||
|
||||
/* Confirm finished or partial messages */
|
||||
while (curpeer->confirm) {
|
||||
unsigned char msg[2];
|
||||
|
||||
/* There is a confirm messages to send */
|
||||
msg[0] = PEER_MSG_CLASS_CONTROL;
|
||||
msg[1] = PEER_MSG_CTRL_RESYNCCONFIRM;
|
||||
|
||||
/* message to buffer */
|
||||
repl = bi_putblk(si_ic(si), (char *)msg, sizeof(msg));
|
||||
if (repl <= 0) {
|
||||
/* no more write possible */
|
||||
if (repl == -1)
|
||||
goto full;
|
||||
appctx->st0 = PEER_SESS_ST_END;
|
||||
goto switchstate;
|
||||
}
|
||||
curpeer->confirm--;
|
||||
}
|
||||
|
||||
/* noting more to do */
|
||||
goto out;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue