The latest version of this file can be found at http://jstyx.sourceforge.net/docs/InfernoTutorial.html

Inferno tutorial

Requirements

It is perfectly possible to work through this tutorial with a single computer (Windows NT/2000/XP, Linux, Solaris, MacOSX or FreeBSD). However, it is more satisfying to use two networked computers to show yourself just how easy it is to connect them and exchange data, especially if the computers are running different operating systems.

As we shall see, many Inferno commands have direct equivalents in Unix, so familiarity with Unix or Linux is useful but by no means essential. A three-button mouse is highly desirable for working within Inferno’s graphical environment.

Why Inferno?

With so many other distributed computing technologies out there, why are we introducing another one, which is probably less well-known than others? There are several reasons:

Installing Inferno

Installing Inferno is very easy:

  1. Download the latest version from Vita Nuova’s website at http://www.vitanuova.com/inferno/downloads.html. (At the time of writing, the latest version is the Fourth Edition, 20040905.) Unless you have a narrowband Internet connection, the easiest thing to do is to download the CD image.
  2. You may wish to install Inferno as a dedicated user (on Unix and Linux I normally create a user and group called inferno to own the installation), but this is optional.
  3. Instructions for installing are on the download page but, in a nutshell, you need to: (i) Unzip the CD image; (ii) burn to a CD; (iii) insert the CD and run the relevant installation program in the <cdroot>/install directory.
  4. The installation should proceed with no warnings or errors. I have heard reports of some CD burners not correctly burning the CD image, so if you get error messages, try burning the CD on a different machine (I use x-cdroast on Red Hat Linux 9 with no problems).
  5. Create a new user (e.g. Jon) by copying the <inferno root>/usr/inferno directory to <inferno root>/usr/Jon and giving Jon ownership of this directory and all its contents. Do this for as many users as you like.
  6. Set the environment variable EMU to the string "-r<inferno root>". (e.g. setenv EMU "-r/usr/inferno" in the C shell).
  7. Add the directory containing the correct executables to your PATH. For example, on Linux, the executables are in <inferno root>/Linux/386/bin and in Windows (NT, 2000 and XP) the executables are in <inferno root>/Nt/386/bin.

Running Inferno

Inferno is normally run as a non-privileged user (i.e. not root). When Inferno interacts with the host OS (e.g. to run a native program), any programs will then run with the privileges of the user that started Inferno. Therefore Inferno should not be able to damage the installation of the host OS.

Test that you can run Inferno by typing emu at a command prompt. If you get a message like "panic: root path does not exist" or "'/dis' file does not exist", you have not set your EMU environment variable correctly (see item 6 in the section "Installing Inferno"). You can also specify the root of the distribution by running "emu -r<inferno root>". This is especially useful if you have multiple Inferno installations on the same machine.

If all is well, you will get a semicolon as a command-line prompt. Type pwd and press enter. This will give you the current directory in Inferno (not the host OS), which will probably be Inferno's root directory (/, a single slash). Type lc and press enter and you will see all the files and directories in the current directory.

To quit Inferno on most systems, press Ctrl-C. On Solaris (on my system at least) it seems that the backspace key is used to quit. This can be rather annoying as you can easily end up quitting Inferno when you meant to erase a character. If you work in Inferno in GUI mode (see "GUI applications" below), this is not a problem.

Basic Inferno

You should now be at an Inferno command prompt (the semicolon). Your username in Inferno is the same as the username in the host OS that you used to run Inferno. To check what the name of the current user is (the equivalent of whoami in Unix), enter "cat /dev/user" at the command prompt (you are reading the file /dev/user).

Change into your home directory by entering "cd" with no arguments (note that Inferno, unlike Unix, does not understand the tilde character ˜ to represent your home directory). If you get a message like "cd: /usr/Jon: '/usr/Jon' does not exist" then you haven't created this user; see step 5 in the section "Installing Inferno".

Basic commands

Many commands in Inferno have direct equivalents in Unix:

An important command is os, which runs a program in the host operating system. For example, on Unix, type "os uname". This runs the uname program, captures its output and prints the results on the Inferno console (the result is the name of the host OS). On Windows, try "os ipconfig", which will output the details of your network connection(s). The output from the executable can be piped into Inferno programs and vice-versa. For example, on Windows, the command "os ipconfig | wc" will count the lines, words and characters in the output from the Windows program ipconfig, using the Inferno program wc.

