Skip to contentSkip to conversation

nodemanager, ocfs2, dlm

RFC In review David Teigland 4 participants 7 messages Jul 18, 2005 – Jul 20, 2005 OCFS2

lore
Share & tools
lore
#0 lore raw

RFC 1/1 nodemanager, ocfs2, dlm

Some of the comments about the dlm concerned how it's configured (from user space.) In particular, there was interest in seeing the dlm and ocfs2 use common methods for their configuration.

The first area I'm looking at is how we get addresses/ids of other nodes. Currently, the dlm uses an ioctl on a misc device and ocfs2 uses a separate kernel module called "ocfs2_nodemanager" that's based on configfs.

I've taken a stab at generalizing ocfs2_nodemanager so the dlm could use it (removing ocfs-specific stuff). It still needs some work, but I'd like to know if this appeals to the ocfs group and to others who were interested in seeing some similarity in dlm/ocfs configuration.

Thanks,
Dave

drivers/Kconfig +2 -0
diff -urN a/drivers/Kconfig b/drivers/Kconfig
@@ -68,4 +68,6 @@
 
 source "drivers/dlm/Kconfig"
 
+source "drivers/nodemanager/Kconfig"
+
 endmenu
drivers/Makefile +1 -0
diff -urN a/drivers/Makefile b/drivers/Makefile
@@ -70,3 +70,4 @@
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_DLM)		+= dlm/
+obj-$(CONFIG_NODEMANAGER)	+= nodemanager/
drivers/nodemanager/Kconfig +9 -0
diff -urN a/drivers/nodemanager/Kconfig b/drivers/nodemanager/Kconfig
@@ -0,0 +1,9 @@
+menu "Node Manager"
+
+config NODEMANAGER
+	tristate "Node Manager"
+	help
+	Node addresses and ID"s are provided from user space and made
+	available to kernel components from this module.
+
+endmenu
drivers/nodemanager/Makefile +3 -0
diff -urN a/drivers/nodemanager/Makefile b/drivers/nodemanager/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_NODEMANAGER) +=	nodemanager.o
+
+nodemanager-y :=		nodemanager.o
drivers/nodemanager/nodemanager.c +655 -0

655 lines not on this page · raw message

drivers/nodemanager/nodemanager.h +37 -0
diff -urN a/drivers/nodemanager/nodemanager.h b/drivers/nodemanager/nodemanager.h
@@ -0,0 +1,37 @@
+/*
+ * nodemanager.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ * Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef NODEMANAGER_H
+#define NODEMANAGER_H
+
+#define NODEMANAGER_MAX_NODES		255
+#define NODEMANAGER_INVALID_NODE_NUM	255
+#define NODEMANAGER_MAX_NAME_LEN	__NEW_UTS_LEN	/* 64 */
+
+u32 nodemanager_nodeid_to_addr(int nodeid);
+int nodemanager_addr_to_nodeid(u32 addr);
+int nodemanager_our_nodeid(void);
+u32 nodemanager_our_addr(void);
+
+#endif
+
#1 lore raw
Quoted 9 lines · David Teigland

Some of the comments about the dlm concerned how it's configured (from user space.) In particular, there was interest in seeing the dlm and ocfs2 use common methods for their configuration.

The first area I'm looking at is how we get addresses/ids of other nodes. Currently, the dlm uses an ioctl on a misc device and ocfs2 uses a separate kernel module called "ocfs2_nodemanager" that's based on configfs.

Quoted 4 lines

I've taken a stab at generalizing ocfs2_nodemanager so the dlm could use it (removing ocfs-specific stuff). It still needs some work, but I'd like to know if this appeals to the ocfs group and to others who were interested in seeing some similarity in dlm/ocfs configuration.

Hi Dave, I finally found time to read through this.

Yes, I most definetely like where this is going!

drivers/nodemanager/nodemanager.c line 25

Quoted 3 lines
drivers/nodemanager/nodemanager.c +3 -0
+/* TODO:
+   - generic addresses (IPV4/6)
+   - multiple addresses per node

The nodeid, I thought, was relative to a given DLM namespace, no? This concept seems to be missing here, or are you suggesting the nodeid to be global across namespaces?

Also, eventually we obviously need to have state for the nodes - up/down et cetera. I think the node manager also ought to track this.

How would kernel components use this and be notified about changes to the configuration / membership state?

Sincerely,
Lars Marowsky-Br?e <[email protected]>

Signature · 4 lines
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business	 -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"
#2 lore raw
Quoted 3 lines · Lars Marowsky-Bree

The nodeid, I thought, was relative to a given DLM namespace, no? This concept seems to be missing here, or are you suggesting the nodeid to be global across namespaces?

I'm not sure I understand what you mean. A node would have the same nodeid across different dlm locking-domains, assuming, of course, those dlm domains were in the context of the same cluster. The dlm only uses nodemanager to look up node addresses, though.

Quoted 2 lines

Also, eventually we obviously need to have state for the nodes - up/down et cetera. I think the node manager also ought to track this.

We don't have a need for that information yet; I'm hoping we won't ever need it in the kernel, but we'll see.

Quoted 2 lines

How would kernel components use this and be notified about changes to the configuration / membership state?

"Nodemanager" is perhaps a poor name; at the moment its only substantial purpose is to communicate node address/id associations in a way that's independent of a specific driver or fs.

Changes to cluster configuration/membership happen in user space, of course. Those general events will have specific consequences to a given component (fs, lock manager, etc). These consequences vary quite widely depending on the component you're looking at.

There are at least two ways to handle this:

1. Pass cluster events and data into the kernel (this sounds like what you're talking about above), notify the effected kernel components, each kernel component takes the cluster data and does whatever it needs to with it (internal adjustments, recovery, etc).

2. Each kernel component "foo-kernel" has an associated user space component "foo-user". Cluster events (from userland clustering infrastructure) are passed to foo-user -- not into the kernel. foo-user determines what the specific consequences are for foo-kernel. foo-user then manipulates foo-kernel accordingly, through user/kernel hooks (sysfs, configfs, etc). These control hooks would largely be specific to foo.

We're following option 2 with the dlm and gfs and have been for quite a while, which means we don't need 1. I think ocfs2 is moving that way, too. Someone could still try 1, of course, but it would be of no use or interest to me. I'm not aware of any actual projects pushing forward with something like 1, so the persistent reference to it is somewhat baffling.

Dave

#3 lore raw
Quoted 4 lines · David Teigland
Quoted 2 lines

Also, eventually we obviously need to have state for the nodes - up/down et cetera. I think the node manager also ought to track this.

We don't have a need for that information yet; I'm hoping we won't ever need it in the kernel, but we'll see.

Hm, I'm thinking a service might have a good reason to want to know the possible list of nodes as opposed to the currently active membership; though the DLM as the service in question right now does not appear to need such.

But, see below.

Quoted 14 lines

There are at least two ways to handle this:

1. Pass cluster events and data into the kernel (this sounds like what you're talking about above), notify the effected kernel components, each kernel component takes the cluster data and does whatever it needs to with it (internal adjustments, recovery, etc).

2. Each kernel component "foo-kernel" has an associated user space component "foo-user". Cluster events (from userland clustering infrastructure) are passed to foo-user -- not into the kernel. foo-user determines what the specific consequences are for foo-kernel. foo-user then manipulates foo-kernel accordingly, through user/kernel hooks (sysfs, configfs, etc). These control hooks would largely be specific to foo.

Quoted 5 lines

We're following option 2 with the dlm and gfs and have been for quite a while, which means we don't need 1. I think ocfs2 is moving that way, too. Someone could still try 1, of course, but it would be of no use or interest to me. I'm not aware of any actual projects pushing forward with something like 1, so the persistent reference to it is somewhat baffling.

Right. I thought that the node manager changes for generalizing it where pushing into sort-of direction 1. Thanks for clearing this up.

Sincerely,
Lars Marowsky-Br?e <[email protected]>

Signature · 4 lines
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business	 -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"
#4 lore raw
In reply to David Teigland
Quoted 4 lines · David Teigland

I've taken a stab at generalizing ocfs2_nodemanager so the dlm could use it (removing ocfs-specific stuff). It still needs some work, but I'd like to know if this appeals to the ocfs group and to others who were interested in seeing some similarity in dlm/ocfs configuration.

Let me get this straight. The proposal is to expose cluster membership as a virtual filesystem and use that as the primary membership interface? So that, e.g., a server on the cluster does a getdents to find out what nodes are in the cluster or uses inotify to learn about membership changes, instead of subscribing for and receiving membership events directly from the cluster membership manager?

Or what is this about, just providing a nice friendly view of the cluster to the administrator, not intended to be used by cluster infrastructure components?

Regards,

Daniel

#5 lore raw
In reply to David Teigland

Hi David,

Quoted 5 lines · David Teigland

Some of the comments about the dlm concerned how it's configured (from user space.) In particular, there was interest in seeing the dlm and ocfs2 use common methods for their configuration.

The first area I'm looking at is how we get addresses/ids of other nodes.

Right. So this doesn't take into account other parts of node management (communication, heartbeat, etc). OCFS2 and dlm would still be handling that stuff on their own for now. For OCFS2 that would mean that an ocfs2_nodemanager would still exist, but as a much smaller module sitting on top of 'nodemanager'.

Quoted 4 lines

I've taken a stab at generalizing ocfs2_nodemanager so the dlm could use it (removing ocfs-specific stuff). It still needs some work, but I'd like to know if this appeals to the ocfs group and to others who were interested in seeing some similarity in dlm/ocfs configuration.

While I agree that some things look like they still need a bit of work, I like the direction this is taking - thanks for getting this ball rolling. My questions and comments below:

drivers/nodemanager/nodemanager.c line 41

Quoted 5 lines
drivers/nodemanager/nodemanager.c +5 -0
+enum {
+	NM_NODE_ATTR_NODEID = 0,
+	NM_NODE_ATTR_ADDRESS,
+	NM_NODE_ATTR_LOCAL,
+};

So no port attribute. The OCFS2 network code normally takes port from the node manager in order to determine how to talk to a given node. We'll have to figure out how to resolve that. The easiest would be to add 'port' back, but I think that might be problematic if we have multiple cluster network infrastructures as we do today.

Another way to handle this would be to have userspace symlink to the node items as an attribute on an ocfs2_tcp item. We could store 'port' as a second attribute. This would have the added benefit of pinning node information while OCFS2 uses it.

drivers/nodemanager/nodemanager.c line 185

Quoted 4 lines
drivers/nodemanager/nodemanager.c +4 -0
+struct node {
+	spinlock_t		nd_lock;
+	struct config_item	nd_item; 
+	char			nd_name[NODEMANAGER_MAX_NAME_LEN+1];

An accessor function for this would be nice for pretty prints - maybe strcpy into a passed string.

drivers/nodemanager/nodemanager.c line 186

Quoted 1 line
drivers/nodemanager/nodemanager.c +1 -0
+	int			nd_nodeid;

This definitely won't work with OCFS2... Nodeid (what used to be called node_num) needs to be unsigned. Otherwise this will break all our nodemap stuff which uses a bitmap to represent cluster state.

drivers/nodemanager/nodemanager.c line 192

Quoted 6 lines
drivers/nodemanager/nodemanager.c +6 -0
+	u32			nd_ipv4_address;
+	struct rb_node		nd_ip_node;
+	int			nd_local;
+	unsigned long		nd_set_attributes;
+	struct idr		nd_status_idr;
+	struct list_head	nd_status_list;

What are these two for? They don't seem to be referenced elsewhere...

Quoted 13 lines
drivers/nodemanager/nodemanager.c +13 -0
+static ssize_t node_local_write(struct node *node, const char *page,
+				size_t count)
+{
+	struct cluster *cluster = node_to_cluster(node);
+	unsigned long tmp;
+	char *p = (char *)page;
+
+	tmp = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	tmp = !!tmp; /* boolean of whether this node wants to be local */
+

