[Date Prev][Date Next] [Chronological] [Thread] [Top]

RE: overlay and failover



>> -----Original Message-----
>> From: owner-openldap-devel@OpenLDAP.org
>> [mailto:owner-openldap-devel@OpenLDAP.org]On Behalf Of Pierangelo
>> Masarati
>
>> > I'm playing with overlays, and I need to deal with errors
>> > while doing some DN/attr rewrite/remap.  If I need to return
>> > an error result from inside an over_op_func(), I cannot use
>> > send_ldap_*() funcs because they try to call the overlay
>> > response infrastructure, which is corrupted because
>> > over_op_func() puts its own copy of the backend data/info
>> > in op->o_bd.  If I simply return an error code, the client
>> > hangs. What is the suggested approach, or how could
>> > we implement a mechanism to abort an operation from inside
>> > an overlay?  Am I missing anything?
>
>> I note that over_op_func() casts a  slap_overinst* in bd_info
>> before calling each overlay's function, but then a slap_overinfo*
>> structure is read from bd_info; this is harmless as soon as
>> each function simply uses it as a BackendInfo*, but it becomes
>> a crasher if one calls any response function from an overlay.
>> I guess any slap_overinst should contain slap_overinfo as a
>> subset to allow either cast; or, at least, a cast to either
>> should allow a safe retrieval of oi_list.
>
> When an overlay is configured on a backend, that backend's bd_info
> points to a slap_overinfo structure. The slap_overinfo contains a field
> oi_list which is a linked list of slap_overinst structures, one entry
> per active overlay on that backend. As you already noted, the
> slap_overinst structures are placed in op->o_bd->bd_info when each
> overlay is invoked. (Here, op->o_bd is a local copy of the original op's
> o_bd so it can be changed at will.)
>
> When you want to make a call into slapd from an overlay, you must
> restore the original slap_overinfo in op->o_bd->bd_info first. This is
> always pointed to by the on_info field in the current slap_overinst.
>
> E.g.
>
> int some_overlay_func(Operation *op, SlapReply *rs)
> {
> 	slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
> 	Entry *e;
> 	int rc;
> ...
> 	op->o_bd->bd_info = (BackendInfo *)on->on_info;
> 	rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
> ...
> }
>
> The current approach means, of course, that you should not call a
> function that will wind up re-invoking the current overlay function,
> otherwise it will loop until the stack overflows.

The problem is much simpler and trickier: if I try to send
a result, the over_back_response() casts a BackendInfo *, which
is really pointing to a slap_overinst *, into a slap_overinfo *
and dies because what it pretends to be a list of slap_overinst *
is actually bogus.  I see a few approaches:

1) return a specific error code (e.g. SLAP_CB_FAILOVER) which
instructs over_op_func() to issue the error
2) rearrange slap_overinfo so that it actually is a slap_overinst
plus the BackendInfo data structure so that either cast succeeds
3) as you said, when calling a result function from inside
an overlay, restore the correct op->o_bd->bd_info field, relying
on the fact that if I'm inside an overlay function I can do it
safely :)

Another issue remains open, in my opinion.  If I need to return
an error code from inside an overlay function, it would be
nice that the result functions that are invoked go all the way
back from the overlay level where the error occurs back to the
first, in reverse order, wouldn't it?

More comments?

Ando.

-- 
Pierangelo Masarati
mailto:pierangelo.masarati@sys-net.it