diff options
author | Sunil Mushran <sunil.mushran@oracle.com> | 2011-05-19 17:34:11 -0400 |
---|---|---|
committer | Joel Becker <jlbec@evilplan.org> | 2011-05-26 00:05:15 -0400 |
commit | bddefdeec5bc56ba5aa2c2ca8c904cdff58e7e5b (patch) | |
tree | ec3a61ccfd5bba4d5fba55b6aa9844d3dfa25d78 /fs/ocfs2/dlm/dlmdomain.c | |
parent | 98ba073c606fba7a48a8e0d36e3b02105d31c768 (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.c | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 3b179d6cbde0..3aff23feefdc 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 | */ |
136 | static const struct dlm_protocol_version dlm_protocol = { | 138 | static 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 | ||
491 | static 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 | |||
489 | static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm) | 513 | static 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 | ||
557 | static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm, | 582 | static 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 | ||
604 | static 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 | ||
581 | static void dlm_leave_domain(struct dlm_ctxt *dlm) | 633 | static 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 | |||
1796 | bail: | 1858 | bail: |
1797 | if (status) | 1859 | if (status) |
1798 | dlm_unregister_domain_handlers(dlm); | 1860 | dlm_unregister_domain_handlers(dlm); |