The latest version of this file can be found at http://jstyx.sourceforge.net/docs/InfernoTutorial.html
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.
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 is very easy:
<cdroot>/install
directory.<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.EMU
to the string "-r<inferno root>"
.
(e.g. setenv EMU "-r/usr/inferno"
in the C shell).<inferno root>/Linux/386/bin
and in Windows (NT, 2000 and XP) the executables are in <inferno root>/Nt/386/bin
.
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.
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".
Many commands in Inferno have direct equivalents in Unix:
ls
command.
To see the details of the files, enter ls –l
. To see the file list
formatted more nicely, enter lc
. Your home directory (on a new
installation) should contain three directories and a file: charon/ keyring/
lib/ namespace
. When using the lc
command, directories are designated by
a slash after the name.cd
command.cp
command, and to move or rename a
file, use mv
.rm
.man
command (e.g. "man cp"
). To view the output one page at
a time, pipe the output to p
, the pager command: "man cp
| p"
. Use the enter key to move to the next page.cat
(e.g. "cat /LICENCE | p"
or "cat /dev/user"
).echo
(e.g. "echo
hello world"
). To output without the trailing newline use "echo –n."
>
operator, e.g. "echo hello world > hello.txt"
. To
append to a file, use >>
, e.g. "echo from mars >>
hello.txt".
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
.
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.
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.
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).
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.
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?)
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.
(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.
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?)
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:
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.
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.
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.
We've had a very brief look at Inferno, but we've seen many important things in action: