Skip to content

Commit

Permalink
Add OOM testing of parsing replicas
Browse files Browse the repository at this point in the history
Fix memory issues when the parsing of replicas fails.

Signed-off-by: Björn Svensson <[email protected]>
  • Loading branch information
bjosv committed Oct 11, 2024
1 parent 12920a0 commit f16041a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
17 changes: 12 additions & 5 deletions src/cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,6 @@ static int cluster_master_slave_mapping_with_name(valkeyClusterContext *cc,
}

if (node_old->slaves != NULL) {
node_old->slaves->free = NULL;
while (listLength(node_old->slaves) > 0) {
lnode = listFirst(node_old->slaves);
if (listAddNodeHead(node->slaves, lnode->value) == NULL) {
Expand Down Expand Up @@ -958,7 +957,6 @@ static dict *parse_cluster_nodes(valkeyClusterContext *cc, valkeyReply *reply) {
ret = cluster_master_slave_mapping_with_name(
cc, &nodes_name, master, master->name);
if (ret != VALKEY_OK) {
freeValkeyClusterNode(master);
goto error;
}
}
Expand Down Expand Up @@ -1050,12 +1048,21 @@ static dict *parse_cluster_nodes(valkeyClusterContext *cc, valkeyReply *reply) {
error:
sdsfreesplitres(part, count_part);
sdsfreesplitres(slot_start_end, count_slot_start_end);
if (nodes != NULL) {
dictRelease(nodes);
}
if (nodes_name != NULL) {
/* Only free parsed replicas since the `nodes` dict owns primary nodes. */
dictIterator di;
dictInitIterator(&di, nodes_name);
dictEntry *de;
while ((de = dictNext(&di))) {
valkeyClusterNode *node = dictGetEntryVal(de);
if (node->role == VALKEY_ROLE_SLAVE)
freeValkeyClusterNode(node);
}
dictRelease(nodes_name);
}
if (nodes != NULL) {
dictRelease(nodes);
}
return NULL;
}

Expand Down
10 changes: 6 additions & 4 deletions tests/ct_out_of_memory_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ void test_alloc_failure_handling(void) {
cc = valkeyClusterContextInit();
assert(cc);
}
cc->flags |= VALKEYCLUSTER_FLAG_ADD_SLAVE;

// Add nodes
{
Expand Down Expand Up @@ -170,14 +171,14 @@ void test_alloc_failure_handling(void) {

// Connect
{
for (int i = 0; i < 128; ++i) {
for (int i = 0; i < 148; ++i) {
prepare_allocation_test(cc, i);
result = valkeyClusterConnect2(cc);
assert(result == VALKEY_ERR);
ASSERT_STR_EQ(cc->errstr, "Out of memory");
}

prepare_allocation_test(cc, 128);
prepare_allocation_test(cc, 148);
result = valkeyClusterConnect2(cc);
assert(result == VALKEY_OK);
}
Expand Down Expand Up @@ -493,6 +494,7 @@ void test_alloc_failure_handling_async(void) {
acc = valkeyClusterAsyncContextInit();
assert(acc);
}
acc->cc->flags |= VALKEYCLUSTER_FLAG_ADD_SLAVE;

// Set callbacks
{
Expand All @@ -519,14 +521,14 @@ void test_alloc_failure_handling_async(void) {

// Connect
{
for (int i = 0; i < 126; ++i) {
for (int i = 0; i < 146; ++i) {
prepare_allocation_test(acc->cc, i);
result = valkeyClusterConnect2(acc->cc);
assert(result == VALKEY_ERR);
ASSERT_STR_EQ(acc->cc->errstr, "Out of memory");
}

prepare_allocation_test(acc->cc, 126);
prepare_allocation_test(acc->cc, 146);
result = valkeyClusterConnect2(acc->cc);
assert(result == VALKEY_OK);
}
Expand Down

0 comments on commit f16041a

Please sign in to comment.