Mainframes as a lifestyle choice

I started working at IBM last year on mainframe compilers with the goal of making mainframes feel a little more modern. Hence, a lot of my time is spent in z/OS. The interface I use to z/OS is Unix System Services (USS, a.k.a. the command line), but if I were up for bucking the whole moderm thing, I could break out the ol’ 3270 terminal and work that way.

Part of the reason I took the job was the opportunity to get paid to work on compilers, but also because I have a fascination with older computer technology. Working with mainframes for the past year I’ve had to navigate some practices I don’t care for, but I’ve also come away with a deep appreciation for the technology at work in machines that can still run code from 50 years ago.

I’ve got a lot to learn about mainframes and what I do know may not be entirely accurate, but here are some things that stand out from the past year.

POSIX – sort of USS on z/OS is POSIX compliant. That version of POSIX, however, is not exactly recent. When you write scripts and systems programs in an environment whose standard is 20 years old, you soon realize how much you take for granted when you’re used to modern Linux and BSD systems. The default interactive shell makes you pine for a 3270 terminal. If Bash is available, there’s a good chance it’s from 1997. Any other shells? Forget it. It took a while but I’m content with my set up (Bash is now circa 2011) and I’m more comfortable with the primitiveness of much of the system. It’s made me think in different ways about how to implement some things, which I appreciate. It’s not yet at the point where it’s a serious impediment, but I’ll be honest in that it’s walking a fine line. As for system interfaces via C, well, that’s for a future post.

EBCDIC is a thing As soon as you attempt to get modern software working on z/OS you will run into ASCII/EBCDIC issues. Even copying files between systems (or working, say, on remote files with TRAMP in Emacs) requires some forethought. You find out very quickly just how little attention is paid to dealing with anything beyond ASCII in many software projects. This is understandable since few people have access to mainframes and of those that do, few attempt to run modern software on them. EBCDIC has been railed on at length in the past and I won’t rehash it here. Suffice it to say that EBCDIC lost, but it’s still on mainframes so you can’t ignore it. z/OS supports ASCII and UTF-8, but it’s not as simple as just saying, “I’ll use that instead of EBCDIC.”

Lack of virtualization Probably the most maddening thing about mainframe development is that you’re relegated to running everything on an actual remote system; you don’t do things in a local virtual machine. (It is possible, but no one really does it, usually citing performance.) This comes with all the disadvantages you would imagine: lack of control of resources, BOFHs, reliance on the network, differences between machines, and so forth. It just adds friction to the whole development process. Also, you don’t get privileged access on these systems, which can be real pain. Let’s just say I’m not a fan and leave it at that.

Backwards compatibility One of the most important concerns in my work, if not the most important, is backward compatibility. It’s also the most compelling part of my job. The depths of compatibility in z/OS is pretty incredible. For one thing, z/OS supports three addressing modes: 24, 31, and 64 bit. 24-bit is compatible with the memory subsystem on the System/360! That said, 31-bit compatibility is more important since 24-bit isn’t used much, as far as I know. Beyond that, it’s the language interoperability that is more fascinating. COBOL and PL/I are common on the mainframe, in addition to assembler. I haven’t heard of much C/C++. It is vitally important to (most? all?) IBM’s mainframe customers that anything new work with existing programs and libraries. (CICS and DB2 are the canonical examples.) These things don’t necessarily share data layouts and calling conventions, but you want native code to call native code, so how do you deal with that? That’s an engineering aspect of my job that’s keeping my interest right now. Trying to get good answers to the problem of making the new work with the old and looking at ways to transition the old to the new with low cost and no downtime is enough to make me not get too annoyed with the not-so-great aspects of mainframe development.