ID: h01
Name: loadable_modules
Created: 12/10/2001
Based on: v2.15
Prereqs: none
Okay folks, here it is. A completely reworked patch that provides
dynamically loadable module support.
This time around, all device drivers are included and almost all driver
data has been made private to each driver. All direct references to
main code data and functions has been removed and replaced with indirect
access through the System Control Block.
Currently, only device modules are supported, but the module interface
should be able to support other types as well. And it can be easily
extended if needed.
There are 3 new commands, 1 configuration file change, and a new
loading/unloading process. Let's do the config file change first:
For each module you wish to load at startup, add the following line
to your hercules.cnf file:
MODULE <filename> where <filename> is the name of the module
By default, the modules will get installed in '/usr/local/lib' and you
need to make sure that it is included in /etc/ld.so.conf or your
LD_LIBRARY_PATH environment variable. You can also specify the full
path on the MODULE line if you so desire.
If you choose not to enable module support, you may leave the MODULE
line in your hercules.cnf file. It will be tolerated with only a warning
message.
The 3 new commands are:
modadd <filename> Loads a new module
moddel <filename> [force] Unloads a module
modlist [filename] Lists currently loaded modules
Currently, the FORCE option on the MODDEL command only works for device
modules. It automatically performs a DETACH for each device using the
module. (Sorry, there's no automatic re-attach. :-))
This brings us to the load/unload process. In the last patch, all you
had to do is detach all of the devices that was using a given module and
that module would automatically be unloaded. Now, you have to issue the
MODDEL command to get the module unloaded. Also, you'll need to use the
MODADD command to load a module, whereas before all you had to do is
attach a device.
This automatic loading/unloading process can be put back in and I may very
well do that RSN, but I wanna play with some other things first. :-)
It might help if I told you how to enable module support, eh? Well, just
include "--enable-modules" when you run the "configure" script. Or, if
you prefer you can use "--disable-modules" too. :-)
Of course, what would Hax be without caveats:
1) To make things MUCH easier, I've included a static pointer to the
SYSBLK in each driver. It is set when the module is loaded and
remains constant throughout its life. This isn't so bad unless
you're trying to load the module in an environment where loaded
objects are shared among all active processes. Having the static
pointer would mean that if multiple Hercules processes were running,
the pointer in the module would only be able to reference one of
the Hercules environments at a time.
This really isn't that much of a big deal. How many instances of
Hercules can your CPU handle? :-)
2) The console driver private data is only "pseudo" private. There are
many references in the main code that makes it rather difficult to
completely privatize the data. It doesn't hurt anything, it's just
not consistent with the rest of the modules.
3) The CKDDASD driver utilizes a couple of bits in the System Control
Block. One is for global CKD key tracing and the other is for a
SYNCIO workaround. Again, no big deal.
4) Windows support should be possible with this version of the patch. I
just haven't gotten around to it yet.
5) As usual, UAYOR.
===============================================================================
Update: 12/10/2001
Oops, forgot and left console debugging turned on. Sorry 'bout that.
===============================================================================
Updated: 12/10/2001
Well, I guess I should've gone over this a tad more. If you happen
to issue the "devinit" command multiple times while only specifying
the device number, Herc will segfault due to me attempting to free
the devices storage when it's already freed.
I must apologize for this blatant oversight.
===============================================================================
Updated: 12/11/2001
Let's try not to do THAT again. I made some really STOO-PID mistakes with
this one. I "think" I've found all of my brain farts, and have added a
few additional checks in the process. I've also made the console data
private.
So far, I'm running successfully. All the crap that I was seeing after
running for a bit seems to have been corrected so, if you're brave, go
ahead and try it again. :-)
===============================================================================
Updated: 12/12/2001
A few more "minor" fixes. The first being that the unload never actually
worked. The second was a segfault when the force option was used. To be
honest, I'm not certain I've tackled the latter. I couldn't pin down the
exact issue with it. But, somewhere along the line, it stopped occurring
so I reckon I got it. We'll see...
I also got rid of one more (harmless) senior moment. I think the code is
back to at least 45 years old. I'd say it was around 100 when I released
this Hax back on the 10th.
The modlist command now allows you to specify a module name to get just
the info for that module.
Aside from a couple of fields, most all console data has not been made
private.
===============================================================================
Updated: 12/15/2001
Added a config file option and panel command to set the location of modules.
Both use the same format:
modpath [pathname]
Where pathname is the path to the directory containing the modules. It MUST
end with a slash. If you do not include the pathname, the module path will
be nullified and the system default search order is restored.
Also, if used in the config file, it's location important. If all of your
modules are in the same directory then just put the "modpath" statement before
any of the "module" statements. You may use more than one "modpath" statement
if your modules reside in different locations. For example:
modpath /usr/local/some_modules/
module module1.mod
module module2.mod
module module3.mod
modpath /usr/local/other_modules/
module other1.mod
module other2.mod
The last "modpath" statement will be the active one when issuing module
commands from the panel, unless you change it with the "modpath" panel
command.
===============================================================================
Updated: 12/16/2001
Cleaned up Makefile.am a little (I guess). I still can't get the darn thing
to do what I want. Oh, well. It works. At least it's a bit more "natural"
now.
If anybody has suggestions on how this should be done, you have my email
addy. :-)
Oh yea, I suppose I should tell ya. Now the modules get installed into the
$(pkglibdir) directory. If you're using the standard values, this will be
'/usr/local/lib/hercules'. Because this is not in the standard search path
for loadable modules, you'll need to tell the system about it. There are
several ways to do this:
1) Specify one of the default system lib directories at install time:
make pkglibdir=/usr/lib install
2) Add '/usr/local/lib/hercules' to your /etc/ld.so.conf file or your
LD_LIBRARY_PATH environment variable
3) Specify the path in your config file with the MODPATH statement:
MODPATH <module path>/ <---- trailing slash
4) Specify the path on each MODULE statement:
MODULE <module path>/tapedev.mod
===============================================================================