Skip to content

Commit

Permalink
Add node recovery callbacks
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
goldwynr committed Feb 23, 2015
1 parent ca8895d commit cf921cc
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 9 deletions.
1 change: 1 addition & 0 deletions drivers/md/bitmap.c
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/md/bitmap.h
Expand Up @@ -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:
Expand Down
62 changes: 57 additions & 5 deletions drivers/md/md-cluster.c
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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))
Expand All @@ -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;
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion drivers/md/md-cluster.h
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion drivers/md/md.c
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/md/md.h
Expand Up @@ -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 */
Expand Down

0 comments on commit cf921cc

Please sign in to comment.