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

Re: modify/add: <ATTRIBUTE>: merge error





--On Wednesday, March 22, 2006 3:16 PM -0800 Charles Stephens <cfs@cowlabs.com> wrote:

Unfortunately, this is not possible since we can't easily reproduce  the
problem and we have over 40 replicas in production.  I guess my  question
would be then what could cause this kind of behavior?  I did  notice that
it is only occurring on the 10 most loaded servers.

Hm, well, since there is no change in the underlying database between 2.3.11 and 2.3.20, it is simply an upgrade of the binaries (stop slapd, update the software, restart slapd). I'm sure that would be somewhat time consuming on 40 replicas, but it should be doable...


The code involved here is in modify_add_values function, in mods.c under servers/slapd:

   /* no - add them */
   if ( mod->sm_desc->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) {
       rc = ordered_value_add( e, mod->sm_desc, a,
           pmod.sm_values, pmod.sm_nvalues );
   } else {
       rc = attr_merge( e, mod->sm_desc, pmod.sm_values, pmod.sm_nvalues );
   }

   if ( a != NULL && permissive ) {
       ch_free( pmod.sm_values );
       if ( pmod.sm_nvalues ) ch_free( pmod.sm_nvalues );
   }

   if ( rc != 0 ) {
       /* this should return result of attr_merge */
       *text = textbuf;
       snprintf( textbuf, textlen,
           "modify/%s: %s: merge error",
           op, mod->sm_desc->ad_cname.bv_val );
       return LDAP_OTHER;
   }


So that is coming from the function attr_merge, found in servers/slapd/attr.c


/*
* attr_merge - merge the given type and value with the list of
* attributes in attrs.
*
* nvals must be NULL if the attribute has no normalizer.
* In this case, a->a_nvals will be set equal to a->a_vals.
*
* returns  0   everything went ok
*      -1  trouble
*/


This then calls:

   rc = value_add( &(*a)->a_vals, vals );

so this is where our return code is coming from.

This is in servers/slapd/value.c:

int
value_add(
   BerVarray   *vals,
   BerVarray   addvals )
{
   int     n, nn = 0;
   BerVarray   v2;

   if ( addvals != NULL ) {
       for ( ; !BER_BVISNULL( &addvals[nn] ); nn++ )
           ;   /* NULL */
   }

   if ( *vals == NULL ) {
       *vals = (BerVarray) SLAP_MALLOC( (nn + 1)
           * sizeof(struct berval) );
       if( *vals == NULL ) {
           Debug(LDAP_DEBUG_TRACE,
             "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
           return LBER_ERROR_MEMORY;
       }
       n = 0;

   } else {
       for ( n = 0; !BER_BVISNULL( &(*vals)[n] ); n++ ) {
           ;   /* Empty */
       }
       *vals = (BerVarray) SLAP_REALLOC( (char *) *vals,
           (n + nn + 1) * sizeof(struct berval) );
       if( *vals == NULL ) {
           Debug(LDAP_DEBUG_TRACE,
             "value_add: SLAP_MALLOC failed.\n", 0, 0, 0 );
           return LBER_ERROR_MEMORY;
       }
   }

   v2 = &(*vals)[n];
   for ( ; !BER_BVISNULL( addvals ); v2++, addvals++ ) {
       ber_dupbv( v2, addvals );
       if ( BER_BVISNULL( v2 ) ) break;
   }
   BER_BVZERO( v2 );

   return LDAP_SUCCESS;
}


So there are only *two* return paths out of here besides success, which is what we must be hitting. They are both: LBER_ERROR_MEMORY.


So, basically, you are running out of memory.

--Quanah



--
Quanah Gibson-Mount
Principal Software Developer
ITS/Shared Application Services
Stanford University
GnuPG Public Key: http://www.stanford.edu/~quanah/pgp.html