Pass the full list of pools to acquire_address, enumerate in providers

If the provider has access to the full pool list, it can enumerate
them twice, for example to search for existing leases first, and
only search for new leases in a second step.

Fixes lease enumeration in attr-sql using multiple pools.
This commit is contained in:
Martin Willi
2012-09-11 16:18:28 +02:00
parent dc7b79d8a5
commit 594c58e111
10 changed files with 109 additions and 73 deletions
+20 -8
View File
@@ -81,18 +81,29 @@ static uintptr_t hash_transaction(dhcp_transaction_t *transaction)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
private_dhcp_provider_t *this, char *pool,
private_dhcp_provider_t *this, linked_list_t *pools,
identification_t *id, host_t *requested)
{
if (streq(pool, "dhcp") && requested->get_family(requested) == AF_INET)
{
dhcp_transaction_t *transaction, *old;
host_t *vip;
dhcp_transaction_t *transaction, *old;
enumerator_t *enumerator;
char *pool;
host_t *vip = NULL;
if (requested->get_family(requested) != AF_INET)
{
return NULL;
}
enumerator = pools->create_enumerator(pools);
while (enumerator->enumerate(enumerator, &pool))
{
if (!streq(pool, "dhcp"))
{
continue;
}
transaction = this->socket->enroll(this->socket, id);
if (!transaction)
{
return NULL;
continue;
}
vip = transaction->get_address(transaction);
vip = vip->clone(vip);
@@ -101,9 +112,10 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
(void*)hash_transaction(transaction), transaction);
this->mutex->unlock(this->mutex);
DESTROY_IF(old);
return vip;
break;
}
return NULL;
enumerator->destroy(enumerator);
return vip;
}
METHOD(attribute_provider_t, release_address, bool,
+13 -5
View File
@@ -170,22 +170,28 @@ static bool responsible_for(private_ha_attribute_t *this, int bit)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
private_ha_attribute_t *this, char *name, identification_t *id,
private_ha_attribute_t *this, linked_list_t *pools, identification_t *id,
host_t *requested)
{
enumerator_t *enumerator;
pool_t *pool;
int offset = -1, byte, bit;
host_t *address;
char *name;
enumerator = pools->create_enumerator(pools);
this->mutex->lock(this->mutex);
pool = get_pool(this, name);
if (pool)
while (enumerator->enumerate(enumerator, &name))
{
pool = get_pool(this, name);
if (!pool)
{
continue;
}
if (pool->base->get_family(pool->base) !=
requested->get_family(requested))
{
this->mutex->unlock(this->mutex);
return NULL;
continue;
}
for (byte = 0; byte < pool->size / 8; byte++)
{
@@ -214,6 +220,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
}
}
this->mutex->unlock(this->mutex);
enumerator->destroy(enumerator);
if (offset != -1)
{
address = offset2host(pool, offset);
@@ -90,19 +90,31 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
}
METHOD(attribute_provider_t, acquire_address, host_t*,
private_stroke_attribute_t *this, char *name, identification_t *id,
private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id,
host_t *requested)
{
enumerator_t *enumerator;
mem_pool_t *pool;
host_t *addr = NULL;
char *name;
enumerator = pools->create_enumerator(pools);
this->lock->read_lock(this->lock);
pool = find_pool(this, name);
if (pool)
while (enumerator->enumerate(enumerator, &name))
{
addr = pool->acquire_address(pool, id, requested);
pool = find_pool(this, name);
if (pool)
{
addr = pool->acquire_address(pool, id, requested);
if (addr)
{
break;
}
}
}
this->lock->unlock(this->lock);
enumerator->destroy(enumerator);
return addr;
}
@@ -27,6 +27,7 @@ static void* testing(void *thread)
int i;
host_t *addr[ALLOCS];
identification_t *id[ALLOCS];
linked_list_t *pools;
/* prepare identities */
for (i = 0; i < ALLOCS; i++)
@@ -37,17 +38,23 @@ static void* testing(void *thread)
id[i] = identification_create_from_string(buf);
}
pools = linked_list_create();
pools->insert_last(pools, "test");
/* allocate addresses */
for (i = 0; i < ALLOCS; i++)
{
addr[i] = hydra->attributes->acquire_address(hydra->attributes,
"test", id[i], NULL);
pools, id[i], NULL);
if (!addr[i])
{
pools->destroy(pools);
return (void*)FALSE;
}
}
pools->destroy(pools);
/* release addresses */
for (i = 0; i < ALLOCS; i++)
{