GUI Applications

You are not restricted to command-line interaction with Inferno. Type "wm/wm" at the command prompt and a graphical desktop environment will appear:

Click on the Vita Nuova logo in the bottom left to bring up the menu shown in this picture (the equivalent of Windows’ Start menu). Note that the window cannot be resized! If you want a bigger window, set the environment variable EMU to "-r<inferno root> -g1024x768" and restart Inferno. You can set the window to any size with the –g switch.

In the menu, click on Charon to launch the built-in web browser. This is rather basic, but functional. Play around with it. Close Charon and launch the Manual program from the "Start menu". This displays the same information as the man command-line program but in a friendlier way.

The Inferno desktop is not designed as a replacement for Windows, KDE or any other heavyweight environment. Rather, it’s a lightweight container for simple GUI apps. These apps are written in Limbo, Inferno’s own programming language which uses a variant of Tk for graphical interfaces. TODO: say more about Limbo somewhere

Launch a shell window from the "Start menu". This gives you the same environment that you had from the command line. You can open as many shell windows as you like. Close each shell window by clicking the X in the top right-hand corner. This also kills any programs that have been started from this window. You can cut and paste within and between shell windows by using the middle mouse button (or scroll wheel). Note that "Snarf" essentially means "Copy". If your mouse only has two buttons... get a three-button one (or one with a clickable scroll wheel)! It makes life an awful lot easier.

The Send command is particularly useful. Select a piece of text anywhere in the shell window (e.g. a previous command), click and hold the middle mouse button over it, highlight the word “Send” and release the middle button. The text will be copied and pasted at the command prompt and Enter is pressed for you. In other words, the text you selected will be entered as a command.

Key Inferno concepts

Before we go any further, we should go through some key concepts of Inferno. It is these concepts that make Inferno such a good system for distributed computing.

Everything looks like a file

The most important concept in Inferno is that everything is virtualised as a file or set of files. We’ve already seen an example of this when we read the /dev/user file to get the name of the current user (see "Basic Inferno" above). By contrast, other operating systems represent the current user name as an environment variable. Another example is that the current time can be found by reading the /dev/time file (with the command "cat /dev/time"). It is the logical extension of Unix's metaphors of representing devices such as serial ports (/dev/ttyS0, etc) and the mouse (dev/mouse) as files. The important thing to realise is that this representation of everything as a file does not mean that everything is a file, in the sense of bytes on a hard disk.

Therefore, to interact with devices and programs in the Inferno world, we read from and write to files. This design replaces the more typical method of using APIs (Application Programming Interfaces) to interface with systems. The problem with the API approach is that it is essentially unbounded; there could be any number of API functions for a device. In contrast, the number of possible file operations are very small (TODO: reference Styx stuff here).

Namespaces

A hierarchy of files in an Inferno system is called a namespace. It is similar to a "filesystem" except that not all of the files in an Inferno namespace need be literal files on the hard disk. For example, the namespace for a digital camera might look like this:

       /   (The root of the namespace)
       |
 -----------
 |         |
ctl      images/

The ctl file is a special file (a synthetic file) that the user uses to send commands to the camera. For example, to take a picture, the user might enter the command "echo snap > ctl" (this writes the word "snap" to the ctl file). The resulting image can then be read from the images/ directory.

Mounting remote namespaces

To get access to namespaces exposed by remote system, we use the mount command. This is very similar in principle to Unix’s mount command; we specify what we want to mount and where in our own namespace we want to mount it. For example, if the namespace for the digital camera in the previous section was hosted on a computer called camera.somewhere.com on port 1234, we would enter the command "mount tcp!camera.somewhere.com!1234 /n/remote". Then the namespace of the camera would appear in the /n/remote directory of our system. We could then take a picture using the remote camera by issuing the command "echo snap > /n/remote/ctl". We shall try some more examples of the mount command later in this tutorial. (TODO: shall we?)

No difference between local and remote files

You may have noticed from the last paragraph that once we had mounted the remote camera’s namespace, we didn’t need to tell the echo command that /n/remote/ctl actually represented a remote file. This is because, in Inferno, applications do not know the difference between local and remote files. They use the same method for communicating with both. The applications simply send out messages and the operating system directs the messages to the correct destination. The protocol for these messages is called Styx.

The Styx protocol

