This document describes in detail the system design of netmaintain, a software system for the management and tracking of computer inventory (Sun workstations) at Rice University. In addition to this document, refer to the following for more information:
The purpose of this document is to provide a detailed description of the system leading to actual implementation. The discussion is divided into the following sections:
The netmaintain system is designed for tracking and taking inventory of networked workstations, and the software provides a user-friendly interface to collect, analyze and store the relevant information. To achieve these functionalities, the system is composed of the following subsystems:
Relational Database: Server and Schema Design
With the database server in place (msqld), the client application is built by writing embedded SQL programs in C++ using the API provided by mSQL (see manual). The design of the client application with embedded SQL is described in the later sections.
Ideally, in the Netmaintain database, each table contains only a subset of all the attributes of the netmaintain relation scheme. In order to process queries it might be necessary to do relational joins of the tables
HOWEVER, because of the customers request, regardless of the functional dependencies present in the database scheme (i.e. updating the value of a particular field does not imply that all occurrence of this field must be updated), the schema is designed to consist of a single table ONLY containing all the attributes. Essentially, this schema defines a single relation for the netinfo relational scheme.
The following table definitions are written in mSQL syntax. They are executable at the msql terminal monitor.
"catalog" table that lists the attributes to be found in each relation. This is just for internal bookkeeping and is really not used in any queries. This was provided to allow flexibility in the future when additional fields are to be included in the database: adding new fields amounts to creating new tables with which joins queries are performed.
create table catalog (
attrib_name char(20) primary key,
r_table char(20)
) \p\g
"nets" table contains information of the network topology at the topmost level at Rice University. Again this is not directly used in any of the queries since the same information is NOW duplicated in the 'basic_info' table.
create table nets ( net_ip_addr char(30) primary key, net_name char(30) ) \p\g
"basic_info" table that stores all the results obtained either thru a polling or as the result of a user edit operation an any and all of the attributes
create table basic_info (
mach_name char(30),
mach_ip_addr char(30) primary key,
status char(30),
class char(30),
parent char(30),
ossystem char(30),
mailer char(30),
memory char(30),
disk char(100),
tape char(30),
printer char(30),
cdrom char(30),
floppy char(30),
frame_buffer char(30),
location char(30),
contact_name char(30),
phone char(30),
notes char(200),
date_modified char(30)
) \p\g
"personnel" table contains information on the `administrative' people responsible for the maintainence of the specific network entities. The contact names (of above = 'tech' contact person) are assumed unique and are designated as primary keys for this relation. Again for reasons explained above this is actually not used. Currently when adopted this table will for each `tech' contact name a list of administrative name(s) will result. **** Right now this table is irrelevant ****
create table personnel ( person_name char(30) primary key, phone_number char(30), admin_name char(200), admin_phone char(200) ) \p\gReturn to Table of Contents
Client Application (netmaintain): Tcl Front-End
The Tcl/Tk front-end provides a user-friendly interface to view the contents of, and interact with, the database. The subsystem is written for use with Tcl 7.4 and Tk 4.0.
The following design issues are discussed:
The netmaintain executable, when run in GUI mode, calls the proper functions to include tcl/tk scripts and then sources the file netmaintain_GUI.tcl. This file sources the rest of the necessary files. When these files are moved, modify the following:
This pollID is passed back into NCFuncs so that the C code "knows" which set of information to use.
Because one proc creates a window and then finishes, all this data must be global. This could create name conflicts between windows or name pollution as windows get created and deleted.
To solve this problem, for each window requiring storage we create one global array. If the window is called "toplevelFoo" then the toplevelFoo.storage global array is created. Elements in this array store the information. For example, toplevelFoo.storage(pollID) holds the pollID of a window. Then when a toplevel is destroyed, we do not call the Tk proc destroy directly. Instead we call the proc Ndestroy which first unsets the array (if it exists) and then calls destroy.
For one entry, the user types a string consisting of: tabs, the substring OR, *, ?, and other (regular) characters.
A tab means "AND". All "OR"s are logically grouped within "AND"s.
'*' and '?' are GLOB-style (replacing 0 or more characters and 1 character respectively)
A string of characters, *, and ? matches a field in the database if the string matches any tab-delimited subfield of the field.
mSQL uses % for * and . for ? so these replacements are made (and actual . and % characters are replaced with \. and \%.
The actual conversion is best seen by example (\t for tab):
A query of the field "Name" and the string "foo" becomes:
WHERE Name like 'foo' OR Name like '%\tfoo'
OR Name like 'foo\t%'
OR Name like '%\tfoo\t%'
A query of the field "Memory" and the string "foo \t bar OR baz" becomes:
WHERE Memory like 'foo' OR Memory like '%\tfoo'
OR Memory like 'foo\t%'
OR Memory like '%\tfoo\t%'
WHERE Memory like 'bar' OR Memory like '%\tbar'
OR Memory like 'bar\t%'
OR Memory like '%\tbar\t%'
OR Memory like 'baz'
OR Memory like '%\tbaz'
OR Memory like 'baz\t%'
OR Memory like '%\tbaz\t%'
Notice that the \t (an AND) causes 2 query strings. The NCFunc will do the AND of thse 2 queries.
If the window is not for an "Edit Group", the IP field must pass the NipCheck proc (meaning it has the form 255.255.255.255). For "Edit Group", the user cannot edit the IP field.
If the Name or Parent field does not pass the NmachCheck proc the user is warned and may cancel. However, machine form of machine.name.something is not strictly enforced.
IF the window is not an "Edit Group" and not a "Create" THEN
IF the IP field is no longer its original value THEN
1. The update will make a new record in the database.
2. The user must choose to either delete the record with
the original IP or leave it in the database.
ELSEIF
The IP value no longer exists in the database THEN
The user must choose to either create a new record or
cancel.
IF the window is a "Create" THEN
IF the IP value already exists in the database THEN
The user must choose to either replace the existing record
or cancel.
IF the window is not a "New" THEN
IF the relevant portion of the database has been modified
since the window was created THEN
The user must choose to either update the database
anyway or cancel.
Return to Table of Contents
C++ Implementation of Client Application and Database Access
While Tcl/Tk are used to implemented the GUI front-end, interaction with the database server and the process of automatic polling need to be implemented by C/C++ functions. Specifically, C functions are to be written to interface with the Tcl interpreter (the NCFuncs). These routines further call on other lower-level routines for database interaction, automatic polling, etc. implemented in C++. Descriptions of these files, with the C++ declaration (in *.h files) and implementation (in *.cc files) are presented below.
autopoll.h and autopoll.cc contain the declaration and implementation of the class AutoPollInfo which provides the facilities for specifying the time for automated network polling.
config.h and config.cc contain the declaration and implementation of the Config class which manages the initial set-up for a particular session of netmaintain.
database.h and database.cc contain the declaration and implementation of the Database class. This class provides the low-level functions of establishing connections with the server, sending SQL queries, processing query results and packaging them to higher level routines.
errorlog.h and errorlog.cc contain declaration and implementation of the class ErrorLog which provides facilities for output of error messages during program execution.
fieldmap.h and fieldmap.cc contain the declaration and implementation of the FieldMap class. This class holds the names of the fields at the appropriate indices. The information is obtained only once from the Database object upon instantiation of the class. The information about the fields in the database table is then sent to the Tcl caller, which keeps track of this information for the entire span of program execution.
fileio.h and fileio.cc contain declaration and implementation of basic facilities for file I/O, as in the case of reading in system configuration files.
list.h and list.c contain the declaration and implementation of the List class, which dynamically adjusts its size as elements are added (string). This is primarily a utility for the rest of the software implementation.
machinerec.h and machinerec.cc contain the declaration and implementation of the MachineRecord class. This class is used to keep track of information about a particular machine, either from interacting with the database or from polling the network.
netcode.h and netcode.cc contain the declaration and implementation of the functions associated with getting information about a machine over the network.
netmaintain.h and netmaintain.cc contain the declarations of all global variables for the entire program.
netstructure.h and netstructure.cc contain the declaration and implementation, respectively, for the class NetStructure, and its supporting classes IPadd and NetRange. These read from the root config file, which describes net and subnets, and builds a concept of the net structure. These classes are used to determine which DB records are subnets and in polling the network.
tclfuncs.h and tclfuncs.cc contain the declarations and implementations of the C functions called by Tcl (see header file for details on function prototypes). These functions are registered as NCFunc commands in Tcl; they generally perform operations on the database and control the passing of info between the DB and Tcl.
main.cc contains the main(argc,argv) function for starting up Tcl and initializing the Tcl interpreter. The main() function determines whether a GUI front-end is run or a command-line mode is run, by checking the command line arguments to the program. It also contains the function Tcl_AppInit which registers the custom commands (as NCFuncs with the Tcl interpreter..
rootinfo.ntm is user-editable file which contains the current structure of the Rice campus network. The contents of the file is read by the program to determine network addresses and names for polling. performs complete polling.
Gathering Information Over the Network
During polling, certain information about the network entities (individual machines) need to be obtained. This is accomplished via low-level C++ routines for starting processes running C-shell and AWK scripts for getting such information as IP address, mail exchanger, etc. In addition to the C++ source code (netcode.h and netcode.cc ), several scripts are written for the probing functions:
NMScript-IPlookup.awk and NMScript-IPlookup.csh
NMScript-MXlookup.awk and NMScript-MXlookup.csh
NMScript-Namelookup.awk and NMScript-Namelookup.csh
NMScript-OSlookup.awk and NMScript-OSlookup.csh