[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: kernel or syskold not supporting flavours



Manoj Srivastava writes:
 > 	As it stands, the Flavours hack does allow one to keep
 >  multiple flavours of the same kernel version simultaneously on ones
 >  machine, and to switch back and forth using a boot manager, and even
 >  have klogd work with it.
 > 
 > 	Is that not an accurate assesment?

Yep.

 > Yann> It seems to me that the reason is just that System.map includes
 > Yann> this numeric version instead of the string.  But I can't figure
 > Yann> out why it is so ?
 > 
 > 	Umm, the reason for what? (I am confused). Since klogd does
 >  not have access to the System.map file, (we are talking about how
 >  klogd discovers where the System.map file is, corrrect?), the
 >  contents of the System.map file should not have a bearing on this.

Uh, here I got confused too.  Here's output from kern.log:

==== without "-k ..."
Mar 23 22:05:58 bylbo kernel: klogd 1.3-3, log source = /proc/kmsg started.
Mar 23 22:05:59 bylbo kernel: Symbol table has incorrect version number. 
Mar 23 22:05:59 bylbo kernel: Cannot find map file.
Mar 23 22:05:59 bylbo kernel: Error seeking in /dev/kmem 
Mar 23 22:05:59 bylbo kernel: Error adding kernel module table entry. 
====

==== with "-k ..."
Mar 23 22:07:25 bylbo kernel: klogd 1.3-3, log source = /proc/kmsg started.
Mar 23 22:07:26 bylbo kernel: Loaded 2589 symbols from /boot/System.map-2.0.33-std.
Mar 23 22:07:26 bylbo kernel: Symbols do not match kernel version.
Mar 23 22:07:26 bylbo kernel: Error seeking in /dev/kmem 
Mar 23 22:07:26 bylbo kernel: Error adding kernel module table entry. 
====

Obviously there are even problems with the "-k" option.

Then I downloaded the source and had a look at ksym.c, where all this
stuff seems to be located:


* function CheckVersion() checks that the Version_* symbol (probably
taken from the found System.map), by building a version string from
the version code, and comparing against the release string returned by
uname().  This is a problem with flavours, and is IMHO bad, because it
involves *divisions* (not even shifts) to build the string, and
compares a string, which is I guess less efficient than building a
code from the string, and comparing the 2 integers.  And this will fix
the "Symbols do not match kernel version." problem.

* With no -k option, FindSymbolFile() first tries, and finds
"System.map-2.0.33-std".  Then it uses CheckVersion() to verify that
the map file is matching the current kernel: the test fails "Symbol
table has incorrect version number." (see above - same problem).  Then
it tries, and doesn't find any other possible file for the map, and
says "Cannot find map file."

...fixing CheckVersion() will fix both cases, and we won't need the
"-k" kludge any more.

* The 2 last messages come from AddModule() in sys_mod.c.  The 2nd one
tells the funcall failed, the 1st one is emitted by the function, most
probably because the 1st parameter (p->value) is bad, where p points
to a symbol in the sym table as reported by the kernel
(get_kernel_syms() syscall).  Don't know much about that.


Here is a patch that should fix the System.map related problems.  Note
that it is largely untested, but I think it should be quite close to
be usable as-is.

====
--- ksym.c.orig	Mon Mar 23 23:23:03 1998
+++ ksym.c	Mon Mar 23 23:32:30 1998
@@ -438,7 +438,7 @@
 	
 
 {
-	auto int	vnum,
+	auto int	vnum, kvnum,
 			major,
 			minor,
 			patch;
@@ -458,21 +458,9 @@
 
 
 	/*
-	 * Since the symbol looks like a kernel version we can start
-	 * things out by decoding the version string into its component
-	 * parts.
+	 * Get the numeric code from the system map.
 	 */
 	vnum = atoi(version + strlen(prefix));
-	major = vnum / 65536;
-	vnum -= (major * 65536);
-	minor = vnum / 256;
-	patch = vnum - (minor * 256);
-	if ( debugging )
-		fprintf(stderr, "Version string = %s, Major = %d, " \
-		       "Minor = %d, Patch = %d.\n", version +
-		       strlen(prefix), major, minor, \
-		       patch);
-	sprintf(vstring, "%d.%d.%d", major, minor, patch);
 
 	/*
 	 * We should now have the version string in the vstring variable in
@@ -486,12 +474,23 @@
 		Syslog(LOG_ERR, "Cannot get kernel version information.");
 		return(0);
 	}
+
+	if ( sscanf (utsname.release, "%d.%d.%d", major, minor, patch) < 3 )
+	{
+		Syslog(LOG_ERR, "Kernel send bogus release string `%s'.",
+		       utsname.release);
+		return(0);
+	}
+
+	/* Compute the version code from data sent by the kernel */
+	kvnum = (major << 16) | (minor << 8) | patch;
+	
 	if ( debugging )
 		fprintf(stderr, "Comparing kernel %s with symbol table %s.\n",\
 		       utsname.release, vstring);
 
 	/* Failure. */
-	if ( strcmp(vstring, utsname.release) != 0 )
+	if ( vnum != kvnum )
 		return(-1);
 
 	/* Success. */
====

cents += 2,
-- 
Yann Dirson  <ydirson@a2points.com>      | Stop making M$-Bill richer & richer,
alt-email:     <dirson@univ-mlv.fr>      |     support Debian GNU/Linux:
debian-email:   <dirson@debian.org>      |         more powerful, more stable !
http://www.a2points.com/homepage/3475232 | Check <http://www.debian.org/>


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org


Reply to: