From: rpeterso@sourceware.org <rpeterso@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/cman-kernel/src proc.c
Date: 7 Nov 2006 18:09:01 -0000 [thread overview]
Message-ID: <20061107180901.9074.qmail@sourceware.org> (raw)
CVSROOT: /cvs/cluster
Module name: cluster
Branch: STABLE
Changes by: rpeterso at sourceware.org 2006-11-07 18:09:01
Modified files:
cman-kernel/src: proc.c
Log message:
This is the fix for Bugzilla Bug 213723: [CS4] system crashes
with the command less /proc/cluster/status
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman-kernel/src/proc.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.11.2.2.4.1.2.3&r2=1.11.2.2.4.1.2.4
--- cluster/cman-kernel/src/Attic/proc.c 2006/04/24 12:33:26 1.11.2.2.4.1.2.3
+++ cluster/cman-kernel/src/Attic/proc.c 2006/11/07 18:09:01 1.11.2.2.4.1.2.4
@@ -41,6 +41,33 @@
extern char nodename[];
extern struct cluster_node *us;
static struct seq_operations cluster_info_op;
+static struct seq_operations cluster_status_info_op;
+
+enum status_state {
+ state_protocol_version,
+ state_config_version,
+ state_cluster_name,
+ state_cluster_id,
+ state_cluster_member,
+ state_cluster_member_state,
+ state_nodes,
+ state_expected_votes,
+ state_total_votes,
+ state_quorum,
+ state_active_subsystems,
+ state_nodename,
+ state_nodeid,
+ state_nodeaddrs,
+ state_done
+};
+
+struct cluster_status_info {
+ enum status_state state;
+ unsigned int total_votes;
+ unsigned int max_expected;
+ int node_addr_count;
+ struct sockaddr_in6 *saddr;
+};
int sm_proc_open(struct inode *inode, struct file *file);
int sm_debug_info(char *b, char **start, off_t offset, int length);
@@ -97,88 +124,203 @@
};
-
-static int proc_cluster_status(char *b, char **start, off_t offset, int length)
+static void cluster_status_state_mch(struct seq_file *m,
+ struct cluster_status_info *csi)
{
- struct list_head *nodelist;
- struct cluster_node *node;
- struct cluster_node_addr *node_addr;
- unsigned int total_votes = 0;
- unsigned int max_expected = 0;
- int c = 0;
-
- c += sprintf(b+c,
- "Protocol version: %d.%d.%d\n",
- CNXMAN_MAJOR_VERSION, CNXMAN_MINOR_VERSION,
- CNXMAN_PATCH_VERSION);
-
- c += sprintf(b+c,
- "Config version: %d\nCluster name: %s\nCluster ID: %d\nCluster Member: %s\nMembership state: ",
- config_version,
- cluster_name, cluster_id,
- we_are_a_cluster_member?"Yes":"No");
-
- membership_state(b+c, length-c);
- c += strlen(b+c);
- c += sprintf(b+c, "\n");
-
- if (!we_are_a_cluster_member)
- return c;
-
- /* Total the votes */
- down(&cluster_members_lock);
- list_for_each(nodelist, &cluster_members_list) {
- node = list_entry(nodelist, struct cluster_node, list);
- if (node->state == NODESTATE_MEMBER) {
- total_votes += node->votes;
- max_expected =
- max(max_expected, node->expected_votes);
+ int i;
+
+ if (!csi ||
+ (!we_are_a_cluster_member && csi->state > state_cluster_member_state))
+ return;
+
+ switch (csi->state) {
+ case state_protocol_version:
+ seq_printf(m, "Protocol version: %d.%d.%d\n",
+ CNXMAN_MAJOR_VERSION, CNXMAN_MINOR_VERSION,
+ CNXMAN_PATCH_VERSION);
+ break;
+
+ case state_config_version:
+ seq_printf(m, "Config version: %d\n", config_version);
+ break;
+
+ case state_cluster_name:
+ seq_printf(m,"Cluster name: %s\n", cluster_name);
+ break;
+
+ case state_cluster_id:
+ seq_printf(m, "Cluster ID: %d\n", cluster_id);
+ break;
+
+ case state_cluster_member:
+ seq_printf(m,"Cluster Member: %s\n",
+ we_are_a_cluster_member ? "Yes" : "No");
+ break;
+
+ case state_cluster_member_state:
+ {
+ char node_state_buf[256];
+
+ membership_state(node_state_buf, sizeof(node_state_buf));
+ seq_printf(m, "Membership state: %s\n",node_state_buf);
+ break;
}
- }
- up(&cluster_members_lock);
+ case state_nodes:
+ seq_printf(m, "Nodes: %d\n", cluster_members);
+ break;
+
+ case state_expected_votes:
+ seq_printf(m, "Expected_votes: %d\n", csi->max_expected);
+ break;
+
+ case state_total_votes:
+ seq_printf(m, "Total_votes: %d\n", csi->total_votes);
+ break;
+
+ case state_quorum:
+ seq_printf(m, "Quorum: %d %s\n", get_quorum(),
+ cluster_is_quorate ? " " : "Activity blocked");
+ break;
+
+ case state_active_subsystems:
+ seq_printf(m, "Active subsystems: %d\n", atomic_read(&use_count));
+ break;
+
+ case state_nodename:
+ seq_printf(m, "Node name: %s\n", nodename);
+ break;
- if (quorum_device && quorum_device->state == NODESTATE_MEMBER)
- total_votes += quorum_device->votes;
+ case state_nodeid:
+ if (!us)
+ break;
+ seq_printf(m, "Node ID: %d\n", us->node_id);
+ break;
- c += sprintf(b+c,
- "Nodes: %d\nExpected_votes: %d\nTotal_votes: %d\nQuorum: %d %s\n",
- cluster_members, max_expected, total_votes,
- get_quorum(),
- cluster_is_quorate ? " " : "Activity blocked");
- c += sprintf(b+c, "Active subsystems: %d\n",
- atomic_read(&use_count));
-
- c += sprintf(b+c, "Node name: %s\n", nodename);
-
- if (us) {
- c += sprintf(b+c, "Node ID: %d\n", us->node_id);
-
- c += sprintf(b+c, "Node addresses: ");
- list_for_each_entry(node_addr, &us->addr_list, list) {
- struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)node_addr->addr;
- if (saddr->sin6_family == AF_INET6) {
- c += sprintf(b+c, "%x:%x:%x:%x:%x:%x:%x:%x ",
- be16_to_cpu(saddr->sin6_addr.s6_addr16[0]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[1]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[2]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[3]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[4]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[5]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[6]),
- be16_to_cpu(saddr->sin6_addr.s6_addr16[7]));
+ case state_nodeaddrs:
+ seq_printf(m, "Node addresses: ");
+ for (i = 0; i < csi->node_addr_count; i++) {
+ if (csi->saddr[i].sin6_family == AF_INET6) {
+ seq_printf(m, "%x:%x:%x:%x:%x:%x:%x:%x ",
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[0]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[1]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[2]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[3]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[4]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[5]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[6]),
+ be16_to_cpu(csi->saddr[i].sin6_addr.s6_addr16[7]));
}
else {
- struct sockaddr_in *saddr4 = (struct sockaddr_in *)saddr;
+ struct sockaddr_in *saddr4 = (struct sockaddr_in *)&csi->saddr[i];
uint8_t *addr = (uint8_t *)&saddr4->sin_addr;
- c+= sprintf(b+c, "%u.%u.%u.%u ",
- addr[0], addr[1], addr[2], addr[3]);
+ seq_printf(m, "%u.%u.%u.%u ",
+ addr[0], addr[1], addr[2], addr[3]);
}
- }
- c += sprintf(b+c, "\n\n");
- }
- return c;
+ }
+ seq_printf(m, "\n\n");
+ break;
+
+ case state_done:
+ break;
+
+ default:
+ break;
+ }
}
+static void *cluster_status_seq_start(struct seq_file *m, loff_t * pos)
+{
+ struct cluster_status_info *csi;
+ struct list_head *nodelist;
+ struct cluster_node *node;
+ struct cluster_node_addr *node_addr;
+
+ if (!m->private) {
+ csi = kmalloc(sizeof(struct cluster_status_info), GFP_KERNEL);
+ m->private = csi;
+ if (!csi)
+ return NULL;
+ memset(csi, 0, sizeof(struct cluster_status_info));
+ }
+ else
+ csi = m->private;
+
+ csi->state = *pos;
+ if (*pos == 0) {
+ if (!we_are_a_cluster_member)
+ return csi;
+
+ /* Total the votes */
+ down(&cluster_members_lock);
+ list_for_each(nodelist, &cluster_members_list) {
+ node = list_entry(nodelist, struct cluster_node, list);
+ if (node->state == NODESTATE_MEMBER) {
+ csi->total_votes += node->votes;
+ csi->max_expected =
+ max(csi->max_expected, node->expected_votes);
+ }
+ }
+ up(&cluster_members_lock);
+ if (quorum_device && quorum_device->state == NODESTATE_MEMBER)
+ csi->total_votes += quorum_device->votes;
+
+ if (us) {
+ int i;
+
+ csi->node_addr_count = 0;
+ list_for_each_entry(node_addr, &us->addr_list, list) {
+ csi->node_addr_count++;
+ }
+ csi->saddr = kmalloc(csi->node_addr_count *
+ sizeof(struct sockaddr_in6), GFP_KERNEL);
+ if (!csi->saddr) {
+ csi->node_addr_count = 0;
+ return csi;
+ }
+ i = 0;
+ list_for_each_entry(node_addr, &us->addr_list, list) {
+ memcpy(&csi->saddr[i++],
+ node_addr->addr, sizeof(struct sockaddr_in6));
+ }
+ }
+ }
+
+ return csi;
+}
+
+static void *cluster_status_seq_next(struct seq_file *m, void *p, loff_t * pos)
+{
+ struct cluster_status_info *csi = p;
+
+ csi->state++;
+ if (!we_are_a_cluster_member && csi->state >= state_cluster_member_state)
+ csi->state = state_done;
+ *pos = csi->state;
+ if (csi->state >= state_done)
+ return NULL;
+ return csi;
+}
+
+static int cluster_status_seq_show(struct seq_file *m, void *p)
+{
+ struct cluster_status_info *csi = p;
+
+ if (csi->state < state_done)
+ cluster_status_state_mch(m, csi);
+ return 0;
+}
+
+static void cluster_status_seq_stop(struct seq_file *m, void *p)
+{
+ struct cluster_status_info *csi = m->private;
+
+ if (m->private) {
+ if (csi->saddr)
+ kfree(csi->saddr);
+ kfree(m->private);
+ m->private = NULL;
+ }
+}
/* Allocate one of these for /proc/cluster/nodes so we can keep a track of where
* we are */
@@ -192,6 +334,11 @@
return seq_open(file, &cluster_info_op);
}
+static int cluster_status_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &cluster_status_info_op);
+}
+
static void *cluster_seq_start(struct seq_file *m, loff_t * pos)
{
struct cluster_seq_info *csi;
@@ -290,6 +437,21 @@
.owner = THIS_MODULE,
};
+static struct seq_operations cluster_status_info_op = {
+ .start = cluster_status_seq_start,
+ .next = cluster_status_seq_next,
+ .stop = cluster_status_seq_stop,
+ .show = cluster_status_seq_show
+};
+
+static struct file_operations cluster_status_fops = {
+ .open = cluster_status_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+ .owner = THIS_MODULE,
+};
+
static struct file_operations service_fops = {
.open = sm_proc_open,
.read = seq_read,
@@ -351,7 +513,7 @@
procentry = create_proc_entry("cluster/status", S_IRUGO, NULL);
if (procentry)
- procentry->get_info = proc_cluster_status;
+ procentry->proc_fops = &cluster_status_fops ;
procentry = create_proc_entry("cluster/services", S_IRUGO, NULL);
if (procentry)
next reply other threads:[~2006-11-07 18:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-07 18:09 rpeterso [this message]
-- strict thread matches above, loose matches on Subject: below --
2006-11-07 17:47 [Cluster-devel] cluster/cman-kernel/src proc.c rpeterso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061107180901.9074.qmail@sourceware.org \
--to=rpeterso@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.