Computone Logo
1060 Windward Ridge Parkway Suite 100
Alpharetta, GA 30085-3992
(800) 241-3946 or (770) 625-0000
World Wide Web - http://www.computone.com
e-mail: sales@computone.com

iservd Release 2.1


We ran across an inconsistency in Solaris when running on an Intel platform versus a Sparc platform.  To solve the problem introduced by symbolic links for device names resolving to a relative location, I added the capability to provide an absolute path in the iservd.conf file.  If an entry begins with a slash, it will be interpreted as the fully-qualified name. Otherwise "/dev/" will be prepended to it to form the fully-qualified name.

The default name of the log file assumes a flat structure whereas in previous releases "/tmp/" was blindly prepended to each config file entry.  With this release "/tmp/" is prepended to the basename of the entry.  This is backward compatable with previous releases.

Examples:

Config File Entry
Fully-qualified
Device Name
Fully-qualified
Log File Name
ttyI00 /dev/ttyI00 /tmp/ttyI00.debug
ttyI01 /dev/ttyI01 /tmp/ttyI01.debug
term/timeclock /dev/term/timeclock /tmp/timeclock.debug
/checkouts/lane1.prt2 /checkouts/lane1.prt2 /tmp/lane1.prt2.debug
/dev/term/is00 /dev/term/is00 /tmp/is00.debug

 

iservd Release 2.0


As the major release number indicates, a fair number of significant changes have been implemented in this release of iservd.  I have not yet had the opportunity to test it on all platforms that were previously supported.  However, I have tested it on Linux on a Pentium, on HP-UX, AIX, SunOS (sun4 and sparc), and on Solaris on a Pentium.
Problems Identified
With that said, let's move on to the exciting stuff. A number of problems were identified in iservd that related to the lock file.  In prior versions, the lock file's location defaulted to /etc/iservd.pids but could be overridden.  Through a series of "kill -9" signals sent to individual processes resulted in a corrupt lock file. This, in turn, could cause ports on the IntelliServer to become non-functional, and in extreme cases, terminate processes that were not related to iservd at all.
Release 1.4.0 saw some problems fixed specific to AIX.  It took a combination of OS patches and a workaround in code to avoid an iservd parent from hanging.  In some cases the process would runaway accumulating large amounts of CPU time.  This was actually being spent in an infinite loop in the AIX kernel - thus the need for the OS patches.
On architectures where auto push is enabled (-DPUSH_A in the Makefile), the pseudo-tty was being initialized correctly (cooked mode, etc.) on the first connection.  Should the connection ever be broken, however, the pseudo-tty was being deleted and reconstructed without properly resetting these modes.  This has been corrected in this release.
Architecture - Old and New
Let's talk a moment about a previous release of iservd.  iservd actually had 3 distinct major functions to it, the highest in the hierarchy is the "Boss" function. The other two functions constituted a parent-child communication "pair" one for each direction of data flow.
The Boss was in charge of examining the configuration file, and starting an iservd process for each configured port which becomes the "parent" half of the communication pair. After all these Parents were started, the Boss terminated without error.
Examining a communication pair in more detail, the Parent first examined the lock file (defaults to/etc/iservd.pids) for another Parent process running on the pseudo-tty specified in the command line by the Boss.  If it found one, the new Parent process would merely terminate.  Otherwise, it will add itself to the lock file then wait for a connection to be established with the IntelliServer.  Once successfully doing this, it would start the other half of the communication pair - the Child.  The Parent assumes responsibility for reading data from the pseudo-tty and sending it to the IntelliServer while the Child handles data flowing in the opposite direction: from the IntelliServer to the pseudo-tty.  When the Parent was signaled to terminate, it would first terminate the Child, then remove itself from the lock file and exit.
If the Parent were sent a SIGKILL signal (kill -9), it would terminate without doing any of the cleanup work needed.  Thus the lock file would become inconsistent and a child would be left hanging around as an orphan.  More specifically, the lock file will be left with an entry referring to a now non-existent Parent process.  Repeating this process would result in multiple Children running for a specific pseudo-tty.
Running "iservd -K" will invoke the Boss functionality, except instead of scanning the configuration file and starting Parents, it will scan the lock file and send a SIGTERM to each process.  After waiting a short period of time, if there were any processes left running, it would send a SIGKILL to the ones that were left.  Combining this with the process outlined in the previous paragraph, it is entirely conceivable that an unrelated program could be started and assume the same process ID that has been left in the lock file.  Running "iservd -K" will SIGTERM this process (perhaps a database service?) and follow it up with a SIGKILL.
So... What I'd do to fix it?  The philosophy of maintaining information as dynamic as process IDs in a container as static as a file really rubbed my fur wrong.  A file hangs around through system bounces and such.  One alternative would be to place everything in a shared memory segment.  At least this goes away in a system bounce.  However, it hangs around through iservd bounces.  I wanted to implement an architecture that would start fresh each time iservd started.
Take, for a moment, just the communication functionality of iservd, and put it in a program called iservdc.  In a completely separate program, place all the functionality of the Boss in to a module by itself and call it a "Job Manager".  The Job Manager's job is to parse the configuration file, spawn children, each known as a Job, that become the Parents of the communication pairs, and track the entire life of each.  When one of the Parents die, it's the Job Manager's job to restart it.  When the configuration file changes, it's the Job Manager's job to re-read it, killing Parents currently running on ports that no longer exist in the configuration file, starting Parents that are new in the configuration file, and bouncing Parents whose parameters have changed.  So, the Job Manager hangs around after starting each job. It uses a small amount of memory (~10kB), a slot in the process table (of course), and cpu time only when prompted by the receipt of a signal.
Stick with me here. For backward compatibility, let's call the Job Manager iservd.  It spawns iservdc processes that handle communication with a single port.  Since iservd's purpose is to parse the configuration file, I've added a slightly new slant on the meaning of the first field.  Now, not only does the first field designate the name of the pseudo-tty that will be created (for interface to an application), but it also designates a "Job ID".
In summary, iservd is now the Job Manager. It reads the configuration file and starts an iservdc for each job found, and tracks the life of the job, restarting them if necessary. iservdc is the communication pair containing both the Parent and the Child functionality.
The Details
Iservd accepts 5 options.  If you give it an invalid option (like -?) you'll receive some brief usage instructions:
iservd: invalid option -- ?

