summaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2009-05-28 04:00:03 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2009-05-28 04:00:03 +0000
commit8a39576dd1aa645162b9d768a7463a1b065c1b09 (patch)
tree5d0e6e17bf2cee6be830e3e80fb65831348028fa /sys/compat
parent01e5f291129a8084934221aab6228c72cc1c6423 (diff)
Merge r191972 from HEAD to stable/7:
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)
Notes
svn path=/stable/7/; revision=192950
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_mib.c63
-rw-r--r--sys/compat/linux/linux_mib.h6
2 files changed, 55 insertions, 14 deletions
diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c
index 634d51db2077..c4fad14d51c5 100644
--- a/sys/compat/linux/linux_mib.c
+++ b/sys/compat/linux/linux_mib.c
@@ -52,7 +52,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;
};
SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
@@ -83,7 +83,7 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, osname,
"Linux kernel OS name");
static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.4.2";
-static int linux_use_linux26 = 0;
+static int linux_osrel = 2004002;
static int
linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
@@ -126,6 +126,37 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version,
"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 prison *
@@ -229,21 +260,21 @@ linux_get_osrelease(struct thread *td, char *dst)
}
int
-linux_use26(struct thread *td)
+linux_kernver(struct thread *td)
{
struct prison *pr;
struct linux_prison *lpr;
- int use26 = linux_use_linux26;
+ int osrel;
pr = td->td_ucred->cr_prison;
if (pr != NULL) {
if (pr->pr_linux != NULL) {
lpr = (struct linux_prison *)pr->pr_linux;
- use26 = lpr->pr_use_linux26;
+ osrel = lpr->pr_osrel;
}
- }
-
- return (use26);
+ } else
+ osrel = linux_osrel;
+ return (osrel);
}
int
@@ -251,20 +282,26 @@ linux_set_osrelease(struct thread *td, char *osrelease)
{
struct prison *pr;
struct linux_prison *lpr;
- int use26;
-
- use26 = (strlen(osrelease) >= 3 && osrelease[2] == '6');
+ int error;
pr = linux_get_prison(td);
if (pr != NULL) {
lpr = (struct linux_prison *)pr->pr_linux;
+ error = linux_map_osrel(osrelease, &lpr->pr_osrel);
+ if (error) {
+ mtx_unlock(&pr->pr_mtx);
+ return (error);
+ }
strcpy(lpr->pr_osrelease, osrelease);
- lpr->pr_use_linux26 = use26;
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 = use26;
mtx_unlock(&osname_lock);
}
diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h
index 85f616352ad0..398626c072f8 100644
--- a/sys/compat/linux/linux_mib.h
+++ b/sys/compat/linux/linux_mib.h
@@ -40,6 +40,10 @@ int linux_set_osrelease(struct thread *td, char *osrelease);
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_ */