Date: Fri, 13 Oct 1995 16:45:46 -0700 From: "Jordan K. Hubbard" <jkh@time.cdrom.com> To: Terry Lambert <terry@lambert.org> Cc: julian@ref.tfs.com, jhay@mikom.csir.co.za, hackers@FreeBSD.ORG Subject: Re: IPX now available Message-ID: <612.813627946@time.cdrom.com> In-Reply-To: Your message of "Fri, 13 Oct 1995 11:06:48 PDT." <199510131806.LAA17852@phaeton.artisoft.com>
next in thread | previous in thread | raw e-mail | index | archive | help
> Right now, it is a Roman orgy, which is order bound. The LKM's sysmbols > are added to the kernel symbol space for subsequent loads. The LKM's > themselves are free to access anything that they can see. Why not do this through an "access list" of sorts? Something like this, maybe: #define VAR_T_INT 1 #define VAR_T_STATIC_STR 2 #define VAR_T_INDIRECT 3 #define VAR_T_USERDEF 100 /* Anything above is user type */ typedef struct _var { int type; int readOnly; union { struct { void *(*get)(struct _var *); void (*put)(struct _var *, void *newval); } acc; int ival; char *sval; } data; void *ext; } Var; Would represent a shared kernel/LKM variable or function pointer. Then you'd have these functions: int variable_add_table(HTable *newtable); extern Var *variable_register(char *name); extern void *variable_get(char *name, int *err); extern void variable_put(char *name, void *nvalue, int *err); The first function installs a hash table into the ordered list that will be used to look up Var structures by name in variable_{get,put}(). I figured you could implement a trivial scoping mechanism with it later but use it for installing just one global kernel-wide hash table for now. The second routine allocates and adds a new Var structure to the hash table, indexed by name. The client would be expected to fill in the components of the Var structure directly in the case of a non-NULL return (I suppose that you could also make an access function for this and avoid diddling any of Var's values directly, either way is fine by me). If a variable is of one of the "canned" types, in this example either INT or STATIC_STR, then variable_get() just fetches that value directly and returns it, variable_put() just stomping a new one into place (assuming that readOnly isn't set). If the value is of type INDIRECT, then the variable's get() function is called with the variable structure as an argument and that function is expected to return the value. Likewise, the put() function is expected to store the new value properly into the variable, modulo readOnly. Both access functions are free to modify `ext', which is their hook value. The passed in `err' variable would also be set according to whether or not the operation was successful since you can't count on the return values signifying anything. I think you could do some neat stuff with this. At kernel startup time, a hash table is registered and all the things the kernel wants to "export" registered with it. Then an LKM is loaded, but it doesn't reference anything from global space. It has its own local variables which it initializes by calling variable_get(). If the kernel has "revoked" access to some object then the LKM will be expected to check the status from get accordingly and either die neatly or attempt to deal with the problem more intelligently somehow (it might try a different name, succeed, and then realize it's running on a different revision of the kernel and make some internal adjustments). Likewise, since you can indirect the value of any variable through the `acc' pointers, the kernel can change some internal interface fairly radically and simply adjust the access pointers in the initialization code. The LKMs will neither know nor care. Hell, for all they know a message has just been sent to a remote node to satisfy the request! Or is that simply stretching the existing paradigm too much? :-) Jordan
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?612.813627946>