PERFORCE change 99144 for review

Roman Divacky rdivacky at FreeBSD.org
Tue Jun 13 17:14:39 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=99144

Change 99144 by rdivacky at rdivacky_witten on 2006/06/13 17:12:02

	Make the LINUXBASE path settable via sysctl. Useful when you have more then one linux bases
	installed etc.
	
	example:
	sysctl compat.linux.emulpath=/tmp/linux/
	/tmp/linux/bin/grep
	Usage: grep [OPTION]... PATTERN [FILE]...

Affected files ...

.. //depot/projects/soc2006/rdivacky_linuxolator/amd64/linux32/linux32_sysvec.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_mib.c#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_mib.h#2 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#2 edit

Differences ...

==== //depot/projects/soc2006/rdivacky_linuxolator/amd64/linux32/linux32_sysvec.c#2 (text+ko) ====

@@ -1018,7 +1018,7 @@
 					ELFOSABI_LINUX,
 					EM_386,
 					"Linux",
-					"/compat/linux",
+					linux_emul_path,
 					"/lib/ld-linux.so.1",
 					&elf_linux_sysvec,
 					NULL,
@@ -1029,7 +1029,7 @@
 					ELFOSABI_LINUX,
 					EM_386,
 					"Linux",
-					"/compat/linux",
+					linux_emul_path,
 					"/lib/ld-linux.so.2",
 					&elf_linux_sysvec,
 					NULL,

==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_mib.c#2 (text+ko) ====

@@ -38,7 +38,10 @@
 #include <sys/jail.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
 
+extern Elf32_Brandinfo *linux_brandlist[];
 #include "opt_compat.h"
 
 #ifdef COMPAT_LINUX32
@@ -52,6 +55,7 @@
 	char	pr_osname[LINUX_MAX_UTSNAME];
 	char	pr_osrelease[LINUX_MAX_UTSNAME];
 	int	pr_oss_version;
+	char	pr_emul_path[LINUX_NAME_MAX];
 };
 
 SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
@@ -81,6 +85,32 @@
 	    0, 0, linux_sysctl_osname, "A",
 	    "Linux kernel OS name");
 
+char	linux_emul_path[LINUX_NAME_MAX] = "/compat/linux/";
+
+static int
+linux_sysctl_linux_emul_path(SYSCTL_HANDLER_ARGS)
+{
+           char emul_path[LINUX_NAME_MAX];
+	   int error;
+	   Elf32_Brandinfo **brandinfo;
+
+	   linux_get_emul_path(req->td, emul_path);
+	   error = sysctl_handle_string(oidp, emul_path, LINUX_NAME_MAX, req);
+	   if (error || req->newptr == NULL)
+	      	return (error);
+	   error = linux_set_emul_path(req->td, emul_path);
+	   for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
+		 ++brandinfo)
+	      	if (elf32_insert_brand_entry(*brandinfo) < 0)
+		   error = EINVAL;	   
+	   return (error);
+}
+
+SYSCTL_PROC(_compat_linux, OID_AUTO, emulpath,
+	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON,
+	    0, 0, linux_sysctl_linux_emul_path, "A",
+	    "Linux kernel OS emulation path");
+
 static char	linux_osrelease[LINUX_MAX_UTSNAME] = "2.4.2";
 
 static int
@@ -246,6 +276,51 @@
 	return (0);
 }
 
+void
+linux_get_emul_path(struct thread *td, char *dst)
+{
+	register struct prison *pr;
+	register struct linux_prison *lpr;
+
+	pr = td->td_ucred->cr_prison;
+	if (pr != NULL) {
+		mtx_lock(&pr->pr_mtx);
+		if (pr->pr_linux != NULL) {
+			lpr = (struct linux_prison *)pr->pr_linux;
+			if (lpr->pr_emul_path[0]) {
+				bcopy(lpr->pr_emul_path, dst, LINUX_NAME_MAX);
+				mtx_unlock(&pr->pr_mtx);
+				return;
+			}
+		}
+		mtx_unlock(&pr->pr_mtx);
+	}
+
+	mtx_lock(&osname_lock);
+	bcopy(linux_emul_path, dst, LINUX_NAME_MAX);
+	mtx_unlock(&osname_lock);
+}
+
+int
+linux_set_emul_path(struct thread *td, char *emul_path)
+{
+	struct prison *pr;
+	struct linux_prison *lpr;
+
+	pr = linux_get_prison(td);
+	if (pr != NULL) {
+		lpr = (struct linux_prison *)pr->pr_linux;
+		strcpy(lpr->pr_emul_path, emul_path);
+		mtx_unlock(&pr->pr_mtx);
+	} else {
+		mtx_lock(&osname_lock);
+		strcpy(linux_emul_path, emul_path);
+		mtx_unlock(&osname_lock);
+	}
+
+	return (0);
+}
+
 int
 linux_get_oss_version(struct thread *td)
 {

==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_mib.h#2 (text+ko) ====

@@ -40,4 +40,7 @@
 int	linux_get_oss_version(struct thread *td);
 int	linux_set_oss_version(struct thread *td, int oss_version);
 
+void	linux_get_emul_path(struct thread *td, char *dst);
+int	linux_set_emul_path(struct thread *td, char *emul_path);
+
 #endif /* _LINUX_MIB_H_ */

==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#2 (text+ko) ====

@@ -858,7 +858,7 @@
 					ELFOSABI_LINUX,
 					EM_386,
 					"Linux",
-					"/compat/linux",
+					linux_emul_path,
 					"/lib/ld-linux.so.1",
 					&elf_linux_sysvec,
 					NULL,
@@ -869,7 +869,7 @@
 					ELFOSABI_LINUX,
 					EM_386,
 					"Linux",
-					"/compat/linux",
+					linux_emul_path,
 					"/lib/ld-linux.so.2",
 					&elf_linux_sysvec,
 					NULL,


More information about the p4-projects mailing list