svn commit: r191972 - head/sys/compat/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun May 10 18:27:21 UTC 2009
Author: dchagin
Date: Sun May 10 18:27:20 2009
New Revision: 191972
URL: http://svn.freebsd.org/changeset/base/191972
Log:
Introduce linux_kernver() interface which is intended for an exact
designation of the emulated kernel version.
linux_kernver() returns integer value formatted as 'VVVMMMIII' where
VVV - version, MMM - major revision, III - minor revision.
Approved by: kib (mentor)
Modified:
head/sys/compat/linux/linux_mib.c
head/sys/compat/linux/linux_mib.h
Modified: head/sys/compat/linux/linux_mib.c
==============================================================================
--- head/sys/compat/linux/linux_mib.c Sun May 10 18:25:14 2009 (r191971)
+++ head/sys/compat/linux/linux_mib.c Sun May 10 18:27:20 2009 (r191972)
@@ -54,7 +54,7 @@ struct linux_prison {
char pr_osname[LINUX_MAX_UTSNAME];
char pr_osrelease[LINUX_MAX_UTSNAME];
int pr_oss_version;
- int pr_use_linux26; /* flag to determine whether to use 2.6 emulation */
+ int pr_osrel;
};
static unsigned linux_osd_jail_slot;
@@ -87,7 +87,7 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, osn
"Linux kernel OS name");
static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.6.16";
-static int linux_use_linux26 = 1;
+static int linux_osrel = 2006016;
static int
linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
@@ -130,6 +130,37 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, oss
"Linux OSS version");
/*
+ * Map the osrelease into integer
+ */
+static int
+linux_map_osrel(char *osrelease, int *osrel)
+{
+ char *sep, *eosrelease;
+ int len, v0, v1, v2, v;
+
+ len = strlen(osrelease);
+ eosrelease = osrelease + len;
+ v0 = strtol(osrelease, &sep, 10);
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
+ return (EINVAL);
+ osrelease = sep + 1;
+ v1 = strtol(osrelease, &sep, 10);
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
+ return (EINVAL);
+ osrelease = sep + 1;
+ v2 = strtol(osrelease, &sep, 10);
+ if (osrelease == sep || sep != eosrelease)
+ return (EINVAL);
+
+ v = v0 * 1000000 + v1 * 1000 + v2;
+ if (v < 1000000)
+ return (EINVAL);
+
+ *osrel = v;
+ return (0);
+}
+
+/*
* Returns holding the prison mutex if return non-NULL.
*/
static struct linux_prison *
@@ -187,7 +218,7 @@ linux_alloc_prison(struct prison *pr, st
strncpy(lpr->pr_osname, linux_osname, LINUX_MAX_UTSNAME);
strncpy(lpr->pr_osrelease, linux_osrelease, LINUX_MAX_UTSNAME);
lpr->pr_oss_version = linux_oss_version;
- lpr->pr_use_linux26 = linux_use_linux26;
+ lpr->pr_osrel = linux_osrel;
mtx_unlock(&osname_lock);
}
done:
@@ -297,14 +328,17 @@ linux_prison_set(void *obj, void *data)
mtx_unlock(&pr->pr_mtx);
return (error);
}
- if (osname)
- strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
if (osrelease) {
+ error = linux_map_osrel(osrelease, &lpr->pr_osrel);
+ if (error) {
+ mtx_unlock(&pr->pr_mtx);
+ return (error);
+ }
strlcpy(lpr->pr_osrelease, osrelease,
LINUX_MAX_UTSNAME);
- lpr->pr_use_linux26 = strlen(osrelease) >= 3 &&
- osrelease[2] == '6';
}
+ if (osname)
+ strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
if (gotversion)
lpr->pr_oss_version = oss_version;
mtx_unlock(&pr->pr_mtx);
@@ -471,19 +505,19 @@ linux_get_osrelease(struct thread *td, c
}
int
-linux_use26(struct thread *td)
+linux_kernver(struct thread *td)
{
struct prison *pr;
struct linux_prison *lpr;
- int use26;
+ int osrel;
lpr = linux_get_prison(td, &pr);
if (lpr != NULL) {
- use26 = lpr->pr_use_linux26;
+ osrel = lpr->pr_osrel;
mtx_unlock(&pr->pr_mtx);
} else
- use26 = linux_use_linux26;
- return (use26);
+ osrel = linux_osrel;
+ return (osrel);
}
int
@@ -491,18 +525,25 @@ linux_set_osrelease(struct thread *td, c
{
struct prison *pr;
struct linux_prison *lpr;
+ int error;
lpr = linux_get_prison(td, &pr);
if (lpr != NULL) {
+ error = linux_map_osrel(osrelease, &lpr->pr_osrel);
+ if (error) {
+ mtx_unlock(&pr->pr_mtx);
+ return (error);
+ }
strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME);
- lpr->pr_use_linux26 =
- strlen(osrelease) >= 3 && osrelease[2] == '6';
mtx_unlock(&pr->pr_mtx);
} else {
mtx_lock(&osname_lock);
+ error = linux_map_osrel(osrelease, &linux_osrel);
+ if (error) {
+ mtx_unlock(&osname_lock);
+ return (error);
+ }
strcpy(linux_osrelease, osrelease);
- linux_use_linux26 =
- strlen(osrelease) >= 3 && osrelease[2] == '6';
mtx_unlock(&osname_lock);
}
Modified: head/sys/compat/linux/linux_mib.h
==============================================================================
--- head/sys/compat/linux/linux_mib.h Sun May 10 18:25:14 2009 (r191971)
+++ head/sys/compat/linux/linux_mib.h Sun May 10 18:27:20 2009 (r191972)
@@ -43,6 +43,10 @@ int linux_set_osrelease(struct thread *t
int linux_get_oss_version(struct thread *td);
int linux_set_oss_version(struct thread *td, int oss_version);
-int linux_use26(struct thread *td);
+int linux_kernver(struct thread *td);
+
+#define LINUX_KERNVER_2006000 2006000
+
+#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000)
#endif /* _LINUX_MIB_H_ */
More information about the svn-src-head
mailing list