EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Adding error msgs to dbAccess.c
From: Bruce Hill <[email protected]>
To: "Allison, Stephanie" <[email protected]>
Cc: Techtalk <[email protected]>
Date: Thu, 13 Jun 2013 16:03:15 -0700
Hi Stephanie,
I liked your suggestion, so I updated my patch to include checks
to set READ_ACCESS_ALARM and WRITE_ACCESS_ALARM as
appropriate.

Regards,
- Bruce

On 6/12/2013 4:14 PM, Allison, Stephanie wrote:
Hi Bruce,

Regarding the problem where a record is tagged LINK INVALID when it tries to write to a read-only PV (same being true with trying to read from a no-read-access PV), instead of a message, I think both dbAccess.c and dbCa.c could be smart enough to check for the specific bad access status and set the PV to WRITE_ACCESS INVALID (or READ_ACCESS INVALID) instead of the more generic LINK INVALID.

Thanks for reminding me that a LINK status on a record does not necessarily mean some INP or OUT link with MS has an abnormal severity.  Can also mean bad status from dbGet and dbPut and will show up even if the INP or OUT is NMS.

Stephanie Allison

-----Original Message-----
From:[email protected]  [mailto:[email protected]] On Behalf
Of Bruce Hill
Sent: Friday, June 07, 2013 8:12 PM
To: Techtalk
Subject: Adding error msgs to dbAccess.c

We recently had an issue where an IOC that had been
working for over a year stopped working.   On investigation,
we found that one of the PV's was in a LINK INVALID state.

We finally traced that to dbAccess.c, and from there to a
gateway configuration issue in which a missing hostname
made a PV read-only that the IOC needed to write to.

I've created a small patch for 3.14.12 dbAccess.c that adds calls
to recGblRecordError where recGblSetSevr is being called
to set LINK INVALID due to a CA put error, along with a
couple of other places where SEVR is set w/o any error msg.
This would have saved us long hours of debugging if it
had been in place earlier, so I thought it might be worth
adding to base.

Thanks,
- Bruce

--
Bruce Hill
Member Technical Staff
SLAC National Accelerator Lab
2575 Sand Hill Road M/S 10
Menlo Park, CA  94025

Index: dbCa.c
===================================================================
--- dbCa.c	(.../import/ANL/epics/base/base-3.14.12.3/src/db)	(revision 12907)
+++ dbCa.c	(.../trunk/pcds/epics/base/current/src/db)	(revision 12907)
@@ -333,6 +333,7 @@
     long   status = 0;
     short  link_action = 0;
 
+    assert(plink->type == CA_LINK);
     assert(pca);
     /* put the new value in */
     epicsMutexMustLock(pca->lock);
@@ -411,6 +412,26 @@
     return pca->isConnected;
 }
 
+int dbCaHasReadAccess(const struct link *plink)
+{
+    caLink *pca;
+
+    if (!plink || plink->type != CA_LINK) return FALSE;
+    pca = (caLink *)plink->value.pv_link.pvt;
+    if (!pca || !pca->chid) return FALSE;
+    return pca->hasReadAccess;
+}
+
+int dbCaHasWriteAccess(const struct link *plink)
+{
+    caLink *pca;
+
+    if (!plink || plink->type != CA_LINK) return FALSE;
+    pca = (caLink *)plink->value.pv_link.pvt;
+    if (!pca || !pca->chid) return FALSE;
+    return pca->hasWriteAccess;
+}
+
 #define pcaGetCheck \
     assert(plink); \
     if (plink->type != CA_LINK) return -1; \
Index: dbCa.h
===================================================================
--- dbCa.h	(.../import/ANL/epics/base/base-3.14.12.3/src/db)	(revision 12907)
+++ dbCa.h	(.../trunk/pcds/epics/base/current/src/db)	(revision 12907)
@@ -40,6 +40,8 @@
 #define dbCaPutLink(plink, dbrType, pbuffer, nRequest) \
     dbCaPutLinkCallback((plink), (dbrType), (pbuffer), (nRequest), 0, 0)
 epicsShareFunc int dbCaIsLinkConnected(const struct link *plink);
