Accessing ROOT Files Remotely via a rootd Server


Reading and writing ROOT files over the net can be done by creating a TNetFile object instead of a TFile object. Since the TNetFile class inherits from the TFile class it has exactly the same interface and behaviour. The only difference is that it reads and writes via a remote rootd daemon.

TNetFile URL

TNetFile file names are in standard URL format with protocol "root" or "roots" (for secure authentication). The following are valid TNetFile URL's:

roots://hpsalo/files/aap.root
root://hpbrun.cern.ch/root/hsimple.root
root://pcna49a:5151/~na49/data/run821.root
root://pcna49d.cern.ch:5050//v1/data/run810.root

The only difference with the well known httpd URL's is that the root of the remote file tree is the remote user's home directory. Therefore an absolute pathname requires a // after the host or port specifier (as shown in the last example above). Further the expansion of the standard shell characters, like ~, $, .., etc. is handled as expected. The default port on which the remote rootd listens is 1094 and this default port is assumed by TNetFile (actually by TUrl which is used by TNetFile). Port number 1094 has officially been assigned by IANA for rootd.

The rootd Daemon

The rootd daemon works with the TNetFile class. It allows remote access to ROOT database files in either read or read/write mode. The rootd daemon can be found in the directory $ROOTSYS/bin. It can be started either via inetd or by hand from the command line (no need to be super user). Its performance is comparable with NFS but while NFS requires all kind of system permissions to setup, rootd can be started by any user. The simplest way to start rootd is by running it from the command line while being logged on to the remote machine. Once started rootd goes immediately in the background (no need for the &) and you can log out from the remote node. The only argument required is the port number (> 2048) on which your private rootd will listen. Using TNetFile you can now read and write files on the remote machine. For example:

hpsalo [12] telnet fsgi02.fnal.gov
login: minuser
Password:
<fsgi02>
rootd -p 5151
<fsgi02> exit
hpsalo [13] root
root [0] TFile *f = TFile::Open("root://fsgi02.fnal.gov:5151/file.root","new")
Name (fsgi02.fnal.gov:rdm): minuser
Password:
root [1]
f.ls()

In the above example rootd runs on the remote node under user id minuser and listens to port 5151. When creating a TNetFile object you have to specify this same port number 5151 and use minuser (and corresponding password) as login id. When rootd is started in this way you can only login with the user id under which rootd was started on the remote machine. However, you can make many connections since the original rootd will fork (spawn) a new rootd that will service the requests from the TNetFile. The original rootd keeps listening on the specified port for other connections. Each time a TNetFile makes a connection it gets a new private rootd that will handle its requests. At the end of a root session when all TNetFiles are closed only the original rootd will stay alive ready to service future TNetFiles.

Remote Authentication

Connecting to a rootd daemon requires a remote user id and password. TNetFile supports three ways for you to provide your login information:

  1. Setting it globally via the static TAuthenticate functions TAuthenticate::SetUser() and TAuthenticate::SetPasswd()
  2. Via the ~/.rootnetrc file. This file has the same format as the ~/.netrc file as used by ftp, with in addition the keyword secure instead of machine to tell the system that that line should be used for secure authentication (see below about SRP and roots)
  3. Via the ~/.netrc file (same format and file as used by ftp), which will be tried after ~/.rootnetrc has been tried
  4. Via command line prompt

The different methods will be tried in the order given above. On machines with AFS rootd will obtain an AFS token (if it has been compiled with AFS support. To rebuild rootd with AFS support see the install instructions).

Shadow Passwords

