kern/124487: Extending the PROCFS (/proc) filesystem: patch + rationale

Ighighi ighighi at gmail.com
Wed Jun 11 13:20:09 UTC 2008


>Number:         124487
>Category:       kern
>Synopsis:       Extending the PROCFS (/proc) filesystem: patch + rationale
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 11 13:20:08 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Ighighi
>Release:        6.3-STABLE
>Organization:
>Environment:
FreeBSD 6.3-STABLE #0: Wed Jun  4 15:18:20 VET 2008i
>Description:
(This is something I've been running successfully since 2006 with FreeBSD
6.2-PRERELEASE (RELENG_6) but kept to myself out of fear that purists will
feel offended ;)

This patch extends the FreeBSD /proc filesystem (procfs) by adding support
for some entries that are present on other systems: Linux, Solaris and even
NetBSD (/proc/self & /proc/<pid>/exe)

The entries in question are:
/proc/self       -- Pointer to /proc/<pid> (FreeBSD uses /proc/curproc)
/proc/<pid>/exe  -- FreeBSD uses /proc/<pid>/file
/proc/<pid>/cwd  -- Pointer to the current working directory.
/proc/<pid>/root -- Pointer to the root directory.

I think it's convenient to add those because a lot of software originally
developed in the above systems above will integrate more easily, including
software in ports as you will see:
>How-To-Repeat:
I did a strings-scan on /usr/local that yielded the following (edited):

/usr/local/bin/upx: /proc/self/exe
/usr/local/bin/gdf: /proc/self
/usr/local/bin/gcp: /proc/self
/usr/local/bin/gchgrp: /proc/self
/usr/local/bin/gmv: /proc/self
/usr/local/bin/pterm: /proc/self/exe
/usr/local/bin/putty: /proc/self/exe
/usr/local/bin/puttytel: /proc/self/exe
/usr/local/bin/goldfind: /proc/self
/usr/local/bin/gfind: /proc/self
/usr/local/bin/gchown: /proc/self
/usr/local/bin/gchmod: /proc/self
/usr/local/bin/ginstall: /proc/self
/usr/local/bin/grm: /proc/self
/usr/local/bin/gdu: /proc/self
/usr/local/bin/supertux: /proc/self/exe
/usr/local/bin/supertux: Couldn't read /proc/self/exe, using default path: /usr/local/share/supertux
/usr/local/bin/gtar: /proc/self
/usr/local/Adobe/Acrobat7.0/ENU/Reader/intellinux/lib/librt3d.so: /proc/self/exe
/usr/local/intel_cc_80/bin/icpi: /proc/self/exe
/usr/local/intel_cc_80/bin/icpi: A/proc/self/cwd

The above files were installed by the following ports:
/usr/local/bin/upx: upx-3.02
/usr/local/bin/gdf: coreutils-6.9_2
/usr/local/bin/gcp: coreutils-6.9_2
/usr/local/bin/gchgrp: coreutils-6.9_2
/usr/local/bin/gmv: coreutils-6.9_2
/usr/local/bin/pterm: putty-0.60
/usr/local/bin/putty: putty-0.60
/usr/local/bin/puttytel: putty-0.60
/usr/local/bin/goldfind: findutils-4.4.0_1
/usr/local/bin/gfind: findutils-4.4.0_1
/usr/local/bin/gchown: coreutils-6.9_2
/usr/local/bin/gchmod: coreutils-6.9_2
/usr/local/bin/ginstall: coreutils-6.9_2
/usr/local/bin/grm: coreutils-6.9_2
/usr/local/bin/gdu: coreutils-6.9_2
/usr/local/bin/supertux: supertux-0.1.3_3
/usr/local/bin/supertux: supertux-0.1.3_3
/usr/local/bin/gtar: gtar-1.20
/usr/local/Adobe/Acrobat7.0/ENU/Reader/intellinux/lib/librt3d.so: acroread7-7.0.9_3,1
/usr/local/intel_cc_80/bin/icpi: icc-8.1.038_1
/usr/local/intel_cc_80/bin/icpi: icc-8.1.038_1

>Fix:
The attached patch is against -CURRENT.
The patch to RELENG_6 is available to anyone on demand.

This patch is a trivial one...
/proc/self & /proc/<pid>/exe exist in FreeBSD but with different names.
The code for /proc/<pid>/cwd & /proc/<pid>/root was copied verbatim from
src/sys/compat/linprocfs/linprocfs.c,v 1.119 2008/03/31 12:01:18 kib.

Patch attached with submission follows:

