svn commit: r226973 - in projects/varsym: . bin/ln lib/libc/sys lib/libutil sys/amd64/conf sys/compat/freebsd32 sys/conf sys/kern sys/sys tools/regression/usr.bin/varsym usr.bin/varsym

Brooks Davis brooks at FreeBSD.org
Mon Oct 31 23:27:25 UTC 2011


Author: brooks
Date: Mon Oct 31 23:27:24 2011
New Revision: 226973
URL: http://svn.freebsd.org/changeset/base/226973

Log:
  Bring in an updated varsym patch from my P4 tree.

Added:
  projects/varsym/TODO
  projects/varsym/lib/libc/sys/varsym.2
  projects/varsym/sys/kern/kern_varsym.c
  projects/varsym/sys/sys/varsym.h
  projects/varsym/tools/regression/usr.bin/varsym/
  projects/varsym/tools/regression/usr.bin/varsym/Makefile
  projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset_default.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_get.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_list.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_set.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.list_basic.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.list_clear_proc.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_denied.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_toomany.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_override.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_proc.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_sys.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.proc_basic.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.sh
  projects/varsym/tools/regression/usr.bin/varsym/regress.sys_basic.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.sys_cleared.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.sys_deleted.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.sys_override.out
  projects/varsym/tools/regression/usr.bin/varsym/regress.t
  projects/varsym/usr.bin/varsym/
  projects/varsym/usr.bin/varsym/Makefile
  projects/varsym/usr.bin/varsym/varsym.1
  projects/varsym/usr.bin/varsym/varsym.c
Modified:
  projects/varsym/bin/ln/ln.1
  projects/varsym/lib/libc/sys/Makefile.inc
  projects/varsym/lib/libc/sys/Symbol.map
  projects/varsym/lib/libutil/login.conf.5
  projects/varsym/lib/libutil/login_cap.h
  projects/varsym/lib/libutil/login_class.3
  projects/varsym/lib/libutil/login_class.c
  projects/varsym/sys/amd64/conf/GENERIC
  projects/varsym/sys/compat/freebsd32/freebsd32_misc.c
  projects/varsym/sys/compat/freebsd32/freebsd32_proto.h
  projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h
  projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c
  projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c
  projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c
  projects/varsym/sys/compat/freebsd32/syscalls.master
  projects/varsym/sys/conf/files
  projects/varsym/sys/conf/options
  projects/varsym/sys/kern/init_sysent.c
  projects/varsym/sys/kern/kern_exec.c
  projects/varsym/sys/kern/kern_fork.c
  projects/varsym/sys/kern/syscalls.c
  projects/varsym/sys/kern/syscalls.master
  projects/varsym/sys/kern/systrace_args.c
  projects/varsym/sys/kern/vfs_lookup.c
  projects/varsym/sys/sys/priv.h
  projects/varsym/sys/sys/proc.h
  projects/varsym/sys/sys/syscall.h
  projects/varsym/sys/sys/syscall.mk
  projects/varsym/sys/sys/sysproto.h

Added: projects/varsym/TODO
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/varsym/TODO	Mon Oct 31 23:27:24 2011	(r226973)
@@ -0,0 +1,5 @@
+pre-commit:
+- get review, tweak as necessicary
+
+post-commit:
+- add jail or vimage support

Modified: projects/varsym/bin/ln/ln.1
==============================================================================
--- projects/varsym/bin/ln/ln.1	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/bin/ln/ln.1	Mon Oct 31 23:27:24 2011	(r226973)
@@ -212,6 +212,47 @@ No options may be supplied in this simpl
 which performs a
 .Xr link 2
 operation using the two passed arguments.
+.Sh VARIANT SYMLINKS
+.Dx
+supports a special kind of dynamic
+symbolic link called a
+.Em variant symlink .
+The
+.Ar source_file
+of a variant symlink may contain one or more
+variable names.  Each of these variable
+names is enclosed in braces and preceded by a
+dollar sign in the style of variable references in
+.Xr sh 1
+and
+.Xr csh 1 .
+.Pp
+Whenever a variant symlink is followed, each
+variable found in
+.Ar source_file
+is replaced by its associated value.
+In this manner, a variant symlink may resolve to different
+paths based on context.  The facility
+supports per-process, per-user, and system-wide varsyms.
+.Pp
+Varsym variables can be set with the
+.Xr varsym 1
+utility.  Regular
+.Xr environ 7
+environment variables are
+not used to resolve variant symlinks.
+.Ss EXAMPLE
+.Bd -literal -offset indent
+sysctl -w vfs.varsym.enable=1
+
+ln -s 'a%{fubar}b' test
+
+echo 'Hello' > axxb
+echo 'Goodbye' > ayyb
+
+varsym fubar=xx cat test
+varsym fubar=yy cat test
+.Ed
 .Sh COMPATIBILITY
 The
 .Fl h ,
