/* Ajith - Syntax Higlighter - End ----------------------------------------------- */

9.30.2008

CERN's LHC is also powered by GNU/LINUX

Everyone knew about Large Hadron Collider (LHC) Experiment (a snip at $10 billion) conducted by CERN.
The Large Hadron Collider (LHC) is the world's largest and highest-energy particle accelerator complex, intended to collide opposing beams of protons or lead, two of several types of hadrons, at up to 99.99 percent the speed of light.

CERN played a pivotal part in the evolution of the internet we know and love today. Tim Berners-Lee invented the hypertext link when he was working at CERN as an independent contractor in the 1980s. He saw the opportunity to link his hypertext to the Transmission Control Protocol (TCP) and the Domain Name System (DNS) The rest, as they say, is history.
Berners-Lee designed the first web browser, built the fist server and the first website was launched at CERN in August 1991. And he gave away world wide web to the world as a gift for Free.

CERN is home to not only a spirit of free enquiry, but to the use of free software itself. For starters CERN’s 20,000 servers use GNU/Linux. In fact they developed their own version of Scientific Linux (SL), a recompiled version of Red Hat Enterprise Linux, in conjunction with Fermilab and other labs across the world.


Coming to LHC experiment, LHC will output data on a truly massive scale that threatens to simply overwhelm the bandwidth of the current web: it is reported that the experiment will produce one gigabyte of data every second and that deluge requires a whole new way of handling data and distributing petabytes of information.

To solve that problem CERN came up with the Grid. This is being seen widely as the future of the web. Two large bottlenecks have been identified: the shortage of IP addresses and bandwidth. The former is being solved with the introduction of IPv6 which should render addresses virtually inexhaustible. As the number of users and web-enabled devices grows however and the web churns out more and more data, the other choke point therefore becomes bandwidth. CERN’s solution is The Grid.

The primary architecture of the computing grid is the “TIER” and there are three of them: 0, 1 and 2. The first centres on CERN itself, the second covers various sites across Asia, Europe and North America and the third is represented by individual labs, universities and private companies. Tier 0 - capable of managing up to 10 gigabytes per second across fibre optic cables. Checkout ZDNet's video on CERN's 3D digital camera.


CERN’s choice of GNU/Linux is no one off. To manage such a vast data output from the LHC some controlling software was required to manage the petabytes of data for users sitting at their computers across the world on the computing grid and GNU?LINUX is the best option for it. Users need to access the data transparently even though it is sitting on geographically disparate servers housing those petabytes. It is the opensource community that plays a great role in all the scientific experiments as well as in new innovative stuff. It is quite clear that even if it is a Super computer or a billion dollar Scientific Experiment or a new innovative technology it is the opensource community and GNU/LINUX that comes for the rescue rather than the propreitary stuff.

Actual link where you can have much more information about this topic is at this link.

9.16.2008

Client Server example with PIPES

This example shows a combined use of unnamed and named pipes to produce a client–server relationship. Let us discuss first about the PROBLEM we are going to try.

There is a single Server process which runs continuously in background eventhough if there is no client to interact with it. Client processes runs in foreground and interacts with the server process. Both the client and server processes will run on the same machine (So server process will run background forever until it is manually killed).

The Client process accepts a command (probably a shell command) from the user and send's it to the Server via a FIFO which is a public channel between Client and Server for processing. Let us name this FIFO as PUBLIC fifo since its existence is known to all clients and the server. Once the command is received, the Server executes it using the popen–pclose sequence (which generates an unnamed pipe in the Server process). After execution Server process should return the output of the command executed to the client over a FIFO which is a private channel between the client and server. Let us name this FIFO as PRIVATE fifo. The Client, upon receipt, displays the output on the screen.

NOTE: Each and every Client process should have its own unique PRIVATE fifo to receive information from Server.

Check out the diagrammatic representation of the PROBLEM.


To ensure that both Server and Client processes use the same PUBLIC fifo name and have the same message format for the data sent through the FIFO, a local header file named local.h is created.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/limits.h>
#include <string.h>
#include <stdio.h>

#define B_SIZE (PIPE_BUF/2)

const char *PUBLIC = "/tmp/PUBLIC";

struct message {
char fifo_name[B_SIZE];
char cmd_line[B_SIZE];
};

The format of the message sent over the PUBLIC fifo is declared within the struct statement. The message structure consists of two character array's namely fifo_name, stores the name of the PRIVATE fifo of the Client process and cmd_line, stores the command to be executed by the Server.