#
# (!c) 2006-2008 by Ighighi
#
# This patch extends the FreeBSD /proc filesystem (procfs) by adding
# support for some entries that are present on other systems: Linux,
# Solaris and even NetBSD: /proc/self & /proc/<pid>/exe
#
# Currently, these entries are:
# + /proc/self       -- Pointer to /proc/<pid> (FreeBSD uses /proc/curproc)
# + /proc/<pid>/exe  -- FreeBSD uses /proc/<pid>/file
# + /proc/<pid>/cwd  -- Pointer to the current working directory.
# + /proc/<pid>/root -- Pointer to the root directory.
#
# Notes:
# + /proc/self & /proc/<pid>/exe exist in FreeBSD but with different names.
#
# + The code for /proc/<pid>/cwd & /proc/<pid>/root was copied verbatim from
#   src/sys/compat/linprocfs/linprocfs.c,v 1.119 2008/03/31 12:01:18 kib.
#
# + As you can see, there's no new code so this patch is a trivial one.
#
# To apply this patch, run:
#   patch -d /usr < /path/to/procfs.patch
#
#   Rebuild the kernel if PSEUDOFS was compiled statically (as is the case
#   with GENERIC).  If compiled as a module, unmount every procfs/linprocfs
#   filesystems and unload all kernel modules that depend on procfs(5) and
#   linprocfs(5):
#     /sbin/umount -v -a -t linprocfs,procfs
#     /sbin/kldunload -v linprocfs
#     /sbin/kldunload -v procfs
#
#   To install the module, run:
#     cd /usr/src/sys/modules/procfs
#     make clean && make && make install
#   At this stage you may either reboot the system or resume operation with:
#     /sbin/mount -v -a -t linprocfs,procfs
#

--- src/sys/fs/procfs/procfs.c.orig	2008-01-13 10:14:05.000000000 -0430
+++ src/sys/fs/procfs/procfs.c	2008-06-11 06:15:40.840606357 -0430
@@ -61,6 +61,45 @@
 #include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
 
+#include <sys/filedesc.h>
+#include <sys/jail.h>
+
+/*
+ * Filler function for proc/pid/cwd
+ * Copied verbatim from src/sys/compat/linprocfs/linprocfs.c,v 1.119
+ */
+int
+procfs_doproccwd(PFS_FILL_ARGS)
+{
+	char *fullpath = "unknown";
+	char *freepath = NULL;
+
+	vn_fullpath(td, p->p_fd->fd_cdir, &fullpath, &freepath);
+	sbuf_printf(sb, "%s", fullpath);
+	if (freepath)
+		free(freepath, M_TEMP);
+	return (0);
+}
+
+/*
+ * Filler function for proc/pid/root
+ * Copied verbatim from src/sys/compat/linprocfs/linprocfs.c,v 1.119
+ */
+int
+procfs_doprocroot(PFS_FILL_ARGS)
+{
+	struct vnode *rvp;
+	char *fullpath = "unknown";
+	char *freepath = NULL;
+
+	rvp = jailed(p->p_ucred) ? p->p_fd->fd_jdir : p->p_fd->fd_rdir;
+	vn_fullpath(td, rvp, &fullpath, &freepath);
+	sbuf_printf(sb, "%s", fullpath);
+	if (freepath)
+		free(freepath, M_TEMP);
+	return (0);
+}
+
 /*
  * Filler function for proc/pid/self
  */
@@ -161,6 +200,8 @@ procfs_init(PFS_INIT_ARGS)
 
 	pfs_create_link(root, "curproc", procfs_docurproc,
 	    NULL, NULL, NULL, 0);
+	pfs_create_link(root, "self", procfs_docurproc,
+	    NULL, NULL, NULL, 0);
 
 	dir = pfs_create_dir(root, "pid",
 	    procfs_attr, NULL, NULL, PFS_PROCDEP);
@@ -193,6 +234,13 @@ procfs_init(PFS_INIT_ARGS)
 
 	pfs_create_link(dir, "file", procfs_doprocfile,
 	    NULL, procfs_notsystem, NULL, 0);
+	pfs_create_link(dir, "exe", procfs_doprocfile,
+	    NULL, procfs_notsystem, NULL, 0);
+
+	pfs_create_link(dir, "cwd", &procfs_doproccwd,
+	    NULL, NULL, NULL, 0);
+	pfs_create_link(dir, "root", &procfs_doprocroot,
+	    NULL, NULL, NULL, 0);
 
 	return (0);
 }
--- src/sys/fs/procfs/procfs.h.orig	2005-01-06 14:10:40.000000000 -0400
+++ src/sys/fs/procfs/procfs.h	2008-06-11 06:13:52.896643927 -0430
@@ -38,6 +38,8 @@
 
 #ifdef _KERNEL
 
+int	 procfs_doproccwd(PFS_FILL_ARGS);
+int	 procfs_doprocroot(PFS_FILL_ARGS);
 int	 procfs_docurproc(PFS_FILL_ARGS);
 int	 procfs_doproccmdline(PFS_FILL_ARGS);
 int	 procfs_doprocctl(PFS_FILL_ARGS);


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list