LCLS Controls

SLC-Aware IOC Design

This is a work-in-progress!! 

Debbie Rogind 11/22/04

Last Modified: 2/2/05

 

Database Input/Output Utilities

Quick Links

Introduction

Public Prototypes

Blocking

Data – Lists

Resource Management

Functional Flow

            dblist.c

            dbl.c

            dbget.c

            dbupdate.c

            dbcheck.c – DBS helper routines

Message Logging

Diagnostics

1         Scope

The following document describes the software design for the SLC-aware IOC Database Input/Output (I/O) Utilities.  The utility routines described in this document are both publicly available routines that are useful to all SLC-aware threads, as well as “helper” routines available to the database service (DBS) threads.  This document includes a description of each utility, the calling parameters, error message generated, and the include files required to use them in a thread.

2         Introduction

The database I/O utilities are re-entrant routines which allow SLC-aware IOC threads to read and store SLC supertype data that has been downloaded from the SLC Control System. The routines closely mirror some of the I/O routines in the legacy micro software. One change from the legacy code is that all of the data access (dbl*) utilities require list arguments in order to enforce list generation in a job thread’s initial setup, possible when the thread uses these for periodic updates during operations.

2.1      Background

2.2      References

See the Database Service Design document by Debbie Rogind.

Refer to General Purpose Utilities document by Diane Fairley for explanation of some common utilities used, such as slcGetJobIndexByName(), cvtToVMS() and cvtFromVMS().

2.3      Requirements

See the SLC-Aware IOC Functional Requirements document by Stephanie Allison.

3         Database Input / Output Utilities

3.1      Public Prototypes

The following section provides a quick overview of the public database access utilities available to all threads.

3.1.1      dblist.c

Threads include: dblist.h in order to gain access to routines which create and free lists containing pointers to desired data. If a thread does not dblistalloc() specifically, dblist() will. All threads must perform a dblistfree() on each list prior to exiting. Refer to Data – Lists for a list discussion.
 
vmsstat_t  dblist   (const char  * const prim_a,  
                               const char  * const unit_a,  
                               const char * const secn_a,  
                               dbheader_ts ** const dblist_pps)
 
vmsstat_t  dblistalloc  (const unsigned short bytes_in_element,  
                                      const unsigned short num_elements, 
                                      dbheader_ts ** const dbdata_pps)
 
vmsstat_t  dblistfree   (const dbheader_ts * const dbdata_or_list_ps)

3.1.2      dbl.c

Threads include: dbl.h in order to gain access to routines which read and write data of all types, including listing all units for a given primary (dblunits()). A dblget() or dblput() call must be preceeded with dblist().

 

vmsstat_t dblunits (const char  * const prim_a,  
                                dbheader_ts ** const dbdata_pps)
 
vmsstat_t  dblget   (const dbheader_ts * const dblist_ps , 
                                dbheader_ts **const dbdata_pps)
 
vmsstat_t  dblput   (const dbheader_ts * const dblist_ps,  
                                 const dbheader_ts * const dbdata_ps)

3.1.3      dbget.c

Threads include: dbget.h in order to gain access to routines to get different attributes for their data, once retrieved. Many of these routines will be called by the vxWorks/Cexp shells.

 

vmsstat_t  dbgetUnitAsString(const unsigned short unit, 
                                                   char * const unit_a)
 
char dbgetFormat (const char * const prim_a, 
                                 const char * const secn_a)
 
int dbgetWidth (const char * const prim_a, 
                           const char * const secn_a)
 
int dbgetCount (const char * const prim_a, 
                           const char * const unit_a, 
                           const char * const secn_a)
 
vmsstat_t dbgetMeta (const char * const prim_a, 
                                     const char * const unit_a, 
                                      const char * const secn_a, 
                                      char * format, 
                                      int * width, 
                                      int * count)
 
const char * const dbVersion_a dbgetVersion (void)

3.1.4      dbupdate.c

Threads include: dbupdate.h and call dbupdate() in order to update the Alpha with data previously stored via dblput(). Threads must be willing to wait in order to complete this call (refer to Updates to Alpha).

 
vmsstat_t dbupdate(const char * const jobName_a)

3.1.5      Return codes

All of the above utilities return a 4 byte unsigned VMS condition code, vmsstat_t, defined in  util/dbdef.hc or in util/micrdef.hc

3.1.6      Arguments