When your system uses shadow passwords you have to compile rootd with -DR__SHADOWPW (see $ROOTSYS/rootd/Module.mk). Since shadow passwords can only be accessed while being superuser (root) this works only when the server is started via inetd. This is inconvenient when you want to run rootd as private user. To solve this problem you should create a file $HOME/.rootdpass containing your encrypted password. If this file exists its password is used for authentication. This method overrides all other authentication methods. To create an encrypted password use a perl script like:
#! /usr/bin/perl
srand(time());
my $randletter = "(int (rand(26)) + (int (rand(1) + .5) % 2 ? 65 : 97))";
my $salt = sprintf("%c%c", eval $randletter, eval $randletter);
my $plaintext = shift;
my $crypttext = crypt($plaintext, $salt);
print "${crypttext}\n";
and store the output in $HOME/.rootdpass.

Secure Remote Authentication

Rootd also supports a completely secure authentication mechanism based on the SRP package developed at Stanford. SRP, Secure Remote Passwords, uses a so called ``asymmetric key exchange protocol'' in which no passwords are ever send over the wire. To read about the main features of SRP look at: http://srp.stanford.edu/advantages.html.

To build rootd with SRP you have to do the following:

Several binary distributions already come with everything needed to run SRP (check for the existence of, for example, $ROOTSYS/lib/libSRPAuth.so).

Using the General TFile::Open() Function

To make life simple we provide a general function to open any type of file (except shared memory files of class TMapFile). This functionality is provided by the static TFile::Open() function:

         TFile *TFile::Open(const Text_t *name, Option_t *option="",
                       const Text_t *title="",

Depending on the name argument the function returns either a TFile, a TNetFile or a TWebFile object. In case a TNetFile URL specifies a local file a TFile object will be returned (and of course no login information is needed). The arguments of the Open() function are the same as the ones for the TFile constructor.

A Sample Session

root [0] TFile *f1 = TFile::Open("local/file.root", "update")
root [1] TFile *f2 = TFile::Open("root://pcna49a.cern.ch/data/file.root", "new")
Name (pcna49a:rdm):
Password:

root [2] TFile *f3 = TFile::Open("roots://pcna49a.cern.ch/data/file2.root", "new")
Name (pcna49a:rdm):
Secure Password:

root [3] TFile *f4 = TFile::Open("http://root.cern.ch/~rdm/hsimple.root")
root [4] f4.ls()
TWebFile** http://root.cern.ch/~rdm/hsimple.root
TWebFile* http://root.cern.ch/~rdm/hsimple.root
KEY: TH1F hpx;1 This is the px distribution
KEY: TH2F hpxpy;1 py vs px
KEY: TProfile hprof;1 Profile of pz versus px
KEY: TNtuple ntuple;1 Demo ntuple
root [5] hpx.Draw()

Starting rootd via inetd

If you expect to often connect via TNetFile to a remote machine it is more efficient to install rootd as a service of the inetd super daemon. In this way it is not necessary for each user to run a private rootd. However, this requires a one time modification of two system files (and super user priviliges to do so). Add to /etc/services the line:

rootd     1094/tcp

and to /etc/inetd.conf the line:

rootd stream tcp nowait root /usr/local/root/bin/rootd rootd -i

After these changes force inetd to reread its config file with "kill -HUP <pid inetd>".

Setup in this way it is not necessary to specify a port number in the URL given to TNetFile. TNetFile assumes the default port to be 1094 as specified above in the /etc/services file.

Systems using the new xinetd super daemon, like RedHat 7.0, should create a file /etc/xinetd.d/rootd with the following contents:

# default: on
# description: The rootd daemon allows remote access to ROOT files.
service rootd
{
        disable = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/local/root/bin/rootd
        server_args             = -i
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
}

Rootd Command Line Arguments

Rootd support the following arguments:

   -i           says we are started by inetd
   -p port#     specifies port number to listen on
   -d level     level of debug info written to syslogd
                0 = no debug (default)
                1 = minimum
                2 = medium
                3 = maximum

Anonymous rootd Usage

Rootd can also be configured for anonymous usage (like anonymous ftp). To setup rootd to accept anonymous logins do the following (while being logged in as root): That's all.

Several remarks:


Rene Brun, Fons Rademakers
Last update 1/8/2000 by FR