One of the cornerstones of the Inferno architecture is the Unix idea with file devices brought to the limit: everything is represented in Inferno files. For example, there is no “socket” concept in Inferno.
Files
Inferno files contain not only devices (analogue of
/dev/
) and processes (analogue of
/proc/
), but also such things as DNS resolver, sockets and environment variables (environment) (the list is not complete :)).
For example, in order to open a tcp connection to the site
www.habrahabr.ru , you need to do the following operations:
- open file
/net/cs
- write the string 'tcp! www.habrahabr.ru! http' into it
- read the answer from it (this will be the string '/ net / tcp / clone 217.147.30.151! 80')
- open file
/net/tcp/clone
- read a number from it (identifier of this connection, then ID), and a new subdirectory of
/net/tcp/
ID /
with ctl
, data
, status
, etc. files will automatically appear in the /net/tcp/
directory /net/tcp/
- write to the
/net/tcp/
ID /ctl
file the string 'connect 217.147.30.151! 80' - read / write file
/net/tcp/
ID /data
Explanation of examples. Examples for brevity are given in sh, not Limbo.
;
- invitation sh.>[1=0]
- redirect STDOUT to STDIN.<>/path
- open STDIN for reading + write to / path.read
- reads from STDIN and prints the specified number of bytes to STDOUT.`{...}
is to execute a command and return its output.
; { echo -n 'tcp!www.habrahabr.net!http' >[1=0]; read -o 0 8192; } <>/net/cs /net/tcp/clone 209.85.84.157!80 ; { id=`{read} echo 'connect 209.85.84.157!80' >/net/tcp/$id/ctl echo 'HEAD / HTTP/1.0' >/net/tcp/$id/data echo 'Host: www.habrahabr.ru' >/net/tcp/$id/data echo >/net/tcp/$id/data read </net/tcp/$id/data } <>/net/tcp/clone HTTP/1.1 200 OK Date: Sun, 27 May 2007 11:33:42 GMT Server: Apache/2.0.52 (Red Hat) X-Powered-By: PHP/5.1.4 Set-Cookie: vsid=3X02X521137108; expires=Fri, 25-May-2012 11:33:43 GMT; path=/ Connection: close Content-Type: text/html; charset=UTF-8
The work with environment variables is the same: there is a
/env/
directory, the files in which are variable names, and the contents of files are the values ​​of variables. Accordingly, the creation / deletion of a file is the creation / deletion of an environment variable.
To access information on the processes used directory
/prog/
. Moreover, absolutely all operations are performed through its subdirectories and files - including debugging (i.e., no POSIX ptrace is needed) and obtaining information on the status of the process (i.e. no wait / waitpid syscol).
')
The operation of all these virtual files is provided by various means - for example,
/net/tcp/
and
/env/
implemented through the Inferno drivers, and the DNS resolver
/net/cs
implemented by a regular application.
This approach has simplified many things:
- for working with the network, the usual file API is enough; some POSIX functions (socket, connect, bind, listen, etc.) are no longer needed
- similarly, there is no special API for working with environment variables (clearenv, putenv, setenv, getenv, etc.)
- since the Styx protocol allows you to share files over the network, you can do, for example, the following tricks:
- if a machine on the local network that does not have a real IP address, mounts a directory
/net/
gateway to the Internet, then it will get a direct Internet connection without having to configure NAT or masquerade pieces on the gateway - if the
/dev/cons
, /dev/keyboard
and /dev/pointer
files from the workstation are mounted to the remote server, then on the server it will be possible to run graphical applications that will be controlled from the workstation terminal - all without the special a-protocol For X-Window! .. plus we get built-in (in Styx) authorization, authentication and encryption - if you mount the
/prog/
directory (similar to /proc/
) to a local machine from a remote server, you can debug processes running on the remote machine with a local debugger - and the debugger will not even know about it, because it just works through files in /prog/
But, from my point of view, much more important is not the fact that the need for a heap of syscols is no longer there, but the fact that there are much less “features” that need to be known for high-quality programming! For example, in Unix files have some features, special files (Unix-sockets, pipes, some devices) are different, and others have sockets - and in Inferno they are all identical files with the same behavior.
Distributed computing
The “correct” program in Inferno should be written not in the style of traditional Unix utilities (read STDIN, write STDOUT), but in the style of the Styx file server. In other words, the input / output of such a utility should not be STDIN / STDOUT, but a virtual file or directory with files a la
/net/cs
or
/net/tcp/
.
This makes it very easy to build distributed systems. For example, suppose there is a module in our project that counts something. It is implemented as a separate process that exports a
./calc
file, into which you can write tasks and read the result from it. If there is a need to speed up the calculations by transferring this subtask to a separate, more powerful server, then two steps are enough: run this module on another server;
./calc
file from this server. And that's all - the rest of the project will not even notice that this module is running on another server!
Namespaces
Namespaces in Inferno are similar to those used in many programming languages ​​... only in Inferno they apply to files and directories.
In fact, the privileges and capabilities of the program under Inferno are limited to which files (for any resource = file) it has access to. By manipulating the namespace, for each application you can create your own, isolated (a la chroot) environment, with your devices in
/dev/
(as above in the example with a remote terminal), with your network cards in
/net/
(as above in the NAT example ), etc.
For example, in Windows there is such a feature - you log in from any computer on the network and get YOUR desktop and YOUR directory “my documents”. In Inferno, having logged in from any terminal and having access to your keys / certificates, you can manipulate the namespace to create 100% the same environment that you have on your main computer. And to implement this, there are no special “features” in Inferno - the usual commands are mount, bind and Styx protocol.
Perhaps all this does not sound very important, but the principle of working with applications changes dramatically - we usually try to ensure that the application works in a variety of conditions (which complicates it significantly), and in Inferno we use the namespace, mount commands and bind create exactly the environment for which this application is designed.