diff options
author | David Teigland <teigland@redhat.com> | 2007-05-18 10:03:35 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-07-09 03:22:42 -0400 |
commit | 8b0e7b2cf35aa827ed5efb508c1879481b970496 (patch) | |
tree | c1304a8b65cd0e1b474623903ba0907bc209f439 | |
parent | 79d72b54483bf81b9f9de0dd555c710ac7267986 (diff) |
[DLM] wait for config check during join [6/6]
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>
-rw-r--r-- | fs/dlm/dlm_internal.h | 2 | ||||
-rw-r--r-- | fs/dlm/lockspace.c | 30 | ||||
-rw-r--r-- | fs/dlm/member.c | 6 | ||||
-rw-r--r-- | fs/dlm/rcom.c | 4 |
4 files changed, 40 insertions, 2 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index a8d6e993697c..03ba6c4fd5c2 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -472,6 +472,8 @@ struct dlm_ls { | |||
472 | 472 | ||
473 | wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ | 473 | wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ |
474 | int ls_uevent_result; | 474 | int ls_uevent_result; |
475 | struct completion ls_members_done; | ||
476 | int ls_members_result; | ||
475 | 477 | ||
476 | struct miscdevice ls_device; | 478 | struct miscdevice ls_device; |
477 | 479 | ||
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index a3a50e67e4dd..c8f0c15ac166 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -197,13 +197,24 @@ static int do_uevent(struct dlm_ls *ls, int in) | |||
197 | else | 197 | else |
198 | kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); | 198 | kobject_uevent(&ls->ls_kobj, KOBJ_OFFLINE); |
199 | 199 | ||
200 | log_debug(ls, "%s the lockspace group...", in ? "joining" : "leaving"); | ||
201 | |||
202 | /* dlm_controld will see the uevent, do the necessary group management | ||
203 | and then write to sysfs to wake us */ | ||
204 | |||
200 | error = wait_event_interruptible(ls->ls_uevent_wait, | 205 | error = wait_event_interruptible(ls->ls_uevent_wait, |
201 | test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); | 206 | test_and_clear_bit(LSFL_UEVENT_WAIT, &ls->ls_flags)); |
207 | |||
208 | log_debug(ls, "group event done %d %d", error, ls->ls_uevent_result); | ||
209 | |||
202 | if (error) | 210 | if (error) |
203 | goto out; | 211 | goto out; |
204 | 212 | ||
205 | error = ls->ls_uevent_result; | 213 | error = ls->ls_uevent_result; |
206 | out: | 214 | out: |
215 | if (error) | ||
216 | log_error(ls, "group %s failed %d %d", in ? "join" : "leave", | ||
217 | error, ls->ls_uevent_result); | ||
207 | return error; | 218 | return error; |
208 | } | 219 | } |
209 | 220 | ||
@@ -490,6 +501,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
490 | 501 | ||
491 | init_waitqueue_head(&ls->ls_uevent_wait); | 502 | init_waitqueue_head(&ls->ls_uevent_wait); |
492 | ls->ls_uevent_result = 0; | 503 | ls->ls_uevent_result = 0; |
504 | init_completion(&ls->ls_members_done); | ||
505 | ls->ls_members_result = -1; | ||
493 | 506 | ||
494 | ls->ls_recoverd_task = NULL; | 507 | ls->ls_recoverd_task = NULL; |
495 | mutex_init(&ls->ls_recoverd_active); | 508 | mutex_init(&ls->ls_recoverd_active); |
@@ -540,10 +553,21 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
540 | /* let kobject handle freeing of ls if there's an error */ | 553 | /* let kobject handle freeing of ls if there's an error */ |
541 | do_unreg = 1; | 554 | do_unreg = 1; |
542 | 555 | ||
556 | /* This uevent triggers dlm_controld in userspace to add us to the | ||
557 | group of nodes that are members of this lockspace (managed by the | ||
558 | cluster infrastructure.) Once it's done that, it tells us who the | ||
559 | current lockspace members are (via configfs) and then tells the | ||
560 | lockspace to start running (via sysfs) in dlm_ls_start(). */ | ||
561 | |||
543 | error = do_uevent(ls, 1); | 562 | error = do_uevent(ls, 1); |
544 | if (error) | 563 | if (error) |
545 | goto out_stop; | 564 | goto out_stop; |
546 | 565 | ||
566 | wait_for_completion(&ls->ls_members_done); | ||
567 | error = ls->ls_members_result; | ||
568 | if (error) | ||
569 | goto out_members; | ||
570 | |||
547 | dlm_create_debug_file(ls); | 571 | dlm_create_debug_file(ls); |
548 | 572 | ||
549 | log_debug(ls, "join complete"); | 573 | log_debug(ls, "join complete"); |
@@ -551,6 +575,10 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
551 | *lockspace = ls; | 575 | *lockspace = ls; |
552 | return 0; | 576 | return 0; |
553 | 577 | ||
578 | out_members: | ||
579 | do_uevent(ls, 0); | ||
580 | dlm_clear_members(ls); | ||
581 | kfree(ls->ls_node_array); | ||
554 | out_stop: | 582 | out_stop: |
555 | dlm_recoverd_stop(ls); | 583 | dlm_recoverd_stop(ls); |
556 | out_delist: | 584 | out_delist: |
@@ -588,6 +616,8 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace, | |||
588 | error = new_lockspace(name, namelen, lockspace, flags, lvblen); | 616 | error = new_lockspace(name, namelen, lockspace, flags, lvblen); |
589 | if (!error) | 617 | if (!error) |
590 | ls_count++; | 618 | ls_count++; |
619 | else if (!ls_count) | ||
620 | threads_stop(); | ||
591 | out: | 621 | out: |
592 | mutex_unlock(&ls_lock); | 622 | mutex_unlock(&ls_lock); |
593 | return error; | 623 | return error; |
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index f08faec3d854..073599dced2a 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -233,6 +233,12 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
233 | *neg_out = neg; | 233 | *neg_out = neg; |
234 | 234 | ||
235 | error = ping_members(ls); | 235 | error = ping_members(ls); |
236 | if (!error || error == -EPROTO) { | ||
237 | /* new_lockspace() may be waiting to know if the config | ||
238 | is good or bad */ | ||
239 | ls->ls_members_result = error; | ||
240 | complete(&ls->ls_members_done); | ||
241 | } | ||
236 | if (error) | 242 | if (error) |
237 | goto out; | 243 | goto out; |
238 | 244 | ||
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 6bfbd6153809..f71c23542f0f 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -90,7 +90,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | |||
90 | log_error(ls, "version mismatch: %x nodeid %d: %x", | 90 | log_error(ls, "version mismatch: %x nodeid %d: %x", |
91 | DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid, | 91 | DLM_HEADER_MAJOR | DLM_HEADER_MINOR, nodeid, |
92 | rc->rc_header.h_version); | 92 | rc->rc_header.h_version); |
93 | return -EINVAL; | 93 | return -EPROTO; |
94 | } | 94 | } |
95 | 95 | ||
96 | if (rf->rf_lvblen != ls->ls_lvblen || | 96 | if (rf->rf_lvblen != ls->ls_lvblen || |
@@ -98,7 +98,7 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | |||
98 | log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", | 98 | log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", |
99 | ls->ls_lvblen, ls->ls_exflags, | 99 | ls->ls_lvblen, ls->ls_exflags, |
100 | nodeid, rf->rf_lvblen, rf->rf_lsflags); | 100 | nodeid, rf->rf_lvblen, rf->rf_lsflags); |
101 | return -EINVAL; | 101 | return -EPROTO; |
102 | } | 102 | } |
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |