Friday, September 19, 2014

Minix 3.3.0 x86

Introduction

It's all over the web... Minix 3.3.0 is out! And it's got a long list of improvements over 3.2.1, not the least of which are support for shared object libraries and ARM platforms.

In case you don't know much about Minix, Wikipedia can do a much better job describing it and microkernels and the famous debate over microkernels vs. monolithic kernels than I can. So I'll leave that to them.

I love new software, almost as much as I love old software, so for that past few days, I've been giving Minix 3.3.0 a spin.

Installation

The 3.3.0 iso is available at http://download.minix3.org/iso/minix_R3.3.0-588a35b.iso.bz2. I downloaded it from there, aimed my (admittedly aging) VMware 8.0.6 at it, and let the magic happen.

The VM configuration was straightforward. I gave it a 2G disk image, 256M of ram, and removed the devices I didn't intend to use, like the floppy, sound card and printer.

The Minix installation was as simple as powering on the VM and following the directions. Log in as root (with no password), run "setup", choose "automatic mode"... the directions are explicit and the process is intuitive.

Minix 3.3.0 x86 - 1. install

The only marginally tricky step is if you manually configure ethernet, make sure to give the fully qualified domain name (eg. minix330x86.firstworks.com rather than just minix303x86) or later if you install apache, it will complain that it can't determine the fully qualified domain name.

Upon reboot, I seemed to have a working system.

Minix 3.3.0 x86 - 2. first boot

Post-Install Tweaks

...but it turned out that I did have to configure a few things manually.

The installer didn't ask me for my domain name and didn't extract it from the hostname, so I added a search command to /etc/resolv.conf.

# Use Minix nonamed for now
nameserver 127.0.0.1
search firstworks.com

The system didn't appear to know its hostname either, which turned out to be the result of duplicate entries in /etc/hosts. Commenting out the line that correlated the system's IP with %nameserver fixed that.

#192.168.123.157        %nameserver     #minix330x86.firstworks.com
192.168.123.37  %nameserver     #DNS 1

192.168.123.157 minix330x86.firstworks.com

I also gave root a password, updated pkgin, installed openssh...

# passwd
Changing local password for root.
New password:
Retype new password:
# pkgin update
...
# pkgin install openssh
...

...and rebooted again to enable ssh.

Adding a User

Adding a user was straightforward:

useradd -m dmuse
passwd dmuse

I could log in as me now and access the VM via remotely but I can't live without sudo and pkgin didn't have any idea what I was talking about when I tried to install it.

# pkgin install sudo
sudo is not available on the repository
calculating dependencies... done.
nothing to do.

Hmmm... Yeah, I remember that from 3.2.1 too.

I've built sudo from source on a bunch of systems though, perhaps it could be built on Minix too. I never tried on 3.2.1, I just used root for everything. Sad, I know.

Turns out, yes, you can build sudo from source, but it takes a little effort.

First, you need a compiler. The documentation alleges that gcc and clang are both available but gcc isn't on the CD and pkgin didn't appear to know anything about a native gcc toolchain. Surprisingly, it knew about a mingw32 cross-compiler, but nothing native. It did know about clang though, so I gave it a try.

# pkgin install clang
...
# pkgin install binutils
...

Sudo version 1.6.9p23 has worked well for me on various old RedHat and Solaris platforms, so I tried building it. It needed a little coaxing, but only a little.

First off, configure had never heard of clang so I created some symlinks.

# cd /usr/pkg/bin
# ln -s clang cc
# ln -s clang++ c++

I also had to edit interfaces.c and add a line like:

#define IFF_LOOPBACK 0x8

after the includes. Minix doesn't define an IFF_LOOPBACK flag and after looking at the code, it appeared harmless to define it. After that, sudo built and installed smoothly.

$ ./configure --prefix=/usr/local/sudo-1.6.9p23
configure: Configuring Sudo version 1.6.9
...
checking for cc... cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
...
$ make
cc -c -I. -I. -O2 -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_SUDOERS_TMP=\"/etc/sudoers.tmp\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  check.c
cc -c -I. -I. -O2 -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_SUDOERS_TMP=\"/etc/sudoers.tmp\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  env.c
cc -c -I. -I. -O2 -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_SUDOERS_TMP=\"/etc/sudoers.tmp\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  getspwuid.c
cc -c -I. -I. -O2 -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_SUDOERS_TMP=\"/etc/sudoers.tmp\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  gettime.c
...
cc -o sudo check.o env.o getspwuid.o gettime.o goodpath.o fileops.o find_path.o  interfaces.o logging.o parse.o set_perms.o sudo.o sudo_edit.o  tgetpass.o zero_bytes.o  sudo_auth.o passwd.o sudo.tab.o lex.yy.o alloc.o defaults.o   -lcrypt  
cc -c -I. -I. -O2 -D_PATH_SUDOERS=\"/etc/sudoers\" -D_PATH_SUDOERS_TMP=\"/etc/sudoers.tmp\" -DSUDOERS_UID=0 -DSUDOERS_GID=0 -DSUDOERS_MODE=0440  visudo.c
cc -o visudo visudo.o fileops.o gettime.o goodpath.o find_path.o zero_bytes.o  sudo.tab.o lex.yy.o alloc.o defaults.o
$ su
Password:
# make install
...

And I added /usr/local/sudo-1.6.9p23/bin to the PATH environment variable in /etc/profile and added a line for myself at the end of /etc/sudoers...

dmuse ALL=(ALL) NOPASSWD: ALL

...but it didn't work. Turns out on Minix, programs need read and execute permissions to run. Execute alone isn't good enough.

# cd /usr/local/sudo-1.6.9p23/bin
# chmod 555 sudo
# chmod u+s sudo

Ha! That made it work.

$ sudo ls /
bin          boot_monitor home         proc         service      usr
boot         dev          lib          root         sys          var
boot.cfg     etc          mnt          sbin         tmp

Woohoo!

Remote Access and File Transfer

Minix 3.3.0 was looking pretty good from a remote access and file transfer standpoint, at least from the command line.

I could ssh in and out, transfer files with scp, sftp and regular ftp. Wget and lynx were available from pkgin. Tar, gzip, bzip2 and unzip were all installed by default. Zip wasn't but it was available from pkgin.

Ping was installed by default, but oddly telnet wasn't and it also wasn't available from pkgin. It's difficult to track down some connectivity issues without telnet, but I hoped I wouldn't need it.

The Web

Apache was available via pkgin, version 2.0.65nb2 to be precise. I installed it but it wouldn't start. After digging through the logs I eventually discovered that it needs the directory /usr/pkg/var/run to exist. After creating that, it ran just fine.

I did have trouble getting it to run cgi's. I configured it the same way I've configured it dozens of times before, but it just wouldn't work. The mod_cgi module didn't appear to be installed and didn't appear to be linked in statically either.

Between this and gcc, I got to looking around in the pkgin repository a little. Several apache modules were in there, but many more were missing. Other odd combinations of things were in there too. For example, various firefox language packs were available, but firefox itself wasn't. Hmm... This release just came out. I'll bet that some packages still need a little patching and so they and everything that depends on them isn't getting built yet. Maybe in a few weeks or months more will be available.

X Windows

X was a total loss. It wasn't installed as part of the base distribution, no x11 package was available and attempts to aim pkgin at the 3.2.1 repository failed pretty badly too.

I guess I could have tried building from source. Maybe later. Or maybe if I wait a few weeks or months a package will just appear one day.

Development

I had working C and C++ compilers, and Minix 3.3.0 alleged to support shared object libraries.

I was itching to try and get my software running.

Almost immediately I ran into trouble though. CVS wasn't available through pkgin. Fortunately version 1.11.23 built cleanly from source. Then there were issues with libtool, and clang throws a lot more warnings that gcc, and there were goofy problems with threads, and Minix doesn't like it if you use ioctl to set blocking/nonblocking IO on sockets, you have to use fcntl.

That sounds like a lot but as usual, though it took a while to track down solutions, in the end it just took some minor tweaks to the Rudiments library and a few even more minor tweaks to my build script to get the SQL Relay client software running.

