aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2007-05-18 10:03:35 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:22:42 -0400
commit8b0e7b2cf35aa827ed5efb508c1879481b970496 (patch)
treec1304a8b65cd0e1b474623903ba0907bc209f439
parent79d72b54483bf81b9f9de0dd555c710ac7267986 (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.h2
-rw-r--r--fs/dlm/lockspace.c30
-rw-r--r--fs/dlm/member.c6
-rw-r--r--fs/dlm/rcom.c4
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}