All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] Add register_sysctl_table_path function
@ 2006-08-03 11:05 Olaf Kirch
  0 siblings, 0 replies; only message in thread
From: Olaf Kirch @ 2006-08-03 11:05 UTC (permalink / raw)
  To: nfs

From: Olaf Kirch <okir@suse.de>
Subject: Add register_sysctl_table_path function

  There are a number of modules that register a sysctl table
  somewhere deeply nested in the sysctl hierarchy, such as
  fs/nfs, fs/xfs, dev/cdrom, etc.

  They all specify several dummy ctl_tables for the path name.
  This patch implements register_sysctl_table_path that takes
  an additional path name, and makes up dummy sysctl nodes
  for each component.

Signed-off-by: Olaf Kirch <okir@suse.de>

 include/linux/sysctl.h |   10 ++++++
 kernel/sysctl.c        |   79 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 87 insertions(+), 2 deletions(-)

Index: linux-2.6.18/include/linux/sysctl.h
===================================================================
--- linux-2.6.18.orig/include/linux/sysctl.h
+++ linux-2.6.18/include/linux/sysctl.h
@@ -1006,8 +1006,18 @@ struct ctl_table_header
 	struct completion *unregistering;
 };
 
+/* struct ctl_path describes where in the hierarchy a table is added */
+struct ctl_path
+{
+	int ctl_name;
+	const char *procname;
+	mode_t mode;
+};
+
 struct ctl_table_header * register_sysctl_table(ctl_table * table, 
 						int insert_at_head);
+struct ctl_table_header * register_sysctl_table_path(ctl_table *table,
+						struct ctl_path *path);
 void unregister_sysctl_table(struct ctl_table_header * table);
 
 #else /* __KERNEL__ */
Index: linux-2.6.18/kernel/sysctl.c
===================================================================
--- linux-2.6.18.orig/kernel/sysctl.c
+++ linux-2.6.18/kernel/sysctl.c
@@ -135,6 +135,7 @@ static int parse_table(int __user *, int
 		       ctl_table *, void **);
 static int proc_doutsstring(ctl_table *table, int write, struct file *filp,
 		  void __user *buffer, size_t *lenp, loff_t *ppos);
+static void __insert_sysctl_table(struct ctl_table_header *, int);
 
 static ctl_table root_table[];
 static struct ctl_table_header root_table_header =
@@ -1353,6 +1354,74 @@ struct ctl_table_header *register_sysctl
 	if (!tmp)
 		return NULL;
 	tmp->ctl_table = table;
+	__insert_sysctl_table(tmp, insert_at_head);
+	return tmp;
+}
+
+/**
+ * register_sysctl_table_path - register a systl table below a given node
+ * @npath: The number of entries in the path array.
+ * @path: An array of ctl_path items. We assume that the procname strings
+ *        are valid for the lifetime of the registration.
+ * @table: the table structure to register
+ *
+ * This works like register_sysctl_table except that the table isn't
+ * registered at the sysctl root, but at the specified location in the
+ * sysctl hierarchy
+ */
+struct ctl_table_header *register_sysctl_table_path(ctl_table *table,
+				struct ctl_path *path)
+{
+	struct ctl_table_header *header;
+	struct ctl_table *new, **prevp;
+	unsigned int	n, npath;
+
+	/* Count the path components. If the path is empty,
+	 * fall back to the normal register_sysctl_table() */
+	for (npath = 0; path[npath].procname; ++npath)
+		;
+
+	if (npath == 0)
+		return register_sysctl_table(table, 0);
+
+	/* For each path component, allocate a 2-element ctl_table array.
+	 * The first array element will be filled with the sysctl entry
+	 * for this, the second will be the sentinel (ctl_name == 0).
+	 *
+	 * We allocate everything in one go so that we don't have to
+	 * worry about freeing additional memory in unregister_sysctl_table.
+	 */
+	header = kzalloc(sizeof(struct ctl_table_header)
+			+ 2 * npath * sizeof(struct ctl_table), GFP_KERNEL);
+	if (!header)
+		return NULL;
+	new = (struct ctl_table *) (header + 1);
+
+	/* Now connect the dots */
+	prevp = &header->ctl_table;
+	for (n = 0; n < npath; ++n, ++path) {
+		/* Copy the procname */
+		new->procname = path->procname;
+		new->ctl_name = path->ctl_name;
+		new->mode     = path->mode;
+
+		*prevp = new;
+		prevp = &new->child;
+
+		new += 2;
+	}
+
+	*prevp = table;
+	__insert_sysctl_table(header, 0);
+	return header;
+}
+
+/*
+ * Insert ctl_table_header into hierarchy
+ */
+void __insert_sysctl_table(struct ctl_table_header * tmp,
+			int insert_at_head)
+{
 	INIT_LIST_HEAD(&tmp->ctl_entry);
 	tmp->used = 0;
 	tmp->unregistering = NULL;
@@ -1363,9 +1432,8 @@ struct ctl_table_header *register_sysctl
 		list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
 	spin_unlock(&sysctl_lock);
 #ifdef CONFIG_PROC_FS
-	register_proc_table(table, proc_sys_root, tmp);
+	register_proc_table(tmp->ctl_table, proc_sys_root, tmp);
 #endif
-	return tmp;
 }
 
 /**
@@ -2493,6 +2561,12 @@ struct ctl_table_header * register_sysct
 	return NULL;
 }
 
+struct ctl_table_header * register_sysctl_table_path(ctl_table * table,
+						struct ctl_path * path)
+{
+	return NULL;
+}
+
 void unregister_sysctl_table(struct ctl_table_header * table)
 {
 }
@@ -2512,6 +2586,7 @@ EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_table);
+EXPORT_SYMBOL(register_sysctl_table_path);
 EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-08-03 11:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-03 11:05 [PATCH 1/4] Add register_sysctl_table_path function Olaf Kirch

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.