cluster: RHEL6 - fenced: use cpg ringid
by David Teigland
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: f300d76b20ffc02fdda22ac205eb3b1c8258d544
Parent: 67aa7e900364b651aaf0a8b89acbd8157aa551cf
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Mar 19 11:10:13 2010 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon May 17 08:43:57 2010 -0500
fenced: use cpg ringid
bz 584140
Use the new totem cpg callback to synchronize cman events and cpg events.
Without this fix, the following two test cases cause fenced to become
confused and stuck.
test 1
------
- nodes 1,2,3,4
- configure no fencing for all, or force fencing to fail
- service cman start on all
- use iptables to add network partition: 1 | 2,3,4
- remove iptables partition resulting in merge: 1,2,3,4
- nodes 2,3,4 should kill corosync on node 1 automatically
- reboot node 1 if any dlm or gfs were being used
(otherwise just verify all cluster daemons have exited)
- service cman start on node 1
- fence_tool ls on 1,2,3,4 should all show normal state
(4 members, 0 victims, wait state none, members 1,2,3,4)
fence domain
member count 4
victim count 0
victim now 0
master nodeid 2
wait state none
members 1 2 3 4
test 2
------
- nodes 1,2,3,4
- configure no fencing for all, or force fencing to fail
- service cman start on all
- use iptables to add network partition: 1,2 | 3,4
- remove iptables partition resulting in merge: 1,2,3,4
- reboot nodes 1 and 2 if any dlm or gfs were being used
(otherwise just verify all cluster daemons have exited)
(a variation of this test reboots nodes 3 and 4 instead)
- service cman start on nodes 1 and 2
- fence_tool ls on 1,2,3,4 should all show normal state
(4 members, 0 victims, wait state none, members 1,2,3,4)
fence domain
member count 4
victim count 0
victim now 0
master nodeid 2
wait state none
members 1 2 3 4
Signed-off-by: David Teigland <teigland(a)redhat.com>
---
fence/fenced/cpg.c | 285 ++++++++++++++++++++++++++++++++++----------
fence/fenced/fd.h | 7 +
fence/fenced/main.c | 1 +
fence/fenced/member_cman.c | 16 ++-
4 files changed, 244 insertions(+), 65 deletions(-)
diff --git a/fence/fenced/cpg.c b/fence/fenced/cpg.c
index c9d86f3..a8629b9 100644
--- a/fence/fenced/cpg.c
+++ b/fence/fenced/cpg.c
@@ -73,7 +73,11 @@ struct id_info {
};
static cpg_handle_t cpg_handle_daemon;
+static cpg_handle_t cpg_handle_domain;
+static struct cpg_name group_name_daemon;
+static struct cpg_name group_name_domain;
static int cpg_fd_daemon;
+static int cpg_fd_domain;
static struct protocol our_protocol;
static struct list_head daemon_nodes;
static struct cpg_address daemon_member[MAX_NODES];
@@ -132,6 +136,38 @@ static void log_config(const struct cpg_name *group_name,
m_buf, j_buf, l_buf);
}
+static void log_ringid(cpg_handle_t handle,
+ struct cpg_ring_id *ringid,
+ const uint32_t *member_list,
+ size_t member_list_entries)
+{
+ char m_buf[128];
+ size_t i, len, pos;
+ int ret;
+ const char *name = "unknown";
+
+ if (handle == cpg_handle_domain)
+ name = group_name_domain.value;
+ else if (handle == cpg_handle_daemon)
+ name = group_name_daemon.value;
+
+ memset(m_buf, 0, sizeof(m_buf));
+
+ len = sizeof(m_buf);
+ pos = 0;
+ for (i = 0; i < member_list_entries; i++) {
+ ret = snprintf(m_buf + pos, len - pos, " %u",
+ member_list[i]);
+ if (ret >= len - pos)
+ break;
+ pos += ret;
+ }
+
+ log_debug("%s ring %u:%llu %zu memb%s",
+ name, ringid->nodeid, (unsigned long long)ringid->seq,
+ member_list_entries, m_buf);
+}
+
static void fd_info_in(struct fd_info *fi)
{
fi->fd_info_size = le32_to_cpu(fi->fd_info_size);
@@ -372,7 +408,7 @@ static void node_history_start(struct fd *fd, int nodeid)
node->add_time = time(NULL);
}
-static void node_history_left(struct fd *fd, int nodeid)
+static void node_history_left(struct fd *fd, int nodeid, uint32_t seq)
{
struct node_history *node;
@@ -383,9 +419,10 @@ static void node_history_left(struct fd *fd, int nodeid)
}
node->left_time = time(NULL);
+ node->left_seq = seq;
}
-static void node_history_fail(struct fd *fd, int nodeid)
+static void node_history_fail(struct fd *fd, int nodeid, uint32_t seq)
{
struct node_history *node;
@@ -396,6 +433,7 @@ static void node_history_fail(struct fd *fd, int nodeid)
}
node->fail_time = time(NULL);
+ node->fail_seq = seq;
node->check_quorum = 1;
}
@@ -646,36 +684,11 @@ static void receive_victim_done(struct fd *fd, struct fd_header *hd, int len)
free(node);
}
+/* we know that the quorum value here is consistent with the cpg events
+ because the ringid's are in sync per the previous check_ringid_done */
+
static int check_quorum_done(struct fd *fd)
{
- struct node_history *node;
- int wait_count = 0;
-
- /* We don't want to trust the cluster_quorate value until we know
- that cman has seen the same nodes fail that we have. So, we
- first make sure that all nodes we've seen fail are also
- failed in cman, then we can just check cluster_quorate. This
- assumes that we'll get to this function to do all the checks
- before any of the failed nodes can actually rejoin and become
- cman members again (if that assumption doesn't hold, perhaps
- do something with timestamps of join/fail). */
-
- list_for_each_entry(node, &fd->node_history, list) {
- if (!node->check_quorum)
- continue;
-
- if (!is_cluster_member_reread(node->nodeid)) {
- node->check_quorum = 0;
- } else {
- log_debug("check_quorum %d is_cluster_member",
- node->nodeid);
- wait_count++;
- }
- }
-
- if (wait_count)
- return 0;
-
if (!cluster_quorate) {
log_debug("check_quorum not quorate");
return 0;
@@ -685,8 +698,28 @@ static int check_quorum_done(struct fd *fd)
return 1;
}
+/* wait for cman ringid and cpg ringid to be the same so we know our
+ information from each service is based on the same node state */
+
+static int check_ringid_done(struct fd *fd)
+{
+ if (cluster_ringid_seq != (uint32_t)fd->cpg_ringid.seq) {
+ log_debug("check_ringid cluster %u cpg %u:%llu",
+ cluster_ringid_seq, fd->cpg_ringid.nodeid,
+ (unsigned long long)fd->cpg_ringid.seq);
+ return 0;
+ }
+
+ log_debug("check_ringid done cluster %u cpg %u:%llu",
+ cluster_ringid_seq, fd->cpg_ringid.nodeid,
+ (unsigned long long)fd->cpg_ringid.seq);
+ return 1;
+}
+
static int wait_conditions_done(struct fd *fd)
{
+ if (!check_ringid_done(fd))
+ return 0;
if (!check_quorum_done(fd))
return 0;
return 1;
@@ -829,6 +862,25 @@ static int match_change(struct fd *fd, struct change *cg, struct fd_header *hd,
return 0;
}
+ /* this start message couldn't have been sent for a cg preceding
+ a confchg when the sending node failed or left */
+
+ if ((node->fail_seq > cg->seq) || (node->left_seq > cg->seq)) {
+ log_debug("match_change %d:%u skip cg %u fail cg %u left cg %u",
+ hd->nodeid, seq, cg->seq,
+ node->fail_seq, node->left_seq);
+ return 0;
+ }
+
+ /* if we matched the last start message from this node against our
+ cg N, then don't match this stsart message against an earlier cg */
+
+ if (node->last_match_seq > cg->seq) {
+ log_debug("match_change %d:%u skip cg %u last matched cg %u",
+ hd->nodeid, seq, cg->seq, node->last_match_seq);
+ return 0;
+ }
+
/* verify this is the right change by matching the counts
and the nodeids of the current members */
@@ -863,6 +915,8 @@ static int match_change(struct fd *fd, struct change *cg, struct fd_header *hd,
if (members_mismatch)
return 0;
+ node->last_match_seq = cg->seq;
+
log_debug("match_change %d:%u matches cg %u", hd->nodeid, seq, cg->seq);
return 1;
}
@@ -917,19 +971,45 @@ static int match_change(struct fd *fd, struct change *cg, struct fd_header *hd,
is > cpg ringid, then return 0 for conditions_done so we won't send
start and will wait until the most recent cpg confchg (matching the
current cman one) to send a start. Waits for cpg to catch up with cman.
+
+ Final solution is the patch adding check_ringid_done() that waits for
+ cman and cpg to both be on the same ringid before going ahead to check
+ quorum and send starts.
*/
static struct change *find_change(struct fd *fd, struct fd_header *hd,
struct fd_info *fi, struct id_info *ids)
{
struct change *cg;
+ struct change *cg1 = NULL, *cg2 = NULL;
list_for_each_entry_reverse(cg, &fd->changes, list) {
if (!match_change(fd, cg, hd, fi, ids))
continue;
- return cg;
+
+ if (!(hd->flags & FD_MFLG_DUPLICATE_CG))
+ return cg;
+
+ /* this start message is for the second of two matching cg's */
+
+ if (!cg1) {
+ cg1 = cg;
+ log_debug("find_change %d:%u match1 %u look for dup",
+ hd->nodeid, hd->msgdata, cg1->seq);
+ continue;
+ } else {
+ cg2 = cg;
+ log_debug("find_change %d:%u match1 %u match2 %u",
+ hd->nodeid, hd->msgdata, cg1->seq, cg2->seq);
+ break;
+ }
}
+ if (cg1 && cg2)
+ return cg2;
+ if (cg1)
+ return cg1;
+
log_debug("find_change %d:%u no match", hd->nodeid, hd->msgdata);
return NULL;
}
@@ -1062,19 +1142,17 @@ static int count_ids(struct fd *fd)
return count;
}
-static void send_info(struct fd *fd, int type)
+static void send_info(struct fd *fd, struct change *cg, int type,
+ uint32_t flags)
{
- struct change *cg;
struct fd_header *hd;
struct fd_info *fi;
struct id_info *id;
struct node_history *node;
char *buf;
- uint32_t flags;
+ uint32_t idflags;
int len, id_count;
- cg = list_first_entry(&fd->changes, struct change, list);
-
id_count = count_ids(fd);
len = sizeof(struct fd_header) + sizeof(struct fd_info) +
@@ -1095,6 +1173,8 @@ static void send_info(struct fd *fd, int type)
hd->type = type;
hd->msgdata = cg->seq;
+ hd->flags = flags;
+
if (cg->we_joined)
hd->flags |= FD_MFLG_JOINING;
if (fd->init_complete || fd->local_init_complete)
@@ -1114,11 +1194,11 @@ static void send_info(struct fd *fd, int type)
/* fill in id_info entries */
list_for_each_entry(node, &fd->node_history, list) {
- flags = 0;
+ idflags = 0;
if (find_memb(cg, node->nodeid))
- flags = IDI_NODEID_IS_MEMBER;
+ idflags = IDI_NODEID_IS_MEMBER;
- id->flags = cpu_to_le32(flags);
+ id->flags = cpu_to_le32(idflags);
id->nodeid = cpu_to_le32(node->nodeid);
id->fence_external_node= cpu_to_le32(node->fence_external_node);
id->fence_master = cpu_to_le32(node->fence_master);
@@ -1128,8 +1208,8 @@ static void send_info(struct fd *fd, int type)
id++;
}
- log_debug("send_%s cg %u flags %x counts %u %d %d %d %d",
- type == FD_MSG_START ? "start" : "complete",
+ log_debug("send_%s %d:%u flags %x started %u m %d j %d r %d f %d",
+ type == FD_MSG_START ? "start" : "complete", our_nodeid,
cg->seq, hd->flags, fd->started_count, cg->member_count,
cg->joined_count, cg->remove_count, cg->failed_count);
@@ -1138,9 +1218,45 @@ static void send_info(struct fd *fd, int type)
free(buf);
}
+static int same_members(struct change *cg1, struct change *cg2)
+{
+ struct member *memb;
+
+ list_for_each_entry(memb, &cg1->members, list) {
+ if (!find_memb(cg2, memb->nodeid))
+ return 0;
+ }
+ return 1;
+}
+
static void send_start(struct fd *fd)
{
- send_info(fd, FD_MSG_START);
+ struct change *cg = list_first_entry(&fd->changes, struct change, list);
+ struct change *cgtmp;
+ uint32_t flags = 0;
+
+ /* look for a previous matching cg that we don't want others to
+ confuse for this one */
+
+ list_for_each_entry(cgtmp, &fd->changes, list) {
+ if (cgtmp->sent_start)
+ continue;
+
+ if (cgtmp->seq < cg->seq &&
+ cgtmp->member_count == cg->member_count &&
+ cgtmp->joined_count == cg->joined_count &&
+ cgtmp->remove_count == cg->remove_count &&
+ cgtmp->failed_count == cg->failed_count &&
+ same_members(cgtmp, cg)) {
+ log_debug("duplicate old cg %u new cg %u",
+ cgtmp->seq, cg->seq);
+ flags = FD_MFLG_DUPLICATE_CG;
+ }
+ }
+
+ cg->sent_start = 1;
+
+ send_info(fd, cg, FD_MSG_START, flags);
}
/* same content as a start message, a new (incomplete) node will look for
@@ -1149,7 +1265,9 @@ static void send_start(struct fd *fd)
static void send_complete(struct fd *fd)
{
- send_info(fd, FD_MSG_COMPLETE);
+ struct change *cg = list_first_entry(&fd->changes, struct change, list);
+
+ send_info(fd, cg, FD_MSG_COMPLETE, 0);
}
/* FIXME: better to just look in victims list for any nodes with init_victim? */
@@ -1317,9 +1435,9 @@ static int add_change(struct fd *fd,
list_add_tail(&memb->list, &cg->removed);
if (memb->failed)
- node_history_fail(fd, memb->nodeid);
+ node_history_fail(fd, memb->nodeid, cg->seq);
else
- node_history_left(fd, memb->nodeid);
+ node_history_left(fd, memb->nodeid, cg->seq);
log_debug("add_change cg %u remove nodeid %d reason %d",
cg->seq, memb->nodeid, left_list[i].reason);
@@ -1350,8 +1468,8 @@ static int add_change(struct fd *fd,
list_for_each_entry(memb, &cg->members, list)
node_history_init(fd, memb->nodeid);
- log_debug("add_change cg %u counts member %d joined %d remove %d "
- "failed %d", cg->seq, cg->member_count, cg->joined_count,
+ log_debug("add_change cg %u m %d j %d r %d f %d",
+ cg->seq, cg->member_count, cg->joined_count,
cg->remove_count, cg->failed_count);
list_add(&cg->list, &fd->changes);
@@ -1526,9 +1644,36 @@ static void deliver_cb_domain(cpg_handle_t handle,
apply_changes(fd);
}
-static cpg_callbacks_t cpg_callbacks_domain = {
+/* save ringid to compare with cman's.
+ also save member_list to double check with cman's member list?
+ they should match */
+
+static void totem_cb_domain(cpg_handle_t handle,
+ struct cpg_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list)
+{
+ struct fd *fd;
+
+ log_ringid(handle, &ring_id, member_list, member_list_entries);
+
+ fd = find_fd_handle(handle);
+ if (!fd) {
+ log_error("totem_cb no fence domain for handle");
+ return;
+ }
+
+ fd->cpg_ringid.nodeid = ring_id.nodeid;
+ fd->cpg_ringid.seq = ring_id.seq;
+
+ apply_changes(fd);
+}
+
+static cpg_model_v1_data_t cpg_callbacks_domain = {
.cpg_deliver_fn = deliver_cb_domain,
.cpg_confchg_fn = confchg_cb_domain,
+ .cpg_totem_confchg_fn = totem_cb_domain,
+ .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
};
static void process_cpg_domain(int ci)
@@ -1552,32 +1697,35 @@ static void process_cpg_domain(int ci)
int fd_join(struct fd *fd)
{
cpg_error_t error;
- cpg_handle_t h;
struct cpg_name name;
- int i = 0, f, ci;
+ int i = 0, ci;
- error = cpg_initialize(&h, &cpg_callbacks_domain);
+ error = cpg_model_initialize(&cpg_handle_domain, CPG_MODEL_V1,
+ (cpg_model_data_t *)&cpg_callbacks_domain,
+ NULL);
if (error != CPG_OK) {
- log_error("cpg_initialize error %d", error);
+ log_error("cpg_model_initialize error %d", error);
goto fail_free;
}
- cpg_fd_get(h, &f);
+ cpg_fd_get(cpg_handle_domain, &cpg_fd_domain);
- ci = client_add(f, process_cpg_domain, NULL);
+ ci = client_add(cpg_fd_domain, process_cpg_domain, NULL);
list_add(&fd->list, &domains);
- fd->cpg_handle = h;
+ fd->cpg_handle = cpg_handle_domain;
fd->cpg_client = ci;
- fd->cpg_fd = f;
+ fd->cpg_fd = cpg_fd_domain;
fd->joining_group = 1;
memset(&name, 0, sizeof(name));
sprintf(name.value, "fenced:%s", fd->name);
name.length = strlen(name.value) + 1;
+ memcpy(&group_name_domain, &name, sizeof(struct cpg_name));
+ log_debug("cpg_join %s ...", name.value);
retry:
- error = cpg_join(h, &name);
+ error = cpg_join(cpg_handle_domain, &name);
if (error == CPG_ERR_TRY_AGAIN) {
sleep(1);
if (!(++i % 10))
@@ -1594,7 +1742,7 @@ int fd_join(struct fd *fd)
fail:
list_del(&fd->list);
client_dead(ci);
- cpg_finalize(h);
+ cpg_finalize(cpg_handle_domain);
fail_free:
free(fd);
return error;
@@ -1612,6 +1760,7 @@ int fd_leave(struct fd *fd)
sprintf(name.value, "fenced:%s", fd->name);
name.length = strlen(name.value) + 1;
+ log_debug("cpg_leave %s ...", name.value);
retry:
error = cpg_leave(fd->cpg_handle, &name);
if (error == CPG_ERR_TRY_AGAIN) {
@@ -2084,9 +2233,19 @@ static void confchg_cb_daemon(cpg_handle_t handle,
}
}
-static cpg_callbacks_t cpg_callbacks_daemon = {
+static void totem_cb_daemon(cpg_handle_t handle,
+ struct cpg_ring_id ring_id,
+ uint32_t member_list_entries,
+ const uint32_t *member_list)
+{
+ log_ringid(handle, &ring_id, member_list, member_list_entries);
+}
+
+static cpg_model_v1_data_t cpg_callbacks_daemon = {
.cpg_deliver_fn = deliver_cb_daemon,
.cpg_confchg_fn = confchg_cb_daemon,
+ .cpg_totem_confchg_fn = totem_cb_daemon,
+ .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
};
void process_cpg_daemon(int ci)
@@ -2145,9 +2304,11 @@ int setup_cpg_daemon(void)
our_protocol.daemon_max[1] = 1;
our_protocol.daemon_max[2] = 1;
- error = cpg_initialize(&cpg_handle_daemon, &cpg_callbacks_daemon);
+ error = cpg_model_initialize(&cpg_handle_daemon, CPG_MODEL_V1,
+ (cpg_model_data_t *)&cpg_callbacks_daemon,
+ NULL);
if (error != CPG_OK) {
- log_error("daemon cpg_initialize error %d", error);
+ log_error("daemon cpg_model_initialize error %d", error);
goto ret;
}
@@ -2156,6 +2317,7 @@ int setup_cpg_daemon(void)
memset(&name, 0, sizeof(name));
sprintf(name.value, "fenced:daemon");
name.length = strlen(name.value) + 1;
+ memcpy(&group_name_daemon, &name, sizeof(struct cpg_name));
log_debug("cpg_join %s ...", name.value);
retry:
@@ -2196,6 +2358,7 @@ void close_cpg_daemon(void)
sprintf(name.value, "fenced:daemon");
name.length = strlen(name.value) + 1;
+ log_debug("cpg_leave %s ...", name.value);
retry:
error = cpg_leave(cpg_handle_daemon, &name);
if (error == CPG_ERR_TRY_AGAIN) {
diff --git a/fence/fenced/fd.h b/fence/fenced/fd.h
index 9f64dff..39a34ad 100644
--- a/fence/fenced/fd.h
+++ b/fence/fenced/fd.h
@@ -64,6 +64,7 @@ extern int daemon_quit;
extern int cluster_down;
extern struct list_head domains;
extern int cluster_quorate;
+extern uint32_t cluster_ringid_seq;
extern uint64_t quorate_time;
extern int our_nodeid;
extern char our_name[MAX_NODENAME_LEN+1];
@@ -95,6 +96,7 @@ do { \
#define FD_MFLG_JOINING 1 /* accompanies start, we are joining */
#define FD_MFLG_COMPLETE 2 /* accompanies start, we have complete info */
+#define FD_MFLG_DUPLICATE_CG 4
struct fd_header {
uint16_t version[3];
@@ -122,6 +124,7 @@ struct change {
int failed_count;
int state; /* CGST_ */
int we_joined;
+ int sent_start;
uint32_t seq; /* just used as a reference when debugging */
uint64_t create_time;
};
@@ -146,6 +149,9 @@ struct node_history {
int fence_external_node;
int fence_master;
int fence_how; /* VIC_DONE_ */
+ uint32_t last_match_seq;
+ uint32_t fail_seq;
+ uint32_t left_seq;
};
struct node {
@@ -172,6 +178,7 @@ struct fd {
struct list_head node_history;
int init_complete;
int local_init_complete;
+ struct cpg_ring_id cpg_ringid;
/* general domain membership */
diff --git a/fence/fenced/main.c b/fence/fenced/main.c
index deb9515..a371dc8 100644
--- a/fence/fenced/main.c
+++ b/fence/fenced/main.c
@@ -1069,6 +1069,7 @@ int daemon_quit;
int cluster_down;
struct list_head domains;
int cluster_quorate;
+uint32_t cluster_ringid_seq;
uint64_t quorate_time;
int our_nodeid;
char our_name[MAX_NODENAME_LEN+1];
diff --git a/fence/fenced/member_cman.c b/fence/fenced/member_cman.c
index a245adf..b9d8341 100644
--- a/fence/fenced/member_cman.c
+++ b/fence/fenced/member_cman.c
@@ -148,9 +148,17 @@ int name_to_nodeid(char *name)
static void update_cluster(void)
{
+ cman_cluster_t info;
int quorate = cluster_quorate;
int i, rv;
+ rv = cman_get_cluster(ch, &info);
+ if (rv < 0) {
+ log_error("cman_get_cluster error %d %d", rv, errno);
+ return;
+ }
+ cluster_ringid_seq = info.ci_generation;
+
cluster_quorate = cman_is_quorate(ch);
if (!quorate && cluster_quorate)
@@ -171,8 +179,8 @@ static void update_cluster(void)
if (old_nodes[i].cn_member &&
!is_cluster_member(old_nodes[i].cn_nodeid)) {
- log_debug("cluster node %d removed",
- old_nodes[i].cn_nodeid);
+ log_debug("cluster node %d removed seq %u",
+ old_nodes[i].cn_nodeid, cluster_ringid_seq);
node_history_cluster_remove(old_nodes[i].cn_nodeid);
}
@@ -182,8 +190,8 @@ static void update_cluster(void)
if (cman_nodes[i].cn_member &&
!is_old_member(cman_nodes[i].cn_nodeid)) {
- log_debug("cluster node %d added",
- cman_nodes[i].cn_nodeid);
+ log_debug("cluster node %d added seq %u",
+ cman_nodes[i].cn_nodeid, cluster_ringid_seq);
node_history_cluster_add(cman_nodes[i].cn_nodeid);
}
13 years, 11 months
cluster: RHEL6 - cman init: wait for corosync daemon to exit on stop
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 67aa7e900364b651aaf0a8b89acbd8157aa551cf
Parent: 72c3cd7f4550dcce1988cb012ea32a8a9e092cdb
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Sat May 15 07:59:24 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Sat May 15 08:01:17 2010 +0200
cman init: wait for corosync daemon to exit on stop
corosync could take time to exit after a shutdown/stop process is started.
The correct init script behavior is to wait for the daemon to exit.
Resolves: rhbz#592103
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/init.d/cman.in | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in
index 4578972..ef0e5ba 100644
--- a/cman/init.d/cman.in
+++ b/cman/init.d/cman.in
@@ -505,7 +505,14 @@ stop_cman()
if cman_running; then
errmsg=$( cman_tool $cman_leave_opts -t $CMAN_SHUTDOWN_TIMEOUT \
-w leave $cmanremove 2>&1 ) || return 1
+ ok
+ echo -n " Waiting for corosync to shutdown:"
+ while status corosync > /dev/null 2>&1; do
+ sleep 1
+ echo -n "."
+ done
fi
+ return 0
}
start_qdiskd()
13 years, 12 months
cluster: STABLE3 - cman init: wait for corosync daemon to exit on stop
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: b41e5e2a73b8777c26dc51fd1e805bad51eb3203
Parent: 7dc421cbf11fcec7de9f73266cef70a54a13cb8c
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Sat May 15 07:59:24 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Sat May 15 07:59:24 2010 +0200
cman init: wait for corosync daemon to exit on stop
corosync could take time to exit after a shutdown/stop process is started.
The correct init script behavior is to wait for the daemon to exit.
Resolves: rhbz#592103
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/init.d/cman.in | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in
index e0281be..b7eba95 100644
--- a/cman/init.d/cman.in
+++ b/cman/init.d/cman.in
@@ -565,7 +565,14 @@ stop_cman()
if cman_running; then
errmsg=$( cman_tool $cman_leave_opts -t $CMAN_SHUTDOWN_TIMEOUT \
-w leave $cmanremove 2>&1 ) || return 1
+ ok
+ echo -n " Waiting for corosync to shutdown:"
+ while status corosync > /dev/null 2>&1; do
+ sleep 1
+ echo -n "."
+ done
fi
+ return 0
}
start_qdiskd()
13 years, 12 months
cluster: RHEL6 - Revert "halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list"
by Fabio M. Di Nitto
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 72c3cd7f4550dcce1988cb012ea32a8a9e092cdb
Parent: cecf7f219af89600d06e8b5cb7627ae77aca3c4d
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Sat May 15 07:55:34 2010 +0200
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Sat May 15 07:55:34 2010 +0200
Revert "halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list"
This reverts commit cecf7f219af89600d06e8b5cb7627ae77aca3c4d.
---
rgmanager/src/resources/lvm.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index 7f174ca..4b7155c 100644
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -47,7 +47,7 @@ function ha_lvm_proper_setup_check
# lvm.conf:activation/volume_list; otherwise, machines
# will be able to activate the VG regardless of the tags
##
- if lvm dumpconfig activation/volume_list | grep "\"$OCF_RESKEY_vg_name\""; then
+ if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then
ocf_log err "HA LVM: Improper setup detected"
ocf_log err "- $OCF_RESKEY_vg_name found in \"volume_list\" in lvm.conf"
return $OCF_ERR_GENERIC
13 years, 12 months
resource-agents: master - halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/resource-agents.git?p=resource-agents.git...
Commit: 0078bf0667c11d8359452823b3fb9c2a008aaac6
Parent: 9deb0cdb544086a9f053eeda21b6491ec3be1784
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Fri May 14 15:35:47 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Fri May 14 15:35:47 2010 -0500
halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
If the name of the VG controlled by rgmanager is a substring of the name
of the node, the HA-LVM script will complain of an improper setup.
The fix is to also look for the associated quotes that are necessary when
specifying strings in lvm.conf. Thanks to John Ruemker for the patch.
---
rgmanager/src/resources/lvm.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index 4b7155c..7f174ca 100644
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -47,7 +47,7 @@ function ha_lvm_proper_setup_check
# lvm.conf:activation/volume_list; otherwise, machines
# will be able to activate the VG regardless of the tags
##
- if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then
+ if lvm dumpconfig activation/volume_list | grep "\"$OCF_RESKEY_vg_name\""; then
ocf_log err "HA LVM: Improper setup detected"
ocf_log err "- $OCF_RESKEY_vg_name found in \"volume_list\" in lvm.conf"
return $OCF_ERR_GENERIC
13 years, 12 months
cluster: RHEL6 - halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cecf7f219af89600d06e8b5cb7627ae77aca3c4d
Parent: cae5311a3695e7a6a73e572a9db8e8a5bc148c1d
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Fri May 14 15:28:06 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Fri May 14 15:31:22 2010 -0500
halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
If the name of the VG controlled by rgmanager is a substring of the name
of the node, the HA-LVM script will complain of an improper setup.
The fix is to also look for the associated quotes that are necessary when
specifying strings in lvm.conf. Thanks to John Ruemker for the patch.
---
rgmanager/src/resources/lvm.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index 4b7155c..7f174ca 100644
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -47,7 +47,7 @@ function ha_lvm_proper_setup_check
# lvm.conf:activation/volume_list; otherwise, machines
# will be able to activate the VG regardless of the tags
##
- if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then
+ if lvm dumpconfig activation/volume_list | grep "\"$OCF_RESKEY_vg_name\""; then
ocf_log err "HA LVM: Improper setup detected"
ocf_log err "- $OCF_RESKEY_vg_name found in \"volume_list\" in lvm.conf"
return $OCF_ERR_GENERIC
13 years, 12 months
cluster: RHEL55 - halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 5bde34c1fee9e5c5ba70d4997898328eb07d5b70
Parent: 7804e516b06c77cdfb3d5a969018cee6b05b5003
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Fri May 14 15:28:06 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Fri May 14 15:29:10 2010 -0500
halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
If the name of the VG controlled by rgmanager is a substring of the name
of the node, the HA-LVM script will complain of an improper setup.
The fix is to also look for the associated quotes that are necessary when
specifying strings in lvm.conf. Thanks to John Ruemker for the patch.
---
rgmanager/src/resources/lvm.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index a972aaf..0ffcadf 100755
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -66,7 +66,7 @@ function ha_lvm_proper_setup_check
# lvm.conf:activation/volume_list; otherwise, machines
# will be able to activate the VG regardless of the tags
##
- if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then
+ if lvm dumpconfig activation/volume_list | grep "\"$OCF_RESKEY_vg_name\""; then
ocf_log err "HA LVM: Improper setup detected"
ocf_log err "- $OCF_RESKEY_vg_name found in \"volume_list\" in lvm.conf"
return $OCF_ERR_GENERIC
13 years, 12 months
cluster: RHEL56 - halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 1298d52cbc0d32fdc49add7bfe1f8ddf122bc3f0
Parent: 7a7f801aad7b13b81833b4417b0ff5ee17694ffc
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Fri May 14 15:28:06 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Fri May 14 15:28:06 2010 -0500
halvm: Fix bug 506587: lvm agent incorrectly reports vg is in volume_list
If the name of the VG controlled by rgmanager is a substring of the name
of the node, the HA-LVM script will complain of an improper setup.
The fix is to also look for the associated quotes that are necessary when
specifying strings in lvm.conf. Thanks to John Ruemker for the patch.
---
rgmanager/src/resources/lvm.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index a972aaf..0ffcadf 100755
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -66,7 +66,7 @@ function ha_lvm_proper_setup_check
# lvm.conf:activation/volume_list; otherwise, machines
# will be able to activate the VG regardless of the tags
##
- if lvm dumpconfig activation/volume_list | grep $OCF_RESKEY_vg_name; then
+ if lvm dumpconfig activation/volume_list | grep "\"$OCF_RESKEY_vg_name\""; then
ocf_log err "HA LVM: Improper setup detected"
ocf_log err "- $OCF_RESKEY_vg_name found in \"volume_list\" in lvm.conf"
return $OCF_ERR_GENERIC
13 years, 12 months
cluster: RHEL56 - HA LVM: Use CLVM with local machine kernel targets (bz 585229)
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: 7a7f801aad7b13b81833b4417b0ff5ee17694ffc
Parent: 30b9fa486ce20a1788b463dad7c856d13ba05c48
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Thu Apr 29 14:07:04 2010 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Fri May 14 15:20:35 2010 -0500
HA LVM: Use CLVM with local machine kernel targets (bz 585229)
When a logical volume is activated in a cluster exclusively,
the kernel targets used are single machine targets. This
means we can use CLVM to protect the LVM metadata and still
better align ourselves with active/passive application stacks.
Making this change also simplifies HA LVM setup. There is no
more setting up tags, volume_list entries, or updating the
initrd.
Updating HA-LVM in this way also addresses the following bugs:
- 509368
- 583769
- 572311
---
rgmanager/src/resources/lvm.sh | 52 ++-----------
rgmanager/src/resources/lvm_by_lv.sh | 75 +++++++++++++++++-
rgmanager/src/resources/lvm_by_vg.sh | 147 +++++++++++++++++++++++++++++++++-
3 files changed, 221 insertions(+), 53 deletions(-)
diff --git a/rgmanager/src/resources/lvm.sh b/rgmanager/src/resources/lvm.sh
index ffb0b21..a972aaf 100755
--- a/rgmanager/src/resources/lvm.sh
+++ b/rgmanager/src/resources/lvm.sh
@@ -36,19 +36,6 @@ export LC_ALL LANG PATH
rv=0
################################################################################
-# clvm_check
-#
-################################################################################
-function clvm_check
-{
- if [[ $(vgs -o attr --noheadings $1) =~ .....c ]]; then
- return 1
- fi
-
- return 0
-}
-
-################################################################################
# ha_lvm_proper_setup_check
#
################################################################################
@@ -106,18 +93,10 @@ function ha_lvm_proper_setup_check
case $1 in
start)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
+ if ! [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ ha_lvm_proper_setup_check || exit 1
fi
- ha_lvm_proper_setup_check || exit 1
-
- rv=0
-
if [ -z $OCF_RESKEY_lv_name ]; then
vg_start || exit 1
else
@@ -133,20 +112,13 @@ status|monitor)
else
lv_status || exit 1
fi
- rv=0
;;
stop)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
- fi
-
- if ! ha_lvm_proper_setup_check; then
- ocf_log err "WARNING: An improper setup can cause data corruption!"
+ if ! [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ if ! ha_lvm_proper_setup_check; then
+ ocf_log err "WARNING: An improper setup can cause data corruption!"
+ fi
fi
if [ -z $OCF_RESKEY_lv_name ]; then
@@ -154,35 +126,23 @@ stop)
else
lv_stop || exit 1
fi
- rv=0
;;
recover|restart)
$0 stop || exit $OCF_ERR_GENERIC
$0 start || exit $OCF_ERR_GENERIC
- rv=0
;;
meta-data)
cat `echo $0 | sed 's/^\(.*\)\.sh$/\1.metadata/'`
- rv=0
;;
validate-all|verify-all)
- ##
- # We can safely ignore clustered volume groups (VGs handled by CLVM)
- ##
- if ! clvm_check $OCF_RESKEY_vg_name; then
- ocf_log notice "$OCF_RESKEY_vg_name is a cluster volume. Ignoring..."
- exit 0
- fi
-
if [ -z $OCF_RESKEY_lv_name ]; then
vg_verify || exit 1
else
lv_verify || exit 1
fi
- rv=0
;;
*)
echo "usage: $0 {start|status|monitor|stop|restart|meta-data|verify-all}"
diff --git a/rgmanager/src/resources/lvm_by_lv.sh b/rgmanager/src/resources/lvm_by_lv.sh
index 1937b9f..da15a15 100644
--- a/rgmanager/src/resources/lvm_by_lv.sh
+++ b/rgmanager/src/resources/lvm_by_lv.sh
@@ -101,10 +101,22 @@ lv_activate_resilient()
fi
}
+lv_status_clustered()
+{
+ #
+ # Check if device is active
+ #
+ if [[ ! $(lvs -o attr --noheadings $lv_path) =~ ....a. ]]; then
+ return $OCF_ERR_GENERIC
+ fi
+
+ return $OCF_SUCCESS
+}
+
# lv_status
#
# Is the LV active?
-lv_status()
+lv_status_single()
{
declare lv_path="$OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
declare dev="/dev/$lv_path"
@@ -167,6 +179,16 @@ lv_status()
return $OCF_SUCCESS
}
+function lv_status
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_status_clustered
+ else
+ lv_status_single
+ fi
+}
+
# lv_activate_and_tag
lv_activate_and_tag()
{
@@ -334,7 +356,29 @@ lv_activate()
return $OCF_SUCCESS
}
-function lv_start
+function lv_start_clustered
+{
+ if ! lvchange -aey $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed to activate logical volume, $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+
+ if ! lvconvert --repair --use-policies $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed to cleanup $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ if ! lvchange -aey $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name; then
+ ocf_log err "Failed second attempt to activate $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ ocf_log notice "Second attempt to activate $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name successful"
+ return $OCF_SUCCESS
+ fi
+ return $OCF_SUCCESS
+}
+
+function lv_start_single
{
if ! lvs $OCF_RESKEY_vg_name >& /dev/null; then
lv_count=0
@@ -355,7 +399,22 @@ function lv_start
return 0
}
-function lv_stop
+function lv_start
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_start_clustered
+ else
+ lv_start_single
+ fi
+}
+
+function lv_stop_clustered
+{
+ lvchange -aln $OCF_RESKEY_vg_name/$OCF_RESKEY_lv_name
+}
+
+function lv_stop_single
{
if ! lv_activate stop; then
return 1
@@ -363,3 +422,13 @@ function lv_stop
return 0
}
+
+function lv_stop
+{
+ # We pass in the VG name to see of the logical volume is clustered
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ lv_stop_clustered
+ else
+ lv_stop_single
+ fi
+}
diff --git a/rgmanager/src/resources/lvm_by_vg.sh b/rgmanager/src/resources/lvm_by_vg.sh
index 014dcbf..08d8c98 100755
--- a/rgmanager/src/resources/lvm_by_vg.sh
+++ b/rgmanager/src/resources/lvm_by_vg.sh
@@ -85,14 +85,18 @@ function strip_and_add_tag
return $OCF_SUCCESS
}
+function vg_status_clustered
+{
+ return $OCF_SUCCESS
+}
+
# vg_status
#
# Are all the LVs active?
-function vg_status
+function vg_status_single
{
local i
local dev
- local readdev
local my_name=$(local_node_name)
#
@@ -144,13 +148,88 @@ function vg_status
return $OCF_SUCCESS
}
+##
+# Main status function for volume groups
+##
+function vg_status
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_status_clustered
+ else
+ vg_status_single
+ fi
+}
+
function vg_verify
{
# Anything to verify?
return $OCF_SUCCESS
}
-function vg_start
+function vg_start_clustered
+{
+ local a
+ local results
+ local all_pvs
+ local resilience
+
+ ocf_log info "Starting volume group, $OCF_RESKEY_vg_name"
+
+ if ! vgchange -aey $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed to activate volume group, $OCF_RESKEY_vg_name"
+ ocf_log notice "Attempting cleanup of $OCF_RESKEY_vg_name"
+
+ if ! vgreduce --removemissing $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed to make $OCF_RESKEY_vg_name consistent"
+ return $OCF_ERR_GENERIC
+ fi
+
+ if ! vgchange -aey $OCF_RESKEY_vg_name; then
+ ocf_log err "Failed second attempt to activate $OCF_RESKEY_vg_name"
+ return $OCF_ERR_GENERIC
+ fi
+
+ ocf_log notice "Second attempt to activate $OCF_RESKEY_vg_name successful"
+ return $OCF_SUCCESS
+ else
+ # The activation commands succeeded, but did they do anything?
+ # Make sure all the logical volumes are active
+ results=(`lvs -o name,attr --noheadings 2> /dev/null $OCF_RESKEY_vg_name`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then
+ all_pvs=(`pvs --noheadings -o name 2> /dev/null`)
+ resilience=" --config devices{filter=["
+ for i in ${all_pvs[*]}; do
+ resilience=$resilience'"a|'$i'|",'
+ done
+ resilience=$resilience"\"r|.*|\"]}"
+
+ vgchange -aey $OCF_RESKEY_vg_name $resilience
+ break
+ fi
+ a=$(($a + 2))
+ done
+
+ # We need to check the LVs again if we made the command resilient
+ if [ ! -z $resilience ]; then
+ results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name $resilience 2> /dev/null`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ! ${results[$(($a + 1))]} =~ ....a. ]]; then
+ ocf_log err "Failed to activate $OCF_RESKEY_vg_name"
+ return $OCF_ERR_GENERIC
+ fi
+ a=$(($a + 2))
+ done
+ ocf_log err "Orphan storage device in $OCF_RESKEY_vg_name slowing operations"
+ fi
+ fi
+
+ return $OCF_SUCCESS
+}
+
+function vg_start_single
{
local a
local results
@@ -238,7 +317,55 @@ function vg_start
return $OCF_SUCCESS
}
-function vg_stop
+##
+# Main start function for volume groups
+##
+function vg_start
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_start_clustered
+ else
+ vg_start_single
+ fi
+}
+
+function vg_stop_clustered
+{
+ local a
+ local results
+ typeset self_fence=""
+
+ case ${OCF_RESKEY_self_fence} in
+ "yes") self_fence=1 ;;
+ 1) self_fence=1 ;;
+ *) self_fence="" ;;
+ esac
+
+ # Shut down the volume group
+ # Do we need to make this resilient?
+ vgchange -aln $OCF_RESKEY_vg_name
+
+ # Make sure all the logical volumes are inactive
+ results=(`lvs -o name,attr --noheadings $OCF_RESKEY_vg_name 2> /dev/null`)
+ a=0
+ while [ ! -z ${results[$a]} ]; do
+ if [[ ${results[$(($a + 1))]} =~ ....a. ]]; then
+ if [ "$self_fence" ]; then
+ ocf_log err "Unable to deactivate $lv_path REBOOT"
+ sync
+ reboot -fn
+ else
+ ocf_log err "Logical volume $OCF_RESKEY_vg_name/${results[$a]} failed to shutdown"
+ fi
+ return $OCF_ERR_GENERIC
+ fi
+ a=$(($a + 2))
+ done
+
+ return $OCF_SUCCESS
+}
+
+function vg_stop_single
{
local a
local results
@@ -279,3 +406,15 @@ function vg_stop
return $OCF_SUCCESS
}
+
+##
+# Main stop function for volume groups
+##
+function vg_stop
+{
+ if [[ $(vgs -o attr --noheadings $OCF_RESKEY_vg_name) =~ .....c ]]; then
+ vg_stop_clustered
+ else
+ vg_stop_single
+ fi
+}
13 years, 12 months
cluster: RHEL6 - cman: only load ckpt service by default
by Christine Caulfield
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=...
Commit: cae5311a3695e7a6a73e572a9db8e8a5bc148c1d
Parent: bd99e6e4616fddeba7b53333308a57fb327709a8
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Tue May 11 08:48:26 2010 +0100
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Tue May 11 08:48:26 2010 +0100
cman: only load ckpt service by default
Of all the openais services, cman only uses ckpt. So, in the interests
of not loading things we do not support, this patch only loads that service.
Other openais services can be loaded by adding stanzas to cluster.conf
Product Management Request
rhbz#568407
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
cman/cman_tool/join.c | 12 +++++++-----
cman/daemon/cman-preconfig.c | 42 +++++++++++++++++++++++++++++++++---------
2 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/cman/cman_tool/join.c b/cman/cman_tool/join.c
index 308d19b..c6cf4ef 100644
--- a/cman/cman_tool/join.c
+++ b/cman/cman_tool/join.c
@@ -176,13 +176,15 @@ int join(commandline_t *comline, char *main_envp[])
}
if (comline->noconfig_opt) {
envp[envptr++] = strdup("CMAN_NOCONFIG=true");
- snprintf(config_modules, sizeof(config_modules), "cmanpreconfig%s",
- comline->noopenais_opt?"":":openaisserviceenablestable");
+ snprintf(config_modules, sizeof(config_modules), "cmanpreconfig");
}
else {
- snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig%s", comline->config_lcrso,
- comline->noopenais_opt?"":":openaisserviceenablestable");
+ snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig", comline->config_lcrso);
}
+ if (comline->noopenais_opt) {
+ envp[envptr++] = strdup("CMAN_NOOPENAIS=true");
+ }
+
snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s", config_modules);
envp[envptr++] = strdup(scratch);
@@ -358,7 +360,7 @@ int join(commandline_t *comline, char *main_envp[])
strncpy(envname, envvar, PATH_MAX);
if (equal-envvar < PATH_MAX) {
envname[equal-envvar] = '\0';
-
+
res = confdb_key_create_typed(confdb_handle, object_handle, envname,
equal+1, strlen(equal+1),CONFDB_VALUETYPE_STRING);
}
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 2352670..fb08e96 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -137,6 +137,19 @@ static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage
}
+/* Adds a service to objdb for the main corosync engine to load */
+static void add_service(struct objdb_iface_ver0 *objdb, const char *name)
+{
+ hdb_handle_t object_handle;
+
+ objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+ "service", strlen("service"));
+ objdb->object_key_create_typed(object_handle, "name",
+ name, strlen(name) + 1, OBJDB_VALUETYPE_STRING);
+ objdb->object_key_create_typed(object_handle, "ver",
+ "0", 2, OBJDB_VALUETYPE_STRING);
+}
+
/* Build a localhost ip_address */
static int get_localhost(int family, struct sockaddr_storage *localhost)
{
@@ -504,6 +517,9 @@ static int get_env_overrides(void)
if (debug > 0)
debug = 1;
}
+ if (getenv("CMAN_NOOPENAIS")) {
+ disable_openais = 1;
+ }
return 0;
}
@@ -599,9 +615,6 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
if (!mcast_name)
return -1;
- /* See if the user wants our default set of openais services (default=yes) */
- objdb_get_int(objdb, object_handle, "disable_openais", &disable_openais, 0);
-
objdb->object_key_create_typed(object_handle, "nodename",
nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
}
@@ -879,12 +892,7 @@ static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
"0", 2, OBJDB_VALUETYPE_STRING);
/* Make sure we load our alter-ego - the main cman module */
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "service", strlen("service"));
- objdb->object_key_create_typed(object_handle, "name",
- "corosync_cman", strlen("corosync_cman") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "ver",
- "0", 2, OBJDB_VALUETYPE_STRING);
+ add_service(objdb, "corosync_cman");
/* Define cman as the quorum provider for corosync */
objdb->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle);
@@ -896,6 +904,12 @@ static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
objdb->object_key_create_typed(object_handle, "provider",
"quorum_cman", strlen("quorum_cman") + 1, OBJDB_VALUETYPE_STRING);
+
+ /* Load openais services we need (unless told not to) */
+ if (!disable_openais) {
+ add_service(objdb, "openais_ckpt");
+ }
+
}
/* If ccs is not available then use some defaults */
@@ -1274,6 +1288,16 @@ static void setup_old_compat(struct objdb_iface_ver0 *objdb, hdb_handle_t cluste
objdb->object_key_create_typed(gfs_handle, plock_ownership,
"0", 2, OBJDB_VALUETYPE_STRING);
}
+
+ /* Load a full set of openais services */
+ if (!disable_openais) {
+ add_service(objdb, "openais_clm");
+ add_service(objdb, "openais_evt");
+ add_service(objdb, "openais_msg");
+ add_service(objdb, "openais_lck");
+ add_service(objdb, "openais_tmr");
+ /* ckpt is added as part of normal startup */
+ }
}
static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
13 years, 12 months