<html><head><!-- this stylesheet will later on be added by lfparser automatically: -->

<style type="text/css">
<!--
  pre { font-family:monospace,Courier }
  pre.code { font-family:monospace,Courier;background-color:#aedbe8; }
  p.code { width:80%; alignment:center; background-color:#aedbe8; 
        border-style:none; border-width:medium; border-color:#aedbe8; 
        padding:0.1cm ; text-align:left }
-->
</style></head>
<body>

<h1>Talking to a Running Process</h1>
<h4>ArticleCategory: [Choose a category, translators: do not translate
this, see list below for available categories]</h4>
SoftwareDevelopment
<h4>AuthorImage:[Here we need a little image from you]</h4>
<img src="../../common/images/article300/BobSmith2.jpg"
 alt="[Photo of the Author]">

<h4>TranslationInfo:[Author + translation history. mailto: or
http://homepage]</h4>
<p>original in en <a href="nospam:bob/at/linuxtoys.org">Bob Smith
</a>&nbsp; </p>

<h4>AboutTheAuthor:[A small biography about the author]</h4>
<p>
Bob is a Linux programmer and an electronics hobbyist. You
can find his latest project at <a
href="http://www.runtimeaccess.com">www.runtimeaccess.com</a>  and
his homepage at www.linuxtoys.org.
</p>

<h4>Abstract:[Here you write a little summary]</h4>
Run Time Access is a library that lets you view the data
structures in your program as tables in a PosgreSQL database
or as files in a virtual file system (similar to /proc). 
Using RTA makes it easy to give your daemon or service several
types of management interfaces such as web, shell, SNMP, or
framebuffer.

<h4>ArticleIllustration:[One image that will end up at the top of the
article]</h4>
<img src="../../common/images2/article338/top_image.gif" alt="Run Time Access" hspace="10">

<h4>ArticleBody:[The main part of the article]</h4>


<h2>10 Second Overview</h2>
<p>Say you have a program with data in an array of structures.
The structure and array are defined as:
<table border=0><tr><td>
<pre class="code">struct mydata {
    char   note[20];
    int    count;
}

struct mydata mytable[] = {
  { &quot;Sticky note&quot;, 100 },
  { &quot;Music note&quot;, 200 },
  { &quot;No note&quot;, 300 },
};
</pre></td></tr></table></p>
<p>
If you build your program with the Run Time Access library
you will be able to examine and set the program&#39;s internal
data from the command line or from another program.  Your data
appears as if it were in a PostgreSQL database.  The following
illustrates how you might use Bash and psql, the PostgreSQL
command line tool, to set and read data in your program.  

<pre># myprogram  &amp;

# psql -c &quot;UPDATE mytable SET note = &#39;A note&#39; LIMIT 1&quot;
UPDATE 1

# psql -c &quot;SELECT * FROM mytable&quot;
   note     | count
------------+-------
 A note     | 100
 Music note | 200
 No note    | 300

#
</pre></p>
<p>
This article explains why something like RTA is needed, how to use
the RTA library, and what advantages you can expect from using RTA.
</p>
<p>&nbsp;</p>

<h2>Many UIs -- One Service</h2>
<p>
Traditional UNIX communicated with a service by putting its
configuration data into /etc/application.conf and its accumulated
output in /var/log/application.log.   This accepted approach is
probably wrong for today&#39;s services that run on appliances
and are configured by relatively untrained sys-admins.  The
traditional approach fails because we now want several types
of simultaneous user interfaces, and we want each of those
interfaces to exchange configuration, status, and statistics
with the service while it is running.  What is needed is
run time access.
</p>
<p>
Newer services need many types of user interfaces and we
developers may not be able to predict what interface will be
needed most.  What we need to do is to separate the user 
interface from the service using a common protocol and to
build the user interfaces using the common protocol.  This
makes it easier to add interfaces when needed and the separation
may make testing easier since each piece can be tested
independently.  We want an architecture something like this:
</p>
<center>
<img src="../../common/images2/article338/many_ui.gif" alt="One service -- many interfaces"
 hspace="10" >
</center>
<p>
The types of user interface to consider include web, command
line, framebuffer, SNMP, keypad and LCD, LDAP, native Windows,
and other custom interfaces.  Clearly a common API and protocol
to all the user interfaces would be a good idea.   But what kind
of API and protocol?
</p>
<p>&nbsp;</p>

<h2>A Database Interface</h2>
<p>
RTA chooses to use a PostgreSQL database as the common API and
protocol.  Configuration, state, and statistics are put into
arrays of structures that appear on the API as tables in a
PostgreSQL database.  The user interface programs are written
as clients connecting to a PostgreSQL database.  This approach
has two big benefits:
</p><ul>
<li>The user interface clients use a well known, well documented,
and well debugged API.  Using PostgreSQL dramatically reduces
development time.  Also, PostgreSQL has binding for C, Java, PHP,
Perl, and almost all other popular languages so you can program
the UI in the language right for the job.
</li><li>The paradigm of <i>table in a database</i>   matches
fairly well how most of us write programs that provide a service.
We use data structures for what would be <i>rows</i> and arrays
or linked-list for what would be <i>tables</i>.
</li></ul>
<p></p>
<p>
The RTA library is the glue that ties our arrays or linked lists
of data structures to the PostgreSQL clients.  The architecture
of an application using RTA should look something like ...
</p>

<center>
<img src="../../common/images2/article338/app_arch.gif" alt="RTA Application Architecture"
 hspace="10" >
</center>

<p>
Here we call it a <i>management interface</i> since it is intended
for status, statistics, and configuration.  Although only one
interface is shown, you should remember that you can have many
interfaces for your application, and they can all access the
application simultaneously.
</p>
<p>
PosgreSQL uses TCP as the transport protocol so your application
needs to be able to bind to a TCP port and accept connections
from the various user interfaces.  All bytes received from an
accepted connection are passed into RTA using the dbcommand()
subroutine.  Any data to be returned to the client is in a
buffer returned from dbcommand().  
</p>
<p>
How does RTA know what tables are available?  You have to tell it.
</p>
<p>&nbsp;</p>


<h2>Defining Tables</h2>
<p>
You tell RTA about your tables with data structures and by
calling the rta_add_table() subroutine.  The TBLDEF data
structure describes a table and the COLDEF structure
describes a column.  Here is an example that illustrates how
to add a table to the RTA interface.
</p>
<p>
Say you have a data structure with a string of length 20 and
an integer, and that you want to export a table with 5 of these
structures.  You can define the structure and table as follows:
<br>
<pre class="code">    struct myrow {
        char    note[20];
        int     count;
    };

    struct myrow mytable[5];
</pre>
</p>
<p>
Each field in the <tt>myrow</tt> data structure is a column in a
database table.  We need to tell RTA the name of the column,
what table it is in, its data type, its offset from the start
of the row, and whether or not it is read-only.  We can also
define <i>callback</i> routines which are called before the column
is read and/or after it is written.  For our example we will
assume that <tt>count</tt> is read-only and that we want 
<tt>do_note()</tt> called whenever there is a write to the 
<tt>note</tt> field.  We build an array of COLDEF which is added
to the TBLDEF and which has one COLDEF for each structure member.

</p><pre class="code">    COLDEF mycols[] = {
        {
            &quot;atable&quot;,          // table name for SQL
            &quot;note&quot;,            // column name for SQL
            RTA_STR,           // data type of column/field
            20,                // width of column in bytes
            0,                 // offset from start of row
            0,                 // bitwise OR of boolean flags
            (void (*)()) 0,    // called before read
            do_note(),         // called after write
            &quot;The last field of a column definition is a string &quot;
            &quot;to describe the column.  You might want to explain &quot;
            &quot;what the data in the column means and how it is &quot;
            &quot;used.&quot;},
        {
            &quot;atable&quot;,          // table name for SQL
            &quot;count&quot;,           // column name for SQL
            RTA_INT,           // data type of column/field
            sizeof(int),       // width of column in bytes
            offsetof(myrow, count),  // offset from start of row
            RTA_READONLY,      // bitwise OR of boolean flags
            (void (*)()) 0,    // called before read
            (void (*)()) 0,    // called after write
            &quot;If your tables are the interface between the user &quot;
            &quot;interfaces and the service, then the comments in &quot;
            &quot;column and table definitions form the functional &quot;
            &quot;specification for your project and may be the best &quot;
            &quot;documentation available to the developers.&quot;
    };
</pre>
<p>
Write callbacks can be the real engine driving your application.
You may want to have changes to a table trigger other changes
or a reconfiguration of your application.  
</p>
<p>

You tell RTA about tables by giving it the name of the table,
the length of each row, an array of COLDEFS to describe the
columns, a count of the columns, the name of the save file
if you want some of the columns to be non-volatile, and a string
to describe the table.   If the table is a static array of
structs you give the starting address and the number of
rows in the table.  If the table is implemented as a linked
list you give RTA a routine to call to <i>iterate</i> from one row
to the next.  

</p><pre class="code">TBLDEF   mytableDef = {
      &quot;atable&quot;,                 // table name
      mytable,                  // address of table
      sizeof(myrow),            // length of each row
      5,                        // number of rows
      (void *) NULL,            // iterator function
      (void *) NULL,            // iterator callback data
      mycols,                   // Column definitions
      sizeof(mycols / sizeof(COLDEF), // # columns
      &quot;&quot;,                       // save file name
      &quot;A complete description of the table.&quot;
};
</pre>
<p>
Normally you would want the table name as seen by SQL to be
the same as its name inside the program.  The example switched
from <tt>mytable</tt> to <tt>atable</tt> just to show that the
names do not need to be the same.
</p>
<p>
Given all of the above code, you can now tell RTA about your
table.
</p><pre class="code">    rta_add_table(&amp;mytableDef);
</pre>
<p>
That&#39;s all there is to it.  To use RTA you need to learn
how to use two data structures (COLDEF and TBLDEF) and
two subroutines (dbcommand() and rta_add_table()).
</p>
<p>
The above code is meant to give you a taste of how RTA
works.  It is not meant as a full tutorial or complete
working example.  A complete working example and a full
full description of the RTA API and data structures  is 
on the RTA web site (<a
href="http://www.runtimeaccess.com">www.runtimeaccess.com</a>).
</p>
<p>
Just as you define tables for use in your application, so
RTA defines its own set of internal tables.  The two most
interesting of these table are rta_tables and rta_columns
which are, of course, tables to list and describe all of
the tables and columns you&#39;ve defined.  These are the
so-called <i>system tables</i>.  The system tables do for
a database what <tt>ls</tt> does for a file system and
<tt>getnext()</tt> does for SNMP.
</p>
<p>&nbsp;</p>


<h2>The Table Editor</h2>
<p>
One of the utilities that ships with RTA is a small PHP
program that uses the system tables to list your RTA tables
in a web browser window.  The table names are links and
clicking on a table name displays the first 20 rows of the
table.  If the table has any editable fields you can click
on a row to open up an edit window for that row.  All this
is done using the table and column descriptions found in the
system tables.  The data flow is depicted in the following
diagram.
</p>

<img src="../../common/images2/article338/tbl_edit.gif" alt="Generic Table Editor" hspace="10"
 >

<p>
The top level view of the table editor display for the RTA
sample application is shown below.
</p>

<table cellpadding="8" align="center" width="95%">
<tbody><tr><td>
<center><h4>RTA Table Editor</h4></center>
<table border="3" cellpadding="4" align="center" width="95%" style="font-size: smaller;">
<tbody><tr><th>Table Name</th><th>Description</th></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=rta_tables&amp;offset=0&amp;nrows=7">rta_tables</a></td>
<td>The table of all tables in the system.  This is a pseudo table and not
an array of structures like other tables.</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=rta_columns&amp;offset=0&amp;nrows=54">rta_columns</a></td>
<td>The list of all columns in all tables along with their
attributes.</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=pg_user&amp;offset=0&amp;nrows=1">pg_user</a></td>
<td>The table of Postgres users.  We spoof this table so that any user
name in a WHERE clause appears in the table as a legitimate user with no
super, createDB, trace or catupd capability.</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=rta_dbg&amp;offset=0&amp;nrows=1">rta_dbg</a></td>
<td>Configure of debug logging.  A callback on the &#39;target&#39; field closes
and reopens syslog().  None of the values in this table are saved to disk.
If you want non-default values you need to change the rta source or do an
SQL_string() to set the values when you initialize your program.</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=rta_stat&amp;offset=0&amp;nrows=1">rta_stat</a></td>
<td>Usage and error counts for the rta package.</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=mytable&amp;offset=0&amp;nrows=20">mytable</a></td>
<td>A sample application table</td></tr>
<tr>
<td><a href="http://www.runtimeaccess.com/rta_view.php?table=UIConns&amp;offset=0&amp;nrows=20">UIConns</a></td>
<td>Data about TCP connections from UI frontend programs</td></tr>
</tbody></table>
</td></tr></tbody></table>




<p>
By the way, if all has gone well in the publishing of this
LinuxFocus article, the table names given above should have
live links to the sample application running on the RTA
web server in Santa Clara, California.  A good link to follow
is the <tt>mytable</tt> link.
</p>
<p>&nbsp;</p>


<h2>Two Commands</h2>
<p>
Run Time Access is a library that links management or user
interface programs written with the PostgreSQL client library
(libpq) to your application or daemon.  RTA is an interface,
not a database.  As such, it needs only two SQL commands,
SELECT and UPDATE.
</p>
<p>

The syntax for the SELECT statement is:<br>

<pre>  SELECT column_list FROM table [where_clause] [limit_clause]
</pre>

</p>
<p>
The column_list is a comma separated list of column names.
The where_clause is an AND separated list of comparisons. 
The comparison operators are =, |=, &gt;=, &lt;=, &gt;, and &lt;.  A 
limit_clause has the form <tt>[LIMIT i] [OFFSET j]</tt>,
where <tt>i</tt> is the maximum number of rows to return and we 
skip over <tt>j</tt> rows before starting output.  Some examples
might help clarify the syntax.
</p><pre class="code">  SELECT * FROM rta_tables

  SELECT notes, count FROM atable WHERE count &gt; 0

  SELECT count FROM atable WHERE count &gt; 0 AND notes = &quot;Hi Mom!&quot;

  SELECT count FROM atable LIMIT 1 OFFSET 3
</pre>
<p>
Setting the LIMIT to 1 and specifying an OFFSET is a way
to get a specific row.  The last example above is equivalent
to the C code <tt>(mytable[3].count)</tt>.
</p>
<p>

The syntax of the UPDATE statement is:<br>
<pre>UPDATE table SET update_list [where_clause] [limit_clause]
</pre>
<br>
The where_clause and limit clause are as described above.  The
update_list is a comma separated list of column assignments.
Again, some examples will help.
</p>
<pre class="code">  UPDATE atable SET notes = &quot;Not in use&quot; WHERE count = 0

  UPDATE rta_dbg SET trace = 1

  UPDATE ethers SET mask = &quot;255.255.255.0&quot;,  
                    addr = &quot;192.168.1.10&quot;    
                WHERE name = &quot;eth0&quot;
</pre>
<p>
RTA recognizes both upper and lower case reserved words  
although the examples here use upper case for all of the
SQL reserved words.
</p>
<p>&nbsp;</p>

 
<h2>Download and Build</h2>
<p>
You can download RTA from its web site at <a href="http://www.runtimeaccess.com">www.runtimeaccess.com</a> (copyright of RTA is LGPL).
Be careful in selecting which version of RTA to download.
The latest RTA version uses the newer PostgreSQL protocol
introduced with the 7.4 version of PostgreSQL.  Most
current Linux distributions use the 7.3 version.  While
you can use an older version of RTA for initial trials
you should use the latest version to get the latest bug
fixes and enhancements.
</p>
<p>
Untarring the package should give you the following
directories:
<pre>
  ./doc            # a copy of the RTA web site
  ./empd           # a prototype deamon built with RTA
  ./src            # source files for the RTA library
  ./table_editor   # PHP source for the table editor
  ./test           # source for a sample application
  ./util           # utilities used in writing RTA
</pre>

</p>
<p>
Thanks to Graham Phillips, the 1.0 version of
RTA has autoconf support.  Graham ported RTA from Linux
to Mac OS X, Windows, and FreeBSD.  Using the 1.0 release
you can build RTA with the usual 
</p><pre class="code">  ./configure
  make
  make install      # (as root)
</pre>
<p>
The installation puts librtadb.so and the associated
library files in the /usr/local/lib directory.  To
use RTA you can add this directory to /etc/ld.so.conf
and running the ldconfig command, or you can add the
directory to your loader path with:
</p><pre class="code">  export LD_LIBRARY_PATH=/usr/local/lib
</pre>
<p>
The installation puts the RTA header file, rta.h, in
/usr/local/include.
</p>
<p>

The make builds a test program in the <tt>test</tt>
directory and you can test your installation by changing
directory to the test directory and running <tt>./app &amp;</tt>.
A <tt>netstat -nat</tt> should show a program listening 
on port 8888.  Now you can run psql and issue SQL commands
against your test application.
</p><pre class="code">  cd test
  ./app &amp;

  psql -h localhost -p 8888
  Welcome to psql 7.4.1, the PostgreSQL interactive terminal.

  Type:  \copyright for distribution terms
         \h for help with SQL commands
         \? for help on internal slash commands
         \g or terminate with semicolon to execute query
         \q to quit

  # select name from rta_tables;
      name     
  -------------
   rta_tables
   rta_columns
   rta_dbg
   rta_stat
   mytable
   UIConns
  (6 rows)
</pre>
<p>
While it looks like you are connected to a database, you
are not.  Don&#39;t forget: the only two commands you can use
are SELECT and UPDATE.
</p>
<p>&nbsp;</p>


<h2>Advantages of RTA</h2>
<p>
The advantages of separating the user interface programs from
the daemon proper fall into the broad categories of design,
coding, debug, and capabilities.
</p>
<p>
From a design point of view, the division forces you to decide 
early in the design what exactly is offered as part of the UI 
without worrying how it is displayed. The thought process 
required to design the tables forces you to think through the 
real design of your application. The tables might form the 
internal functional specification of your application.
</p>
<p>
While coding, the table definitions are what the daemon 
engineers build to and what the UI engineers build from. The 
division of UI and daemon means you can hire UI experts and 
daemon experts independently and they can code independently 
which might help bring the product to market sooner. Since 
there are Postgres bindings for PHP, Tcl/Tk, Perl, and &quot;C&quot;, 
your developers can use the right tool for the job.
</p>
<p>
Debug is faster and easier because both the UI and the daemon 
engineers can simulate the other half easily. For example, the 
UI engineers could run their UI programs against a real Postgres 
DB which has the same tables the daemon will have. Testing the 
daemon can be easier and more complete since it is easy to 
build test scripts to simulate the UI, and it is easy to 
examine internal status and statistics while a test runs. 
The ability to force an internal state or condition helps 
test corner-cases which are sometimes difficult to do in a 
lab setup.
</p>
<p>
The capability of your product can be expanded with RTA.  Your 
customers will really appreciate being able to see detailed 
status information and statistics while the program is running.

Separating the UIs from the daemon means you can have more UI
programs: SNMP, command line, web, LDAP, and the list goes on.
This flexibility will be important to you if (when!) your
customers ask for custom UIs.
</p>
<p>
RTA offers several other features you might want in a package 
of this type:
</p><ul>
 <li> Application data model reflected by the API data model </li>
 <li> Remote access to the application </li>
 <li> Use of standards and existing software by the application </li>
 <li> Few new protocols and APIs to learn </li>
 <li> Discovery mechanisms for the application </li>
 <li> Few constraints on the application </li>
 <li> Resource locking </li>
 <li> CPU and memory efficiency </li>
</ul>
<p>&nbsp;</p>


<h2>Summary</h2>
<p>
This article has presented a very brief introduction to
the RTA library and its capabilities.  The RTA web site
has a FAQ, a complete description of the API, and several
sample client programs.  
</p>
<p>
Just as RTA can make your data structures visible as
tables in a database, so it can make them visible as
files in a virtual file system.  (Using the File System in
Userspace (FUSE) package by Miklos Szeredi.)  The web
site has more information on how to use the file system
interface.
</p>




<!-- vim: set sw=2 ts=2 et tw=74: --></body></html>