Caput with callback does not notify failure

Bug #1781874 reported by Michael Abbott
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Confirmed
Undecided
Unassigned

Bug Description

If caput with callback is used to write to a PV which rejects the caput then success is returned.

An example exchange (captured with wireshark and decoded with the caproto plugin) follows:

Asynchronous

Client -> IOC
    Command: Write (0x0004)
    Payload Size: 8
    DBR Type: DOUBLE (6)
    Data Count: 1
    Operation ID: 1
    Server Channel ID: 519
    Value: 0

IOC -> Client
    Command: Error (0x000b)
    Payload Size: 48
    Data Type: 0x0000
    Data Count: 0
    Client Channel ID: 1
    Status: ECA_PUTFAIL (0x000000a0)
    Channel Access
        Command: Write (0x0004)
        Payload Size: 8
        Data Type: 0x0006
        Data Count: 1
        Param 1: 0x00000207
        Param 2: 0x00000001
    Error Message: TS-DI-TMBF-02:MEM:CAPTURE_S

Synchronous

Client -> IOC
    Command: Write Notify (0x0013)
    Payload Size: 8
    DBR Type: DOUBLE (6)
    Data Count: 1
    Operation ID: 3
    Server Channel ID: 520
    Value: 0

IOC -> Client
    Command: Write Notify (0x0013)
    Payload Size: 0
    DBR Type: DOUBLE (6)
    Data Count: 1
    Operation ID: 3
    Status: ECA_NORMAL (0x00000001)

The code paths in the server for synchronous and asynchronous caput processing are very different.

Note that this bug has an impact on bug #1741844.

Tags: caput
Revision history for this message
Michael Abbott (michael-abbott) wrote :

No, this is not exactly a duplicate. In particular, this bug report is actually reporting a deficiency in the CA implementation of the return from Write Notify, whereas #1741844 is reporting a problem with the caput command line tool.

Clearly these two reports can be merged, as there is a common underlying issue, but the conversation in #1741844 completely misses the fact that the server side implementation of CA is failing to report completion failure.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

To be clear. Your issue is ECA_NORMAL in the Write Notify case? This is write_notify_action() vs. write_action() in camessage.c. Can you say which Base version(s) are involved. write_notify_action() changed quite a lot from 3.14 -> 3.15.

If it's >=3.15 then I think I see a problem where the status is being dropped.

Revision history for this message
Michael Abbott (michael-abbott) wrote :

Alas, I'm only able to report against 3.14 at the moment.

Revision history for this message
Michael Abbott (michael-abbott) wrote :

Sorry, forgot to actually answer your question: yes, I'm reporting that Write Notify returns ECA_NORMAL even though the record processing step has rejected the put (by returning the appropriate error code from the record process function).

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> If it's >=3.15 then I think I see a problem where the status is being dropped.'

Scratch that. There was an indirection which I didn't notice right away.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

The return of dbProcess() is (and was) being ignored in dbNotify.c (used by CA put w/ callback, but is checked in dbPutField() which is used by CA put w/o callback.

3.14

https://github.com/epics-base/epics-base/blob/d3bcf5737fb9a627c82d3862aa14e565d4fbf88e/src/db/dbNotify.c#L233

7.0 (also >=3.15)

https://github.com/epics-base/epics-base/blob/5c6d275001c02c9ff818d0a7029eb7685360f072/modules/database/src/ioc/db/dbNotify.c#L264

Revision history for this message
Andrew Johnson (anj) wrote :

@MD: We do have some tests for dbNotify in the base-3.16 and 7.0 trees; the tests for the input record types in src/std/rec/test/asynSoftChannel.* check the operation of the soft callback device supports which use dbNotify to do a processGet on the INP link target. Unfortunately though the target record used is a subRecord, which might seem ideal for testing this condition except that its process() routine always returns 0 no matter what the sub returns. Same for the aSub, and for various other record types as well.

The return value from process() has always been hard to work out how to use; if record A forward links to B and B's process() returns an error, should A's process() return that error code? If B is asynchronous and it only returns an error from the async-completion call to process() though, the error would go elsewhere... What to do with the status values from all the INP links that are PP so their process() routines are also called?

I have a small and simple change that might fix this, but I haven't worked out how to test it yet.

Changed in epics-base:
status: New → Confirmed
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> The return value from process() has always been hard to work out how to use

Agreed, though dbProcess()!=0 seems a good place to start. Additionally,
maybe checking whether the targeted record has INVALID_ALARM after all processing
is complete? Alarms are the error propagation tool of choice in processing chains.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.