[patch] RFC: /proc/module namespace

Jeff Garzik (jgarzik@pobox.com)
Thu, 02 Sep 1999 01:28:46 -0400


This is a multi-part message in MIME format.
--------------CCDC90CB44C7BBECBFEB0A77
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

The attached patch against 2.3.16 creates a new /proc/module directory.
Comments on this proposal and code are welcome.

This new feature provides a /proc playground for modules. As it stands
now, any random driver or module that exports something to /proc
generally must create a file, or directory, in /proc root. Over time
that can get messy.

My patch adds three functions which allow a module to create
/proc/module/{MODULE_NAME} directory. Underneath this directory, a
module can store can number of internal /proc dir nodes.

Sample usage:

int init_module (void)
{
struct proc_dir_entry *parent;

/* create /proc/mydriver/ directory */
if (proc_module_register ("mydriver")) return -1;

parent = proc_module_find ("mydriver");
if (!parent) return -1;

proc_register (parent, one); /* create /proc/module/mydriver/one_file
*/
proc_register (parent, two); /* create
/proc/module/mydriver/another_file */
}

void cleanup_module (void)
{
/* remove /proc/mymodule and all inodes beneath it */
proc_module_unregister ("mymodule");
}
--------------CCDC90CB44C7BBECBFEB0A77
Content-Type: text/plain; charset=us-ascii;
name="patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="patch"

Index: include/linux/proc_fs.h
===================================================================
RCS file: /home/cvsgarzik/linux_2_3/include/linux/proc_fs.h,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 proc_fs.h
--- proc_fs.h 1999/08/24 03:37:00 1.1.1.5
+++ proc_fs.h 1999/09/02 05:15:58
@@ -54,7 +54,8 @@
PROC_SOUND,
PROC_MTRR, /* whether enabled or not */
PROC_FS,
- PROC_SYSVIPC
+ PROC_SYSVIPC,
+ PROC_MODULE,
};

enum pid_directory_inos {
@@ -323,12 +324,33 @@
extern struct proc_dir_entry proc_sys;
extern struct proc_dir_entry proc_openprom;
extern struct proc_dir_entry proc_pid;
+extern struct proc_dir_entry proc_root_module;
extern struct proc_dir_entry proc_pid_fd;
extern struct proc_dir_entry proc_mca;
extern struct proc_dir_entry *proc_bus;
extern struct proc_dir_entry *proc_sysvipc;

extern struct inode_operations proc_scsi_inode_operations;
+extern struct inode_operations proc_dir_inode_operations;
+extern struct inode_operations proc_file_inode_operations;
+extern struct inode_operations proc_net_inode_operations;
+extern struct inode_operations proc_netdir_inode_operations;
+extern struct inode_operations proc_openprom_inode_operations;
+extern struct inode_operations proc_mem_inode_operations;
+extern struct inode_operations proc_sys_inode_operations;
+extern struct inode_operations proc_array_inode_operations;
+extern struct inode_operations proc_arraylong_inode_operations;
+extern struct inode_operations proc_kcore_inode_operations;
+extern struct inode_operations proc_profile_inode_operations;
+extern struct inode_operations proc_kmsg_inode_operations;
+extern struct inode_operations proc_link_inode_operations;
+extern struct inode_operations proc_fd_inode_operations;
+#if CONFIG_AP1000
+extern struct inode_operations proc_ringbuf_inode_operations;
+#endif
+extern struct inode_operations proc_omirr_inode_operations;
+extern struct inode_operations proc_ppc_htab_inode_operations;
+extern struct inode_operations proc_sysvipc_inode_operations;

extern void proc_root_init(void);
extern void proc_base_init(void);
@@ -346,6 +368,64 @@
return proc_unregister(proc_net, x);
}

