diff options
Diffstat (limited to 'drivers/block/drbd/drbd_receiver.c')
-rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d065c646b35a..3f096e7959b4 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -899,7 +899,8 @@ retry: | |||
899 | 899 | ||
900 | drbd_thread_start(&mdev->asender); | 900 | drbd_thread_start(&mdev->asender); |
901 | 901 | ||
902 | drbd_send_protocol(mdev); | 902 | if (!drbd_send_protocol(mdev)) |
903 | return -1; | ||
903 | drbd_send_sync_param(mdev, &mdev->sync_conf); | 904 | drbd_send_sync_param(mdev, &mdev->sync_conf); |
904 | drbd_send_sizes(mdev, 0); | 905 | drbd_send_sizes(mdev, 0); |
905 | drbd_send_uuids(mdev); | 906 | drbd_send_uuids(mdev); |
@@ -2513,6 +2514,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol | |||
2513 | } | 2514 | } |
2514 | 2515 | ||
2515 | if (hg == -100) { | 2516 | if (hg == -100) { |
2517 | /* FIXME this log message is not correct if we end up here | ||
2518 | * after an attempted attach on a diskless node. | ||
2519 | * We just refuse to attach -- well, we drop the "connection" | ||
2520 | * to that disk, in a way... */ | ||
2516 | dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); | 2521 | dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); |
2517 | drbd_khelper(mdev, "split-brain"); | 2522 | drbd_khelper(mdev, "split-brain"); |
2518 | return C_MASK; | 2523 | return C_MASK; |
@@ -2538,6 +2543,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol | |||
2538 | } | 2543 | } |
2539 | } | 2544 | } |
2540 | 2545 | ||
2546 | if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) { | ||
2547 | if (hg == 0) | ||
2548 | dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n"); | ||
2549 | else | ||
2550 | dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.", | ||
2551 | drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET), | ||
2552 | abs(hg) >= 2 ? "full" : "bit-map based"); | ||
2553 | return C_MASK; | ||
2554 | } | ||
2555 | |||
2541 | if (abs(hg) >= 2) { | 2556 | if (abs(hg) >= 2) { |
2542 | dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); | 2557 | dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); |
2543 | if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) | 2558 | if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) |
@@ -2585,7 +2600,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) | |||
2585 | struct p_protocol *p = (struct p_protocol *)h; | 2600 | struct p_protocol *p = (struct p_protocol *)h; |
2586 | int header_size, data_size; | 2601 | int header_size, data_size; |
2587 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; | 2602 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; |
2588 | int p_want_lose, p_two_primaries; | 2603 | int p_want_lose, p_two_primaries, cf; |
2589 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; | 2604 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; |
2590 | 2605 | ||
2591 | header_size = sizeof(*p) - sizeof(*h); | 2606 | header_size = sizeof(*p) - sizeof(*h); |
@@ -2598,8 +2613,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) | |||
2598 | p_after_sb_0p = be32_to_cpu(p->after_sb_0p); | 2613 | p_after_sb_0p = be32_to_cpu(p->after_sb_0p); |
2599 | p_after_sb_1p = be32_to_cpu(p->after_sb_1p); | 2614 | p_after_sb_1p = be32_to_cpu(p->after_sb_1p); |
2600 | p_after_sb_2p = be32_to_cpu(p->after_sb_2p); | 2615 | p_after_sb_2p = be32_to_cpu(p->after_sb_2p); |
2601 | p_want_lose = be32_to_cpu(p->want_lose); | ||
2602 | p_two_primaries = be32_to_cpu(p->two_primaries); | 2616 | p_two_primaries = be32_to_cpu(p->two_primaries); |
2617 | cf = be32_to_cpu(p->conn_flags); | ||
2618 | p_want_lose = cf & CF_WANT_LOSE; | ||
2619 | |||
2620 | clear_bit(CONN_DRY_RUN, &mdev->flags); | ||
2621 | |||
2622 | if (cf & CF_DRY_RUN) | ||
2623 | set_bit(CONN_DRY_RUN, &mdev->flags); | ||
2603 | 2624 | ||
2604 | if (p_proto != mdev->net_conf->wire_protocol) { | 2625 | if (p_proto != mdev->net_conf->wire_protocol) { |
2605 | dev_err(DEV, "incompatible communication protocols\n"); | 2626 | dev_err(DEV, "incompatible communication protocols\n"); |
@@ -3118,13 +3139,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h) | |||
3118 | 3139 | ||
3119 | put_ldev(mdev); | 3140 | put_ldev(mdev); |
3120 | if (nconn == C_MASK) { | 3141 | if (nconn == C_MASK) { |
3142 | nconn = C_CONNECTED; | ||
3121 | if (mdev->state.disk == D_NEGOTIATING) { | 3143 | if (mdev->state.disk == D_NEGOTIATING) { |
3122 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 3144 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); |
3123 | nconn = C_CONNECTED; | ||
3124 | } else if (peer_state.disk == D_NEGOTIATING) { | 3145 | } else if (peer_state.disk == D_NEGOTIATING) { |
3125 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); | 3146 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); |
3126 | peer_state.disk = D_DISKLESS; | 3147 | peer_state.disk = D_DISKLESS; |
3148 | real_peer_disk = D_DISKLESS; | ||
3127 | } else { | 3149 | } else { |
3150 | if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) | ||
3151 | return FALSE; | ||
3128 | D_ASSERT(oconn == C_WF_REPORT_PARAMS); | 3152 | D_ASSERT(oconn == C_WF_REPORT_PARAMS); |
3129 | drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); | 3153 | drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); |
3130 | return FALSE; | 3154 | return FALSE; |
@@ -3594,10 +3618,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) | |||
3594 | 3618 | ||
3595 | /* asender does not clean up anything. it must not interfere, either */ | 3619 | /* asender does not clean up anything. it must not interfere, either */ |
3596 | drbd_thread_stop(&mdev->asender); | 3620 | drbd_thread_stop(&mdev->asender); |
3597 | |||
3598 | mutex_lock(&mdev->data.mutex); | ||
3599 | drbd_free_sock(mdev); | 3621 | drbd_free_sock(mdev); |
3600 | mutex_unlock(&mdev->data.mutex); | ||
3601 | 3622 | ||
3602 | spin_lock_irq(&mdev->req_lock); | 3623 | spin_lock_irq(&mdev->req_lock); |
3603 | _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); | 3624 | _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); |
@@ -4054,6 +4075,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h) | |||
4054 | { | 4075 | { |
4055 | /* restore idle timeout */ | 4076 | /* restore idle timeout */ |
4056 | mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; | 4077 | mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; |
4078 | if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags)) | ||
4079 | wake_up(&mdev->misc_wait); | ||
4057 | 4080 | ||
4058 | return TRUE; | 4081 | return TRUE; |
4059 | } | 4082 | } |