summaryrefslogtreecommitdiffstats
path: root/drivers/md/md-cluster.c
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.com>2014-03-30 00:42:49 -0500
committerGoldwyn Rodrigues <rgoldwyn@suse.com>2015-02-23 07:30:11 -0600
commitcf921cc19cf7c1e99f730a2faa02d80817d684a2 (patch)
tree702ad727e3310bc64b890bbe3195e50c3944370f /drivers/md/md-cluster.c
parentca8895d9bb41e743271c42a4438a296de891b73b (diff)
downloadlinux-cf921cc19cf7c1e99f730a2faa02d80817d684a2.tar.bz2
Add node recovery callbacks
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>
Diffstat (limited to 'drivers/md/md-cluster.c')
-rw-r--r--drivers/md/md-cluster.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index d141d4812c8c..1f3c8f39ecb2 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -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)