(TODO: overhaul this section in light of JStyx?) All communications between Inferno systems, local and remote, are carried out using the Styx protocol (TODO: ref something). Because all messages are file operations (since everything in the Inferno/Styx world is a file), the Styx protocol has a very small command set (only 13 commands). You can probably guess many of the common commands: open, close, read, write, create and delete. Most users will not need to know anything at all about Styx. Styx is an open protocol, and implementations are available (or can be written fairly easily) for several languages, including Java (REF JStyx). Therefore, an application does not have to run within Inferno to communicate with an Inferno system – it just has to be able to "speak" Styx.

The Limbo programming language

Applications in Inferno are written in Limbo, a C-like language that has native support for concurrent programming. Limbo programs are guaranteed to be portable across all installations of Inferno, with no exceptions. You'll probably be glad to know that you won’t need to learn anything about Limbo to go through this tutorial. (TODO: ref some further reading?). Remember that you can run native programs in the host operating system using the os command (see "Basic commands" above); this is what we'll mainly be doing in this tutorial. (TODO: will we?)

A simple distributed system

Now we’re ready to use these ideas to create a very simple distributed system. If you have two computers at your disposal and they are networked, you can install Inferno on both of them and work through the rest of this tutorial. If you only have access to one computer, you can still follow the tutorial by starting the Inferno desktop (see "GUI applications" above) and opening two shell windows. I shall call the two computers (imaginatively) computer1 and computer2 and colour their windows blue and red respectively in the diagrams below. If you are working on a single machine, please take "computer1" and "computer2" to mean "shell window 1" and "shell window 2".

On computer1, open a shell window and change to your home directory with the cd command. Create a new file called hello.txt with the contents "hello from computer 1" by running the command: "echo hello from computer 1 > hello.txt". Verify that the file has been created by running lc, then view the contents of the file with "cat hello.txt".

Now we can expose (i.e. serve up) the whole of the home directory with a single command: "listen -A tcp!*!1234 { export /usr/Jon & }". The listen command runs a server process to listen for network connections (run "man listen" for more details). The "-A" switch means "do not require authentication". The argument "tcp!*!1234" is Inferno's version of a URL; it means "listen for TCP connections on port 1234". The asterisk means "this server" (analogous to "localhost"). When a connection is made, the command in the braces is run. This exports the directory /usr/Jon on the connection.

The screenshot below shows all these commands being executed in the shell window:

Making a connection

On computer2 (or a new shell window), we will now make a connection to this server. (TODO: run ndb/cs.) This is done in a single line: "mount -A tcp!computer1!1234 /n/remote". (If you're running this as two shell windows on the same machine, replace "computer1" with "localhost" or "127.0.0.1".) Again, the "-A" switch means "do not use authentication". You can view the contents of /n/remote with the command "lc /n/remote". You should see the contents of /usr/Jon on computer1, complete with the file hello.txt that we just created. You can read the contents of hello.txt with the command "cat /n/remote/hello.txt". You should get the response "hello from computer 1".

The picture below shows all these commands (with the window bar coloured red to represent that this is computer2):

That’s how easy it is to create a simple distributed system in Inferno; just use the listen and mount commands. We have just shared some files (literal files on the hard disk), but because everything in Inferno is a file, exactly the same method is used for sharing any namespace.

Per-process namespaces

On computer2, open another shell window and examine the contents of the /n/remote directory with "lc /n/remote". There’s nothing there! Why? This is another important concept in Inferno. Every process (and hence every shell window) maintains its own namespace. So if we modify the namespace in one shell window, all other shell windows (and all other processes) are unaffected. This is very handy. An application can mount resources in /n/remote without first having to check that this mount point is in use.

An exception to this is if a file on hard disk is changed within a namespace. In this case, all processes will see the change.

A note about security

There are several important features of Inferno that we haven't covered in this tutorial. A key feature is security; in all the above examples, we turned off authentication, but we could have made secure connections between systems. In this case, the server and client mutually authenticate each other through certificates that are issued by a common certificate authority. Optionally, the messages passing between the systems could have been encrypted using a variety of algorithms.

Once established, a secure connection behaves exactly the same (from an application's point of view) as an insecure one. The Inferno OS transparently handles the task of encrypting and decrypting the Styx messages and so the application does not know that the connection is secure.

Conclusions

We've had a very brief look at Inferno, but we've seen many important things in action: