Merge ~dirk.zimoch/epics-base:info_fields into ~epics-core/epics-base/+git/epics-base:3.16
- Git
- lp:~dirk.zimoch/epics-base
- info_fields
- Merge into 3.16
Status: | Merged |
---|---|
Merge reported by: | Andrew Johnson |
Merged at revision: | 4b2e1597e4fe8daf2c0d4e3acca8cf8773bb95ad |
Proposed branch: | ~dirk.zimoch/epics-base:info_fields |
Merge into: | ~epics-core/epics-base/+git/epics-base:3.16 |
Diff against target: |
150 lines (+64/-1) 7 files modified
documentation/RELEASE_NOTES.html (+5/-0) src/ioc/db/dbIocRegister.c (+7/-0) src/ioc/db/dbTest.c (+21/-0) src/ioc/db/dbTest.h (+2/-0) src/ioc/db/test/dbStaticTest.db (+1/-1) src/ioc/dbStatic/dbStaticLib.c (+26/-0) src/ioc/dbStatic/dbStaticLib.h (+2/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Johnson | Approve | ||
Review via email:
|
Commit message
Description of the change
Allows read access to info fields from Channel Access and EPICS database.
Provides a function to list info fields, optionally filtering for field names.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ralph Lange (ralph-lange) wrote : | # |
I'm with Andrew on this.
Publishing something on the network that was explicitly and documented IOC private ... that would be a major change for info items.
Admittedly there has been more than one moment where I wished these items were visible across CA. They often carry information that might be important when debugging, and IOC consoles are often not easily accessible (at least not in production systems).
Maybe we should rather introduce a second type of info item (pubinfo?) that is known to be accessible through CA (read-only? read/write?) and might have more restrictive naming rules.
Hm. That would be half the way to supporting by-instance fields in records, wouldn't it?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
> I wish you hadn't combined these two different features into one merge
> request. I'm Okay with adding iocsh command(s) to find and list info items,
> but something in me doesn't like the idea of making items visible over the
> network, so I'm going to have to be persuaded to accept that part.
No problem. I can split it.
> There are several reasons that come to mind:
>
> * Field and attribute names must be valid C identifiers; info item names have
> no such restrictions, and an informal standard has developed that suggests
> they should take the form "<subsystem>
> "asyn:FIFO", "Q:group", but nothing enforces this.
At the moment almost everthing except [{$ should work. Spaces probably won‘t work too. I need to test periods.
> * Searches for info items are linear, so slow (searches for record names use a
> hash table, field names use a binary search; admittedly attribute name
> searches are linear).
The search is done only once at connection time. And I don‘t think that records have a lot of info fields (at the moment). But I can probably optimize if this is an issue.
> * Sites would have to add support for info items to their IRMIS/Channel
> Finder/CA Name Server/PV Database etc. or they risk not being able to know for
> sure whether a specific channel name exists or not.
Yes, if they want to have them „public“.
> * Up to now info items have been private to the IOC, so could be used to hold
> semi-secret information.
Security by obscurity? I would rather consider a ca security solution.
I had primalrily remote debugging in mind.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
> I'm with Andrew on this.
>
> Publishing something on the network that was explicitly and documented IOC
> private ... that would be a major change for info items.
Yes, it is. It is a new debug feature. But I understand the security concerns.
What about a contol variable?
Note that info fields cannot shadow real fields.
>
> Admittedly there has been more than one moment where I wished these items were
> visible across CA. They often carry information that might be important when
> debugging, and IOC consoles are often not easily accessible (at least not in
> production systems).
That was the idea.
> Maybe we should rather introduce a second type of info item (pubinfo?) that is
> known to be accessible through CA (read-only? read/write?) and might have more
> restrictive naming rules.
I don‘t agree. The goal was to read the info for debugging.
I will see what‘s possible with channel access secutity.
> Hm. That would be half the way to supporting by-instance fields in records,
> wouldn't it?
<evil-grin> Exactly what I was thinking. </evil-grin>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
https:/
What would per-instance fields be used for, and could they be read-write? Should they support monitor updates? Do server-side filters work with them? Are they string only, long-string only, or allow other data types too? What are the use cases which we can't easily handle another way?
I don't think we should morph info items into per-instance fields without considering the above questions first, so I'm inclined to reject (that part of) this proposal for now.
I'm also concerned about the field namespace getting filled up (it's already pretty busy). I note though that there are no records in Base or synApps that use the field name 'info', and I see no reason why we couldn't introduce hierarchy into the field name, so with Ralph's suggestion we might have channel names for public info items like "<record>
If we're going to do that though I would want the "info" part to be another API that allows registration, but at what level (e.g. global, i.e. all records, or per record-type, or per record instance)? Lots to discuss...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
Info items are not per-instance fields. They are constant read-only strings. But this show the way how per-instance fields can be integrated in the future. Real per-instance fields do indeed need proper design and much discussion. I think they are off topic here.
I will split off the CA part of this proposal fow now.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
> https:/
> -2620006.5 says about record info items that they "can be retrieved by
> programs running on the IOC (they are not visible via Channel Access at all)."
>
I am willing to modify that documentation as well :-)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ralph Lange (ralph-lange) wrote : | # |
So, one step back...
How about a global variable that controls CA visibility of info items and is set to "invisible" by default.
That ensures compatibility, and any installation that wishes to make things visible can do so by setting the variable from the startup script.
That could go into 3.16. EPICS 7 (as a major step) might even switch the default to "visible", not sure.
I do like the "<record>
Read only, string only, no monitors. Would need support for string and long-string. No access to the private pointer.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
Yes, one step back. I pushed a previous version without CA.
Implementing a control variable would be easy. Maybe 3-state: no access, readonly, write.
Are info items mutable? Should they be? There is dbPutInfo but it is not called at run time (yet).
Long string support worked already. No access to private pointer because CA cannot do that and a pointer has no meaning outside the same address space.
I do not like the idea of .info. so much. But it would be easy enough to implement. Basically any separator starting with . would do, e.g. "<record>..<name>" or "<record>.%<name>" or "<record>.#<name>".
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ralph Lange (ralph-lange) wrote : | # |
Out of your separator options, I like "<record>..<name>" best.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
In 3.14 any char after the . that is not isalpha() or '_' results in the VAL field being delivered by channel access, dbgf and links. (In 3.15 and 13.16 this is still the case for dbgf and links but not for channel access any more.)
Thus unfortunately <record>..<name> and similar break backward compatibility. An old 3.14 ioc that does not support ca on info items would deliver something wrong (VAL) instead of nothing. The same for any spelling error like <record>...<name>. So the first char after the . must be a letter or underscore.
This also means that my initial idea was not backward compatible because the info name can start with anything, not necessarily a letter.
So I have tested .info. and it works. Only using non-ASCII chars in the name, such as German umlauts result in the expected problems if character encoding of ioc and client don't match. If they match however everything is fine.
To allow selective merging, this will go to a different branch. But I change dbli to use .info. in its output.
- 71ba16e... by Dirk Zimoch
-
use <record>
.info.< name> for info items
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
We should move discussion of making info items remotely accessible to core-talk, to widen the audience. Please limit further discussion here to the remaining 'dbli' changes.
I committed a streamlined bug-fix for lp: #1754298 to the 3.15 branch, which will conflict with your fix here but I'll clean that up when I merge the branch.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
There is a bug in dbNextMatchingI
How often do you actually use the multiple patterns feature of the dbli command? Is it really that useful, or did you just implement it because you could? None of the other iocsh commands such as dbgrep and dbla support multiple pattern arguments, why is this different?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
Okay, so Launchpad is offsetting my comments in the email copy at least. When I said "doing this check just once" I was talking about the line
if (!patternlist || !*patternlist) return 0;
- d59426f... by Dirk Zimoch
-
bugfix: dbNextMatchingInfo did not find infos in the first record type
- 2e1a45e... by Dirk Zimoch
-
In vxWorks dbli function don't rely on NULL as last argument. Use fixed 12 arguments instead
- 932f9d9... by Dirk Zimoch
-
Make clear that patternlist argument of dbNextMatchingInfo must be NULL terminated
- 3356729... by Dirk Zimoch
-
merge with 3.16 branch
- 704fd02... by Dirk Zimoch
-
typo
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
Core Meeting: We need convincing why you need more than one pattern, only supporting one would simplify the code. If you have a use-case for multiple patterns please explain. We don't like the 12-arg thing (which should be inside #ifdef vxWorks to make that dependency obvious).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dirk Zimoch (dirk.zimoch) wrote : | # |
I'm pretty sure I had a use case but I forgot what it was.
I will change it and simplify the code.
- 4b2e159... by Dirk Zimoch
-
simplify 'dbli' by accepting only one pattern
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew Johnson (anj) wrote : | # |
Merging, with a change to the output formatting from this:
epics> dbli
anj:ai1.info.name1 "value1"
anj:ai1.info.name2 "value2"
anj:ai1.info.name3 "value3" 0x1c0f5e8
to this:
epics> dbli
anj:ai1 info(name1, "value1")
anj:ai1 info(name2, "value2")
anj:ai1 info(name3, "value3", 0x1c0f5e8)
Preview Diff
1 | diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html |
2 | index a4a09c7..28f3a8b 100644 |
3 | --- a/documentation/RELEASE_NOTES.html |
4 | +++ b/documentation/RELEASE_NOTES.html |
5 | @@ -17,6 +17,11 @@ |
6 | |
7 | --> |
8 | |
9 | +<h3>Access to info fields</h3> |
10 | + |
11 | +<p>The new command line function <code>dbli</code> lists and filters info fields. |
12 | +The new API function <code>dbNextMatchingInfo</code> iterates over info fields.</p> |
13 | + |
14 | <h3>Restore use of ledlib for VxWorks command editing</h3> |
15 | |
16 | <p>The epicsReadline refactoring work described below unfortunately disabled the |
17 | diff --git a/src/ioc/db/dbIocRegister.c b/src/ioc/db/dbIocRegister.c |
18 | index 07c9836..4d0b88c 100644 |
19 | --- a/src/ioc/db/dbIocRegister.c |
20 | +++ b/src/ioc/db/dbIocRegister.c |
21 | @@ -152,6 +152,12 @@ static const iocshArg * const dbnrArgs[1] = {&dbnrArg0}; |
22 | static const iocshFuncDef dbnrFuncDef = {"dbnr",1,dbnrArgs}; |
23 | static void dbnrCallFunc(const iocshArgBuf *args) { dbnr(args[0].ival);} |
24 | |
25 | +/* dbli */ |
26 | +static const iocshArg dbliArg0 = { "pattern",iocshArgString}; |
27 | +static const iocshArg * const dbliArgs[1] = {&dbliArg0}; |
28 | +static const iocshFuncDef dbliFuncDef = {"dbli",1,dbliArgs}; |
29 | +static void dbliCallFunc(const iocshArgBuf *args) { dbli(args[0].sval);} |
30 | + |
31 | /* dbla */ |
32 | static const iocshArg dblaArg0 = { "pattern",iocshArgString}; |
33 | static const iocshArg * const dblaArgs[1] = {&dblaArg0}; |
34 | @@ -415,6 +421,7 @@ void dbIocRegister(void) |
35 | iocshRegister(&dblFuncDef,dblCallFunc); |
36 | iocshRegister(&dbnrFuncDef,dbnrCallFunc); |
37 | iocshRegister(&dblaFuncDef,dblaCallFunc); |
38 | + iocshRegister(&dbliFuncDef,dbliCallFunc); |
39 | iocshRegister(&dbgrepFuncDef,dbgrepCallFunc); |
40 | iocshRegister(&dbgfFuncDef,dbgfCallFunc); |
41 | iocshRegister(&dbpfFuncDef,dbpfCallFunc); |
42 | diff --git a/src/ioc/db/dbTest.c b/src/ioc/db/dbTest.c |
43 | index 4bbd406..2f8d406 100644 |
44 | --- a/src/ioc/db/dbTest.c |
45 | +++ b/src/ioc/db/dbTest.c |
46 | @@ -257,7 +257,28 @@ long dbla(const char *pmask) |
47 | dbFinishEntry(pdbentry); |
48 | return 0; |
49 | } |
50 | + |
51 | |
52 | +long dbli(const char *pattern) |
53 | +{ |
54 | + DBENTRY dbentry; |
55 | + void* ptr; |
56 | + |
57 | + if (!pdbbase) { |
58 | + printf("No database loaded\n"); |
59 | + return 0; |
60 | + } |
61 | |
62 | + dbInitEntry(pdbbase, &dbentry); |
63 | + while (dbNextMatchingInfo(&dbentry, pattern) == 0) |
64 | + { |
65 | + printf("%s.info.%s \"%s\"", dbGetRecordName(&dbentry), dbGetInfoName(&dbentry), dbGetInfoString(&dbentry)); |
66 | + if ((ptr = dbGetInfoPointer(&dbentry)) != NULL) printf(" %p", ptr); |
67 | + printf("\n"); |
68 | + } |
69 | + dbFinishEntry(&dbentry); |
70 | + return 0; |
71 | +} |
72 | + |
73 | |
74 | long dbgrep(const char *pmask) |
75 | { |
76 | DBENTRY dbentry; |
77 | diff --git a/src/ioc/db/dbTest.h b/src/ioc/db/dbTest.h |
78 | index 6d457b5..a4d90e2 100644 |
79 | --- a/src/ioc/db/dbTest.h |
80 | +++ b/src/ioc/db/dbTest.h |
81 | @@ -25,6 +25,8 @@ epicsShareFunc long dbl( |
82 | epicsShareFunc long dbnr(int verbose); |
83 | /* list aliases */ |
84 | epicsShareFunc long dbla(const char *pmask); |
85 | +/* list infos */ |
86 | +epicsShareFunc long dbli(const char *patern); |
87 | /*list records with mask*/ |
88 | epicsShareFunc long dbgrep(const char *pmask); |
89 | /*get field value*/ |
90 | diff --git a/src/ioc/db/test/dbStaticTest.db b/src/ioc/db/test/dbStaticTest.db |
91 | index c35ff9a..6303672 100644 |
92 | --- a/src/ioc/db/test/dbStaticTest.db |
93 | +++ b/src/ioc/db/test/dbStaticTest.db |
94 | @@ -1,7 +1,7 @@ |
95 | |
96 | record(x, "testrec") { |
97 | - info("A", "B") |
98 | alias("testalias") |
99 | + info("A", "B") |
100 | } |
101 | |
102 | alias("testrec", "testalias2") |
103 | diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c |
104 | index 4135d7f..a43b49e 100644 |
105 | --- a/src/ioc/dbStatic/dbStaticLib.c |
106 | +++ b/src/ioc/dbStatic/dbStaticLib.c |
107 | @@ -2716,6 +2716,32 @@ long dbNextInfo(DBENTRY *pdbentry) |
108 | return (pinfo ? 0 : S_dbLib_infoNotFound); |
109 | } |
110 | |
111 | +long dbNextMatchingInfo(DBENTRY *pdbentry, const char *pattern) |
112 | +{ |
113 | + long status; |
114 | + |
115 | + if (!pdbentry->precordType) |
116 | + { |
117 | + status = dbFirstRecordType(pdbentry); |
118 | + goto first; |
119 | + } |
120 | + while(1) { |
121 | + status = dbNextInfo(pdbentry); |
122 | + while (status) { |
123 | + status = dbNextRecord(pdbentry); |
124 | + while (status) { |
125 | + status = dbNextRecordType(pdbentry); |
126 | +first: |
127 | + if (status) return status; |
128 | + status = dbFirstRecord(pdbentry); |
129 | + } |
130 | + status = dbFirstInfo(pdbentry); |
131 | + } |
132 | + if (!pattern || !*pattern) return 0; |
133 | + if (epicsStrGlobMatch(dbGetInfoName(pdbentry), pattern)) return 0; |
134 | + } |
135 | +} |
136 | + |
137 | long dbFindInfo(DBENTRY *pdbentry,const char *name) |
138 | { |
139 | dbRecordNode *precnode = pdbentry->precnode; |
140 | diff --git a/src/ioc/dbStatic/dbStaticLib.h b/src/ioc/dbStatic/dbStaticLib.h |
141 | index b2f4a02..92b32d9 100644 |
142 | --- a/src/ioc/dbStatic/dbStaticLib.h |
143 | +++ b/src/ioc/dbStatic/dbStaticLib.h |
144 | @@ -188,6 +188,8 @@ epicsShareFunc long dbFirstInfo(DBENTRY *pdbentry); |
145 | epicsShareFunc long dbNextInfo(DBENTRY *pdbentry); |
146 | epicsShareFunc long dbFindInfo(DBENTRY *pdbentry, |
147 | const char *name); |
148 | +epicsShareFunc long dbNextMatchingInfo(DBENTRY *pdbentry, |
149 | + const char *pattern); |
150 | epicsShareFunc long dbDeleteInfo(DBENTRY *pdbentry); |
151 | epicsShareFunc const char * dbGetInfoName(DBENTRY *pdbentry); |
152 | epicsShareFunc const char * dbGetInfoString(DBENTRY *pdbentry); |
I wish you hadn't combined these two different features into one merge request. I'm Okay with adding iocsh command(s) to find and list info items, but something in me doesn't like the idea of making items visible over the network, so I'm going to have to be persuaded to accept that part.
There are several reasons that come to mind:
* Field and attribute names must be valid C identifiers; info item names have no such restrictions, and an informal standard has developed that suggests they should take the form "<subsystem> :<name> ", e.g. "asyn:READBACK", "asyn:FIFO", "Q:group", but nothing enforces this.
* Searches for info items are linear, so slow (searches for record names use a hash table, field names use a binary search; admittedly attribute name searches are linear).
* Sites would have to add support for info items to their IRMIS/Channel Finder/CA Name Server/PV Database etc. or they risk not being able to know for sure whether a specific channel name exists or not.
* Up to now info items have been private to the IOC, so could be used to hold semi-secret information.