@@ -236,7 +277,8 @@ extension and should not be used in port
 .Xr readlink 2 ,
 .Xr stat 2 ,
 .Xr symlink 2 ,
-.Xr symlink 7
+.Xr symlink 7 ,
+.Xr varsym 1
 .Sh STANDARDS
 The
 .Nm
@@ -251,4 +293,4 @@ command conforms to
 An
 .Nm
 command appeared in
-.At v1 .
+.At v1 . Variant Symlinks appeared in DragonFly BSD .

Modified: projects/varsym/lib/libc/sys/Makefile.inc
==============================================================================
--- projects/varsym/lib/libc/sys/Makefile.inc	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libc/sys/Makefile.inc	Mon Oct 31 23:27:24 2011	(r226973)
@@ -114,7 +114,7 @@ MAN+=	sctp_generic_recvmsg.2 sctp_generi
 	swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \
 	timer_create.2 timer_delete.2 timer_settime.2 \
 	truncate.2 umask.2 undelete.2 \
-	unlink.2 utimes.2 utrace.2 uuidgen.2 vfork.2 wait.2 write.2
+	unlink.2 utimes.2 utrace.2 uuidgen.2 varsym.2 vfork.2 wait.2 write.2
 
 MLINKS+=access.2 eaccess.2 access.2 faccessat.2
 MLINKS+=brk.2 sbrk.2
@@ -210,4 +210,5 @@ MLINKS+=truncate.2 ftruncate.2
 MLINKS+=unlink.2 unlinkat.2
 MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
 MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
-MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
+MLINKS+=write.2 pwrite.2 write.2 writev.2 write.2 pwritev.2
+MLINKS+=varsym.2 varsym_set.2 varsym.2 varsym_get.2 varsym.2 varsym_list.2

