home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / modutils / kerneld / README.kerneld < prev    next >
Encoding:
Text File  |  1998-01-06  |  14.8 KB  |  388 lines

  1.             "Kerneld": An implementation of "kernel deamons"
  2.                                 or
  3.    A truly automatic and invisible support for loadable modules in Linux
  4.  
  5.         Bjorn Ekwall <bj0rn@blox.se> in May 1995 and January + March 1996
  6.  
  7.  
  8. Executive summary:
  9.  
  10.     - Read the section "Extensions", last in this document, and
  11.       decide if you would like to try them.  You don't have to...
  12.       (It's about getting the pid of the "trigger" process
  13.        and about persistent module storage)
  14.  
  15.     - Install the module utilities in this package.
  16.  
  17.     - Apply the the relevant patch to your kernel (for 1.2 kernels)
  18.  
  19.     - Enable CONFIG_KERNELD in "make config"
  20.  
  21.     - Make a kernel with "everything" (but the root fs, root disk)
  22.       as loadable modules.
  23.       Install the modules with "make modules_install"
  24.  
  25.     - A "make install" in this directory will put "kerneld" in /sbin
  26.  
  27.     - Add these lines at the top of /etc/rc:
  28.         if [ -x /sbin/kerneld ]
  29.         then
  30.             /sbin/kerneld
  31.         fi
  32.  
  33.     - Read the man page for modprobe to see if you want to create/change
  34.       the configuration file "/etc/conf.modules"
  35.  
  36.       Example: I have these lines to complement the defaults in modprobe:
  37.         alias scsi_hostadapter aha1542
  38.           alias eth0 3c509
  39.         alias eth1 de620
  40.         options de620 bnc=1
  41.       ("modprobe -c" will show you the current modprobe configuration)
  42.  
  43.     - Remove any explicit "insmod" that you might have in your
  44.       startup scripts (in /etc/rc*/*).
  45.  
  46.     - Reboot and enjoy... i.e. mount some file systems, ifconfig eth0 ...
  47.  
  48.     - Forget about how to do "insmod" manually :-)
  49.  
  50.  
  51.  
  52. Introduction:
  53.  
  54. The aim of "kerneld" is to give the kernel a possibility to send requests
  55. to the user level.  These requests will result in actions by user-level
  56. programs.  The results of these actions will be reported back to the kernel,
  57. if the kernel wants them...
  58.  
  59. The requests we have implemented now support "on demand loading" and
  60. unloading of loadable kernel modules, since it is quite easy for the
  61. kernel to notice when a process requests a functionality that is not
  62. supplied in the standard kernel configuration, but might be implemented
  63. as a loadable kernel module.
  64. A kernel that is configured to use "kerneld" can thus be seen as a
  65. "virtual" full-configured kernel.
  66.  
  67. The "kerneld" support can be seen as an "inverted" fork/exec, where the
  68. kernel can decide, for each fork/exec, whether it wants to wait for an
  69. exit status or not.
  70. If the kernel selects to wait for an exit status, it can also select to
  71. recieve data from "kerneld".
  72.  
  73. I decided to use the IPC message mechanism instead of sockets, since the
  74. IPC "fits" better for this purpose IMHO.  If (=when) the net subsystem is
  75. implemented as loadable modules, this decision will be seen as a wise one :-)
  76.  
  77. I just made a couple of small additions to the kernel IPC support,
  78. and I think that we have something workable...
  79.  
  80.  
  81. Status:
  82.  
  83. The kernel modifications are in a quite a good shape for now, and the
  84. user level "kerneld" as well, although "kerneld" now only handles a few
  85. different actions. It is easy to extend this if you want to...
  86. Note that kerneld automatically removes unused modules and stacks that
  87. it has loaded even without any explicit kernel request for this!
  88.  
  89.  
  90. Modifications:
  91.  
  92. In "ipc/msg.c" there are some small additions, and an added function:
  93.  
  94.     int kerneld_send(int msgtype, int return_size, int msgsz,
  95.         const char *text, const char *return_value);
  96.  
  97. We have also added the following (inline) kernel support functions:
  98.     ksystem (const char *command, int wait_flag);
  99.     request_module (const char *name);
  100.     release_module (const char *name, int wait_flag);
  101.     delayed_release_module (const char *name);
  102.     cancel_release_module (const char *name);
  103.     kerneld_route(const char *ip_route);
  104.  
  105. (See also: <linux/kerneld.h>)
  106.  
  107. For the "request_module()" call, the kernel will wait for "kerneld"
  108. to finish its job. For the other "*module()" calls it will not wait,
  109. unless there is a wait_flag that has been set.
  110.  
  111. Jacques Gelinas and I have added "request_module()" calls for _all_
  112. filesystems, block and character devices, as well as the net drivers.
  113. There is also a "request_module()" in "fs/exec.c" which will try to
  114. load any missing binary format interpreter (such as iBCS).
  115. Note that the kernel will now support _all_ filesystems, devices,
  116. net drivers and binary formats, even those that aren't written yet!
  117. All that is required is that the functionality is available as
  118. a kernel loadable module and that modprobe can find it.
  119. You might have to update "/etc/conf.modules" for the new module though...
  120.  
  121. The additional code is practically insignificant; just a couple of lines
  122. in "fs/devices.c", "fs/super.c", "fs/exec.c", "net/inet/route.c"
  123. and "net/inet/dev.c"...
  124.  
  125.  
  126. "Theory:"
  127.  
  128. A specific kernel message queue is allocated for use as a channel between
  129. the kernel and the user level.  When the user level daemon "kerneld"
  130. opens a message queue with "msgget()", where the flag has the new bit
  131. IPC_KERNELD set (defined in <linux/msg.h>), this queue will be marked
  132. as being the "kerneld" message queue.
  133. All sends and receives on this queue will be handled specially by the kernel.
  134.  
  135. The function "kerneld_send" will add a message from the kernel to the
  136. queue, and this message will be picked up by the user level kernel daemon.
  137. The action requested is encoded in the message type.
  138. The traditional IPC message text array ("mtext") is now divided into two
  139. separate fields; the "id" and "text" fields:
  140.  
  141.     struct kerneld_msg {
  142.         long mtype;
  143.         long id;
  144.         char text[1];
  145.     };
  146.  
  147. The field "id" is used by the kernel to store a sequence number, so that a
  148. return status can be picked up by the correct, sleeping, kernel level process.
  149.  
  150. The user level kernel daemon is really only a "switch(mtype)", where we for
  151. now use 1 as signifying a "system" command, 2 as a request for "insmod"
  152. and 3 as a request for "rmmod", and so on.
  153. The relevent command is executed, using "text" as a parameter.
  154. If the "id" field is 0, it is interpreted by kerneld as an indication
  155. that the kernel don't want any status information.
  156. If the "id" field is non-zero, it will be used as the message type of the
  157. return message, from kerneld to the kernel, and the "id" field will now
  158. instead be used to store the exit value from the executed command.
  159.  
  160.  
  161. If kerneld_send is called with "(return_size & KERNELD_WAIT) == 0", the
  162. kernel will not wait for an "answer" from "kerneld".  Otherwise it will
  163. wait for a message where the type is equal to the sequence number of the
  164. original request.
  165. If "return_size & ~KERNELD_WAIT > 0", and "return_value != NULL", the
  166. returned information in the "text" field will be copied to the area
  167. pointed to by "return_value".
  168. In all cases where the KERNELD_WAIT flag is set, the status will
  169. be returned to the caller of kerneld_send().
  170. In this way it is possible to have concurrent requests to "kerneld".
  171.  
  172. Since the requests are encoded in the message type, it is possible
  173. to have several, independent, kernel deamons, that each "listens"
  174. for a specific message type.
  175.  
  176. The message types from the kernel to kerneld are limited to <= KERNELD_MAXCMD,
  177. so that all sends from the kernel to kerneld will have a type less than that
  178. value (defined in <linux/kerneld.h>).
  179. The sequence numbers start at KERNELD_MINSEQ, which means that all
  180. messages from kerneld back to the kernel will all have a type greater
  181. or equal than this value, but still positive (defined in <linux/kerneld.h),
  182. and thus easily distinguishable.
  183.  
  184. Note that more than one daemon can exist simultanuously, if the other
  185. daemons only "listens" for _one_ specific message type, since the
  186. "normal" kerneld is set up to only look for message types less than 256.
  187.  
  188. This makes the linux kernel somewhat "micro-kernelish", with server
  189. processes that are called by the kernel through a well defined interface!
  190. Note that the "text" field in the message can be any arbitrary bit
  191. pattern, e.g. it is possible to send any type of structs back and forth
  192. between the kernel and the daemon(s)!  The only requirement is that the
  193. kernel and the kerneld processing agree on how to interpret the info.
  194.  
  195.     struct param parameter;
  196.     struct retval return_value;
  197.     int kerneld_function_number = KERNELD_KNOWS_MY_SPECIAL_MAGIC_FUNCTION;
  198.  
  199.     ...
  200.  
  201.     status = kerneld_send(kerneld_function_number,
  202.                 sizeof(struct retval) | KERNELD_WAIT,
  203.                 sizeof(struct param),
  204.                 (char *) ¶meter,
  205.                 (char *) &return_value);
  206.     ...
  207.  
  208.  
  209.  
  210. Check out kdsend.c and kdstat.c for a use of kerneld from user space...
  211.  
  212. Note that modules now can have a "hidden" autoclean attribute, that is set
  213. on modules loaded by kerneld (via the "-k" option to insmod).
  214. Modules marked "autoclean" will be subject to removal attempts every minute.
  215. Since the timer is restarted every time a module is loaded by "kerneld",
  216. a module will be able to stay "unused" in the kernel for max one minute.
  217.  
  218.  
  219.  
  220. Extensions:
  221.  
  222. The "pid" extension:
  223. -------------------
  224.  
  225.   The kerneld protocol can be extended to also send the pid of the process
  226.   that triggered the kerneld event.  The pid of the "triggering" process is
  227.   then available to kerneld, and all programs that are started by kerneld,
  228.   via the environment variable KERNELD_TRIGGER.
  229.   If kerneld was triggered during an interrupt, the pid will be set to 0.
  230.  
  231.   The 2.0-kernels are prepared for this, the only thing you have to do is
  232.   to uncomment the definition in linux/include/linux/kerneld.h, line 18:
  233.  
  234.  
  235. --- linux/include/linux/kerneld.h.org    Mon Jun 10 18:16:31 1996
  236. +++ linux/include/linux/kerneld.h    Mon Jun 10 18:17:24 1996
  237. @@ -14,8 +14,8 @@
  238.   * Uncomment the following line for the new kerneld protocol
  239.   * This includes the pid of the kernel level requester into the kerneld header
  240.   */
  241. -/*
  242.  #define NEW_KERNELD_PROTOCOL
  243. +/*
  244.   */
  245.  #ifdef NEW_KERNELD_PROTOCOL
  246.  #define OLDIPC_KERNELD 00040000   /* use the kerneld message channel */
  247.  
  248.  
  249.   I have tried to make kerneld backwards compatible with un-patched kernels,
  250.   but the patch will require a re-compile of all kerneld-type daemons...
  251.  
  252.   The reason for this extension is to make it possible to e.g. create
  253.   "just-in-time" debuggers for Linux, that are started whenever a fault
  254.   is detected by the kernel.
  255.  
  256.   Another use is to enable custom made "beeps", via the kdsound daemon in
  257.   the GOODIES directory.  The command name, used to select the "beep", can
  258.   easily be found in the "/proc/<pid>/cmdline" file, or via e.g.:
  259.     set `ps hc $KERNELD_TRIGGER`
  260.     case $5 in
  261.     xbiff) ..... ;;
  262.     bash) .... ;;
  263.     *) ... ;;
  264.     esac
  265.  
  266.  
  267. The "persist" extension:
  268. -----------------------
  269.  
  270.   In this release there is support for persistent module storage via kerneld.
  271.   This means that a module can save its internal state, to be restored on
  272.   the next invocation.
  273.  
  274.   Note: this is still experimental, since there is no agreed-upon syntax
  275.     for the keys.  The key _could_ be created by prepending the module name
  276.     to the key name, so that no name collisions would happen (unless we
  277.     _want_ the to happen, of course).
  278.  
  279.   To enble this feature, apply the included "kerneld-persist-patch" to
  280.   the kernel.  This will upgrade linux/include/linux/kerneld.h
  281.  
  282.   If you have libgdbm, and if you want to be able to control the
  283.   behaviour of the persistent storage, you should modify the Makefile
  284.   in this directory according to the instructions at the top.
  285.  
  286.  
  287.   How it works:
  288.  
  289.   If a module wants to save some information that might be useful for
  290.   when it is reloaded at a later time, a call to "set_persist" will
  291.   make this possible.
  292.  
  293.   The syntax is:
  294.     int set_persist(char *key, void *value, size_t size)
  295.  
  296.   where the key can be any string, the value can be anything (including
  297.   structs and arrays) and size is the size of the value to be stored.
  298.   (A negative return value indicates that the kernel couldn't send
  299.   the message to kerneld.)
  300.  
  301.   This call will trigger a kerneld action, where the key and value
  302.   is stored inside kerneld, as well as in a gdbm-file, if you have
  303.   enabled this in the Makefile.
  304.  
  305.   It is possible to use the persistant storage even without gdbm,
  306.   but the information will the be lost as soon as kerneld exits.
  307.  
  308.   The gdbm file will reside in /lib/modules/`uname -r`/persist.gdbm.
  309.  
  310.   The information in the gdbm file can be read and updated by ordinary user
  311.   programs (with the right authorities), and any changes can be reloaded
  312.   into the running kerneld by sending a SIGHUP to kerneld ("kill -1").
  313.  
  314.   Note that kerneld only keeps the gdbm file open as long as it uses it.
  315.   The file will be closed after each update, so the gdbm limitation
  316.   of only one writer at a time is not a big problem...
  317.  
  318.   Also note that kerneld will initialise itself from this gdbm file
  319.   whenever kerneld starts to execute as well.  This makes the information
  320.   even survive re-boots.
  321.  
  322.  
  323.   If a module wants to get the saved persistent information, it could
  324.   do a call to "get_persist", using the same key as was used when the
  325.   information was stored.  See below for insmod support (which is better).
  326.  
  327.   The syntax is:
  328.     int get_persist(char *key, void *value, size_t size)
  329.  
  330.   where the key can be any string, the value is a pointer to the memory
  331.   where the return value should be stored, and size is the size of the
  332.   value to be stored. The returned value will never be larger than this.
  333.   The return value from the call tells how many bytes that were actually
  334.   read, and can be used to verify that the correct data type was read.
  335.  
  336.   If the return value from get_persist is 0, then no value could be
  337.   found for this key.
  338.   A negative return value indicates that the kernel couldn't send
  339.   the message to kerneld, so no persistent information was available.
  340.  
  341.  
  342.   If, for some reason, a module wants to remove a saved entry, this call
  343.   will make that possible:
  344.  
  345.     set_persist("the key", NULL, 0);
  346.  
  347.  
  348.   How to use it in your modules:
  349.  
  350.   An example can be found in "check_persist.c", which shows all the
  351.   normal ways of using the persistent storage.  Even though the example
  352.   puts the call to set_persist in the init_module function, there is
  353.   no limitation to where it can be put in a real module, since the
  354.   kerneld action will be performed asynchronously, i.e. the kernel
  355.   doesn't have to wait until kerneld has stored the value.
  356.  
  357.   It's really quite trivial to use, so go right ahead!
  358.  
  359.   Note that insmod now can conditionally set the values of any symbol
  360.   from a key:
  361.  
  362.     insmod module.o symbol=?key:default_value
  363.  
  364.   If there is no persistent key with that name, the default_value (if any)
  365.   will be used.
  366.   Note that this makes it possible to drop most calls to "get_persist"!
  367.  
  368.   To administer the persistent values, a simple utility "admpersist" is
  369.   included.  It can be used like this:
  370.  
  371.     admpersist        # shows all keys and their values
  372.     admpersist a_key    # shows the value stored by "a_key"
  373.     admpersist a_key=0x1234    # creates/updates the persistent value
  374.     admpersist -d a_key    # deletes the persistent value
  375.  
  376.   More examples:
  377.  
  378.     admpersist -d key1 key2 key3    # delete these persistent values
  379.     admpersist an_array=27,0x1b,033    # handle an integer array
  380.  
  381.   The admpersist utility can handle arrays similar to what insmod does, and
  382.   understands integer values expressed in hex, octal or decimal.
  383.  
  384.   If you want kerneld to note the changes, do a "kill -1" on kerneld.
  385.  
  386.  
  387. Bjorn Ekwall  <bj0rn@blox.se>  in June 1996
  388.