コード例 #1
0
ファイル: cache.c プロジェクト: Joywar/openldap
/*
 * If the entry exists in cache, it is returned in locked status;
 * otherwise, if the parent exists, if it may generate volatile 
 * descendants an attempt to generate the required entry is
 * performed and, if successful, the entry is returned
 */
int
monitor_cache_dn2entry(
	Operation		*op,
	SlapReply		*rs,
	struct berval		*ndn,
	Entry			**ep,
	Entry			**matched )
{
	monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private;
	int 			rc;
	struct berval		p_ndn = BER_BVNULL;
	Entry 			*e_parent;
	monitor_entry_t 	*mp;
		
	assert( mi != NULL );
	assert( ndn != NULL );
	assert( ep != NULL );
	assert( matched != NULL );

	*matched = NULL;

	if ( !dnIsSuffix( ndn, &op->o_bd->be_nsuffix[ 0 ] ) ) {
		return( -1 );
	}

	rc = monitor_cache_get( mi, ndn, ep );
       	if ( !rc && *ep != NULL ) {
		return( 0 );
	}

	/* try with parent/ancestors */
	if ( BER_BVISNULL( ndn ) ) {
		BER_BVSTR( &p_ndn, "" );

	} else {
		dnParent( ndn, &p_ndn );
	}

	rc = monitor_cache_dn2entry( op, rs, &p_ndn, &e_parent, matched );
	if ( rc || e_parent == NULL ) {
		return( -1 );
	}

	mp = ( monitor_entry_t * )e_parent->e_private;
	rc = -1;
	if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
		/* parent entry generates volatile children */
		rc = monitor_entry_create( op, rs, ndn, e_parent, ep );
	}

	if ( !rc ) {
		monitor_cache_lock( *ep );
		monitor_cache_release( mi, e_parent );

	} else {
		*matched = e_parent;
	}
	
	return( rc );
}
コード例 #2
0
static int
monitor_send_children(
	Operation	*op,
	SlapReply	*rs,
	Entry		*e_parent,
	int		sub )
{
	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
	Entry 			*e,
				*e_tmp,
				*e_ch = NULL,
				*e_nonvolatile = NULL;
	monitor_entry_t *mp;
	int			rc,
				nonvolatile = 0;

	mp = ( monitor_entry_t * )e_parent->e_private;
	e_nonvolatile = e = mp->mp_children;

	if ( MONITOR_HAS_VOLATILE_CH( mp ) ) {
		monitor_entry_create( op, rs, NULL, e_parent, &e_ch );
	}
	monitor_cache_release( mi, e_parent );

	/* no volatile entries? */
	if ( e_ch == NULL ) {
		/* no persistent entries? return */
		if ( e == NULL ) {
			return LDAP_SUCCESS;
		}
	
	/* volatile entries */
	} else {
		/* if no persistent, return only volatile */
		if ( e == NULL ) {
			e = e_ch;

		/* else append persistent to volatile */
		} else {
			e_tmp = e_ch;
			do {
				mp = ( monitor_entry_t * )e_tmp->e_private;
				e_tmp = mp->mp_next;
	
				if ( e_tmp == NULL ) {
					mp->mp_next = e;
					break;
				}
			} while ( e_tmp );
			e = e_ch;
		}
	}

	/* return entries */
	for ( monitor_cache_lock( e ); e != NULL; ) {
		monitor_entry_update( op, rs, e );

		if ( op->o_abandon ) {
			/* FIXME: may leak generated children */
			if ( nonvolatile == 0 ) {
				for ( e_tmp = e; e_tmp != NULL; ) {
					mp = ( monitor_entry_t * )e_tmp->e_private;
					e = e_tmp;
					e_tmp = mp->mp_next;
					monitor_cache_release( mi, e );

					if ( e_tmp == e_nonvolatile ) {
						break;
					}
				}

			} else {
				monitor_cache_release( mi, e );
			}

			return SLAPD_ABANDON;
		}
		
		rc = test_filter( op, e, op->oq_search.rs_filter );
		if ( rc == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = e;
			rs->sr_flags = 0;
			rc = send_search_entry( op, rs );
			rs->sr_entry = NULL;
		}

		mp = ( monitor_entry_t * )e->e_private;
		e_tmp = mp->mp_next;

		if ( sub ) {
			rc = monitor_send_children( op, rs, e, sub );
			if ( rc ) {
				/* FIXME: may leak generated children */
				if ( nonvolatile == 0 ) {
					for ( ; e_tmp != NULL; ) {
						mp = ( monitor_entry_t * )e_tmp->e_private;
						e = e_tmp;
						e_tmp = mp->mp_next;
						monitor_cache_release( mi, e );
	
						if ( e_tmp == e_nonvolatile ) {
							break;
						}
					}
				}

				return( rc );
			}
		}

		if ( e_tmp != NULL ) {
			monitor_cache_lock( e_tmp );
		}

		if ( !sub ) {
			/* otherwise the recursive call already released */
			monitor_cache_release( mi, e );
		}

		e = e_tmp;
		if ( e == e_nonvolatile ) {
			nonvolatile = 1;
		}
	}
	
	return LDAP_SUCCESS;
}
コード例 #3
0
ファイル: search.c プロジェクト: jaredmcneill/netbsd-src
static int
monitor_send_children(
	Operation	*op,
	SlapReply	*rs,
	Entry		*e_nonvolatile,
	Entry		*e_ch,
	int		sub )
{
	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
	Entry 			*e,
				*e_tmp;
	monitor_entry_t *mp;
	int			rc,
				nonvolatile = 0;

	e = e_nonvolatile;

	/* no volatile entries? */
	if ( e_ch == NULL ) {
		/* no persistent entries? return */
		if ( e == NULL ) {
			return LDAP_SUCCESS;
		}

	/* volatile entries */
	} else {
		/* if no persistent, return only volatile */
		if ( e == NULL ) {
			e = e_ch;

		/* else append persistent to volatile */
		} else {
			e_tmp = e_ch;
			do {
				mp = ( monitor_entry_t * )e_tmp->e_private;
				e_tmp = mp->mp_next;
	
				if ( e_tmp == NULL ) {
					mp->mp_next = e;
					break;
				}
			} while ( e_tmp );
			e = e_ch;
		}
	}

	/* return entries */
	for ( ; e != NULL; e = e_tmp ) {
		Entry *sub_nv = NULL, *sub_ch = NULL;

		monitor_cache_lock( e );
		monitor_entry_update( op, rs, e );

		if ( e == e_nonvolatile )
			nonvolatile = 1;

		mp = ( monitor_entry_t * )e->e_private;
		e_tmp = mp->mp_next;

		if ( op->o_abandon ) {
			monitor_cache_release( mi, e );
			rc = SLAPD_ABANDON;
			goto freeout;
		}

		if ( sub )
			monitor_find_children( op, rs, e, &sub_nv, &sub_ch );

		rc = test_filter( op, e, op->oq_search.rs_filter );
		if ( rc == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = e;
			rs->sr_flags = REP_ENTRY_MUSTRELEASE;
			rc = send_search_entry( op, rs );
			if ( rc ) {
				for ( e = sub_ch; e != NULL; e = sub_nv ) {
					mp = ( monitor_entry_t * )e->e_private;
					sub_nv = mp->mp_next;
					monitor_cache_lock( e );
					monitor_cache_release( mi, e );
				}
				goto freeout;
			}
		} else {
			monitor_cache_release( mi, e );
		}

		if ( sub ) {
			rc = monitor_send_children( op, rs, sub_nv, sub_ch, sub );
			if ( rc ) {
freeout:
				if ( nonvolatile == 0 ) {
					for ( ; e_tmp != NULL; ) {
						mp = ( monitor_entry_t * )e_tmp->e_private;
						e = e_tmp;
						e_tmp = mp->mp_next;
						monitor_cache_lock( e );
						monitor_cache_release( mi, e );
	
						if ( e_tmp == e_nonvolatile ) {
							break;
						}
					}
				}

				return( rc );
			}
		}
	}
	
	return LDAP_SUCCESS;
}