Subject: Re: LKM support for many filesystems as well as compat_freebsd
To: Michael Graff <explorer@flame.org>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 08/12/1996 17:25:58
On 12 Aug 1996 18:25:28 -0400 
 Michael Graff <explorer@flame.org> wrote:

[ code snippet with #ifdef's... ]

 > Since this code is enabled anytime COMPAT_FREEBSD is compiled in, I assume
 > it doesn't hurt to have it "always" work.  I changed the
 > 	defined(COMPAT_FREEBSD)
 > part to read
 > 	defined(COMPAT_FREEBSD) || defined(COMPAT_FREEBSD_LKM)
 > in this case, and I use
 > 	options COMPAT_FREEBSD_LKM
 > in my config file.  It could be argued that this is a hack and should be
 > based on which emulation is currently active rather than a compile-time
 > hook, but this was easier as an experiment.

Actually, what should probably be done is that should be moved out to 
sys/compat/common ... the snippet you posted seems rather gross :-)  The 
emulations that use that should either make a call to the 
compat_43_sys_getpid() or should include their own :-)

Anyhow, I thought one of the points of LKM'ing was to eliminate the #ifdefs?

 > Also, there are some portions of code which actually check to see which
 > emulation mode a program is running in, using
 > 	#ifdef COMPAT_LINUX
 > 	               /* Linux has a special system setup call as number 0 */
 > 	              if (p->p_emul == &emul_linux_aout ||
 > 	                  p->p_emul == &emul_linux_elf) { ... }
 > 
 > I replaced the COMPAT_LINUX portion as above, and replaced the check with
 > 		      if (p->p_emul == emul_linux_aout || ...
 > 
 > I then added, to a new file I called compat_lkm.c for lack of a better
 > name for this experiment:
 > 	#if defined(COMPAT_LINUX)
 > 	struct emul *emul_linux_aout = &_emul_linux_aout;
 > 	struct emul *emul_linux_elf = &_emul_linux_elf;
 > 	#else
 > 	#if defined(COMPAT_LINUX_LKM)
 > 	struct emul *emul_linux_aout = NULL;
 > 	struct emul *emul_linux_elf = NULL;
 > 	#endif
 > 	#endif

hmm... Perhaps the emul structure pointers should just always exist in 
kern/exec_conf.c, always declared NULL.  In kern/exec_subr.c, a new 
function, emul_init() could be implemented.  This function would fill in 
the emulation struct pointers if the emulations were compiled in 
statically.  It could be implemented something like:

[ . . . ]

/*
 * Emulation struct pointers are always present, and are declared
 * in exec_conf.c
 */

extern struct emul *emul_linux_aout;
extern struct emul *emul_linux_elf;

[ . . . ]

/*
 * Actual emulation structures are only present if the emulation
 * is compiled in statically.
 */

#if defined(COMPAT_LINUX)
extern struct emul _emul_linux_aout;
extern struct emul _emul_linux_elf;
#endif

[ . . . ]

/*
 * Fill in emululation structure pointers for use by statically
 * compiled emulations.
 */
void
emul_init()
{

#if defined(COMPAT_LINUX)
	emul_linux_aout = &_emul_linux_aout;
	emul_linux_elf = &_emul_linux_elf;
#endif

	[ . . . ]
}

I just don't like the notion of having another #define for LKMs, when 
LKMs are supposed to help get rid of that :-)

 > One thing I don't know for certain is what happens if you try to unload
 > freebsd when something is being run in freebsd emulation mode.  I suspect
 > Bad Things.

"Try it."  At the very least, the executable in question will probably 
drop core.  :-)

 > Type    Id  Off Loadaddr Size Info     Rev Module Name
 > VFS       0  21 f881e000 0020 f8825000   1 msdosfs
 > VFS       1  20 f8828000 000c f882a000   1 procfs
 > VFS       2  19 f882e000 0008 f882f000   1 kernfs
 > VFS       3  18 f8830000 0014 f8834000   1 cd9660
 > VFS       4  17 f8836000 0008 f8837000   1 mfs
 > 
 > All of those work just fine.

Cool ... err, what happens when you run out of room in the file system 
switch table?  Also, when you load a file system, I assume that it places 
itself into the appropriate place in the switch table?

 > For filesystems which require syscalls or other kernel modifications, I am
 > somewhat stuck.  I don't know how exactly to do that yet, so currently
 > I just don't load those.  This includes NFS, lfs, and perhaps ffs.

You'd have to just do the additional procedure to LKM'ing a syscall.  I 
guess this entails just installing the appropriate function pointer into 
the appropriate slot in the syscall switch table.

Just some thoughts...

Ciao.

 -- save the ancient forests - http://www.bayarea.net/~thorpej/forest/ -- 
Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffett Field, CA 94035                                Pager: 415.428.6939