Add node recovery callbacks
authorGoldwyn Rodrigues <rgoldwyn@suse.com>
Sun, 30 Mar 2014 05:42:49 +0000 (00:42 -0500)
committerGoldwyn Rodrigues <rgoldwyn@suse.com>
Mon, 23 Feb 2015 13:30:11 +0000 (07:30 -0600)
DLM offers callbacks when a node fails and the lock remastery
is performed:

1. recover_prep: called when DLM discovers a node is down
2. recover_slot: called when DLM identifies the node and recovery
can start
3. recover_done: called when all nodes have completed recover_slot

recover_slot() and recover_done() are also called when the node joins
initially in order to inform the node with its slot number. These slot
numbers start from one, so we deduct one to make it start with zero
which the cluster-md code uses.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
drivers/md/bitmap.c
drivers/md/bitmap.h
drivers/md/md-cluster.c
drivers/md/md-cluster.h
drivers/md/md.c
drivers/md/md.h

index e2aacca46911333c7d7d094e60529950c8a01d05..b43a75a246e7d317af08a62b1b7979bdf88ed0cd 100644 (file)
@@ -637,6 +637,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
        if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
                set_bit(BITMAP_HOSTENDIAN, &bitmap->flags);
        bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
+       strlcpy(bitmap->mddev->bitmap_info.cluster_name, sb->cluster_name, 64);
        err = 0;
 out:
        kunmap_atomic(sb);
index f4e53eadb083b28d138878ae2d561abc8043153a..ec9032f105b85ea778ed7d5540e00da41f0d22b1 100644 (file)
@@ -130,9 +130,9 @@ typedef struct bitmap_super_s {
        __le32 write_behind; /* 60  number of outstanding write-behind writes */
        __le32 sectors_reserved; /* 64 number of 512-byte sectors that are
                                  * reserved for the bitmap. */
-
        __le32 nodes;        /* 68 the maximum number of nodes in cluster. */
-       __u8  pad[256 - 72]; /* set to zero */
+       __u8 cluster_name[64]; /* 72 cluster name to which this md belongs */
+       __u8  pad[256 - 136]; /* set to zero */
 } bitmap_super_t;
 
 /* notes:
index d141d4812c8c4fedfaaaf9e8648116fd5ab7d986..1f3c8f39ecb2a2b4dcd12b936983b47bbc10e0de 100644 (file)
@@ -30,6 +30,8 @@ struct dlm_lock_resource {
 struct md_cluster_info {
        /* dlm lock space and resources for clustered raid. */
        dlm_lockspace_t *lockspace;
+       int slot_number;
+       struct completion completion;
        struct dlm_lock_resource *sb_lock;
        struct mutex sb_mutex;
 };
@@ -136,10 +138,42 @@ static char *pretty_uuid(char *dest, char *src)
        return dest;
 }
 
+static void recover_prep(void *arg)
+{
+}
+
+static void recover_slot(void *arg, struct dlm_slot *slot)
+{
+       struct mddev *mddev = arg;
+       struct md_cluster_info *cinfo = mddev->cluster_info;
+
+       pr_info("md-cluster: %s Node %d/%d down. My slot: %d. Initiating recovery.\n",
+                       mddev->bitmap_info.cluster_name,
+                       slot->nodeid, slot->slot,
+                       cinfo->slot_number);
+}
+
+static void recover_done(void *arg, struct dlm_slot *slots,
+               int num_slots, int our_slot,
+               uint32_t generation)
+{
+       struct mddev *mddev = arg;
+       struct md_cluster_info *cinfo = mddev->cluster_info;
+
+       cinfo->slot_number = our_slot;
+       complete(&cinfo->completion);
+}
+
+static const struct dlm_lockspace_ops md_ls_ops = {
+       .recover_prep = recover_prep,
+       .recover_slot = recover_slot,
+       .recover_done = recover_done,
+};
+
 static int join(struct mddev *mddev, int nodes)
 {
        struct md_cluster_info *cinfo;
-       int ret;
+       int ret, ops_rv;
        char str[64];
 
        if (!try_module_get(THIS_MODULE))
@@ -149,24 +183,30 @@ static int join(struct mddev *mddev, int nodes)
        if (!cinfo)
                return -ENOMEM;
 
+       init_completion(&cinfo->completion);
+
+       mutex_init(&cinfo->sb_mutex);
+       mddev->cluster_info = cinfo;
+
        memset(str, 0, 64);
        pretty_uuid(str, mddev->uuid);
-       ret = dlm_new_lockspace(str, NULL, DLM_LSFL_FS, LVB_SIZE,
-                               NULL, NULL, NULL, &cinfo->lockspace);
+       ret = dlm_new_lockspace(str, mddev->bitmap_info.cluster_name,
+                               DLM_LSFL_FS, LVB_SIZE,
+                               &md_ls_ops, mddev, &ops_rv, &cinfo->lockspace);
        if (ret)
                goto err;
+       wait_for_completion(&cinfo->completion);
        cinfo->sb_lock = lockres_init(mddev, "cmd-super",
                                        NULL, 0);
        if (!cinfo->sb_lock) {
                ret = -ENOMEM;
                goto err;
        }
-       mutex_init(&cinfo->sb_mutex);
-       mddev->cluster_info = cinfo;
        return 0;
 err:
        if (cinfo->lockspace)
                dlm_release_lockspace(cinfo->lockspace, 2);
+       mddev->cluster_info = NULL;
        kfree(cinfo);
        module_put(THIS_MODULE);
        return ret;
@@ -183,9 +223,21 @@ static int leave(struct mddev *mddev)
        return 0;
 }
 
+/* slot_number(): Returns the MD slot number to use
+ * DLM starts the slot numbers from 1, wheras cluster-md
+ * wants the number to be from zero, so we deduct one
+ */
+static int slot_number(struct mddev *mddev)
+{
+       struct md_cluster_info *cinfo = mddev->cluster_info;
+
+       return cinfo->slot_number - 1;
+}
+
 static struct md_cluster_operations cluster_ops = {
        .join   = join,
        .leave  = leave,
+       .slot_number = slot_number,
 };
 
 static int __init cluster_init(void)
index aa9f07bd6b961eeca39bfb1eef0168ece7657549..52a21e0d6dbc5c1a3dc924c5ff4718b84e3ff0c5 100644 (file)
@@ -8,8 +8,9 @@
 struct mddev;
 
 struct md_cluster_operations {
-       int (*join)(struct mddev *mddev);
+       int (*join)(struct mddev *mddev, int nodes);
        int (*leave)(struct mddev *mddev);
+       int (*slot_number)(struct mddev *mddev);
 };
 
 #endif /* _MD_CLUSTER_H */
index 5ed57688e5c5109d32f607618194c1dd0e9937f3..8f310d98f082e6a1e16d7e50d92d77f6e92cfee0 100644 (file)
@@ -7277,7 +7277,7 @@ int md_setup_cluster(struct mddev *mddev, int nodes)
        }
        spin_unlock(&pers_lock);
 
-       return md_cluster_ops->join(mddev);
+       return md_cluster_ops->join(mddev, nodes);
 }
 
 void md_cluster_stop(struct mddev *mddev)
index 80fc89976915725de4f754db88398180790e5786..81e568090d8ff427535d411516df1b73b52cd6ae 100644 (file)
@@ -434,6 +434,7 @@ struct mddev {
                unsigned long           max_write_behind; /* write-behind mode */
                int                     external;
                int                     nodes; /* Maximum number of nodes in the cluster */
+               char                    cluster_name[64]; /* Name of the cluster */
        } bitmap_info;
 
        atomic_t                        max_corr_read_errors; /* max read retries */