+static inline
+struct proc_dir_entry *proc_module_find (const char *module_name)
+{
+ struct proc_dir_entry *p;
+
+ p = proc_root_module.subdir;
+ while (p != NULL) {
+ if (strcmp (p->name, module_name) == 0)
+ return p;
+
+ p = p->next;
+ }
+ return NULL;
+}
+
+static inline int proc_module_unregister(const char *module_name)
+{
+ struct proc_dir_entry *p;
+ int res;
+
+ p = proc_module_find (module_name);
+ if (!p) return -1;
+
+ res = proc_unregister (&proc_root_module, p->low_ino);
+ kfree (p);
+
+ return res;
+}
+
+static inline int proc_module_register(const char *module_name)
+{
+ struct proc_dir_entry *p;
+ char *pname;
+ int res;
+
+ p = (struct proc_dir_entry *)
+ kmalloc (sizeof (struct proc_dir_entry) +
+ strlen (module_name) + 1, GFP_KERNEL);
+ if (!p) return -1;
+
+ pname = ((char *) p) + sizeof (*p);
+
+ memset (p, 0, sizeof (*p));
+ strcpy (pname, module_name);
+
+ p->name = pname;
+ p->namelen = strlen (pname);
+ p->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ p->nlink = 2;
+ p->ops = &proc_dir_inode_operations;
+
+ res = proc_register (&proc_root_module, p);
+ if (res)
+ kfree (p);
+
+ return res;
+}
+
static inline int proc_scsi_register(struct proc_dir_entry *driver,
struct proc_dir_entry *x)
{
@@ -418,27 +498,6 @@
extern int proc_openprom_regdev(struct openpromfs_dev *);
extern int proc_openprom_unregdev(struct openpromfs_dev *);

-extern struct inode_operations proc_dir_inode_operations;
-extern struct inode_operations proc_file_inode_operations;
-extern struct inode_operations proc_net_inode_operations;
-extern struct inode_operations proc_netdir_inode_operations;
-extern struct inode_operations proc_openprom_inode_operations;
-extern struct inode_operations proc_mem_inode_operations;
-extern struct inode_operations proc_sys_inode_operations;
-extern struct inode_operations proc_array_inode_operations;
-extern struct inode_operations proc_arraylong_inode_operations;
-extern struct inode_operations proc_kcore_inode_operations;
-extern struct inode_operations proc_profile_inode_operations;
-extern struct inode_operations proc_kmsg_inode_operations;
-extern struct inode_operations proc_link_inode_operations;
-extern struct inode_operations proc_fd_inode_operations;
-#if CONFIG_AP1000
-extern struct inode_operations proc_ringbuf_inode_operations;
-#endif
-extern struct inode_operations proc_omirr_inode_operations;
-extern struct inode_operations proc_ppc_htab_inode_operations;
-extern struct inode_operations proc_sysvipc_inode_operations;
-
/*
* generic.c
*/
@@ -459,6 +518,10 @@
extern void proc_device_tree_init(void);

#else
+
+static inline struct proc_dir_entry *proc_module_find (const char *module_name) { return 0; }
+static inline int proc_module_unregister(const char *module_name) { return 0; }
+static inline int proc_module_register(const char *module_name) { return 0; }

extern inline int proc_register(struct proc_dir_entry *a, struct proc_dir_entry *b) { return 0; }
extern inline int proc_unregister(struct proc_dir_entry *a, int b) { return 0; }
Index: fs/proc/root.c
===================================================================
RCS file: /home/cvsgarzik/linux_2_3/fs/proc/root.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 root.c
--- root.c 1999/08/31 03:07:19 1.1.1.4
+++ root.c 1999/09/02 05:15:59
@@ -641,6 +641,14 @@
NULL,
NULL, NULL
};
+struct proc_dir_entry proc_root_module = {
+ PROC_MODULE, 6, "module",
+ S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
+ 0, &proc_dir_inode_operations,
+ NULL, NULL,
+ NULL,
+ NULL, NULL
+};
static struct proc_dir_entry proc_root_dma = {
PROC_DMA, 3, "dma",
S_IFREG | S_IRUGO, 1, 0, 0,
@@ -738,6 +746,7 @@
#endif
proc_register(&proc_root, &proc_root_stat);
proc_register(&proc_root, &proc_root_devices);
+ proc_register(&proc_root, &proc_root_module);
proc_register(&proc_root, &proc_root_partitions);
proc_register(&proc_root, &proc_root_interrupts);
proc_register(&proc_root, &proc_root_filesystems);

--------------CCDC90CB44C7BBECBFEB0A77--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/