All device arguments (prim_a,  unit_a,  secn_a), as well as jobName_a,  are 4 chars, left justified, with blank-padding to fill out to 4 chars if necessary. “ALL*” is allowed for unit_a in dblist() and jobName in dbupdate(). Dblunits() returns a list of 4 char non-null-terminated, left justified, blank-padded unit names.

3.1.7      Blocking

3.1.7.1  Read/Write to db

The dblput() and dblget() routines block waiting for access to the database (both utilities wait on dbRWMutex).

3.1.7.2  Updates to Alpha

The dblput() routine stores the upper and lower bounds of its offset address into a dbupdateHiLo array indexed by job so that accumulated updated data for that job (or “ALL*” jobs) may be sent to the Alpha at any time by calling dbupdate(). dbupdate() blocks until the update to the Alpha is complete. The blocking time is up to 15 seconds (per job) plus accumulated blocking times for other jobs ahead of it in the queue. dblput() will also block if the calling job’s updates are currently being sent to the Alpha, as it must wait on the semaphore protecting the dbhilo update list. A slcStop() request will unblock a dblput() and/ or a dbupdate() within a second (a second is the granularity at which dbSend, the thread sending updates to the Alpha, checks its stop flag while processing data).

3.1.7.3  Valid database

The dblist(), and dblunits() routines wait at the DbdownloadEvent_ps forever if the database does not yet exist (!dbgetExists()). This causes job threads, during initial setup, to block on their dblist()/dblunits() calls until after the SLC database has been downloaded. If the database was not downloaded successfully, dbgetExists() will remain false. In this unsuccessful case, when and if the database service threads exit (via stop flag), dbHdlr, prior to termination, will release the dbdownloadEvent_ps if set, thereby unblocking all threads waiting upon it. In this case, an error is returned since dbgetExists() is still false and the threads should terminate.

 

Dblget() and dblput() check dbgetExists() and return an error when trying to access the db and it does not exist. As a precaution, dbupdate() does the same.

 

Dblist(), dblunits, dblget() and dblput() compare the dbVersion_a in the list header with the latest global dbVersion_a downloaded from the Alpha for compatibility, and log an error message if they are out of synch.

3.1.8      Data – Lists

3.1.8.1  Lists

Device threads (“Device Services” in DBS Block Diagram) manage two different kinds of lists:

1) dblist- list comprised of pointers :

·        Each pointer in list is of type dbhEntry_ts * (see dbs/dbhash.h) and points to dictionary hash table entry containing all the meta data for a particular PRIM:UNIT:SECN

·        dblist list is an output argument from dblistalloc(), dblist()

·        dblist is an input argument for dblget(), dblput

Note: in the legacy system, a dblist is comprised of primary/secondary/unit offsets (which, when added together with dbnodes[supertype], address the actual data in memory)

 

and

 

2) dbdata -list comprised of actual data:

·        units (4 char unit names)

o       output argument from dblunits(), dblget()

·        typed data

o       any type of data

o       input argument for dblput()

3.1.8.1.1   List Header Structure

Both lists (dblist and dbdata) have a header structure, dbheader_ts, which does the bookkeeping for the list, while the rest of the list is populated with the data itself. The first header field dbVersion_a is stored for later comparison against the global dbVersion_a of the database (downloaded by the ‘DXUP’ DBS message upon SLC IOC boot, IPL, or upon DBEX coming online) when accessing data. The second element of dbheader_ts, max, is the length in bytes of the array as allocated from the memory pool by dblistalloc(). The third field in dbheader_ts, cur, is set to the number of bytes of data already stored in the list (minus the dbheader size), is initialized to 0 by dblistalloc(), and is updated by the dblistAdd() helper utility as it appends each data item to the list. Dbl* utilities can be called one after another, with the same list, when it makes sense, in order to tack on data to the same list. If at any time the dbl* utility detects that the list is too short (when (cur + bytes_to_add + sizeof(dbheader_ts) ) > max), it calls dblistalloc() to replace it with the next largest list from its memory pool. A thread can also reset the cur field to 0 in order to over-write with new data after the data has been used.

 

The dbheader_ts structure is defined as:

Name

Data type

Represents

Dbheader_ts

 

DB I/O list header

dbVersion_a[8]

 

Max

Cur

dat[1]

Char

 

unsigned short

unsigned short

unsigned short

Version “stamp” at the time the list was generated; 8 bytes ASCII

Max word len of list; includes this header

Current len of list

Data items …

 

3.1.8.1.2   Macros