Let us checkout the functionality steps of a newly created Client process.
  [1].  Create a unique name for the PRIVATE fifo and invoke it.
  [2].  Open the PUBLIC fifo in write mode.
  [3].  Prompt for command from user.
  [4].  Write command to PUBLIC fifo for Server to process.
  [5].  Open PRIVATE fifo in read mode to read the contents from Server..
#include "local.h"
int main()
{
int publicfifo, privatefifo, n;
static char buffer[PIPE_BUF];
struct message msg;

/*Using sprintf to create a unique fifo name
and save into message structure*/
sprintf(msg.fifo_name, "/tmp/fifo%d", getpid());

/*Creating the PRIVATE fifo*/
if(mknod(msg.fifo_name, S_IFIFO | 0666, 0) < 0) {
  perror(msg.fifo_name);
  exit(1);
}

/*Opening PUBLIC fifo in WRITE ONLY mode*/
if((publicfifo = open(PUBLIC,O_WRONLY)) < 0) {
  unlink(msg.fifo_name);
  perror(PUBLIC);
exit(1);
}

while(1) {

  write(fileno(stdout), "\n cmd>", 6);
  memset(msg.cmd_line, 0x0, B_SIZE);
  n = read(fileno(stdin), msg.cmd_line, B_SIZE);

if(strncmp("quit", msg.cmd_line, n-1) == 0) {
  break;
}

write(publicfifo, &msg, sizeof(msg));

if((privatefifo = open(msg.fifo_name, O_RDONLY)) < 0) {
  printf("1\n");
  perror(msg.fifo_name);
  goto CLEANUP;
}

while((n = read(privatefifo, buffer, PIPE_BUF)) > 0) {
  write(fileno(stderr), buffer, n);
}

close(privatefifo);
}

CLEANUP:
close(publicfifo);
unlink(msg.fifo_name);

return 0;
}

Now we will check the Server process.
  [1].  Generate a PUBLIC fifo and open it in both read and write mode. Wait for the message from a Client process.
  [2].  Read the message from PUBLIC fifo.
  [3].  Open the Client's PRIVATE fifo in write mode.
  [4].  Execute the command from Client process using popen.
  [5].  Write the output into Client's PRIVATE fifo.
#include "local.h"

int main() {

int privatefifo, dummyfifo, publicfifo, n, done;
struct message msg;
FILE *fin;
static char buffer[PIPE_BUF];

/*creating the PUBLIC fifo*/
mknod(PUBLIC, S_IFIFO | 0666, 0);

/*
Server process opens the PUBLIC fifo in write mode to make sure that
the PUBLIC fifo is associated with atleast one WRITER process. As a
result it never receives EOF on the PUBLIC fifo. The server process
will block any empty PUBLIC fifo waiting for additional messages to
be written. This technique saves us from having to close and reopen
the public FIFO every time a client process finishes its activities.
*/

if( (publicfifo = open(PUBLIC, O_RDONLY)) < 0 ||
(dummyfifo = open(PUBLIC, O_WRONLY | O_NDELAY)) < 0) {
   perror(PUBLIC);
   exit(1);
}

/*Read the message from PUBLIC fifo*/
while(read(publicfifo, &msg, sizeof(msg)) > 0) {

n=0;
done=0;

do {
  if((privatefifo = open(msg.fifo_name, O_WRONLY|O_NDELAY)) == -1) {
    sleep(5);
  }
  else {
    fin = popen(msg.cmd_line, "r");
    write(privatefifo,"\n",1);

    while((n= read(fileno(fin), buffer, PIPE_BUF)) > 0) {
      write(privatefifo, buffer, n);
      memset(buffer, 0x0, PIPE_BUF);
    }

    pclose(fin);
    close(privatefifo);
    done = 1;
  }
}while(n++ < 5 && !done);

if(!done) {
  perror("Not accessed the private fifo\n");
  exit(1);
}

}
return 0;
}

Compile server.c and client.c and generate server, client executable's. A sample execution of the client-server programs is shown below

[bash]$./server &                                  
[1] 27107

[bash]$./client
cmd>ps
PID TTY TIME CMD
14736 pts/3 00:00:00 csh
27107 pts/3 00:00:00 server
27108 pts/3 00:00:00 client
27109 pts/3 00:00:00 6
cmd>who
gray pts/3 Feb 27 11:28
cmd>quit

$./kill -9 27107
[1] Killed server
$