Minix 3.3.0 x86 - 3. sqlrsh

Look at that, accessing an Oracle database from Minix. Who'd have thought it was possible?

And look at that:

$ ldd /usr/local/firstworks/bin/sqlrsh
/usr/local/firstworks/bin/sqlrsh:
        -lsqlrutil-0.57.1 => /usr/local/firstworks/lib/libsqlrutil-0.57.so.1
        -lrudiments-0.48.1 => /usr/local/firstworks/lib/librudiments-0.48.so.1
        -lmthread.0 => /usr/lib/libmthread.so.0
        -lpthread.20 => /usr/pkg/lib/libpthread.so.20
        -lc.12 => /usr/lib/libc.so.12
        -lssl.1.0.0 => /usr/pkg/lib/libssl.so.1.0.0
        -lcrypto.1.0.0 => /usr/pkg/lib/libcrypto.so.1.0.0
        -lpcre.1 => /usr/pkg/lib/libpcre.so.1
        -lcrypt.1 => /usr/lib/libcrypt.so.1
        -lc++.1 => /usr/lib/libc++.so.1
        -lm.0 => /usr/lib/libm.so.0
        -lsqlrclient-0.57.1 => /usr/local/firstworks/lib/libsqlrclient-0.57.so.1
        -lreadline.6 => /usr/pkg/lib/libreadline.so.6
        -lterminfo.1 => /usr/lib/libterminfo.so.1
        -lhistory.6 => /usr/pkg/lib/libhistory.so.6

Dynamic linking! On Minix!

PostgreSQL was available from pkgin too, so I installed it and SQL Relay compiled against it just fine, but I couldn't get the SQL Relay server to run because the kernel wasn't compiled with support for semaphores. Shared memory, yes. Semaphores, no.

$ ipcs

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status

kernel not configured for semaphores

Grrr.

This caused problems on reboot too, when the PostgreSQL server tried to run.

I figured I'd try recompiling the kernel with support for semaphores, but I couldn't find the kernel source anywhere. It wasn't installed, it's not hidden away on the CD, and it's not available via pkgin. How does one get a hold of the Minix 3.3.0 kernel source? If somebody knows, please clue me in.

Conclusions

Minix 3.3.0 seems to run a bit more smoothly than 3.2.1. Now that I think about it, I can't remember exactly what problems I had with 3.2.1, but it seems like I had problems running certain programs after ssh'ing in and then su'ing and also running out of memory from time to time. I didn't run into any trouble like that at all with 3.3.0. For certain, 3.3.0 is at least as stable as 3.2.1.

I was able to tune it down to 96M of RAM too and everything continued to run fine, even software builds. I might even be able to tune it down more.

Lack of X, gcc and other packages was a drag, but I expect that they'll be available eventually. Fuel for another article, I guess.

Lack of built-in support for semaphores and lack of kernel source was a serious drag. The source has got to be available somewhere though. Maybe I'll find it if I dig a little bit.

Of course, every OS has it's share of endearing features. Here are a few that I ran into while playing around.

  • tab-completion doesn't work after su'ing
  • the route command is implemented as 3 commands: add_route, del_route, pr_routes
  • setsockopt errors for various unsupported options are displayed on the screen from time to time
  • clang requires -Wno-overloaded-virtual to work with rudiments socketclient
  • clang requires -Wno-mismatched-tags to compile sqlrelay c api
  • libtool doesn't know that Minix can create dynamic libs yet, must configure with --with-system-libtool
  • must include -lmthread before -L/usr/pkg/lib -lpthread (or use -pthread instead of both)
  • FIONBIO can't be used on sockets with ioctl, must use fcntl instead

Arguably the clang issues are bugs in my software. I guess I shouldn't count those. The libtool thing is just because this version of Minix is so new and the libtool patches haven't gone mainstream yet.

The mthread thing is a little weird.

It's a brand new release though, with lots of changes under the hood. A few endearing features are to be expected.

I hope X and gcc are available soon, I can't wait to play around with them.

In the mean time though, it's stable enough and doesn't slam the host CPU. I think I'll keep a Minix 3.3.0 VM running and add it to my build farm.