In addition to the utilities dblistalloc() and dblistfree(), there are macros to help with list management, such as to clear a list, and both kinds of lists (dbdata and dblist) can use these. Relevant macros patterned after the legacy code ref_c_inc:dbgetc.h, will be adapted.

3.1.8.2  Resource Management

3.1.8.2.1   SLC-aware IOC  threads

The API is flexible such that a SLC-aware IOC thread can call dblistalloc() prior to calling dblist() or dblunits(), or it can let the relevant dbl*() call take care of allocating space for a list (as long as it has a valid pointer to  pointer input argument).

 

SLC-aware IOC threads that call the public DB I/O list-based utilities are required to free:

  • All pointer lists initially created and output from calls to dblistalloc() or dblist() with the dblistfree() call.
  • All data lists created and output from calls to dblget() and dblunits().

 

3.1.8.2.2   Database Service threads

The legacy dballoc() API, and current API for dblistalloc() specifies input arguments for a) the number of elements and b) the number of bytes in the element. In order to use memory management, (the API remains the same), dblistalloc() will allocate lists in discrete sizes – small and big, using the product ( a x b ) to choose the best fit pool size. The actual bytes allocated for the list from the associated memory pool will be returned in the max field of the list. If the product (a x b) is too large to use the big list, then memory will be allocated from the heap.

 
The epics freeList facility will be used to help manage the two discrete list memory pools. The dblistalloc() initially decides from which pool to allocate based on (bytes_in_element x num_elements). If a small list later exceeds the max small list size, a big list is allocated, the small list is memcpy’ed to the big list, and the little list is freed. If the big list is exceeded, then a callocMustSucceed() is done; the big list is copied to the alloc’ed memory, max is set at (bytes_in_element x num_elements), and the big list is freed.

3.2      Functional Flow

The functional flow for each utility is very dependent upon the dictionary structure. Please reference the SLC IOC Database Service Design section on Dictionary. This section also introduces the db hash table utilities (such as dbhFind()), available by including dbhash.h.

3.2.1      dblist.c

Threads include: dblist.h in order to gain access to routines which create and free lists containing pointers to desired data. If a thread does not dblistalloc() specifically, dblist() will. All threads must perform a dblistfree() on each list prior to exiting. Refer to Data – Lists for a list discussion.

3.2.1.1  dblist()

vmsstat_t  dblist   (const char  * const prim_a,  
                               const char  * const unit_a, 
                               const char  * const secn_a,  
                               dbheader_ts **const dblist_pps):
 

dbcheckWithWait(dblist_pps)

            if (unit = ALL*)            

                        dbcheckPrim(prim_a,  dblist_pps, &ptr), return if error

                        progress linearly through units link list with dictU_ps pointers

                             progress linearly through secns list with dictS_ps pointers

                                    if secn's match:

                                                dbh_ps = dictS_ps->dictEntry

if (!(dbh_ps) || (!(dbh_ps->userPvt)), return error

else

                                                             dblistAdd(dblist_pps, 4, 1, dbh_ps), return if error

                                    if no secn's match for this unit:

                                                log an error and return now

(don't bother with the other units)

                              until secn list end

                        until unit list end

            else

dbh_ps = dbhFind(name = “primunitsecn”)

if  (!dbh_ps) || (!dbh_ps->userPvt) log error and return

else

dblistAdd(dblist_pps,  4, 1, dbh_ps), return if error

3.2.1.2  dblistalloc()

This utility allocates and initializes a data list from a freelist memory pool. The list freelist memory pools (small and big) are initialized by dbHdlr. If a requested list size exceeds the big list size, memory is allocated from the heap.
 
vmsstat_t  dblistalloc  (const unsigned short bytes_in_element,  
                                      const unsigned short num_elements, 
                                       dbheader_ts **const dbdata_pps):
 
               If (dbdata_pps = NULL) return error
               If (*dbdata_pps =NULL)
                               dblistNew()
               else
                               if dbVersion has changed, return error
                               if not enough space in list for (num_elements*bytes_in_element)              
                                              dblistEnlarge()

3.2.1.3  dblistfree()

All slc-aware IOC threads are responsible for freeing dblist and dbdata lists using this call.
vmsstat_t  dblistfree   (const dbheader_ts *const dbdata_or_list_pps):
 
               Free back to small list pool, big list pool, or heap, 
                   depending on “max” field in header 

3.2.1.4  dblistUtil Helper routines

In the file dblistUtil.c, the following helper routines assist in data list management for the public utilities contained in dblist.c.

3.2.1.4.1   dblistInitFreeList

void dblistInitFreeLists (void):

 

            Initialize the small and big free lists using the freeListLib epics facility. This routine is called upon DBS initialization.

3.2.1.4.2    dblistDelFreeLists

void dblistDelFreeLists (void):

            Remove the small and big free lists using the freeListLib epics facility. This routine is called upon DBS exit.

3.2.1.4.3   dblistAdd

vmsstat_t dblistAdd( const unsigned short bytes_in_elem,

                                   const unsigned short num_elems,

           const void *addMe_p,

dbheader_ts ** const db_pps):

 

if (!(*db_pps)) dblistalloc(), return if error

if (! addMe_p), return error

            bytes_to_add = bytes_in_elem * num_elems

            if (bytes to add > (max- (cur+sizeof(dbheader_ts)))

dblistalloc(), return if error

            end if

            copy *addMe_p to *db_ps

            cur += bytes_to_add

 

3.2.1.4.4   dblistNew

This utility is called by dblistalloc().

vmsstat_t dblistNew (const unsigned long bytes_to_allocate,

           dbheader_ts * dbdata_p):

 
               if bytes_to_allocate <  small free list size (=DBL_SZSM)
                               freeListCalloc(small free list)
                               dbdata_p->max = DBL_SZSM             
               else if  bytes_to_allocate <  big free list size (=DBL_SZBIG)
                               freeListCalloc(big free list)
                               dbdata_p->max = DBL_SZBIG            
               else callocMustSucceed (1, bytes_to_allocate) (=get from heap)
                               dbdata_p->max = bytes_to_allocate      
 
               dbdata_p->dbVersion_a = dbgetVersion()

 

3.2.1.4.5   dblistEnlarge

This utility is called by dblistalloc().

vmsstat_t dblistEnlarge (const unsigned long bytes_to_allocate,

                                        dbheader_ts * dbdata_ps)  :

 

Allocate next biggest list:
               If small list – get big list – freeListFree(small list)
               If big –     callocMustSucceed(bytes_to_allocate)
                If heap list – get bigger heap list
               Memcpy smaller list to larger list; keep previous list’s dbVersion_a,
                                              and cur; adjust max

3.2.2      dbl.c

Threads include: dbl.h in order to gain access to routines which read and write data of all types, including listing all units for a given primary (dblunits()).  A dblget() or dblput() call must be preceeded with dblist().

3.2.2.1  Dblunits()

vmsstat_t dblunits (const char  * const prim_a , 
                                dbheader_ts **const dbdata_pps):
 

dbcheckWithWait(dbdata_pps), return if error

dbcheckPrim(prim_a,  dbdata_pps, &dbhEntry_ps), return if error

progress linearly through units link list

            for each unit in linked list,

                        dblistAdd(dbdata_pps, 4, 1, name_a),

return if error

until the end of all units

3.2.2.2  Dblget()

vmsstat_t  dblget   (const dbheader_ts * const dblist_ps , 
                                dbheader_ts **const dbdata_pps):
 

dbcheck(dbdata_pps), return if error

dbcheckHeader(dblist_ps), return if error

For each ptr in dblist:

            Access dbhEntry_ts * ptr from *dblist_ps

                        Copy meta data pointed to by dbhEntry_ts * into local var, including:
                              format, width, count, supertype num (supn), offset ptr (sptr)
                        Lock dbRWMutex
                        Memcpy data from sbnode[supn] + sptr into **dbdata_pps, 
                                              size= width x count
                        Unlock dbRWMutex
                        cvtFromVMS(format, width, count, dbdata_pps, dbdata_pps) 
                         Advance dblist_ps ptr, dbdata_pps ptr, etc
            until end of all ptrs.

3.2.2.3  dblput()

vmsstat_t  dblput   (const dbheader_ts * const dblist_ps , const dbheader_ts * const 
               dbdata_ps):
 

dbcheckHeader(dbdata_pps), return if error

dbcheckHeader(dblist_ps), return if error

For each ptr in dblist:

            Access dbhEntry_ts * ptr from *dblist_ps

                        Log an error and return if going beyond cur in dbdata_ps

                        Copy meta data pointed to by dbhEntry_ts * into local var, including:
                              format, width, count, supertype num (supn), offset ptr (sptr)

                        Form vms_ptr to ST data using sbnode[supn] + sptr

                        Lock dbRWMutex
                        Convert native data to VMS, using meta data above:
                               cvtToVMS(format, width, count, dbdata_ps, vms_ptr),  
                        Unlock dbRWMutex
                        Lo_sptr = sptr; hi_sptr = lo_sptr + ( width x count )
                        Call dbupdateHiLo(job, supn, hi_sptr, lo_sptr)
                              to enter offset pair into job’s dbupdateHiLo array
            until end of all ptrs.

3.2.3      dbget.c

Threads include: dbget.h in order to gain access to routines to get different attributes for their data, once retrieved.

3.2.3.1  dgetUnitAsString()

vmsstat_t  dbgetUnitAsString(const int2u int_unit, char * const unit_a):
 
               Convert integer unit to its ASCII representation : 
               4-char, non null-terminated, blank padded (if necessary), left justified. 
               Return error if unit > 9999 

3.2.3.2  dbgetFormat()

char dbgetFormat (const char * const prim_a, const char * const secn_a):
               

            if (SUCCESS (dbgetMeta(prim_a, ALL*, secn_a, format, width, count))

                        return ( format )                       

           else return (blank)

3.2.3.3  dbgetWidth()

int dbgetWidth (const char * const prim_a, const char * const secn_a):
 

            if (SUCCESS (dbgetMeta(prim_a, ALL*, secn_a, format, width, count))

                        return ( width )

            else return (-1)

3.2.3.4  dbgetCount()

int dbgetCount (const char * const prim_a, const char * const unit_a, 
                           const char * const secn_a):
 

            if (SUCCESS (dbgetMeta(prim_a, unit_a, secn_a, format, width, count))

                        return ( count )             

            else return (-1)

3.2.3.5  dbgetMeta()

This routine returns meta data about a certain prim/unit/secn (unit can be ALL*). This routine could be expanded to return all meta data (supn, sptr) as well.

 

vmsstat_t dbgetMeta (const char * const prim_a, const char * const unit_a, const char * 
               const secn_a, char * format, int * width, int * count):
 
                                       if (strncmp(unit_a, ALL*) == 0)

                                              dbh_ps = dbhFind(name = “prim”)

                                              if  (!dbh_ps ) return error of invalid primary name
                                              if (! dbh_ps->usrPvt) return error of no units
 
                                               firstUnit_a = dbh_ps->userPvt->listUnits.next->name_a
                                              dbgetCatPUSName(prim_a, firstUnit_a, secn_a,
                                                              namePUS_a)
                                       else  /* known unit number */
                                              dbgetCatPUSName(prim_a, unit_a, secn_a,
                                                              namePUS_a)
                                        dbh_ps = dbhFind(namePUS_a)
                                        if  (dbh_ps != NULL) || (dbh_ps->usrPvt != NULL)
                                                             format = dbh_ps->usrPvt->format
                                                             width =  dbh_ps->usrPvt->width
                                                             count = -1  /* flag unknown, for ALL* case */
                                         else return error of invalid secondary 
 

3.2.3.6  dbgetVersion()

const char * const dbVersion_a dbgetdbVersion (void):
               Returns pointer to global value dbVersion_a 

3.2.3.7  dbgetCatPUSName()

void dbgetCatPUSName(const char * prim_a,

                                         const char * unit_a,

                                         const char * secn_a,

                                         char * primUnitSecn_a) :

 

Concatenate the 4 char each input arguments prim_a, unit_a, secn_a, into 12 char string primUnitSecn_a.

3.2.3.8  dbgetBlkPad()

void dbgetBlkPad (char * name_pa) :

           

            Replace first null terminator character found and all chars thereafter (to right) with blank pads.

3.2.4      dbupdate.c

Threads include: dbupdate.h and call dbupdate() in order to update the Alpha with data previously stored via dblput(). Threads must be willing to wait in order to complete this call (refer to Updates to Alpha).  

(Note: This section will not be updated until March 2005)

3.2.4.1  dbupdate()

vmsstat_t dbupdate(const char * const jobName_a):
 

if (jobName != "ALL*")

                        job_id = slcGetJobIndexByName(jobName_a);

                        if (job_id < 0 ) log an error and return

                        status = dbupdateSend(job_id, 1=wait)

            else

                        status = OK

                        for job_id = 0 to N_JOBS

                                    if ( dbupdateSend(job_id, 0=no wait) is not OK ) update status

                        end

            return status

3.2.4.2  dbupdateUtil Helper routines

dbupdateUtil.c is comprised of helper routines which the database service utilities call.

(Note: This section will not be updated until March 2005)

3.2.4.2.1   dbupdateSend

vmsstat_t dbupdateSend(int jobId, unsigned short supn,  epicsBoolean waitFlag):

 

if (dbupdate hilo list [jobId] is not empty):

                        msg.id = DB_UPDATE

                        msg.job = jobId

                        send msg to dbSend, return if error

                        if (waitFlag)

                                    wait on dbAckEvent[jobId]

                                    return dbAckStatus[jobId]

3.2.4.2.2   dbupdateHiLo
vmsstat_t dbupdateHiLo(int jobId, unsigned short supn, unsigned long hiSptr, 
                               unsigned long loSptr):

 

            access dbupateHiLo[supn, jobId]

            if hiSptr/loSptr update is near to DBUP_MAXLOOK items (?), combine

            if list is already full, dbudpateHiLoCompress(jobId, supn, 1)

 

            (adapt algorithm in legacy rmx_dbs: dbmain.c – dbhilo_upate() )

 

3.2.4.2.3   dbupdateHiLoCompress

vmsstat_t dbupdateHiLoCompress (int jobId, epicsBoolean combine):

 

            use same algorithm in legacy rmx_dbs: dbmain.c - microdbsendc()

3.2.5      dbcheck.c – DBS helper routines

Dbcheck.c is comprised of helper routines which the database service utilities call.

3.2.5.1  dbcheckWithWait()

This routine is called by utilities dblist(), and dblunits() in order to wait for the database to be downloaded, if necessary.

 

vmsstat_t dbcheckWithWait(const dbheader_ts ** const db_pps):

 

if (!slcGetDbExists()) {

epicsEventMustWait( dbdownloadEvent_ps)}

            iss= dbcheck(db_pps)

            return iss

3.2.5.2  dbcheck()

This routine is called directly by the utilities (dblget(), dblput(), dbcheckWithWait()) who do not need to wait on the database to be downloaded.

 

vmsstat_t dbcheck(const dbheader_ts ** const db_pps):

 

if (!db_pps)  log a message and return an error

            iss = dbcheckHeader(*db_pps), return if error

            iss = dbcheckExists()

return iss

3.2.5.3  dbcheckHeader()

This routine is called by dbcheck() to check a list’s header values, thereby checking the integrity of the list itself.

 

vmsstat_t dbcheckHeader(const dbheader_ts * const db_ps):

 

            if (!db_ps) log a message and  return (iss) error

            if (!dbcheckExists()) return (iss) an error

            if (cur > max) log a message and return (iss) an error

            iss = dbcheckVersion( db_ps->dbVersion_a)

            return iss

3.2.5.4  dbcheckPrim()

This routine is called to verify that a primary entry exists, and to allocate space for a list, if it hasn’t been allocated already. This routine is called by utilities (dblist() and dblunits()) whose output argument is a list.

 

vmsstat_t dbcheckPrim(const char * const prim_a,

                            dbheader_ts ** const db_pps,

                dbhEntry_ts ** dbhEntry_pps):

 

            if (!db_pps) || (!dbhEntry_pps) log error and return

*dbhEntry_pps = dbhFind(prim_a), log an error and return if ptr is zero

            if ( !(*db_pps)) {

iss = dblistalloc(1, default byte size, db_pps) ,}

return iss

 

Note: dblistalloc() will allocate a small list buffer from the small free list to satisfy above parameters.

3.2.5.5  dbcheckExists()

This utility returns an error if the database does not exist.

vmsstat_t dbcheckExists (void):
 
               if (!slcGetDbExists())
                              return (iss) an error = DB_NODATA?

3.2.5.6  dbcheckVersion()

This utility returns an error (DB_BADMAJOR or DB_BADMINOR?) if the version contained in the list header (input argument) does not match the current DBEX dbVersion global value.

 

vmsstat_t dbcheckVersion(const char * dbVersion_a):
 
               Returns error if (strncmp( dbVersion_a, dbgetVersion(), 8) != 0 )

 

3.2.6      Message Logging

(Note: This section will not be updated until March 2005)

All dbl* utilites will return an error if the db does not exist and log a message to indicate the get or put attempt when database did not exist.

 

The dbcheckVersion() utility logs a message prior to returning false, or 0,  meaning current db version is not in synchronization with the version of db when the list was formed.

 

A dblist() of either non-existent primary, unit, or secondary returns an error, except if unit = ALL*.  (Thus, a mis-spelled device argument will result in an error. A dbunits() of non-existent primary returns an error.)

 

An invalid list for dblist(), dblunits, dlput(), dblget() logs an error message.

 

3.2.7      Diagnostics

TBD