Initial revision
This commit is contained in:
389
nconman.tex
Normal file
389
nconman.tex
Normal file
@ -0,0 +1,389 @@
|
||||
\subsection{The Connection Object}
|
||||
The connection object is a major player in the SICS world. The connection
|
||||
object represents an active connection between the SICS server and a client.
|
||||
There will be one connection object for each client connection. A lot of
|
||||
stuff is associated with a client connection:
|
||||
\begin{itemize}
|
||||
\item A task. This task will read one command from the command fifo and
|
||||
execute it.
|
||||
\item A command fifo which will be filled by the network reader.
|
||||
\item An execution context consisting of user rights for this connection
|
||||
and interrupt status.
|
||||
\item A communication channel to the client.
|
||||
\item A list of log files to which all traffic on the connection will be
|
||||
logged.
|
||||
\item An interface to the SICS interpreter which allows to configure
|
||||
certain aspects of the connection and makes the connection available as
|
||||
a command.
|
||||
\item A list of callbacks registered for the connection. A connection can
|
||||
be automatically notified about changes in system state. These callbacks
|
||||
have to be removed when the client server connection terminates. Otherwise
|
||||
callback code would write to a dead connection causing the program to
|
||||
crash.
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Connection I/O}
|
||||
Due to user requirements for features not considered in the design the
|
||||
I/O facilities of connection have become quite involved.
|
||||
|
||||
Incoming commands are printed into client log files if configured, and
|
||||
into the commandlog if the connection has a privilege $\ge$ user
|
||||
privilege. This is implemented in SCInvoke. Also each command is
|
||||
printed to the server log.
|
||||
|
||||
Output is more sophisticated. First of all there are different output
|
||||
codes given as last parameter to SCWrite. The most important of these
|
||||
are:
|
||||
\begin{description}
|
||||
\item[eError] Error messages.
|
||||
\item[Warning] warnings.
|
||||
\item[Value] values requested by the client.
|
||||
\item[Status] status messages.
|
||||
\end{description}
|
||||
Clients can choose to suppress certain types of messages in order to
|
||||
reduce I/O.
|
||||
|
||||
The logic is mostly implemented in the
|
||||
file static function SCNormalWrite. The follwoing conditions are
|
||||
implemented:
|
||||
\begin{itemize}
|
||||
\item Any output is logged to the
|
||||
server log.
|
||||
\item If the privilege of the connection is $\ge$ user the
|
||||
output is printed to the commandlog as well.
|
||||
\item If the command is executing as part of a Tcl--macro script
|
||||
output to the socket is suppressed. The output is copied into the
|
||||
interpreter for further evaluation instead. This is done in order to
|
||||
prevent excessive output during macro evaluation and in order to make
|
||||
SICS results available in the Tcl interpreter. However, messages of
|
||||
type error or warning are printed to the socket even during macro
|
||||
evaluation.
|
||||
\item In the normal case the output is printed to the socket and all
|
||||
log files configured for the connection.
|
||||
\item As of recent the output function can be modified by setting a
|
||||
new function. One sich function exists which supresses all output to
|
||||
the socket. This is done in order to help when the connection gets
|
||||
lost. For instance with the cron command.
|
||||
\end{itemize}
|
||||
This aspect of the connection object could do with a cleanup. A
|
||||
possible cleanup path is the implementation of the different output
|
||||
strategies in different functions and devise a SCsetOutMode function which
|
||||
switches between the various possibilities. Also, it can be argued if
|
||||
the client specific log files are still needed. Then this part of the
|
||||
code can be cleaned out as well.
|
||||
|
||||
|
||||
\subsubsection{Command Execution Path}
|
||||
In the course of the SICS development the path of a command through
|
||||
the system has become more complex as well. This section describes how
|
||||
it works. The incoming command is collected at the socket by the
|
||||
NetReaderTask. This does a little processing and checks for interrupts
|
||||
issued on the connection and invokes them. But any normal command is
|
||||
put into the connections Command-FIFO. Thus ends the business of the
|
||||
NetReaderTask. The connections task function SCTaskFunction is
|
||||
invoked by the task manager in due time and checks for pending
|
||||
commands on the command stack. If a command is pending it is taken
|
||||
from the stack and executed through SCInvoke.
|
||||
|
||||
\subsubsection{Execution context}
|
||||
Each connection has a user right code associated with it. The there is
|
||||
a second protection scheme in SICS with the token system. This system
|
||||
reserves command input to a certain connection. In the connection
|
||||
object this scheme requires the iGrab field which defines if this
|
||||
connection may execute commands or not. This field is modified through
|
||||
the tasks signal handling function. Code implementing a command may
|
||||
call SCMatchRights in order to check for permission. SCMatchRights
|
||||
will also send appropriate error messages.
|
||||
|
||||
Errors are usually signalled by setting an interrupt code on the
|
||||
connection. An additional field, iError allows to give a more detailed
|
||||
error description if required.
|
||||
|
||||
\subsubsection{Callbacks}
|
||||
SICS can be configured to forward notifications about certain state
|
||||
changes to a connection automatically. This is implemented through the
|
||||
callback system. For more details see \ref{inter}. However, it is
|
||||
important that any callback acting on a connection is registered with
|
||||
the connection object. This allows the removal of the callback when
|
||||
the connection is closed. Otherwsie the system gets filled up with
|
||||
dead callbacks which usuallly cause core dumps when it is tried to
|
||||
send a message to a dead connection.
|
||||
|
||||
|
||||
\subsubsection{The Connection Data Structure}
|
||||
Given the plethora of things to take care of, each connection is
|
||||
represented by a rather large data structure.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$condat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __SConnection {@\\
|
||||
\mbox{}\verb@ /* object basics */@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ char *pName;@\\
|
||||
\mbox{}\verb@ long lMagic;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* I/O control */@\\
|
||||
\mbox{}\verb@ mkChannel *pSock;@\\
|
||||
\mbox{}\verb@ FILE *pFiles[MAXLOGFILES];@\\
|
||||
\mbox{}\verb@ int iMacro;@\\
|
||||
\mbox{}\verb@ int iTelnet;@\\
|
||||
\mbox{}\verb@ int iOutput; @\\
|
||||
\mbox{}\verb@ int iFiles;@\\
|
||||
\mbox{}\verb@ int (*write)(struct __SConnection *pCon,@\\
|
||||
\mbox{}\verb@ char *pMessage, int iCode);@\\
|
||||
\mbox{}\verb@ mkChannel *pDataSock;@\\
|
||||
\mbox{}\verb@ char *pDataComp;@\\
|
||||
\mbox{}\verb@ int iDataPort;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /* execution context */@\\
|
||||
\mbox{}\verb@ int eInterrupt;@\\
|
||||
\mbox{}\verb@ int iUserRights;@\\
|
||||
\mbox{}\verb@ int inUse;@\\
|
||||
\mbox{}\verb@ int iDummy;@\\
|
||||
\mbox{}\verb@ int iGrab;@\\
|
||||
\mbox{}\verb@ int iErrCode;@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* a FIFO */@\\
|
||||
\mbox{}\verb@ pCosta pStack;@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ /* callback registry */@\\
|
||||
\mbox{}\verb@ int iList;@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ /* Tasking Stuff */@\\
|
||||
\mbox{}\verb@ int iEnd;@\\
|
||||
\mbox{}\verb@ }SConnection;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The fields are:
|
||||
\begin{description}
|
||||
\item[pDes] The usual object descriptor belonging to any object within the
|
||||
SICS interpreter. See \ref{inter} for details.
|
||||
\item[pName] The automatically generated name of the connection object in the
|
||||
interpreter.
|
||||
\item[lMagic] is a magic number used internally in order to check if
|
||||
the connection object given as a parameter is valid.
|
||||
|
||||
\item[pChannel] A pointer to a network channel structure. This channel
|
||||
will be used for I/O to the client. If thispointer is NULL I/O is done onto
|
||||
stdin/stdout instead.
|
||||
\item[pFiles] An array of file to which all I/O on this connection will be
|
||||
logged.
|
||||
\item[iOutPut] The currently valid output mask. SICS messages are classified
|
||||
into several output classes. If a message is going to be printed it must
|
||||
have a output class above the one configured as the mask. This was made in
|
||||
order to allow clients to suppress certain messages which are not of
|
||||
interest.
|
||||
\item[iFiles] The number of configured log files.
|
||||
\item[write] a pointer to a function which does the actual writing of
|
||||
a message to the connection.
|
||||
\item[iTelnet] is true when I/O is through a telnet connection.
|
||||
\item[iMacro] This flag is set when the connection is executing a Tcl
|
||||
script. In this mode mode all output is written into the Tcl interpreter and
|
||||
not written to the client. Thus a script can execute silently. As always,
|
||||
there is an exception: errors and warning will still be written to the
|
||||
client.
|
||||
|
||||
\item[iGrab] This is 0 when the connection may execute commands. It is 1 if
|
||||
another connection has grabbed the control token and commands may not be
|
||||
executed. For details about the token system, see the token reference.
|
||||
\item[eInterrupt] This is the current interrupt status of the connection.
|
||||
\item[iUserRights] This integer denotes the user rights associated with the
|
||||
connection. This value is initially deducted from the username password pair
|
||||
given at login to SICS. The value can be configured otherwise afterwards.
|
||||
iUserRights will be used to check at object level if a client may perform
|
||||
the requested operation or not.
|
||||
\item[iErrCode] is the last error code. I think this field is no longer
|
||||
used.
|
||||
|
||||
\item[pSics] is a pointer to an SICS interpreter where to invoke commands.
|
||||
\item[pStack] Is the command FIFO.
|
||||
\item[iList] This is the identifier of a lld list which holds the callbacks
|
||||
registered on this connection object.
|
||||
\item[iEnd] iEnd is a flag which is usually 0. It is set by certain
|
||||
interrupts or if the connection is broken and causes the connection task to
|
||||
end and the connection data structure to be removed from the system.
|
||||
\end{description}
|
||||
Quite a few places in SICS refer to this data structure directly,
|
||||
without a function interface. The reason for this is performance. Therefore
|
||||
this data structure is made public in the conman.h file.
|
||||
|
||||
|
||||
\subsubsection{Connection Functions}
|
||||
The interface to this data structure is defined by the following functions:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$conint {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------ live & death ----------------------------*/@\\
|
||||
\mbox{}\verb@ SConnection *SCreateConnection(SicsInterp *pSics, mkChannel *pSock,@\\
|
||||
\mbox{}\verb@ int iUserRights);@\\
|
||||
\mbox{}\verb@ SConnection *SCCreateDummyConnection(SicsInterp *pSics);@\\
|
||||
\mbox{}\verb@ void SCDeleteConnection(void *pVictim);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*------------------------------- tasking --------------------------------*/@\\
|
||||
\mbox{}\verb@ int SCTaskFunction(void *pCon);@\\
|
||||
\mbox{}\verb@ void SCSignalFunction(void *pCon, int iSignal, void *pSigData);@\\
|
||||
\mbox{}\verb@/* ***************************** I/O ************************************** */@\\
|
||||
\mbox{}\verb@ int SCAddLogFile(SConnection *self, char *name);@\\
|
||||
\mbox{}\verb@ int SCDelLogFile(SConnection *pCon, int iFile);@\\
|
||||
\mbox{}\verb@ void SCSetOutputClass(SConnection *self, int iClass);@\\
|
||||
\mbox{}\verb@ int SCWrite(SConnection *self, char *pBuffer, int iOut);@\\
|
||||
\mbox{}\verb@ int SCRead(SConnection *self, char *pBuffer, int iBufLen); @\\
|
||||
\mbox{}\verb@ int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);@\\
|
||||
\mbox{}\verb@ int SCSendOK(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCnoSock(SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int SCWriteUUencoded(SConnection *pCon, char *pName, void *iData, int iLen);@\\
|
||||
\mbox{}\verb@/************************* CallBack *********************************** */@\\
|
||||
\mbox{}\verb@ int SCRegister(SConnection *pCon, SicsInterp *pSics,@\\
|
||||
\mbox{}\verb@ void *pInter, long lID);@\\
|
||||
\mbox{}\verb@ int SCUnregister(SConnection *pCon, void *pInter);@\\
|
||||
\mbox{}\verb@/******************************* Error **************************************/@\\
|
||||
\mbox{}\verb@ void SCSetInterrupt(SConnection *self, int eCode);@\\
|
||||
\mbox{}\verb@ int SCGetInterrupt(SConnection *self); @\\
|
||||
\mbox{}\verb@ void SCSetError(SConnection *pCon, int iCode);@\\
|
||||
\mbox{}\verb@ int SCGetError(SConnection *pCon); @\\
|
||||
\mbox{}\verb@/****************************** Macro ***************************************/@\\
|
||||
\mbox{}\verb@ int SCinMacro(SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int SCsetMacro(SConnection *pCon, int iMode); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* *************************** Info *************************************** */@\\
|
||||
\mbox{}\verb@ int SCGetRights(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCSetRights(SConnection *pCon, int iNew);@\\
|
||||
\mbox{}\verb@ int SCMatchRights(SConnection *pCon, int iCode);@\\
|
||||
\mbox{}\verb@ int SCGetOutClass(SConnection *self);@\\
|
||||
\mbox{}\verb@ int SCGetGrab(SConnection *pCon);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/* **************************** Invocation ******************************** */@\\
|
||||
\mbox{}\verb@ int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*************************** User Command **********************************/@\\
|
||||
\mbox{}\verb@ int ConfigCon(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||
\mbox{}\verb@ int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The functions in more detail:
|
||||
\begin{description}
|
||||
\item[SCreateConnection] creates a new connection object. Parameters to this
|
||||
call are a pointer to a server data structure, a pointer to a network
|
||||
connection object and the user rights to use in this connection. This
|
||||
also adds a new task function for this connection to the task object.
|
||||
\item[SCCreateDummyConnection] creates a dummy connection for use during
|
||||
system initialisation. Printing to a socket will be suppressed for such a connection. But the output is printed to stdout.
|
||||
|
||||
\item[SCTaskFunction] is the task function which will be registered with the
|
||||
Tasker. This function reads a new command from the command stack (if
|
||||
available) and executes it in the interpreter.
|
||||
\item[SCSignalFunction] is the signal function for the connection
|
||||
object. This function handles interrupts and the token security
|
||||
system.
|
||||
\item[SCDeleteConnection] deletes a connection object and all its data
|
||||
structures. This function will be automatically called by the tasker when
|
||||
the task function returns with a 0.
|
||||
\item[SCAddLogFile] configures the log file name into the connection object.
|
||||
If this suceeds all I/O to the connection will be logged to this file as
|
||||
well.
|
||||
\item[SCSetOutputClass] sets the output class for the connection.
|
||||
\item[SCGetOutClass] returns the output class of the connection.
|
||||
\item[SCWrite] is the most important function of SConnection. Writes the
|
||||
buffer pBuffer with output code iOut to the client. {\em All output to the
|
||||
client has to be channelled through this function!}
|
||||
\item[SCRead] reads data from the client connection into the buffer pBuffer,
|
||||
but maximum iBufLen bytes.
|
||||
\item[SCPrompt] prompts the client for a reply. But waits only for certain
|
||||
timeout period. pPrompt is the prompt for the client, pResult is the buffer
|
||||
with the client reply. Maximum iLen bytes will be copied to
|
||||
pResult. Returns true (1) on a successfull read, else 0 (false).
|
||||
\item[SCSendOK] A short cut which sends OK to the client.
|
||||
\item[SCRegister] registers a callback with the connection. Parameters are:
|
||||
The interpreter to use, the interface with which the callback was
|
||||
registered and the ID of the callback. All automatic notifications to a
|
||||
client MUST be registered with this call. When the connection is deleted all
|
||||
these callbacks will be removed as well. Otherwise a core dump is bound to
|
||||
happen.
|
||||
\item[SCUnregister] will remove all callbacks on interface pInter for this
|
||||
connection.
|
||||
\item[SCSetInterrupt] sets an interrupt on the connection.
|
||||
\item[SCGetInterrupt] retrives the current interrupt status of the
|
||||
connection.
|
||||
\item[SCSetError] sets an error code in the connection.
|
||||
\item[SCGetError] retreives the current error code on the connection.
|
||||
\item[SCinMacro] returns true if the connection is executing a tcl script,
|
||||
returns false otherwise.
|
||||
\item[SCsetMacro] sets the iMacro flag.
|
||||
\item[SCGetRights] returns the current user rights associated with the
|
||||
connection.
|
||||
\item[SCGetGrab] gets the status of the control token for this connection.
|
||||
This calls returns 0 if the connection may execute commands and 1 if another
|
||||
connection has the control token.
|
||||
\item[SCSetRights] sets the user rights for the connection to a new value.
|
||||
\item[SCMatchRights] return true (1) if the iCode matches with the user
|
||||
rights of the connection, 0 (false) otherwise. SCMatchRights also checks for
|
||||
the status of the control token. Suitable error messages are written to pCon
|
||||
if the user rights do not match.
|
||||
\item[SCInvoke] invokes pCommand in the SICS interpreter pSics for the
|
||||
connection pCon. This function also prints the executed command into
|
||||
logfiles and into the commandlog.
|
||||
\end{description}
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"conman.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ C O N N E C T I O N O B J E C T@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ This file defines the connection object data structure and the interface to@\\
|
||||
\mbox{}\verb@ this data structure. This is one of the most important SICS components.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Substantially revised from a prior version.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, September 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSCONNECT@\\
|
||||
\mbox{}\verb@#define SICSCONNECT@\\
|
||||
\mbox{}\verb@#include <stdio.h>@\\
|
||||
\mbox{}\verb@#include "costa.h"@\\
|
||||
\mbox{}\verb@#include "SCinter.h"@\\
|
||||
\mbox{}\verb@#include "network.h"@\\
|
||||
\mbox{}\verb@#include "obdes.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#define MAXLOGFILES 10@\\
|
||||
\mbox{}\verb@@$\langle$condat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#include "nserver.h"@\\
|
||||
\mbox{}\verb@@$\langle$conint {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
Reference in New Issue
Block a user