Wednesday, May 11, 2016

Containerizing simh: BSD in a box

Containers (almost) everywhere

One of the buzzwords of the year is "container". Since it seems that containers and containerized systems are here to stay, I decided to take a look at that technology. Specially after good'ol IBM has blessed it, as can be read here. So it looks the Big Blue is going to push that technology to their Holy zOS land. Or something like that.

So I went to Docker Land and started reading about the stuff. This post is not an explanation about what containers are and how does Docker implements them. There are much better text in the web to learn about that, and I am just the last guy to learn about them, so my explanations would be probably wrong. This blog is about old computers, real and simulated. So let's do some retrocomputing...

Containerizing the past
The idea of packaging an application as a service, with all the dependencies solved so it is basically a software appliance is, of course nice. And, of course, it is not new. We have been able to do that using virtual machines for some time. The main difference is containers pretend to be lightweight and just package what is needed. A VM must include the whole operating system to run, and today operating systems tend to be multi-gigabyte monsters. So the idea of putting, let's say, a PDP-11 simulator with its configuration files and probably also an Operating System (of the "just megabytes" kind) in a nice, ready to run, packaging is appealing. So I wanted to know if that was posible.

It, indeed, is.

And I can offer now the results of this little research, in the form of five docker "images", that you can download and convert into multiple "containers" as you want. The images are the following:

  • jguillaumes/simh-allsims: Contains just the simulator binaries, compiled and ready to run.
  • jguillaumes/simh-pdpbsd: Contains the pdp11 simulator plus a BSD 2.11 image.
  • jguillaumes/simh-vaxbsd: Contains the vax780 simulator plus a BSD 4.3 image.
  • jguillaumes/simh-vaxnbsd: Contains the vax simulator plus a NetBSD 6.0 image.
  • jguillaumes/simh-vax: Contains the vax, vax780 and pdp11 simulator plus a pair of example config files.
To use those images you need to download and install the docker runtime in your machine. There are versions for Windows, Mac OSX and Linux. Oh, you must have a 64 bit system or it wont work at all. 

Using the images

To use the images you can "pull" them from the public Docker repository where I have uploaded them, You can do this explicitly or you can simply try to run the images. Docker will automatically pull what you need. 

Self-contained images

Let's take the PDP-11 BSD 2.11 for a ride:

docker run --name pdpbsd -p 2323:2323 -it jguillaumes/simh-pdpbsd
Unable to find image 'jguillaumes/simh-pdpbsd:latest' locally
latest: Pulling from jguillaumes/simh-pdpbsd

d0ca440e8637: Already exists 
a1e3125132f8: Already exists 
5fc723fb3b91: Already exists 
22f14ee4456b: Already exists 
fe58eb150210: Already exists 
3cacf15d9073: Already exists 
d95addc21743: Pull complete 
a3770888ba4a: Pull complete 
7e7599d06256: Pull complete 
705a1c43d99d: Pull complete 
Digest: sha256:51d3b466eda25296668302bd1ce6f599d2897a077b04d4d289ee27e07f7f4ef5
Status: Downloaded newer image for jguillaumes/simh-pdpbsd:latest
Uncompressing OS image file...

PDP-11 simulator V4.0-0 Beta        git commit id: 7bd58c6d
Logging to file "console.log"
Disabling RK
Disabling HK
Disabling TM
Listening on port 2323
LPT: creating new file
Eth: opened OS device eth0

73Boot from ra(0,0,0) at 0172150

At this point just press RETURN to proceed to boot BSD

: ra(0,0,0)unix
Boot: bootdev=02400 bootcsr=0172150

2.11 BSD UNIX #7: Thu Jun 8 21:53:04 PDT 1995

ra0: Ver 3 mod 3
ra0: RA81  size=891072
attaching qe0 csr 174440
qe0: DEC DEQNA addr 08:00:2b:aa:bb:cc
attaching sl
attaching lo0

phys mem  = 4186112
avail mem = 3730240
user mem  = 307200

May  9 05:49:32 init: configure system

dhv 0 csr 160440 vector 300 attached
lp ? csr 177514 vector 200 skipped:  No autoconfig routines.
ra 0 csr 172150 vector 154 vectorset attached
rl 0 csr 174400 vector 160 attached
tms 0 csr 174500 vector 260 vectorset attached
erase, kill ^U, intr ^C

Now you are in single user mode. It is a good moment to edit some /etc files, or simply press CTRL-D to exit single user mode and proceed to full multiuser...

 Fast boot ... skipping disk checks                                                        
checking quotas: done. 
Assuming NETWORKING system ...
add host dokbsd: gateway localhost
add net default: gateway
starting system logger
May  9 05:49:39 dokbsd vmunix: ra0: Ver 3 mod 3
May  9 05:49:39 dokbsd vmunix: ra0: RA81  size=891072
checking for core dump... 
preserving editor files
clearing /tmp
standard daemons: update cron accounting.
starting network daemons: inetd rwhod printer.
starting local daemons: sendmail.
May  9 05:49:39 dokbsd ntpd[98]: init_ntp: bad drift compensation value
Mon May  9 05:49:39 PDT 2016
May  9 05:49:39 dokbsd init: kernel security level changed from 0 to 1

2.11 BSD UNIX (dokbsd) (console)

login: root
erase, kill ^U, intr ^C

Login as root with no password... and voilĂ ! You are logged into a BSD 2.11 system running on a PDP-11 simulator. The kernel has network support, which is functional. Just edit /etc/resolv.conf to use a working DNS server and you will be in the internets:

# echo "nameserver" >> /etc/resolv.conf 
# ping
PING ( 56 data bytes
64 bytes from icmp_seq=0 ttl=37 time=33.334 ms
64 bytes from icmp_seq=1 ttl=37 time=16.667 ms
64 bytes from icmp_seq=2 ttl=37 time=16.667 ms
64 bytes from icmp_seq=3 ttl=37 time=16.667 ms
--- ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 16.667/20.833/33.334 ms

(Of course I'm supposing your Docker installation is properly configured and your machine has internet access...).

The pdp11 simulator is configured with a DZ terminal multiplexer attached to the port 2323 in the container. This port is mapped to the same 2323 port in the host so you can TELNET into it. If you start several containers you will have to use a different local port for each one (specified as the first number in the -p parameter: if you want to map the 2323 port in the container to the 9999 port in the host, specify -p 9999:2323). If you are using Linux, you can TELNET to localhost; if you are using OSX or Windows you must use the IP address of the Docker host, which can be obtained with the docker-machine ip command. 

You should shut down the system properly (those old unices have filesystems that break easily if you simply stop the simulator) and you will be back at your host prompt:

# shutdown -h now
Shutdown at 06:11 (in 0 minutes) [pid 118]

        *** FINAL System shutdown message from root@dokbsd ***

System going down IMMEDIATELY

System shutdown time has arrived
May  9 06:11:01 dokbsd shutdown: halt by root: 
May  9 06:11:04 dokbsd syslogd: going down on signal 15
CAUTION: some process(es) wouldn't die
syncing disks... done

HALT instruction, PC: 000014 (MOV #1,11616)
Eth: closed eth0
Log file closed
macjordie:~ jguillaumes$ 

Now you have a container in your Docker host. To run it again, do not use the docker run command, which would create a new container. Use the docker start command, followed by a docker attach.

macjordie:~ jguillaumes$ docker start pdpbsd
macjordie:~ jguillaumes$ docker attach pdpbsd

: ra(0,0,0)unix
Boot: bootdev=02400 bootcsr=0172150

2.11 BSD UNIX #7: Thu Jun 8 21:53:04 PDT 1995

If you are not very fast, you will not see the ":" boot prompt (because at the attach time it will already be in the "console"). Just press enter and the boot will continue.

The simh-vaxbsd and simh-vaxnbsd images work just like this one. The BSD 4.3 boots straight into BSD, and the root is also passwordless. The NetBSD one asks for the boot device (just the first time it boots), and its root account has the password "manager". The other two images are a little bit different.

Non self-contained images

The other two images do not contain an OS image for the simulators, so you have to provide one. This can be done in two ways: 

  • Copy the image from your host to the container using docker cp
  • Mount the directory that contains your image into the /machines volume in the container, using the -v parameter of the docker run command as this: 
-v your_image_directory:/machines 

In any case, when you start the machine you will find youself in a shell in the /machines subdirectory, where you can start the simulator you want, providing your own configuration file (the simh-vax image has some samples). The images contain the nano editor so you don't need to fight vi.

There is an annoying bug, probably caused by the linux distribution I've based the images on (Alpine Linux), which does not use the regular C runtime library and somehow messes the console input in simh. It does not display any prompt, but you can type in commands and it works.

Building your own images

The dockerfiles and additional material needed to build those images are available in github. Feel free to clone/fork/reuse whatever you find there. The compressed images for BSD 2.11 and BSD 4.3 are in the repository. The one for NetBSD is not. Check the README.txt file in the vaxnbsd subdirectory for a link to download it (it weights about 260MB). The file contains details and instructions to build the docker images, and suggestions to add your own OS images to build containerized systems. Please remember it is not allowed to distribute VMS under the hobyist license, so keep any VMS image to yourself.

Further information and updates

The images mentioned in this post are available at Docker Hub. Just search for "jguillaumes" and you will find them. The descriptions contain information about its usage. Of course, feel free to contact me with comments, suggestions or bug reports!

Enjoy your containerized PDP-11 and VAXen!