aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlm/dlmdomain.c
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2011-05-19 17:34:11 -0400
committerJoel Becker <jlbec@evilplan.org>2011-05-26 00:05:15 -0400
commitbddefdeec5bc56ba5aa2c2ca8c904cdff58e7e5b (patch)
treeec3a61ccfd5bba4d5fba55b6aa9844d3dfa25d78 /fs/ocfs2/dlm/dlmdomain.c
parent98ba073c606fba7a48a8e0d36e3b02105d31c768 (diff)
ocfs2/dlm: Add new dlm message DLM_BEGIN_EXIT_DOMAIN_MSG
This patch adds a new dlm message DLM_BEGIN_EXIT_DOMAIN_MSG and ups the dlm protocol to 1.2. o2dlm sends this new message in dlm_unregister_domain() to mark the beginning of the exit domain. This message is sent to all nodes in the domain. Currently o2dlm has no way of informing other nodes of its impending exit. This information is useful as the other nodes could disregard the exiting node in certain operations. For example, in resource migration. If two or more nodes were umounting in parallel, it would be more efficient if o2dlm were to choose a non-exiting node to be the new master node rather than an exiting one. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Reviewed-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Joel Becker <jlbec@evilplan.org>
Diffstat (limited to 'fs/ocfs2/dlm/dlmdomain.c')
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c84
1 files changed, 73 insertions, 11 deletions
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 3b179d6cbde..3aff23feefd 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -132,10 +132,12 @@ static DECLARE_WAIT_QUEUE_HEAD(dlm_domain_events);
132 * New in version 1.1: 132 * New in version 1.1:
133 * - Message DLM_QUERY_REGION added to support global heartbeat 133 * - Message DLM_QUERY_REGION added to support global heartbeat
134 * - Message DLM_QUERY_NODEINFO added to allow online node removes 134 * - Message DLM_QUERY_NODEINFO added to allow online node removes
135 * New in version 1.2:
136 * - Message DLM_BEGIN_EXIT_DOMAIN_MSG added to mark start of exit domain
135 */ 137 */
136static const struct dlm_protocol_version dlm_protocol = { 138static const struct dlm_protocol_version dlm_protocol = {
137 .pv_major = 1, 139 .pv_major = 1,
138 .pv_minor = 1, 140 .pv_minor = 2,
139}; 141};
140 142
141#define DLM_DOMAIN_BACKOFF_MS 200 143#define DLM_DOMAIN_BACKOFF_MS 200
@@ -486,6 +488,28 @@ static int dlm_no_joining_node(struct dlm_ctxt *dlm)
486 return ret; 488 return ret;
487} 489}
488 490
491static int dlm_begin_exit_domain_handler(struct o2net_msg *msg, u32 len,
492 void *data, void **ret_data)
493{
494 struct dlm_ctxt *dlm = data;
495 unsigned int node;
496 struct dlm_exit_domain *exit_msg = (struct dlm_exit_domain *) msg->buf;
497
498 if (!dlm_grab(dlm))
499 return 0;
500
501 node = exit_msg->node_idx;
502 mlog(0, "%s: Node %u sent a begin exit domain message\n", dlm->name, node);
503
504 spin_lock(&dlm->spinlock);
505 set_bit(node, dlm->exit_domain_map);
506 spin_unlock(&dlm->spinlock);
507
508 dlm_put(dlm);
509
510 return 0;
511}
512
489static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm) 513static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm)
490{ 514{
491 /* Yikes, a double spinlock! I need domain_lock for the dlm 515 /* Yikes, a double spinlock! I need domain_lock for the dlm
@@ -542,6 +566,7 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
542 566
543 spin_lock(&dlm->spinlock); 567 spin_lock(&dlm->spinlock);
544 clear_bit(node, dlm->domain_map); 568 clear_bit(node, dlm->domain_map);
569 clear_bit(node, dlm->exit_domain_map);
545 __dlm_print_nodes(dlm); 570 __dlm_print_nodes(dlm);
546 571
547 /* notify anything attached to the heartbeat events */ 572 /* notify anything attached to the heartbeat events */
@@ -554,29 +579,56 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
554 return 0; 579 return 0;
555} 580}
556 581
557static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, 582static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, u32 msg_type,
558 unsigned int node) 583 unsigned int node)
559{ 584{
560 int status; 585 int status;
561 struct dlm_exit_domain leave_msg; 586 struct dlm_exit_domain leave_msg;
562 587
563 mlog(0, "Asking node %u if we can leave the domain %s me = %u\n", 588 mlog(0, "%s: Sending domain exit message %u to node %u\n", dlm->name,
564 node, dlm->name, dlm->node_num); 589 msg_type, node);
565 590
566 memset(&leave_msg, 0, sizeof(leave_msg)); 591 memset(&leave_msg, 0, sizeof(leave_msg));
567 leave_msg.node_idx = dlm->node_num; 592 leave_msg.node_idx = dlm->node_num;
568 593
569 status = o2net_send_message(DLM_EXIT_DOMAIN_MSG, dlm->key, 594 status = o2net_send_message(msg_type, dlm->key, &leave_msg,
570 &leave_msg, sizeof(leave_msg), node, 595 sizeof(leave_msg), node, NULL);
571 NULL);
572 if (status < 0) 596 if (status < 0)
573 mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " 597 mlog(ML_ERROR, "Error %d sending domain exit message %u "
574 "node %u\n", status, DLM_EXIT_DOMAIN_MSG, dlm->key, node); 598 "to node %u on domain %s\n", status, msg_type, node,
575 mlog(0, "status return %d from o2net_send_message\n", status); 599 dlm->name);
576 600
577 return status; 601 return status;
578} 602}
579 603
604static void dlm_begin_exit_domain(struct dlm_ctxt *dlm)
605{
606 int node = -1;
607
608 /* Support for begin exit domain was added in 1.2 */
609 if (dlm->dlm_locking_proto.pv_major == 1 &&
610 dlm->dlm_locking_proto.pv_minor < 2)
611 return;
612
613 /*
614 * Unlike DLM_EXIT_DOMAIN_MSG, DLM_BEGIN_EXIT_DOMAIN_MSG is purely
615 * informational. Meaning if a node does not receive the message,
616 * so be it.
617 */
618 spin_lock(&dlm->spinlock);
619 while (1) {
620 node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES, node + 1);
621 if (node >= O2NM_MAX_NODES)
622 break;
623 if (node == dlm->node_num)
624 continue;
625
626 spin_unlock(&dlm->spinlock);
627 dlm_send_one_domain_exit(dlm, DLM_BEGIN_EXIT_DOMAIN_MSG, node);
628 spin_lock(&dlm->spinlock);
629 }
630 spin_unlock(&dlm->spinlock);
631}
580 632
581static void dlm_leave_domain(struct dlm_ctxt *dlm) 633static void dlm_leave_domain(struct dlm_ctxt *dlm)
582{ 634{
@@ -602,7 +654,8 @@ static void dlm_leave_domain(struct dlm_ctxt *dlm)
602 654
603 clear_node = 1; 655 clear_node = 1;
604 656
605 status = dlm_send_one_domain_exit(dlm, node); 657 status = dlm_send_one_domain_exit(dlm, DLM_EXIT_DOMAIN_MSG,
658 node);
606 if (status < 0 && 659 if (status < 0 &&
607 status != -ENOPROTOOPT && 660 status != -ENOPROTOOPT &&
608 status != -ENOTCONN) { 661 status != -ENOTCONN) {
@@ -677,6 +730,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm)
677 730
678 if (leave) { 731 if (leave) {
679 mlog(0, "shutting down domain %s\n", dlm->name); 732 mlog(0, "shutting down domain %s\n", dlm->name);
733 dlm_begin_exit_domain(dlm);
680 734
681 /* We changed dlm state, notify the thread */ 735 /* We changed dlm state, notify the thread */
682 dlm_kick_thread(dlm, NULL); 736 dlm_kick_thread(dlm, NULL);
@@ -909,6 +963,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
909 * leftover join state. */ 963 * leftover join state. */
910 BUG_ON(dlm->joining_node != assert->node_idx); 964 BUG_ON(dlm->joining_node != assert->node_idx);
911 set_bit(assert->node_idx, dlm->domain_map); 965 set_bit(assert->node_idx, dlm->domain_map);
966 clear_bit(assert->node_idx, dlm->exit_domain_map);
912 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); 967 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
913 968
914 printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n", 969 printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n",
@@ -1793,6 +1848,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
1793 if (status) 1848 if (status)
1794 goto bail; 1849 goto bail;
1795 1850
1851 status = o2net_register_handler(DLM_BEGIN_EXIT_DOMAIN_MSG, dlm->key,
1852 sizeof(struct dlm_exit_domain),
1853 dlm_begin_exit_domain_handler,
1854 dlm, NULL, &dlm->dlm_domain_handlers);
1855 if (status)
1856 goto bail;
1857
1796bail: 1858bail:
1797 if (status) 1859 if (status)
1798 dlm_unregister_domain_handlers(dlm); 1860 dlm_unregister_domain_handlers(dlm);