drivers/nodemanager/nodemanager.c line 442

Quoted 10 lines
drivers/nodemanager/nodemanager.c +10 -0
+	/* the only failure case is trying to set a new local node
+	 * when a different one is already set */
+
+	if (tmp && tmp == cluster->cl_has_local &&
+	    cluster->cl_local_node != node->nd_nodeid)
+		return -EBUSY;
+
+	if (!tmp && cluster->cl_has_local &&
+	    cluster->cl_local_node == node->nd_nodeid) {
+		cluster->cl_local_node = 0;

I think we might want to be setting cl_local_node to NODEMANAGER_MAX_NODES here. It seems that ocfs2_nodemanager also does this so we might have just caught a bug you inherited :)

Quoted 30 lines

diff -urN a/drivers/nodemanager/nodemanager.h b/drivers/nodemanager/nodemanager.h

drivers/nodemanager/nodemanager.h +26 -0
@@ -0,0 +1,37 @@
+/*
+ * nodemanager.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ * Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef NODEMANAGER_H
+#define NODEMANAGER_H
+

drivers/nodemanager/nodemanager.h line 36

Quoted 10 lines
drivers/nodemanager/nodemanager.h +10 -0
+#define NODEMANAGER_MAX_NODES		255
+#define NODEMANAGER_INVALID_NODE_NUM	255
+#define NODEMANAGER_MAX_NAME_LEN	__NEW_UTS_LEN	/* 64 */
+
+u32 nodemanager_nodeid_to_addr(int nodeid);
+int nodemanager_addr_to_nodeid(u32 addr);
+int nodemanager_our_nodeid(void);
+u32 nodemanager_our_addr(void);
+
+#endif

You removed o2nm_configured_node_map but we need some sort of method for enumerating over the set of configured nodes.

Also we need a method for querying the existence of a node.
The OCFS2 code usually uses o2nm_get_node_by_num(..) != NULL for this but a simple boolean api call would be cleaner and would avoid exposing the node structure.

That's it for my first pass - I might have additional comments after reading through this some more :)

	--Mark

--
Mark Fasheh
Senior Software Developer, Oracle
[email protected]

#6 lore raw
Quoted 2 lines · Mark Fasheh

For OCFS2 that would mean that an ocfs2_nodemanager would still exist, but as a much smaller module sitting on top of 'nodemanager'.

Yep, factoring out the common bits.

Quoted 5 lines

So no port attribute. The OCFS2 network code normally takes port from the node manager in order to determine how to talk to a given node. We'll have to figure out how to resolve that. The easiest would be to add 'port' back, but I think that might be problematic if we have multiple cluster network infrastructures as we do today.

The port is specific to the component using it (ocfs2, dlm, etc), so defining port as a node property doesn't make sense if nodemanager is providing node info to multiple components.

Quoted 4 lines

Another way to handle this would be to have userspace symlink to the node items as an attribute on an ocfs2_tcp item. We could store 'port' as a second attribute. This would have the added benefit of pinning node information while OCFS2 uses it.

I expect each component will probably use another per-node configfs object for component-specific attributes, using the common bits from the nodemanager object.

Quoted 3 lines

drivers/nodemanager/nodemanager.c line 185

Quoted 1 line
drivers/nodemanager/nodemanager.c +1 -0
+	char			nd_name[NODEMANAGER_MAX_NAME_LEN+1];

An accessor function for this would be nice for pretty prints - maybe strcpy into a passed string.

ok

Quoted 4 lines

drivers/nodemanager/nodemanager.c line 186

Quoted 1 line
drivers/nodemanager/nodemanager.c +1 -0
+	int			nd_nodeid;

This definitely won't work with OCFS2... Nodeid (what used to be called node_num) needs to be unsigned. Otherwise this will break all our nodemap stuff which uses a bitmap to represent cluster state.

ok

Quoted 2 lines

drivers/nodemanager/nodemanager.c line 192

Quoted 1 line
drivers/nodemanager/nodemanager.c +1 -0
+	struct list_head	nd_status_list;

What are these two for? They don't seem to be referenced elsewhere...

Missed ripping them out with the other ocfs-specific stuff.

Quoted 6 lines

drivers/nodemanager/nodemanager.c line 442

Quoted 3 lines
drivers/nodemanager/nodemanager.c +3 -0
+	if (!tmp && cluster->cl_has_local &&
+	    cluster->cl_local_node == node->nd_nodeid) {
+		cluster->cl_local_node = 0;

I think we might want to be setting cl_local_node to NODEMANAGER_MAX_NODES here. It seems that ocfs2_nodemanager also does this so we might have just caught a bug you inherited :)

yep

Quoted 7 lines

You removed o2nm_configured_node_map but we need some sort of method for enumerating over the set of configured nodes.

Also we need a method for querying the existence of a node.
The OCFS2 code usually uses o2nm_get_node_by_num(..) != NULL for this but a simple boolean api call would be cleaner and would avoid exposing the node structure.

Right, those should be on the TODO.

Thanks,
Dave