usage: iservd [-sKR] [-d debugLevel] [-f fileName]

where:

        -s forces iservd to run foreground.

        -K sends signal TERM (terminate) to the currently running iservd

        -R sends signal HUP (reconfig) to the currently running iservd

        -f = Uses specified config file.

        -d debugLevel produces output. 0=none, 1=errors only, 2=verbose. (0)


Normally, iservd will force itself to run in the background.  The -s will prevent this from happening and thus will run in the foreground.  The only purpose for this flag is to aid in debugging.

Note: The options that were supported in previous release of iservd are now supported by iservdc.  As before, these options should be placed in the configuration file.
The File and Program Names
Iservd can be named anything you want.  On an AIX system, it comes out of the make as iservd.aix, on HP as iservd.hp, and on Linux as iservd.lin.  It can also be stored in any directory you want.  Typically I used /usr/iservd.  To come up with a configuration file name, simply add ".conf" to the fully qualified name of the iservd program.  Using Linux as the target machine and the example I just cited, the default configuration file name would be /usr/iservd/iservd.lin.conf.  Along the same lines, the name of the communication pair must be identical to the name of the job manager except with a "c" appended to the base name.  Thus on the same Linux machine, it must be named /usr/iservd/iservdc.lin.  When the job manager starts to run, it records its process id in a file with ".pid" appended to its own program name.  Thus on my machine, it would be /usr/iservd/iservd.lin.pid.  This is how the -K and -R options know to which process a signal should be sent.  On an AIX machine, simply replace the ".lin" with ".aix" wherever it appears and you got it.
Let's assume that you have scripts already established to start and stop iservd.  Of course these reference iservd, not iservd.lin.  It also expects the program to be in the /etc directory.  No sweat.  Just move or copy the programs to the /etc directory, leaving off the machine specific extension, such as ".lin" or ".aix".  The set would then become:
/etc/iservd       Job Manager
/etc/iservdc      Communications Processor
/etc/iservd.conf   Default configuration file.
/etc/iservd.pid    Created at runtime.
Reconfigure iservd
Using the -R option will cause that invocation of iservd to read the iservd.pid file from the directory from which it was executed.  That file is defined to contain the process ID of the Job Manager.  It will then send a SIGHUP to that process.  The following two commands are equivalent:
./iservd -R
kill -1 `cat iservd.pid`
Kill iservd
The -K option is similar to the -R except that it sends a SIGTERM to the Job Manager.
Download and Installation
Pretty straightforward.  So, before going on, let's get a couple of directories straight to avoid confusion.  Let's assume that the installation target directory is in /usr/iservd.  You'll have to determine whether you have uncompress or gunzip.  If you have uncompress, download iservd from here.  If you have  gunzip, download iservd from here.  If you have neither, you can download the uncompressed version from here.  It may take a littler longer, but it's only 241K.  If you downloaded one of the compressed versions, uncompress it in the /usr/iservd directory with the respective utility.

You should now have a single file, iservd-2.0.0.shar.  The next task is to unpack the shell archive.  This is easiest done by redirecting stdin from this file into a shell.

sh <iservd-2.0.0.shar    # Unpack the shell archive
make                     # display configured targets
From the list of configured targets displayed, choose the one that matches your operating system and run make again, this time with your target choice as the sole argument.
make AIX32               # build iservd for AIX
In this example, I've used AIX as the target operating system. You can ignore any warnings you get, but if you get compiler errors, well, I guess there's more work to do.
If you want to deploy this release with the same setup as previous iservd releases, perform the following after any running iservd processes are stopped.  Use "ps -aux" or "ps -ef" to verify this.
mv iservd.aix /etc      # Again, substitute your OS in place of ".aix"
mv iservcat.aix /etc    # and here...
mv iservdc.aix /etc     # and here...
rm /etc/iservd.lok      # No longer needed
The format of the configuration file hasn't change so you can leave the existing /etc/iservd.conf in place.
Are you ready to start it? Here goes...
/etc/iservd >/var/log/iservd.log 2>&1   # Logging is now sent to stdout.
or...
/etc/iservd -d 3 >/ver/log/iservd.log 2>&1   # for some verbose logging.
Questions?
If you have any questions or problems building iservd, please feel free to call Computone Tech Support at 800-241-3946 x2002, or e-mail us at support@computone.com.