drbd: Delayed creation of current-UUID
authorPhilipp Reisner <philipp.reisner@linbit.com>
Fri, 11 Jun 2010 09:26:34 +0000 (11:26 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 14 Oct 2010 12:59:21 +0000 (14:59 +0200)
When a fencing policy of "resource-and-stonith" is configured,
and DRBD looses connection to it's peer, we can delay the
creation of a new current-UUID until IO gets thawed.

That allows one to deploy fence-peer handlers that actually
commit suicide on the machine they get started.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c

index ab20c0062d2119e67acfe934e882016092211465..e0e08f5e0a76183e95e26d6694a7b963a47350ec 100644 (file)
@@ -829,6 +829,7 @@ enum {
                                 * the peer, if it changed there as well. */
        CONN_DRY_RUN,           /* Expect disconnect after resync handshake. */
        GOT_PING_ACK,           /* set when we receive a ping_ack packet, misc wait gets woken */
+       NEW_CUR_UUID,           /* Create new current UUID when thawing IO */
 };
 
 struct drbd_bitmap; /* opaque for drbd_conf */
index 40baddd94a5bc7ff216b6f7633df2fcfc30c4df6..440b1d5dcfe2be8091312c20cb53739cb12f449c 100644 (file)
@@ -1252,12 +1252,23 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
        }
 
        if (fp == FP_STONITH && ns.susp) {
-               /* case1: The outdate peer handler is successful:
-                * case2: The connection was established again: */
-               if ((os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) ||
-                   (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED)) {
+               /* case1: The outdate peer handler is successful: */
+               if (os.pdsk > D_OUTDATED  && ns.pdsk <= D_OUTDATED) {
                        tl_clear(mdev);
+                       if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
+                               drbd_uuid_new_current(mdev);
+                               clear_bit(NEW_CUR_UUID, &mdev->flags);
+                               drbd_md_sync(mdev);
+                       }
+                       spin_lock_irq(&mdev->req_lock);
+                       _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
+                       spin_unlock_irq(&mdev->req_lock);
+               }
+               /* case2: The connection was established again: */
+               if (os.conn < C_CONNECTED && ns.conn >= C_CONNECTED) {
+                       clear_bit(NEW_CUR_UUID, &mdev->flags);
                        spin_lock_irq(&mdev->req_lock);
+                       _tl_restart(mdev, resend);
                        _drbd_set_state(_NS(mdev, susp, 0), CS_VERBOSE, NULL);
                        spin_unlock_irq(&mdev->req_lock);
                }
@@ -1280,8 +1291,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
                if (get_ldev(mdev)) {
                        if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) &&
                            mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) {
-                               drbd_uuid_new_current(mdev);
-                               drbd_send_uuids(mdev);
+                               if (mdev->state.susp) {
+                                       set_bit(NEW_CUR_UUID, &mdev->flags);
+                               } else {
+                                       drbd_uuid_new_current(mdev);
+                                       drbd_send_uuids(mdev);
+                               }
                        }
                        put_ldev(mdev);
                }
index 32d00720470ba4b2277d3dc3088ec89207452aab..d764f3cd5866c9381bebf053a58f3a353d5a6cb1 100644 (file)
@@ -1810,6 +1810,11 @@ static int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nl
 static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
                             struct drbd_nl_cfg_reply *reply)
 {
+       if (test_bit(NEW_CUR_UUID, &mdev->flags)) {
+               drbd_uuid_new_current(mdev);
+               clear_bit(NEW_CUR_UUID, &mdev->flags);
+               drbd_md_sync(mdev);
+       }
        drbd_suspend_io(mdev);
        reply->ret_code = drbd_request_state(mdev, NS(susp, 0));
        if (reply->ret_code == SS_SUCCESS) {