+epicsShareFunc int dbCaHasReadAccess(  const struct link *plink);
+epicsShareFunc int dbCaHasWriteAccess( const struct link *plink);
 
 /* The following are available after the link is connected*/
 epicsShareFunc long dbCaGetNelements(const struct link *plink,
Index: dbAccess.c
===================================================================
--- dbAccess.c	(.../import/ANL/epics/base/base-3.14.12.3/src/db)	(revision 12907)
+++ dbAccess.c	(.../trunk/pcds/epics/base/current/src/db)	(revision 12907)
@@ -579,6 +579,7 @@
 		if (precord->stat==SCAN_ALARM) goto all_done;
 		if (precord->lcnt++ !=MAX_LOCK) goto all_done;
 		if (precord->sevr>=INVALID_ALARM) goto all_done;
+		recGblRecordError(status, precord, "Active scan count exceeded!");
 		recGblSetSevr(precord, SCAN_ALARM, INVALID_ALARM);
 		monitor_mask = recGblResetAlarms(precord);
 		monitor_mask |= DBE_VALUE|DBE_LOG;
@@ -886,7 +887,14 @@
 
         status=dbCaGetLink(plink,dbrType,pbuffer,&stat,&sevr,pnRequest);
         if (status) {
-            recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
+        	struct dbCommon *psource = plink->value.pv_link.precord;
+			if ( !dbCaIsLinkConnected( plink ) ) {
+				recGblRecordError(status, psource, "dbCaGetLink error, link not connected!");
+				recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
+			} if ( !dbCaHasReadAccess( plink ) ) {
+				recGblRecordError(status, psource, "dbCaGetLink error, no read access!");
+				recGblSetSevr(psource, READ_ACCESS_ALARM, INVALID_ALARM);
+			}
         } else {
             inherit_severity(pcalink,precord,stat,sevr);
         }
@@ -920,16 +928,28 @@
                 pdest->rpro = TRUE;
             } else { /* otherwise ask for the record to be processed*/
                 status = dbScanLink(psource, pdest);
+				if (status) {
+					recGblRecordError(status, psource, "Error processing record via PROC field!");
+					recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
+				}
             }
         }
-        if (status)
-            recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
     } else if (plink->type == CA_LINK) {
         struct dbCommon *psource = plink->value.pv_link.precord;
 
         status = dbCaPutLink(plink, dbrType, pbuffer, nRequest);
-        if (status < 0)
-            recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
+        if (status < 0) {
+			if ( !dbCaIsLinkConnected( plink ) ) {
+				recGblRecordError(status, psource, "dbCaPutLink error, link not connected!");
+				recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
+			} if ( !dbCaHasReadAccess( plink ) ) {
+				recGblRecordError(status, psource, "dbCaPutLink error, no read access!");
+				recGblSetSevr(psource, READ_ACCESS_ALARM, INVALID_ALARM);
+			} if ( !dbCaHasWriteAccess( plink ) ) {
+				recGblRecordError(status, psource, "dbCaPutLink error, no write access!");
+				recGblSetSevr(psource, WRITE_ACCESS_ALARM, INVALID_ALARM);
+			}
+		}
     } else {
         cantProceed("dbPutLinkValue: Illegal link type");
     }

References:
Adding error msgs to dbAccess.c Bruce Hill
RE: Adding error msgs to dbAccess.c Allison, Stephanie

Navigate by Date:
Prev: RE: Horner PLC %T readout Mark Rivers
Next: Looking for an network scope (with epics driver!) Emmanuel Mayssat
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: Adding error msgs to dbAccess.c Allison, Stephanie
Next: Is there any plugins or modules for Gaussian fitting? Yingbing Yan
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·