Modified: projects/varsym/lib/libc/sys/Symbol.map
==============================================================================
--- projects/varsym/lib/libc/sys/Symbol.map	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libc/sys/Symbol.map	Mon Oct 31 23:27:24 2011	(r226973)
@@ -326,6 +326,9 @@ FBSD_1.0 {
 	pread;
 	pwrite;
 	truncate;
+	varsym_set;
+	varsym_get;
+	varsym_list;
 };
 
 FBSD_1.1 {

Added: projects/varsym/lib/libc/sys/varsym.2
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/varsym/lib/libc/sys/varsym.2	Mon Oct 31 23:27:24 2011	(r226973)
@@ -0,0 +1,205 @@
+.\" Copyright (c) 2008 The Aerospace Corporation
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the author nor the names of its contributors may
+.\"    be used to endorse or promote products derived from this software
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 29 2008
+.Dt VARSYM 2
+.Os
+.Sh NAME
+.Nm varsym
+.Nd manipulate variant symlink variables
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In varsym.h
+.Ft int
+.Fn varsym_set "int scope" "id_t which" "const char *name" "const char *data"
+.Ft int
+.Fn varsym_get "int scope" "id_t which" "const char *name" "const char *buf" "size_t *size"
+.Ft int
+.Fn varsym_list "int scope" "id_t which" "const char *buf" "size_t *size"
+.Sh DESCRIPTION
+The
+.Fn varsym_set
+function
+sets the variable
+.Fa name
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the value in the null-terminated string pointed to by
+.Fa data .
+If
+.Fa data
+is
+.Dv NULL
+then the variable will be deleted.
+If
+.Fa name
+is
+.Dv NULL
+then all variables will be deleted.
+.Pp
+The
+.Fn varsym_get
+function
+writes the value of the variable
+.Fa name
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the buffer
+.Fa buf
+as a null-terminated string.
+The number of bytes written to
+.Fa which
+are copied back to the variable pointed to by
+.Fa size.
+.Pp
+The
+.Fn varsym_list
+function
+writes the names and values of variables
+in the object specifed by
+.Fa scope
+and
+.Fa which
+to the buffer
+.Fa buf
+with nulls between each entry and a final null indicating end of list.
+The number of bytes written to
+.Fa which
+are copied back to the variable pointed to by
+.Fa size.
+.Pp
+The
+.Fa scope
+argument may be one of:
+.Bl -tag -width VARSYM_PROC
+.It Dv VARSYM_SYS
+Get or set variables in the global system scope.
+.It Dv VARSYM_PROC
+Get or set variables for the given process.
+.El
+.Pp
+The following
+.Xr sysctl 3
+MIB variables control the operation of variant symlinks:
+.Bl -tag -width vfs.varsym.enable
+.It Va vfs.varsym.enable
+Enables support for variant symlinks when set to a non-zero value.
+Defaults to off.
+.It Va vfs.varsym.allow_default
+If set to a non-zero value, variant symlinks may be created with default
+values to be used if no variable is set.
+These values are specified by placing a colon after the variable name in the
+link.
+For example
+.Va ${VAR:defaultvalue} .
+.Pp
+.Sy WARNING :
+Default values should not be used in any way that will effect the execution
+of setuid programs unless users can not control the values of variant
+symlinks.
+Administrators are advised to disable default value support when user
+control of per-process values is allowed.
+.It Va vfs.varsym.max_proc_setsize
+Limits the number of per-processes variables that can be set.
+The default limit is 32.
+This limit is only enforced if unprivleged control is allowed by
+.Va security.bsd.unprivileged_varsym_set_proc .
+.It Va security.bsd.unprivileged_varsym_set_proc
+If set to a non-zero value, non-root users may set per-process variant symlink
+variables.
+.El
+.Sh RETURN VALUES
+.Rv -std varsym_set varsym_get varsym_list
+.Sh ERRORS
+The
+.Fn varsym_set ,
+.Fn varsym_get ,
+and
+.Fn varsym_list
+functions will fail and take no action if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An invalid value is passed for
+.Fa scope
+or
+.Fa which .
+.It Bq Er EPERM
+The
+.Fa which
+variable is set to a value other than 0 or the current processes pid when
+.Fa scope
+is
+.Dv VARSYM_PROC .
+.It Bq Er EOVERFLOW
+The buffer passed to
+.Fn varsym_get
+or
+.Fn varsym_list
+is too small for the data to be returned.
+.It Bq Er E2BIG
+For the
+.Fn varsym_set
+function, the maximum number of variant symlinks for this object has been
+reached.
+.It Bq Er ENOENT
+The requested variant symlink variable does not exist.
+.It Bq Er ENOSYS
+The system does not support variant symlinks or the support has been
+disabled by setting the
+.Xr sysctl 3
+MIB
+.Va vfs.varsym.enable
+to 0.
+.It Bq Er EFAULT
+One of buffers is outside the process's allocated address space.
+.It Bq Er ENAMETOOLONG
+The value of
+.Fa name
+is longer than
+.Dv MAXVARSYM_NAME
+or
+the value of
+.Fa data
+is longer than
+.Dv MAXVARSYM_DATA .
+.El
+.Sh SEE ALSO
+.Xr varsym_clear 3
+.Sh HISTORY
+This version of variant symlinks is derived from variant symlink support that
+first appeared in DragonFlyBSD 1.0.
+.Sh BUGS
+The
+.Fa which
+argument is effectivly unused at this time and must be 0 or the current
+processes pid.

Modified: projects/varsym/lib/libutil/login.conf.5
==============================================================================
--- projects/varsym/lib/libutil/login.conf.5	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libutil/login.conf.5	Mon Oct 31 23:27:24 2011	(r226973)
@@ -245,6 +245,8 @@ from other means.
 .It "timezone	string		Default value of $TZ environment variable.
 .It "umask	number	022	Initial umask. Should always have a leading 0 to
 ensure octal interpretation.
+.It "varsym	list		A comma-separated list of variant symlink variables and
+values to which they are to be set.
 .It "welcome	file	/etc/motd	File containing welcome message.
 .El
 .Sh AUTHENTICATION

Modified: projects/varsym/lib/libutil/login_cap.h
==============================================================================
--- projects/varsym/lib/libutil/login_cap.h	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libutil/login_cap.h	Mon Oct 31 23:27:24 2011	(r226973)
@@ -50,7 +50,8 @@
 #define LOGIN_SETMAC		0x0100		/* set user default MAC label */
 #define LOGIN_SETCPUMASK	0x0200		/* set user cpumask */
 #define LOGIN_SETLOGINCLASS	0x0400		/* set login class in the kernel */
-#define LOGIN_SETALL		0x07ff		/* set everything */
+#define LOGIN_SETVARSYM		0x0800		/* set process variant symlink vars */
+#define LOGIN_SETALL		0x0fff		/* set everything */
 
 #define BI_AUTH		"authorize"		/* accepted authentication */
 #define BI_REJECT	"reject"		/* rejected authentication */
@@ -118,6 +119,7 @@ const char *login_setcryptfmt(login_cap_
 
 int setclasscontext(const char *, unsigned int);
 void setclasscpumask(login_cap_t *);
+void setclassvarsyms(login_cap_t *, const struct passwd *);
 int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int);
 void setclassresources(login_cap_t *);
 void setclassenvironment(login_cap_t *, const struct passwd *, int);

Modified: projects/varsym/lib/libutil/login_class.3
==============================================================================
--- projects/varsym/lib/libutil/login_class.3	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libutil/login_class.3	Mon Oct 31 23:27:24 2011	(r226973)
@@ -175,6 +175,9 @@ no action will be taken.
 .It LOGIN_SETLOGINCLASS
 Set the login class of the current process using
 .Xr setloginclass 2 .
+.It LOGIN_SETVARSYM
+Set process scope variant symlink variables using the list type capability
+"varsym=var1=val1,var2=val2..,varN=valN".
 .It LOGIN_SETALL
 Enables all of the above settings.
 .El
@@ -214,6 +217,7 @@ with LOG_ERR priority and directed to th
 .Xr setlogin 2 ,
 .Xr setloginclass 2 ,
 .Xr setuid 2 ,
+.Xr varsym 2 ,
 .Xr getcap 3 ,
 .Xr initgroups 3 ,
 .Xr login_cap 3 ,

Modified: projects/varsym/lib/libutil/login_class.c
==============================================================================
--- projects/varsym/lib/libutil/login_class.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/lib/libutil/login_class.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/rtprio.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/varsym.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -136,9 +137,15 @@ static struct login_vars {
 };
 
 static char *
-substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nlen)
+substvar(const char * var, const struct passwd * pwd)
 {
-    char    *np = NULL;
+    char	*np = NULL;
+    int		hlen = pwd ? strlen(pwd->pw_dir) : 0;
+    int		nlen = pwd ? strlen(pwd->pw_name) : 0;
+    char	pch = 0;
+
+    if (hlen && pwd->pw_dir[hlen-1] != '/')
+	++pch;
 
     if (var != NULL) {
 	int	tildes = 0;
@@ -196,18 +203,12 @@ void
 setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths)
 {
     struct login_vars	*vars = paths ? pathvars : envars;
-    int			hlen = pwd ? strlen(pwd->pw_dir) : 0;
-    int			nlen = pwd ? strlen(pwd->pw_name) : 0;
-    char pch = 0;
-
-    if (hlen && pwd->pw_dir[hlen-1] != '/')
-	++pch;
 
     while (vars->tag != NULL) {
 	const char * var = paths ? login_getpath(lc, vars->tag, NULL)
 				 : login_getcapstr(lc, vars->tag, NULL, NULL);
 
-	char * np  = substvar(var, pwd, hlen, pch, nlen);
+	char * np  = substvar(var, pwd);
 
 	if (np != NULL) {
 	    setenv(vars->var, np, vars->overwrite);
@@ -233,7 +234,7 @@ setclassenvironment(login_cap_t *lc, con
 		    char	*np;
 
 		    *p++ = '\0';
-		    if ((np = substvar(p, pwd, hlen, pch, nlen)) != NULL) {
+		    if ((np = substvar(p, pwd)) != NULL) {
 			setenv(*set_env, np, 1);
 			free(np);
 		    }
@@ -347,6 +348,31 @@ setclasscpumask(login_cap_t *lc)
 }
 
 
+void
+setclassvarsyms(login_cap_t *lc, const struct passwd * pwd)
+{
+    const char	**varsyms = login_getcaplist(lc, "varsym", ",");
+
+    if (varsyms != NULL) {
+	while (*varsyms != NULL) {
+	    char	*p = strchr(*varsyms, '=');
+
+	    if (p != NULL) {  /* Discard invalid entries */
+		char	*np;
+
+		*p++ = '\0';
+		if ((np = substvar(p, pwd)) != NULL) {
+			/* XXX: should we only ignore ENOSYS? */
+			(void)varsym_set(VARSYM_PROC, 0, *varsyms, np);
+			free(np);
+		}
+	    }
+	    ++varsyms;
+	}
+    }
+}
+
+
 /*
  * setclasscontext()
  *
@@ -400,6 +426,9 @@ setlogincontext(login_cap_t *lc, const s
 	/* Set cpu affinity */
 	if (flags & LOGIN_SETCPUMASK)
 	    setclasscpumask(lc);
+	/* Set variant symlink variables */
+	if (flags & LOGIN_SETVARSYM)
+	    setclassvarsyms(lc, pwd);
     }
     return (mymask);
 }

Modified: projects/varsym/sys/amd64/conf/GENERIC
==============================================================================
--- projects/varsym/sys/amd64/conf/GENERIC	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/amd64/conf/GENERIC	Mon Oct 31 23:27:24 2011	(r226973)
@@ -42,6 +42,7 @@ options 	MSDOSFS			# MSDOS Filesystem
 options 	CD9660			# ISO 9660 Filesystem
 options 	PROCFS			# Process filesystem (requires PSEUDOFS)
 options 	PSEUDOFS		# Pseudo-filesystem framework
+options 	VARSYM			# Variant symlink support
 options 	GEOM_PART_GPT		# GUID Partition Tables.
 options 	GEOM_LABEL		# Provides labelization
 options 	COMPAT_FREEBSD32	# Compatible with i386 binaries

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_misc.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_misc.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/thr.h>
 #include <sys/unistd.h>
 #include <sys/ucontext.h>
+#include <sys/varsym.h>
 #include <sys/vnode.h>
 #include <sys/wait.h>
 #include <sys/ipc.h>
@@ -2514,6 +2515,92 @@ freebsd32_nmount(struct thread *td,
 	return error;
 }
 
+#ifdef VARSYM
+int
+freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap)
+{
+	struct varsym_set_args ap;
+
+	ap.scope = uap->scope;
+	ap.which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+	ap.name = uap->name;
+	ap.data = uap->data;
+
+	return (varsym_set(td, &ap));
+}
+
+
+int
+freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap)
+{
+	int error;
+	id_t which;
+	size_t bufsize;
+	uint32_t bufsize32;
+
+	which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+
+	if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0)
+		return(error);
+	bufsize = bufsize32;
+
+	if ((error = kern_varsym_get(td, uap->scope, which, uap->name,
+	    uap->buf, &bufsize)) != 0)
+		return(error);
+
+	bufsize32 = bufsize;
+	error = copyout(&bufsize32, uap->size, sizeof(bufsize32));
+
+	return(error);
+}
+
+int
+freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap)
+{
+	int error;
+	id_t which;
+	size_t bufsize;
+	uint32_t bufsize32;
+
+	which = (uap->whichlo | ((id_t)uap->whichhi << 32));
+
+	if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0)
+		return(error);
+	bufsize = bufsize32;
+
+	if ((error = kern_varsym_list(td, uap->scope, which, uap->buf,
+	    &bufsize)) != 0)
+		return(error);
+
+	bufsize32 = bufsize;
+	error = copyout(&bufsize32, uap->size, sizeof(bufsize32));
+
+	return(error);
+}
+
+#else /* VARSYM */
+int
+freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap)
+{
+
+	return (ENOSYS);
+}
+
+int
+freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap)
+{
+
+	return (ENOSYS);
+}
+
+int
+freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap)
+{
+
+	return (ENOSYS);
+}
+#endif /* VARSYM */
+
 #if 0
 int
 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_proto.h
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_proto.h	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_proto.h	Mon Oct 31 23:27:24 2011	(r226973)
@@ -580,6 +580,28 @@ struct freebsd32_posix_fallocate_args {
 	char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
 	char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
 };
+struct freebsd32_varsym_set_args {
+	char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+	char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+	char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+	char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+	char data_l_[PADL_(const char *)]; const char * data; char data_r_[PADR_(const char *)];
+};
+struct freebsd32_varsym_get_args {
+	char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+	char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+	char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+	char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+	char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)];
+};
+struct freebsd32_varsym_list_args {
+	char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)];
+	char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)];
+	char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)];
+	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+	char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)];
+};
 #if !defined(PAD64_REQUIRED) && defined(__powerpc__)
 #define PAD64_REQUIRED
 #endif
@@ -690,6 +712,9 @@ int	freebsd32_msgctl(struct thread *, st
 int	freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *);
 int	freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *);
 int	freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *);
+int	freebsd32_varsym_set(struct thread *, struct freebsd32_varsym_set_args *);
+int	freebsd32_varsym_get(struct thread *, struct freebsd32_varsym_get_args *);
+int	freebsd32_varsym_list(struct thread *, struct freebsd32_varsym_list_args *);
 
 #ifdef COMPAT_43
 
@@ -1065,6 +1090,9 @@ int	freebsd7_freebsd32_shmctl(struct thr
 #define	FREEBSD32_SYS_AUE_freebsd32_shmctl	AUE_SHMCTL
 #define	FREEBSD32_SYS_AUE_freebsd32_pselect	AUE_SELECT
 #define	FREEBSD32_SYS_AUE_freebsd32_posix_fallocate	AUE_NULL
+#define	FREEBSD32_SYS_AUE_freebsd32_varsym_set	AUE_NULL
+#define	FREEBSD32_SYS_AUE_freebsd32_varsym_get	AUE_NULL
+#define	FREEBSD32_SYS_AUE_freebsd32_varsym_list	AUE_NULL
 
 #undef PAD_
 #undef PADL_

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h	Mon Oct 31 23:27:24 2011	(r226973)
@@ -424,4 +424,7 @@
 #define	FREEBSD32_SYS_rctl_add_rule	528
 #define	FREEBSD32_SYS_rctl_remove_rule	529
 #define	FREEBSD32_SYS_freebsd32_posix_fallocate	530
-#define	FREEBSD32_SYS_MAXSYSCALL	532
+#define	FREEBSD32_SYS_freebsd32_varsym_set	532
+#define	FREEBSD32_SYS_freebsd32_varsym_get	533
+#define	FREEBSD32_SYS_freebsd32_varsym_list	534
+#define	FREEBSD32_SYS_MAXSYSCALL	535

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -555,4 +555,7 @@ const char *freebsd32_syscallnames[] = {
 	"rctl_remove_rule",			/* 529 = rctl_remove_rule */
 	"freebsd32_posix_fallocate",			/* 530 = freebsd32_posix_fallocate */
 	"#531",			/* 531 = posix_fadvise */
+	"freebsd32_varsym_set",			/* 532 = freebsd32_varsym_set */
+	"freebsd32_varsym_get",			/* 533 = freebsd32_varsym_get */
+	"freebsd32_varsym_list",			/* 534 = freebsd32_varsym_list */
 };

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -592,4 +592,7 @@ struct sysent freebsd32_sysent[] = {
 	{ AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 529 = rctl_remove_rule */
 	{ AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 530 = freebsd32_posix_fallocate */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 531 = posix_fadvise */
+	{ AS(freebsd32_varsym_set_args), (sy_call_t *)freebsd32_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 532 = freebsd32_varsym_set */
+	{ AS(freebsd32_varsym_get_args), (sy_call_t *)freebsd32_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 533 = freebsd32_varsym_get */
+	{ AS(freebsd32_varsym_list_args), (sy_call_t *)freebsd32_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 534 = freebsd32_varsym_list */
 };

Modified: projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c
==============================================================================
--- projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -3034,6 +3034,40 @@ systrace_args(int sysnum, void *params, 
 		*n_args = 5;
 		break;
 	}
+	/* freebsd32_varsym_set */
+	case 532: {
+		struct freebsd32_varsym_set_args *p = params;
+		iarg[0] = p->scope; /* int */
+		uarg[1] = p->whichlo; /* uint32_t */
+		uarg[2] = p->whichhi; /* uint32_t */
+		uarg[3] = (intptr_t) p->name; /* const char * */
+		uarg[4] = (intptr_t) p->data; /* const char * */
+		*n_args = 5;
+		break;
+	}
+	/* freebsd32_varsym_get */
+	case 533: {
+		struct freebsd32_varsym_get_args *p = params;
+		iarg[0] = p->scope; /* int */
+		uarg[1] = p->whichlo; /* uint32_t */
+		uarg[2] = p->whichhi; /* uint32_t */
+		uarg[3] = (intptr_t) p->name; /* const char * */
+		uarg[4] = (intptr_t) p->buf; /* char * */
+		uarg[5] = (intptr_t) p->size; /* uint32_t * */
+		*n_args = 6;
+		break;
+	}
+	/* freebsd32_varsym_list */
+	case 534: {
+		struct freebsd32_varsym_list_args *p = params;
+		iarg[0] = p->scope; /* int */
+		uarg[1] = p->whichlo; /* uint32_t */
+		uarg[2] = p->whichhi; /* uint32_t */
+		uarg[3] = (intptr_t) p->buf; /* char * */
+		uarg[4] = (intptr_t) p->size; /* uint32_t * */
+		*n_args = 5;
+		break;
+	}
 	default:
 		*n_args = 0;
 		break;
@@ -8093,6 +8127,75 @@ systrace_setargdesc(int sysnum, int ndx,
 			break;
 		};
 		break;
+	/* freebsd32_varsym_set */
+	case 532:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "uint32_t";
+			break;
+		case 2:
+			p = "uint32_t";
+			break;
+		case 3:
+			p = "const char *";
+			break;
+		case 4:
+			p = "const char *";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* freebsd32_varsym_get */
+	case 533:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "uint32_t";
+			break;
+		case 2:
+			p = "uint32_t";
+			break;
+		case 3:
+			p = "const char *";
+			break;
+		case 4:
+			p = "char *";
+			break;
+		case 5:
+			p = "uint32_t *";
+			break;
+		default:
+			break;
+		};
+		break;
+	/* freebsd32_varsym_list */
+	case 534:
+		switch(ndx) {
+		case 0:
+			p = "int";
+			break;
+		case 1:
+			p = "uint32_t";
+			break;
+		case 2:
+			p = "uint32_t";
+			break;
+		case 3:
+			p = "char *";
+			break;
+		case 4:
+			p = "uint32_t *";
+			break;
+		default:
+			break;
+		};
+		break;
 	default:
 		break;
 	};

Modified: projects/varsym/sys/compat/freebsd32/syscalls.master
==============================================================================
--- projects/varsym/sys/compat/freebsd32/syscalls.master	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/compat/freebsd32/syscalls.master	Mon Oct 31 23:27:24 2011	(r226973)
@@ -992,3 +992,13 @@
 				    uint32_t offset1, uint32_t offset2,\
 				    uint32_t len1, uint32_t len2); }
 531	AUE_NULL	UNIMPL	posix_fadvise
+532	AUE_NULL	STD	{ int freebsd32_varsym_set(int scope, \
+				    uint32_t whichlo, uint32_t whichhi, \
+				    const char *name, const char *data); }
+533	AUE_NULL	STD	{ int freebsd32_varsym_get(int scope, \
+				    uint32_t whichlo, uint32_t whichhi, \
+				    const char *name, \
+				    char *buf, uint32_t *size); }
+534	AUE_NULL	STD	{ int freebsd32_varsym_list(int scope, \
+				    uint32_t whichlo, uint32_t whichhi, \
+				    char *buf, uint32_t *size); }

Modified: projects/varsym/sys/conf/files
==============================================================================
--- projects/varsym/sys/conf/files	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/conf/files	Mon Oct 31 23:27:24 2011	(r226973)
@@ -2358,6 +2358,7 @@ kern/kern_time.c		standard
 kern/kern_timeout.c		standard
 kern/kern_umtx.c		standard
 kern/kern_uuid.c		standard
+kern/kern_varsym.c		standard
 kern/kern_xxx.c			standard
 kern/link_elf.c			standard
 kern/linker_if.m		standard

Modified: projects/varsym/sys/conf/options
==============================================================================
--- projects/varsym/sys/conf/options	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/conf/options	Mon Oct 31 23:27:24 2011	(r226973)
@@ -183,6 +183,7 @@ SYSVSEM		opt_sysvipc.h
 SYSVSHM		opt_sysvipc.h
 SW_WATCHDOG	opt_watchdog.h
 TURNSTILE_PROFILING
+VARSYM
 VFS_AIO
 VERBOSE_SYSINIT	opt_global.h
 WLCACHE		opt_wavelan.h

Modified: projects/varsym/sys/kern/init_sysent.c
==============================================================================
--- projects/varsym/sys/kern/init_sysent.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/kern/init_sysent.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -566,4 +566,7 @@ struct sysent sysent[] = {
 	{ AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 529 = rctl_remove_rule */
 	{ AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 530 = posix_fallocate */
 	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT },			/* 531 = posix_fadvise */
+	{ AS(varsym_set_args), (sy_call_t *)sys_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 532 = varsym_set */
+	{ AS(varsym_get_args), (sy_call_t *)sys_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 533 = varsym_get */
+	{ AS(varsym_list_args), (sy_call_t *)sys_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC },	/* 534 = varsym_list */
 };

Modified: projects/varsym/sys/kern/kern_exec.c
==============================================================================
--- projects/varsym/sys/kern/kern_exec.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/kern/kern_exec.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -729,6 +729,14 @@ interpret:
 		change_svgid(newcred, newcred->cr_gid);
 		p->p_ucred = newcred;
 		newcred = NULL;
+
+#ifdef VARSYM
+		/*
+		 * Clear local varsym variables.
+		 * Do not clear privleged varsym variables.
+		 */
+		varsymset_clean(&p->p_varsymset);
+#endif
 	} else {
 		if (oldcred->cr_uid == oldcred->cr_ruid &&
 		    oldcred->cr_gid == oldcred->cr_rgid)

Modified: projects/varsym/sys/kern/kern_fork.c
==============================================================================
--- projects/varsym/sys/kern/kern_fork.c	Mon Oct 31 21:05:19 2011	(r226972)
+++ projects/varsym/sys/kern/kern_fork.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -426,6 +426,14 @@ do_fork(struct thread *td, int flags, st
 	else
 		newsigacts = sigacts_alloc();
 
+#ifdef VARSYM
+	/*
+	 * Initialize and copy varsyms
+	 */
+	varsymset_init(&p2->p_varsymset, &p1->p_varsymset);
+	varsymset_init(&p2->p_varsymset_priv, &p1->p_varsymset_priv);
+#endif
+
 	/*
 	 * Copy filedesc.
 	 */

Added: projects/varsym/sys/kern/kern_varsym.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/varsym/sys/kern/kern_varsym.c	Mon Oct 31 23:27:24 2011	(r226973)
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2007-2009 The Aerospace Corporation.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon at backplane.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * $FreeBSD$
+ * $DragonFly: src/sys/kern/kern_varsym.c,v 1.6 2005/01/14 02:25:08 joerg Exp $
+ */
+
+/*
+ * This module implements variable storage and management for variant
+ * symlinks.  These variables may also be used for general purposes.
+ */
+
+#include "opt_varsym.h"
+
+#include <sys/param.h>
+#include <sys/priv.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/ucred.h>
+#include <sys/resourcevar.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/refcount.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
+#include <sys/varsym.h>
+#include <sys/sysproto.h>
+
+#ifdef VARSYM
+
+SYSCTL_NODE(_vfs, OID_AUTO, varsym, CTLFLAG_RD, NULL,
+    "Variant symlink managment");
+
+int varsym_enable = 0;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, enable, CTLFLAG_RW, &varsym_enable, 0,
+    "Enable Variant Symlinks");
+TUNABLE_INT("vfs.varsym.enable",
+    &varsym_enable);
+
+static int varsym_allow_default = 0;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, allow_default, CTLFLAG_RW,
+    &varsym_allow_default, 0,
+    "allow variables to have default values");
+TUNABLE_INT("vfs.varsym.allow_default",
+    &varsym_allow_default);
+
+static int varsym_max_proc_setsize = 32;
+SYSCTL_INT(_vfs_varsym, OID_AUTO, max_proc_setsize, CTLFLAG_RW,
+    &varsym_max_proc_setsize, 0,
+    "maximum number of varsym variables on a process");
+TUNABLE_INT("vfs.varsym_max_proc_setsize",
+    &varsym_max_proc_setsize);
+
+static int unprivileged_varsym_set_proc = 1;
+SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_varsym_set_proc, CTLFLAG_RW,
+    &unprivileged_varsym_set_proc, 0,
+    "allow unprivileged users to set per-process varsym variables");
+TUNABLE_INT("security.bsd.unprivileged_varsym_set_proc",
+    &unprivileged_varsym_set_proc);
+
+MALLOC_DEFINE(M_VARSYM, "varsym", "variable sets for variant symlinks");
+static struct mtx	varsym_mutex;
+static struct varsymset	varsymset_sys;
+
+static int	varsymmake(int scope, const char *name, const char *data);
+static void	varsymdrop(varsym_t var);
+static struct varsyment * varsymlookup(struct varsymset *vss, const char *name,
+                    int namelen);
+static int	varsym_clear(struct thread *td, int scope, id_t which);
+static int	vss2buf(struct varsymset *vss, char *buf, int *bytes,
+		    int maxsize);
+static varsym_t	varsymfind(int scope, const char *name, int namelen);
+
+/*
+ * Initialize the variant symlink subsystem
+ */
+static void
+varsym_sysinit(void *dummy)
+{
+	mtx_init(&varsym_mutex, "varsym", NULL, MTX_DEF);
+	varsymset_init(&varsymset_sys, NULL);
+}
+SYSINIT(announce, SI_SUB_INTRINSIC, SI_ORDER_FIRST, varsym_sysinit, NULL);
+
+/*
+ * Initialize the varsymset for proc0
+ */
+static void
+varsym_p0init(void *dummy)
+{
+	PROC_LOCK(&proc0);
+	varsymset_init(&proc0.p_varsymset, NULL);
+	varsymset_init(&proc0.p_varsymset_priv, NULL);
+	PROC_UNLOCK(&proc0);
+}
+SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_SECOND, varsym_p0init, NULL);
+
+/*
+ * varsymreplace() - called from namei
+ *
+ *	Do variant symlink variable substitution
+ */
+int
+varsymreplace(char *cp, int linklen, int maxlen)
+{
+	int rlen;
+	int xlen;
+	int nlen;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list