Userapi, Reflection

Galen Sampson galen_sampson at yahoo.com
Mon Nov 3 19:25:05 PST 2003


Matthew Dillon wrote:
:All,
:
:   I have been contemplating how the useapi portion of the project will work
:(for those not farmiliar please see
:http://www.dragonflybsd.org/Goals/userapi.cgi).  What I think would be quite
:impressive would be a process that uses reflection (java and c#).  Reflection
:is an api that allows for the creation of types, functions, and classes at run
:time.  Please see http://java.sun.com/docs/books/tutorial/reflect/index.html
:for information how java does this.
:   The idea for userapi would be to use reflection to create callable
:prototypes for systemcalls at run time.  Say we have our special user level
:process that handles system calls.  It is invoked by the kernel like init.  It
:will have a configuration file, containing prototypes for every system call it
:knows how to handle.  If linux changes a prototype for one of their system
:calls, the configuration file could be modified accordingly.  On a SIGHUP the
:process would re-read the configuration file, and modify the prototypes
:accordingly.   The idea is that you could modify, add, and delete system calls
:at runtime, without ever rebooting the os or modifying any code at all.
:   This is just a thought I had.  It is possible that it is infeasible, but I
:thought I would throw the idea out there and see what other might think of it.
:
:Regards,
:Galen Sampson
    Well, I guess the question is:  What type of run-time entity would
    use these prototypes?   I can see adding and removing support for
    particular system calls in libc.so dynamically, but the programs that
    link into libc would have no visibility into the changes after the
    fact.  That is, you would still have to either restart an application 
    or start an application dependant on a new system call after having
    loaded the configuration for the system call.  This doesn't seem much
    different then reinstalling libc on a live system.  Applications are
    still going to hardwire their understanding of a particular syscall's
    API.

   I think I haven't made myself entirely clear (thats not unusual :). 
 The entity that would use these prototypes would be the system call 
proxy itself (nothing else would use it).  Forgive my ignorance on the 
kernel internals, and my possible missreading/misunderstanding of the 
goals envisioned for dragonfly.  I will try to lay out more clearly what 
I meant by the use of reflection.

My current understanding of the userapi goal:
   The userapi goal provides support for emulation and system call 
messaging.  A processes, started and managed by the kernel, is created 
at boot time.  This process is a proxy to the real kernel (a proxy in 
that it acts solely as a forwarding and translating entity).  In 
dragonfly there will be 3 real system calls, send a message to the 
kernel, abort a message sent to the kernel, and wait for a message to be 
returned by the kernel.
   The proxy entity will act on behalf of all other processes system 
calls.  There will be two cases: system calls invoked by a natively 
compiled process, and thus knows the proxy agent is in existent, and 
system calls invoked from every other running process (freebsd binary, 
linux binary, .....).  In the first (native) case, a process will use 
ipc, or some special messaging functionality to execute the proxy's code 
within the callers context.  Reflection does not help in this case.  In 
the second (non-native) case, A process will invoke its notion of a 
system call and all will be handled by the proxy.
   The non-native binary will trap to the kernel.  Its notion of how 
arguments should be arranged is going to occur.  If it thinks its system 
call arguments should be registers, they will be in registers.  If it 
thinks its system call arguments should be on the stack, they will be on 
the stack.  If a kernel receives one of these calls it shouldn't have to 
do anything but forward a trap frame to the user level process acting as 
a proxy.  This proxy will gather up the arguments from the frame into a 
system call message, and send it natively.

How reflection might be used:
   Reflection could be useful in the "gather up the arguments into a 
system call message" stage (a.k.a. emulation stage).  Reflection would 
be used here to generate the code that shims the arguments into a 
message.  Say linux 2.6 comes out and you would like to emulate it.  Say 
linux 2.6 adds a system call.  Instead of modifying the code of the 
proxy itself, you add the prototype to its configuration file, send 
SIGHUP, poof! The new system call is now supported for emulation.

   Hopefully that is somewhat clear.  It may very well be the case that 
the emulation will need to do a series of things besides just gather 
arguments.  In this case it would not make much sense to use reflection 
because the proxy's configuration file would get complex, and you might 
as well write the code.  Also, system calls aren't added or modified all 
that often, and so once again it might not be worth it to add all of 
this complexity.  However, if the emulation is generic enough, then it 
might be worth it.

Regards,
Galen





More information about the Kernel mailing list