Hi everyone,
I’m still working on my overlay for an OpenLDAP server,
and I’ve a few questions, I hope you could help me with:
1. In my overlay, I search for the attribute of a parent (recursively) and then, I return it in the response using the “attr_merge” function as used in the “content” overlay. But, this seems to be a permanent change, the server will always return that attribute, till I restart the server. It’s like if the “attr_merge” function add the attribute in some kind of cache that is only cleared when the server shuts down. I ‘would like my attribute to be return only when I ask it, is there some other function that allow this or maybe a way to clear that cache?
2. I need to free some variables at the end of the request. It seems that the server goes through the response function one last time at the end of the request with an empty entry, I used that condition to free my variable. This seems to work perfectly, but is there may be another way to do that?
3. To determine what attribute I need to look up for parent’s attributes, I use a symbol before the attribute in the search request (ex: “_street”). This means that when the attribute arrives in the search function, it has no attribute description because the attribute name isn’t valid of course! So, I change the name, save the attribute name for later use and then use the “slap_str2ad” function do add the attribute description! But this means that the server as to go look for that attribute description again and this means decreasing the performance. My question is: Is there a way to change and saved the attribute name before the server loads the attribute descriptions and calls the search function?
Since I’ve found a workarounds for question 2 and 3, question 1 is my biggest problem to make my overlay work properly! Thanks for your coming answers!
Johan Jakus
Johan Jakus writes:
In my overlay, I search for the attribute of a parent (recursively)
and then, I return it in the response using the ?attr_merge? function as used in the ?content? overlay. But, this seems to be a permanent change, the server will always return that attribute, till I restart the server. It?s like if the ?attr_merge? function add the attribute in some kind of cache that is only cleared when the server shuts down. I ?would like my attribute to be return only when I ask it, is there some other function that allow this or maybe a way to clear that cache?
Yes, the backend/overlay which returns an entry often owns that entry. If you are result and modifying rs->sr_entry, rs->sr_flags describe ownership of the entry and if it is modifiable. You can call
rs_entry2modifiable( op, rs, on /*the overlay*/ );
to ensure rs->sr_entry is modifiable. If necessary, this duplicates the entry and frees/releases the old one. This invalidates any pointers to/into the old sr_entry. Note how e.g. overlays/valsort.c re-reads rs->sr_entry->e_attrs if the entry was replaced.
At other times you may prefer to duplicate an entry "by hand" with entry_dup() to get a modifiable copy, and free it later with entry_free() or by setting the MUSTBEFREED flag in rs->sr_flags.
If your overlay needs to free the entry in a special way, it can set a entry release function and set the MUSTRELEASE flag to alert other code that the entry can't just be entry_free()d.
I need to free some variables at the end of the request. It seems
that the server goes through the response function one last time at the end of the request with an empty entry, I used that condition to free my variable. This seems to work perfectly, but is there may be another way to do that?
The on_response function is a convenience feature making use of op->o_callback. You could use that directly instead. In that case, use callback.sc_response for your response and callback.sc_cleanup for cleanup. The cleanup function should not assume that the sc_response has been called, since Abandon and a few other things don't.
To determine what attribute I need to look up for parent?s
attributes, I use a symbol before the attribute in the search request (ex: ?_street?). This means that when the attribute arrives in the search function, it has no attribute description because the attribute name isn?t valid of course!
I'm not sure, but this sounds like a hack which some future OpenLDAP version might break with stricter schema schecking or something.
So, I change the name, save the attribute name for later use and then use the ?slap_str2ad? function do add the attribute description! But this means that the server as to go look for that attribute description again and this means decreasing the performance. My question is: Is there a way to change and saved the attribute name before the server loads the attribute descriptions and calls the search function?
Not sure, but possibly you want <struct Operation>.o_extra. Each backend and overlay may register info there on the way into an operation, and remove it on the way out. See e.g. overlays/memberof.c.
However, have you checked optimizing away this extra work saves enough time to be noticeable? Possibly the best solution is to not optimize it.
I wrote:
Yes, the backend/overlay which returns an entry often owns that entry. If you are
*intercepting a*
result and modifying rs->sr_entry, rs->sr_flags describe ownership of the entry and if it is modifiable. You can call
rs_entry2modifiable( op, rs, on /*the overlay*/ );
Hallvard B Furuseth h.b.furuseth@usit.uio.no wrote:
Yes, the backend/overlay which returns an entry often owns that entry. If you are result and modifying rs->sr_entry, rs->sr_flags describe ownership of the entry and if it is modifiable. You can call
rs_entry2modifiable( op, rs, on /*the overlay*/ );
to ensure rs->sr_entry is modifiable. If necessary, this duplicates the entry and frees/releases the old one. This invalidates any pointers to/into the old sr_entry. Note how e.g. overlays/valsort.c re-reads rs->sr_entry->e_attrs if the entry was replaced.
At other times you may prefer to duplicate an entry "by hand" with entry_dup() to get a modifiable copy, and free it later with entry_free() or by setting the MUSTBEFREED flag in rs->sr_flags.
If your overlay needs to free the entry in a special way, it can set a entry release function and set the MUSTRELEASE flag to alert other code that the entry can't just be entry_free()d.
Hey Hallvard! Thanks a lot for your answers, they were very help full!
To be sure, when I use entry_dub(); it makes a duplication of the entry from the server cache to somewhere in the memory. So I just need to make the pointer of the SlapReply point to my new duplicated entry,modified it as wanted,and free it once the response have been send to the client. If, I'm multi-threading and an other request arrives it will use the entry still in the cache and not my modified duplication, is that write? Thanks!
Johan Jakus
Johan Jakus writes:
To be sure, when I use entry_dub(); it makes a duplication of the entry from the server cache to somewhere in the memory. So I just need to make the pointer of the SlapReply point to my new duplicated entry,
...and dispose of the old entry according to rs->sr_flags, and reset the entry-related sr_flags so they do not get applied to the new entry. Which is why it's better to let rs_entry2modifiable() & co maintain rs->sr_entry. Note that a lot of old overlay code also got this wrong. We've cleaned up most of it recently.
modified it as wanted,and free it once the response have been send to the client.
If you want to free the entry yourself, instead you can do
rs_replace_entry(entry_dup(rs->sr_entry));
or the equivalent
e = entry_dup(rs->sr_entry); rs_flush_entry(rs); /* Obey and clear REP_ENTRY_MUST<BEFREED/RELEASE> */ rs->sr_entry = e;
Now your overlay owns the entry and should free it, other modules will not do that. If you won't touch your entry other than freeing once you send it, you may also want to make it modifiable so other overlays can use it instead of doing another entry_dup():
rs->sr_flags |= REP_ENTRY_MODIFIABLE;
Do not keep any pointers into the entry in that case, since they may get invalidated by later overlays.
You can look at these functions in slapd/result.c to see how these flags work. Ignore all the asserts.
If, I'm multi-threading and an other request arrives it will use the entry still in the cache and not my modified duplication, is that write?
Yep.
openldap-technical@openldap.org