Skip to content

Commit

Permalink
[DLM] wait for config check during join [6/6]
Browse files Browse the repository at this point in the history
Joining the lockspace should wait for the initial round of inter-node
config checks to complete before returning.  This way, if there's a
configuration mismatch between the joining node and the existing nodes,
the join can fail and return an error to the application.

Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
  • Loading branch information
David Teigland authored and Steven Whitehouse committed Jul 9, 2007
1 parent 79d72b5 commit 8b0e7b2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
2 changes: 2 additions & 0 deletions fs/dlm/dlm_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ struct dlm_ls {

wait_queue_head_t ls_uevent_wait; /* user part of join/leave */
int ls_uevent_result;
struct completion ls_members_done;
int ls_members_result;

struct miscdevice ls_device;

Expand Down
30 changes: 30 additions & 0 deletions fs/dlm/lockspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in)
else
kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE);

log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving");

/* dlm_controld will see the uevent, do the necessary group management
and then write to sysfs to wake us */

error = wait_event_interruptible(ls->ls_uevent_wait,
test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags));

log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result);

if (error)
goto out;

error = ls->ls_uevent_result;
out:
if (error)
log_error(ls, "group %s failed %d %d", in ? "join" : "leave",
error, ls->ls_uevent_result);
return error;
}

Expand Down Expand Up @@ -490,6 +501,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,

init_waitqueue_head(&ls->ls_uevent_wait);
ls->ls_uevent_result = 0;
init_completion(&ls->ls_members_done);
ls->ls_members_result = -1;

ls->ls_recoverd_task = NULL;
mutex_init(&ls->ls_recoverd_active);
Expand Down Expand Up @@ -540,17 +553,32 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
/* let kobject handle freeing of ls if there's an error */
do_unreg = 1;

/* This uevent triggers dlm_controld in userspace to add us to the
group of nodes that are members of this lockspace (managed by the
cluster infrastructure.) Once it's done that, it tells us who the
current lockspace members are (via configfs) and then tells the
lockspace to start running (via sysfs) in dlm_ls_start(). */

error = do_uevent(ls, 1);
if (error)
goto out_stop;

wait_for_completion(&ls->ls_members_done);
error = ls->ls_members_result;
if (error)
goto out_members;

dlm_create_debug_file(ls);

log_debug(ls, "join complete");

*lockspace = ls;
return 0;

out_members:
do_uevent(ls, 0);
dlm_clear_members(ls);
kfree(ls->ls_node_array);
out_stop:
dlm_recoverd_stop(ls);
out_delist:
Expand Down Expand Up @@ -588,6 +616,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace,
error = new_lockspace(name, namelen, lockspace, flags, lvblen);
if (!error)
ls_count++;
else if (!ls_count)
threads_stop();
out:
mutex_unlock(&ls_lock);
return error;
Expand Down
6 changes: 6 additions & 0 deletions fs/dlm/member.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
*neg_out = neg;

error = ping_members(ls);
if (!error || error == -EPROTO) {
/* new_lockspace() may be waiting to know if the config
is good or bad */
ls->ls_members_result = error;
complete(&ls->ls_members_done);
}
if (error)
goto out;

Expand Down
4 changes: 2 additions & 2 deletions fs/dlm/rcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
log_error(ls, "version mismatch: %x nodeid %d: %x",
DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid,
rc->rc_header.h_version);
return -EINVAL;
return -EPROTO;
}

if (rf->rf_lvblen != ls->ls_lvblen ||
rf->rf_lsflags != ls->ls_exflags) {
log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
ls->ls_lvblen, ls->ls_exflags,
nodeid, rf->rf_lvblen, rf->rf_lsflags);
return -EINVAL;
return -EPROTO;
}
return 0;
}
Expand Down

0 comments on commit 8b0e7b2

Please sign in to comment.