mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 16:57:16 +01:00
464 lines
17 KiB
Markdown
464 lines
17 KiB
Markdown
|
# ZeroMQ on z/OS UNIX System Services
|
||
|
|
||
|
ZeroMQ has been successfully built on z/OS, using [z/OS UNIX System
|
||
|
Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/),
|
||
|
a certified UNIX environment for the [IBM
|
||
|
z-series](http://www-03.ibm.com/systems/z/). The build is possible
|
||
|
with the shell scripts in this directory, as described below.
|
||
|
|
||
|
Tested build combinations:
|
||
|
|
||
|
* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in ILP32 mode
|
||
|
|
||
|
* ZeroMQ 4.0.4, using IBM XL C/C++ compiler, as XPLINK in LP64 mode
|
||
|
|
||
|
* ZeroMQ 4.1-git, using IBM XL C/C++ compiler, as XPLINK in ILP32 mode
|
||
|
|
||
|
Other combinations are likely to work, possibly with minor changes,
|
||
|
but have not been tested. Both static library and DLL modes have been
|
||
|
tested.
|
||
|
|
||
|
There are some minor limitations (detailed below), but all core
|
||
|
functionality tests run successfully.
|
||
|
|
||
|
|
||
|
## Quickstart: building ZeroMQ on z/OS UNIX System Services
|
||
|
|
||
|
Assuming [z/OS UNIX System
|
||
|
Services](http://www-03.ibm.com/systems/z/os/zos/features/unix/) is
|
||
|
installed, and the [z/OS XL C/C++
|
||
|
compiler suite](http://www-03.ibm.com/software/products/en/czos) is
|
||
|
installed, ZeroMQ can be built as follows:
|
||
|
|
||
|
* Download and extract ZeroMQ tar file
|
||
|
|
||
|
* Ensure contents of this directory are present at `builds/zos`
|
||
|
within that extracted diretory (eg, `zeromq-VERSION/builds/zos/`;
|
||
|
copy these files in, if not already present, and make sure the
|
||
|
shell scripts are executable)
|
||
|
|
||
|
* (Optional) set ZCXXFLAGS for additional compile flags (see below)
|
||
|
|
||
|
* Build `libzmq.a` static library and `libzmq.so` dynamic
|
||
|
library, with:
|
||
|
|
||
|
cd zeromq-VERSION
|
||
|
builds/zos/makelibzmq
|
||
|
|
||
|
or to skip the `libzmq.so` dynamic library (only building `libzmq.a`):
|
||
|
|
||
|
cd zeromq-VERSION
|
||
|
BUILD_DLL=false
|
||
|
export BUILD_DLL
|
||
|
builds/zos/makelibzmq
|
||
|
|
||
|
* (Optional, but recommended) build and run the core tests with:
|
||
|
|
||
|
cd zeromq-VERSION
|
||
|
builds/zos/maketests
|
||
|
builds/zos/runtests
|
||
|
|
||
|
* To remove built files, to start again (eg, rebuild with different
|
||
|
compile/link flags):
|
||
|
|
||
|
cd zeromq-VERSION
|
||
|
builds/zos/makeclean
|
||
|
|
||
|
There are details on specifying alternative compilation flags below.
|
||
|
|
||
|
|
||
|
## Quickstart: using ZeroMQ on z/OS UNIX System Services
|
||
|
|
||
|
### Static linking
|
||
|
|
||
|
Install `include/*.h` somewhere on your compiler include path.
|
||
|
|
||
|
Install `src/libzmq.a` somewhere on your library search path.
|
||
|
|
||
|
Compile and link application with:
|
||
|
|
||
|
c++ -Wc,xplink -Wl,xplink ... -+ -o myprog myprog.cpp -lzmq
|
||
|
|
||
|
Run with:
|
||
|
|
||
|
./myprog
|
||
|
|
||
|
|
||
|
### Dynamic linking
|
||
|
|
||
|
Install `include/*.h` somewhere on your compiler include path.
|
||
|
|
||
|
Install `src/libzmq.so` somewhere on your LIBPATH.
|
||
|
|
||
|
Install `src/libzmq.x` somewhere you can reference for import linking.
|
||
|
|
||
|
Compile and link application:
|
||
|
|
||
|
c++ -Wc,xplink -Wc,dll ... -+ -c -o myprog.o myprog.cpp
|
||
|
c++ -Wl,xplink -o myprog myprog.o /PATH/TO/libzmq.x
|
||
|
|
||
|
Run with:
|
||
|
|
||
|
LIBPATH=/DIR/OF/LIBZMQ.SO:/lib:/usr/lib:... # if not in default path
|
||
|
export LIBPATH
|
||
|
./myprog
|
||
|
|
||
|
|
||
|
## ZeroMQ on z/OS UNIX System Services: Application considerations
|
||
|
|
||
|
z/0S UNIX System Services does not provide a way to block the
|
||
|
[`SIGPIPE` signal being generated when a thread writes to a closed socket](http://pic.dhe.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zos.r12.cbcpx01%2Fcbcpg1b0287.htm)
|
||
|
(compare with other platforms that support the `SO_NOSIGPIPE` socket
|
||
|
option, and/or the `MSG_NOSIGNAL` flag on `send()`; z/OS UNIX System
|
||
|
Services supports neither).
|
||
|
|
||
|
As a result, applications using ZeroMQ on z/OS UNIX System Services
|
||
|
have to expect to encounter `SIGPIPE` at various times during the use
|
||
|
of the library, if sockets are unexpectedly disconnected. Normally
|
||
|
`SIGPIPE` will terminate the application.
|
||
|
|
||
|
A simple solution, if `SIGPIPE` is not required for normal operation
|
||
|
of the application (eg, it is not part of a unix pipeline, the
|
||
|
traditional use of `SIGPIPE`), is to set `SIGPIPE` to be ignored
|
||
|
with code like:
|
||
|
|
||
|
#include <signal.h>
|
||
|
...
|
||
|
signal(SIGPIPE, SIG_IGN);
|
||
|
|
||
|
near the start of the application (eg, before initialising the ZeroMQ
|
||
|
library).
|
||
|
|
||
|
If `SIGPIPE` is required for normal operation it is recommended that
|
||
|
the application install a signal handler that flags the signal was
|
||
|
received, and allows the application main loop to determine if it
|
||
|
was received for one of its own file descriptors -- and ignores it if it
|
||
|
none of the applications own file descriptors seems to have changed.
|
||
|
|
||
|
Linking to the `libzmq.a` static library will pull in substantially
|
||
|
all of the library code, which will add about 4MB to the application
|
||
|
size (per executable statically linked with ZeroMQ). If this is a
|
||
|
significant consideration, use of the DLL version is recommended.
|
||
|
|
||
|
See also ZeroMQ test status on z/OS UNIX System Services below
|
||
|
for other caveats.
|
||
|
|
||
|
|
||
|
## Setting other compilation flags
|
||
|
|
||
|
### Optimisation
|
||
|
|
||
|
To build with optimisation:
|
||
|
|
||
|
* set `ZCXXFLAGS` to "`-O2`" before starting build process above
|
||
|
|
||
|
|
||
|
### Full debugging symbols
|
||
|
|
||
|
To build with debugging symbols:
|
||
|
|
||
|
* set `ZCXXFLAGS` to "`-g`" before starting build process above
|
||
|
|
||
|
### 64-bit mode (LP64/amode=64)
|
||
|
|
||
|
To build in 64-bit mode:
|
||
|
|
||
|
The default build is
|
||
|
[ILP32](http://publib.boulder.ibm.com/infocenter/zvm/v6r1/index.jsp?topic=/com.ibm.zos.r9.cbcux01/lp64cop.htm),
|
||
|
the default for the IBM XL C/C++ compiler. To build in LP64 mode
|
||
|
(64-bit):
|
||
|
|
||
|
* set `ZCXXFLAGS` to "`-Wc,lp64 -Wl,lp64`" before starting build
|
||
|
|
||
|
(64-bit mode can be combined with optimisation or debug symbols.)
|
||
|
|
||
|
### Combining compilation flags
|
||
|
|
||
|
Other build flags can be used in `ZXCCFLAGS` if desired. Beware that
|
||
|
they are passed through (Bourne) shell expansion, and passed to both
|
||
|
the compile and link stages; some experimentation of argument quoting
|
||
|
may be required (and arguments requiring parenthesis are particularly
|
||
|
complicated).
|
||
|
|
||
|
|
||
|
## ZeroMQ test status on z/OS UNIX System Services
|
||
|
|
||
|
As of 2014-07-22, 41 of the 43 tests in the core ZeroMQ test suite
|
||
|
pass. There are two tests that are expected to fail:
|
||
|
|
||
|
0. `test_abstract_ipc`: tests Linux-specific IPC functions, and is
|
||
|
expected to fail on non-Linux platforms.
|
||
|
|
||
|
0. `test_fork`: tests ability to use ZeroMQ both before *and* after
|
||
|
fork (and before exec()); this relies on the ability to use
|
||
|
pthreads both before *and* after fork. On z/OS (and some other
|
||
|
UNIX compliant platforms) functions like `pthreads_create` (used
|
||
|
by ZeroMQ) cannot be used after fork and before exec; on z/OS the
|
||
|
call after fork fails with `ELEMULTITHREADFORK` (errno=257) if
|
||
|
ZeroMQ was also used before fork. (On z/OS it appears possible
|
||
|
to use z/OS *after* fork, *providing* it has not been used before
|
||
|
fork -- the problem is the two separate initialisations of the
|
||
|
threading library, before and after fork, attempting to mix
|
||
|
together.) In practice this is unlikely to affect many real-world
|
||
|
programs -- most programs use threads or fork without exec, but
|
||
|
not both.
|
||
|
|
||
|
0. `test_diffserv`: tests ability to set IP_TOS ([IP Type of
|
||
|
Service](http://en.wikipedia.org/wiki/Type_of_service), or
|
||
|
[DiffServ](http://en.wikipedia.org/wiki/Differentiated_Services_Code_Point))
|
||
|
values on sockets. While z/OS UNIX System Services has the
|
||
|
preprocessor defines required, it appears not to support the
|
||
|
required functionality (call fails with "EDC8109I Protocol not
|
||
|
available.")
|
||
|
|
||
|
These three "expected to fail" tests are listed as XFAIL_TESTS, and
|
||
|
`runtests` will still consider the test run successful when they fail
|
||
|
as expected. (`builds/zos/runtests` will automatically skip these
|
||
|
"expected to fail" tests if running "all" tests.)
|
||
|
|
||
|
In addition `test_security_curve` does not do any meaningful testing,
|
||
|
as a result of the CURVE support not being compiled in; it requires
|
||
|
[`libsodium`](http://doc.libsodium.org/), which has not been
|
||
|
ported to z/OS UNIX System Services yet.
|
||
|
|
||
|
Multicast (via `libpgm`) is also not ported or compiled in.
|
||
|
|
||
|
[TIPC](http://hintjens.com/blog:70), a cluster IPC protocol,
|
||
|
is only supported on Linux, so it is not compiled into the z/OS
|
||
|
UNIX System Services port -- and the tests are automatically skipped
|
||
|
if running "all" tests. (However they are not listed in XFAIL_TESTS
|
||
|
because without the TIPC support there is no point in even running
|
||
|
them, and it would be non-trivial to track them by hand.)
|
||
|
|
||
|
|
||
|
## ZeroMQ on z/OS UNIX System Services: Library portability notes
|
||
|
|
||
|
### *.cpp
|
||
|
|
||
|
The source code in ZeroMQ is a combination of a C++ core library
|
||
|
(in `*.cpp` and `*.hpp` files), and a C wrapper (also in `*.cpp`
|
||
|
files). It is all compiled with the C++ compiler. The IBM XL C/C++
|
||
|
complier (at least the version used for initial porting) insists
|
||
|
that C++ source be in `*.C` files (note capital C). To work around
|
||
|
this issue the compile flag `-+` is used (specified in the `zc++`
|
||
|
compiler wrapper), which tells the compiler the file should be
|
||
|
considered C++ despite the file extension.
|
||
|
|
||
|
### XPLINK
|
||
|
|
||
|
The library (and tests) are built in
|
||
|
[XPLINK](http://www.redbooks.ibm.com/abstracts/sg245991.html) mode
|
||
|
with the flags `-Wc,xplink -Wl,xplink` (specified in the `zc++`
|
||
|
compiler wrapper). This is [recommended by IBM for C++
|
||
|
code](http://publib.boulder.ibm.com/infocenter/zvm/v5r4/index.jsp?topic=/com.ibm.zos.r9.ceea200/xplrunt.htm)
|
||
|
due to the small functions. (Amongst other things, using XPLINK
|
||
|
enables function calls with some arguments passed in registers.)
|
||
|
|
||
|
### long long
|
||
|
|
||
|
ZeroMQ makes use of `uint64_t` (which is `unsigned long long` in ILP32
|
||
|
mode). To enable this the compile flag `-Wc,lang(longlong)` is passed
|
||
|
to enable `long long`. This is passed from the `zc++` compiler wrapper
|
||
|
in order to be able to specifically quote the argument to protect the
|
||
|
parentheses from shell expansion.
|
||
|
|
||
|
### BSD-style sockets, with IPv6 support
|
||
|
|
||
|
ZeroMQ uses BSD-style socket handling, with extensions to support IPv6.
|
||
|
BSD-style sockets were merged into SysV-derived UNIX at least a decade
|
||
|
ago, and are required as part of the X/Open Portability Guide at least
|
||
|
as of XPG 4.2. To access this functionality two feature macros are
|
||
|
defined:
|
||
|
|
||
|
_XOPEN_SOURCE_EXTENDED=1
|
||
|
|
||
|
_OPEN_SYS_SOCK_IPV6
|
||
|
|
||
|
The first enables the XPG 4.2 features (including functionality like
|
||
|
`getsockname()`), and the latter exposes IPv6 specific functionality
|
||
|
like `sa_family_t`. These flags are defined in the `cxxall` script.
|
||
|
|
||
|
(The traditional BSD-sockets API, exposed with `_OE_SOCKETS` cannot
|
||
|
be used because it does not support functions like `getsockname()`,
|
||
|
nor does it support IPv6 -- and the API definitions prevent compiling
|
||
|
in LP64 mode due to assumptions about long being 32 bits. Using
|
||
|
`_XOPEN_SOURCE_EXTENDED=1` avoids all these problems.)
|
||
|
|
||
|
### pthreads
|
||
|
|
||
|
ZeroMQ uses the pthreads library to create additional threads to handle
|
||
|
background communication without blocking the main application. This
|
||
|
functionaity is enabled on z/OS UNIX System Services by defining:
|
||
|
|
||
|
_OPEN_THREADS=3
|
||
|
|
||
|
which is done in the `cxxall` script. (The "3" value exposes later
|
||
|
pthreads functionality like `pthread_atfork`, although ZeroMQ does not
|
||
|
currently use all these features.)
|
||
|
|
||
|
If compiling on a *recent* version of z/OS UNIX System Services it
|
||
|
may be worth compiling with:
|
||
|
|
||
|
_UNIX03_THREADS=1
|
||
|
|
||
|
which enables a later version of the threading support, potentially
|
||
|
including `pthread_getschedparam` and pthread_setschedparam`; at
|
||
|
present in the z/OS UNIX System Services port these functions are
|
||
|
hidden and never called. (See [IBM z/OS pthread.h
|
||
|
documentation](http://pic.dhe.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.bpxbd00/pthrdh.htm)
|
||
|
for details on the differences.)
|
||
|
|
||
|
|
||
|
## `platform.hpp` on z/OS UNIX System Services
|
||
|
|
||
|
The build (described above) on z/OS UNIX System Services uses a static
|
||
|
pre-built `platform.hpp` file. (By default `src/platform.hpp` is
|
||
|
dynamically generated as a result of running the `./configure` script.)
|
||
|
The master version of this is in `builds/zos/platform.hpp`.
|
||
|
|
||
|
Beware that this file contains the version number for libzmq (usually
|
||
|
included during the configure phase). If taking the `platform.hpp` from
|
||
|
an older version to use on a newer libzmq be sure to update the version
|
||
|
information near the top of the file.
|
||
|
|
||
|
The pre-built file is used because z/OS does not have the GNU auto tools
|
||
|
(`automake`, `autoconf`, `libtool`, etc) installed, and particularly the
|
||
|
libtool replacement does not work properly with the IBM XL C/C++
|
||
|
compiler.
|
||
|
|
||
|
The `./configure` script (only supplied in the tarballs); built with
|
||
|
`automake` and `autoconf` on another platform), with one small edit,
|
||
|
was used to generate the z/OS `platform.hpp` and then two small changes
|
||
|
(described below) were made by hand to the generated `platform.hpp`.
|
||
|
|
||
|
To be able to run the ./configure script to completion (in tcsh
|
||
|
syntax):
|
||
|
|
||
|
* Edit `./configure` and add:
|
||
|
|
||
|
openedition)
|
||
|
;;
|
||
|
|
||
|
immediately before the line:
|
||
|
|
||
|
as_fn_error $? "unsupported system: ${host_os}." "$LINENO" 5
|
||
|
|
||
|
(somewhere around 17637). This avoids the configure script giving
|
||
|
up early because `openedition` is not recognised.
|
||
|
|
||
|
* set `CXX` to point that the full path to the `builds/zos/zc++` wrapper, eg
|
||
|
|
||
|
setenv CXX "/u/0mq/zeromq-4.0.4/builds/zos/zc++"
|
||
|
|
||
|
* set `CPPFLAGS` to for the feature macros required, eg:
|
||
|
|
||
|
setenv CPPFLAGS "-D_XOPEN_SOURCE_EXTENDED=1 -D_OPEN_THREADS=3 -D_OPEN_SYS_SOCK_IPV6 -DZMQ_HAVE_ZOS"
|
||
|
|
||
|
* set `CXXFLAGS` to enable XPLINK:
|
||
|
|
||
|
setenv CXXFLAGS "-Wc,xplink -Wl,xplink -+"
|
||
|
|
||
|
* run configure script with `--disable-eventfd` (`sys/eventfd.h` does
|
||
|
not exist, but the test for its existance has a false positive on
|
||
|
z/OS UNIX System Services, apparently due to the way the `c++`
|
||
|
compiler wrapper passes errors back from the IBM XL C/C++ compiler),
|
||
|
and with `--with-poller=poll` because `poll` is the most advanced
|
||
|
of the file descriptor status tests available on z/OS. That is:
|
||
|
|
||
|
./configure --disable-eventfd --with-poller=poll
|
||
|
|
||
|
All going well several Makefiles, and `src/platform.hpp` should be
|
||
|
produced. Two additional changes are required to `src/platform.hpp`
|
||
|
which can be appended to the end:
|
||
|
|
||
|
/* ---- Special case for z/OS Unix Services: openedition ---- */
|
||
|
#include <pthread.h>
|
||
|
#ifndef NI_MAXHOST
|
||
|
#define NI_MAXHOST 1025
|
||
|
#endif
|
||
|
|
||
|
(many includes require pthreads-related methods or data structures to
|
||
|
be defined, but not all of them include `pthread.h`, and the value
|
||
|
`NI_MAXHOST` is not defined on z/OS UNIX System Services -- the 1025
|
||
|
value is the conventional value on other platforms).
|
||
|
|
||
|
Having done this the Makefiles can be used to compile individual files
|
||
|
if desired, eg:
|
||
|
|
||
|
cd src
|
||
|
make zmq.o
|
||
|
|
||
|
but note:
|
||
|
|
||
|
* IBM Make will warn of duplicate prerequisites on *every* run of
|
||
|
`make`, and both the generated `src/Makefile` and `tests/Makefile`
|
||
|
have several duplicates. (For `src/Makefile` edit
|
||
|
`libzmq_la_SOURCES` to remove the duplicates.)
|
||
|
|
||
|
* IBM Make does not understand the `@` prefix (eg, `@echo`) as a way
|
||
|
to avoid echoing the command, resulting in an error and the command
|
||
|
being echoed anyway.
|
||
|
|
||
|
* Many of the make targets result in GNU auto tools (`aclocal`, etc)
|
||
|
being invoked, which are likely to fail, and most of the
|
||
|
library-related targets will invoke `libtool` which will cause
|
||
|
compile failures (due to differences in expected arguments).
|
||
|
|
||
|
However running `./configure` to regenerate `src/platform.hpp` may
|
||
|
be useful for later versions of ZeroMQ which add more feature tests.
|
||
|
|
||
|
|
||
|
## Transferring from GitHub to z/OS UNIX System Services
|
||
|
|
||
|
The process of transferring files from GitHub to z/OS UNIX System
|
||
|
Services is somewhat convoluted because:
|
||
|
|
||
|
* There is not a port of git for z/OS UNIX System Services; and
|
||
|
|
||
|
* z/OS uses the EBCDIC (IBM-1047) character set rather than the
|
||
|
ASCII/ISO-8859-1 character set used by the ZeroMQ source code
|
||
|
on GitHub
|
||
|
|
||
|
A workable transfer process is:
|
||
|
|
||
|
* On an ASCII/ISO-8859-1/UTF-8 system with `git` (eg, a Linux system):
|
||
|
|
||
|
git clone https://github.com/zeromq/libzmq.git
|
||
|
git archive --prefix=libzmq-git/ -o /var/tmp/libzmq-git.tar master
|
||
|
|
||
|
* On a ASCII/ISO-8859-1/UTF-8 system with `tar`, and `pax`, and
|
||
|
optionally the GNU auto tools (eg, the same Linux system):
|
||
|
|
||
|
mkdir /var/tmp/zos
|
||
|
cd /var/tmp/zos
|
||
|
tar -xpf /var/tmp/libzmq-git.tar
|
||
|
cd libzmq-git
|
||
|
./autogen.sh # Optional: to be able to run ./configure
|
||
|
cd ..
|
||
|
pax -wf /var/tmp/libzmq-git.pax libzmq-git
|
||
|
compress libzmq-git.pax # If available, reduce transfer size
|
||
|
|
||
|
* Transfer the resulting file (`libzmq-git.pax` or `libzmq-git.pax.Z`)
|
||
|
to the z/OS UNIX System Services system. If using FTP be sure to
|
||
|
transfer the file in `bin` (binary/Image) mode to avoid corruption.
|
||
|
|
||
|
* On the z/OS UNIX System Services system, unpack the `pax` file and
|
||
|
convert all the files to EBCDIC with:
|
||
|
|
||
|
pax -o from=iso8859-1 -pp -rvf libzmq-git-2014-07-23.pax
|
||
|
|
||
|
or if the file was compressed:
|
||
|
|
||
|
pax -o from=iso8859-1 -pp -rvzf libzmq-git-2014-07-23.pax.Z
|
||
|
|
||
|
The result should be a `libzmq-git` directory with the source in
|
||
|
EBCDIC format, on the z/OS UNIX System Services system ready to start
|
||
|
building.
|
||
|
|
||
|
See also the [`pax` man
|
||
|
page](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa500%2Fr4paxsh.htm),
|
||
|
some [`pax` conversion
|
||
|
examples](http://pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa400%2Fbpxza4c0291.htm),
|
||
|
and [IBM's advice on ASCII to EBCDIC conversion
|
||
|
options](http://www-03.ibm.com/systems/z/os/zos/features/unix/bpxa1p03.html)
|