Thanks. The explanation is always simple, after one finds it. The DN of accesslog entries is generated using the reqStart AVA. When logops all and internal operations take place, multiple entries are generated with the same reqStart AVA. So an internal search which is logged because of some overlay eats up the DN of the modrdn, and be_add() called by slapo-accesslog(5) fails because the entry already exists.
Although logging internal entries could be of some use, I see two solutions:
- modify the value of reqStart (e.g. instead of using o_tincr for the
fractional part of the timestamp, we could use an incremental counter initialized with o_tincr and incremented at each logging within the same operation. The counter could be stored somewhere in the operation structure (e.g. in o_extra)
- prevent logging of internal ops; again, this could be achieved by
setting a dedicated o_internal_op field in the Operation structure.
Since this modification could be intrusive, I'd like to gather some comments before proceeding with a fix.
Hm, we've run into this similar problem before with syncprov and introduced op->o_dont_replicate. As a general rule, accesslog is meant to log user operations, not internal operations. Currently accesslog checks (op->o_dont_replicate && op->orm_no_opattrs) to skip logging of write ops. I guess we need a more general flag instead.
A definitive and simple solution, although invasive, would be to:
- add a o_internal flag to the Operation structure
- add a macro BE_INTERNAL(op, rs, op_type) like
#define BE_INTERNAL(op, rs, op_type, rcp) \ { int save_o_internal = op->o_internal; op->o_internal = 1; *rcp = (&op->o_bd->bi_info->bi_op_bind)[op_type]( op, rs ); op->o_internal = save_o_internal; }
fix all calls to internal operations (brrr....)
p.