The Politics of Porting

The flagship application was headed for the rocks. One man seized the wheel and guided the ship to safety—but will he be keelhauled for acting without orders?

I “Steal” the Code

At this point I should say “Don't do what I did.” It is illegal to
copy your employer's source code without permission, and you are likely to find yourself at
the wrong end of a lawsuit if it all goes belly up, but sometimes dire
circumstances require drastic solutions.

In late November 1998, I checked out a full set of source code and, along
with a newly downloaded copy of Oracle 8.0.4, I set up the development
environment on my PC at home; using the unedited Makefile from the
Solaris development directory, I ran make. Not
surprisingly, it all fell
in a heap, throwing up pages of compile errors.

I devoted an hour or two most evenings to stepping through the errors
and debugging them. Those I didn't understand I presented to Richard
Glover, one of the senior UNIX developers at Constellar. He also was
the release manager for the various UNIX versions of the Hub, so he was
a good person to know.

Most of the problems revolved around the Oracle ProC precompiler, which
didn't recognise some Linux-specific directives, such as the
include_next statements in the Linux header files. This was resolved
by copying the relevant files, stripping the
#include_next statements
out and placing the location of our customised version of these files
first in the include path.

There also were assorted issues with library paths. These were trivial
and related solely to the setup on my home PC. They were solved by
adding entries to the LD_LIBRARY_PATH shell variable exactly as it would
be with Solaris. Some macro definitions—ULONG_MAX, INT_MIN, INT_MAX,
LONG_MAX—were missing from the copy of Red Hat that I was using at the
time. I copied them from the relevant Solaris headers as a temporary fix.

I left some minor problems unresolved because my resources were somewhat
limited. For instance, the Hub was required to connect to many and varied
sources of data, and some of these required the use of IBM MQ series
libraries, which I did not have available at the time. In any case, I did
not have the facilities to test such functionality at home. I edited the
main Makefile to disable the linking of these libraries and accepted
that my version of the Hub would be a lightweight, more dynamic kind of
Hub. If it compiled at all, I would be happy.

Some differences found in the Linux version of various utilities were
sorted out by editing scripts to reflect the proper invocation
of particular utilities. I worked my way around some of them, and I ignored
others to save time. Richard would later track down the source of all these
problems and make allowances for them in the platform-specific sections
of various build scripts in the official build environment at work. Those
utilities that required changes to the standard build scripts included
various compiler and linker flags. We were obliged to use the Sun compiler
for the official Solaris build, so moving to Linux and GCC required a
bit of translation with regard to the flags and switches. The use of df,
the shell built-in echo command, ftp, ldd, mknod, nm, ps and lex/yacc
(used for the proprietary Transformation Definition Language) all
required changes when invoked.

As Richard pointed out a few weeks later, the set -o posix option
in bash resolved nearly all the shell script differences, and in any
case, the command-line differences were quite trivial and the solution
obvious. In some cases, it was simply a case of providing Berkeley versions
of the utilities rather than the System V ones, or vice versa.
The situation would be different today, because many of the GNU utilities
standard on Linux
are now included as standard
with Solaris, so porting between the two has become even simpler.

In all, it probably took about two man-days to get a rough-and-ready port
with a binary that at least looked like an executable.

The Smoke Test

I had a binary, now I needed to test it. I checked out a copy of the suite of test
scripts and data used in the daily smoke test at work. After setting the
environment variables for the smoke test, I set the test harness running.

The usual smoke test consisted of more than 200 transactions, and on
the other platforms would take anything from six hours for UNIX versions to more than 24
hours for the Windows NT version—this is not good when testing a daily
build. I ran the test on my home-built Linux port, and within a minute
or two I had errors scrolling up the screen. Disaster. I checked the error
logs, but they were no help. For some reason, the logs didn't provide any
diagnostics for the first few dozen transactions, and this confused me.

It took a while to figure out that the reason there were no diagnostics
in the error log for the initial set of transactions was simply because
the Linux Hub already had run the first few dozen transactions successfully!
This initially was hard to believe, because the same set of transactions
took considerably longer to run on most of the other platforms to
which the Hub was ported. This meant that my rough homebrew Linux
version of the Hub was, without tuning, already faster on my home PC
than some of the other UNIX ports, and several times faster than the
Windows NT port. Even allowing for the differences between the hardware
specifications on which these varied ports ran, it looked good.

I felt sure that if these results could be reproduced in the workplace,
there would have to be an official Linux port.