From c2077a2fbd856fdee3dfde323369e5e91c2ea860 Mon Sep 17 00:00:00 2001 From: Malavan Sotheeswaran <105669860+msotheeswaran@users.noreply.github.com> Date: Thu, 2 Mar 2023 13:51:47 -0500 Subject: [PATCH] Fix rdb fd leak (#579) * close tempfile when done bgsave * declare getTempFileName * open close child pipes in correct place * assert no existing child pipe when opening new child pipe --- src/childinfo.cpp | 1 + src/rdb.cpp | 6 +++--- src/rdb.h | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/childinfo.cpp b/src/childinfo.cpp index ec3e3c133..f1fba91dd 100644 --- a/src/childinfo.cpp +++ b/src/childinfo.cpp @@ -42,6 +42,7 @@ typedef struct { * RDB / AOF saving process from the child to the parent (for instance * the amount of copy on write memory used) */ void openChildInfoPipe(void) { + serverAssert(g_pserver->child_info_pipe[0] == -1); if (pipe(g_pserver->child_info_pipe) == -1) { /* On error our two file descriptors should be still set to -1, * but we call anyway closeChildInfoPipe() since can't hurt. */ diff --git a/src/rdb.cpp b/src/rdb.cpp index 593f3c911..7e2c7f125 100644 --- a/src/rdb.cpp +++ b/src/rdb.cpp @@ -1490,7 +1490,7 @@ int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdb rio rdb; int error = 0; - snprintf(tmpfile,sizeof(tmpfile),"temp-%d-%d.rdb", getpid(), g_pserver->rdbThreadVars.tmpfileNum); + getTempFileName(tmpfile, g_pserver->rdbThreadVars.tmpfileNum); fp = fopen(tmpfile,"w"); if (!fp) { char *cwdp = getcwd(cwd,MAXPATHLEN); @@ -1660,12 +1660,14 @@ int launchRdbSaveThread(pthread_t &child, rdbSaveInfo *rsi) pthread_attr_t tattr; pthread_attr_init(&tattr); pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB + openChildInfoPipe(); if (pthread_create(&child, &tattr, rdbSaveThread, args)) { pthread_attr_destroy(&tattr); for (int idb = 0; idb < cserver.dbnum; ++idb) g_pserver->db[idb]->endSnapshot(args->rgpdb[idb]); args->~rdbSaveThreadArgs(); zfree(args); + closeChildInfoPipe(); return C_ERR; } pthread_attr_destroy(&tattr); @@ -1683,13 +1685,11 @@ int rdbSaveBackground(rdbSaveInfo *rsi) { g_pserver->dirty_before_bgsave = g_pserver->dirty; g_pserver->lastbgsave_try = time(NULL); - openChildInfoPipe(); start = ustime(); latencyStartMonitor(g_pserver->rdb_save_latency); if (launchRdbSaveThread(child, rsi) != C_OK) { - closeChildInfoPipe(); g_pserver->lastbgsave_status = C_ERR; serverLog(LL_WARNING,"Can't save in background: fork: %s", strerror(errno)); diff --git a/src/rdb.h b/src/rdb.h index 2e017e4e0..68dc7a138 100644 --- a/src/rdb.h +++ b/src/rdb.h @@ -151,6 +151,7 @@ int rdbLoad(rdbSaveInfo *rsi, int rdbflags); int rdbLoadFile(const char *filename, rdbSaveInfo *rsi, int rdbflags); int rdbSaveBackground(rdbSaveInfo *rsi); int rdbSaveToSlavesSockets(rdbSaveInfo *rsi); +void getTempFileName(char tmpfile[], int tmpfileNum); void rdbRemoveTempFile(pid_t childpid, int from_signal); int rdbSave(const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi); int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi);