From e9a4bb98173f695e37689e074b3dfe15f7cdca63 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 28 Feb 2026 18:36:03 +0800 Subject: [PATCH 1/2] initdb: reset and preserve errno when scanning cdb_init.d initdb's setup_cdb_schema() checked errno after readdir() iteration, but did not clear errno before entering the loop. On some environments (observed on Ubuntu 24.04), a stale errno value can survive into this check and be misinterpreted as a readdir failure, causing: error while reading cdb_init.d directory: Function not implemented Fix by: - setting errno=0 before the readdir() loop - storing readdir errno immediately after the loop - handling closedir() errors separately - using the saved readdir errno for the post-loop error check This prevents false-positive failures during initdb while preserving proper I/O error reporting. --- src/bin/initdb/initdb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 708cf77ffdf..d9722930435 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2011,6 +2011,7 @@ setup_cdb_schema(FILE *cmdfd) DIR *dir; struct dirent *file; int nscripts; + int readdir_errno; char **scriptnames = NULL; int i; @@ -2024,6 +2025,7 @@ setup_cdb_schema(FILE *cmdfd) /* Collect all files with .sql suffix in array. */ nscripts = 0; + errno = 0; while ((file = readdir(dir)) != NULL) { int namelen = strlen(file->d_name); @@ -2054,11 +2056,18 @@ setup_cdb_schema(FILE *cmdfd) errno = 0; #endif - closedir(dir); + readdir_errno = errno; + + if (closedir(dir)) + { + pg_log_error("could not close cdb_init.d directory: %m"); + exit(1); + } - if (errno != 0) + if (readdir_errno != 0) { /* some kind of I/O error? */ + errno = readdir_errno; pg_log_error("error while reading cdb_init.d directory: %m"); exit(1); } From f91837baa26deca5a4aa56174a7ffebf07dbb5e3 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Mon, 2 Mar 2026 17:38:54 +0800 Subject: [PATCH 2/2] Address the comment --- src/bin/initdb/initdb.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index d9722930435..67e432358f6 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2011,7 +2011,6 @@ setup_cdb_schema(FILE *cmdfd) DIR *dir; struct dirent *file; int nscripts; - int readdir_errno; char **scriptnames = NULL; int i; @@ -2056,19 +2055,16 @@ setup_cdb_schema(FILE *cmdfd) errno = 0; #endif - readdir_errno = errno; - - if (closedir(dir)) + if (errno) { - pg_log_error("could not close cdb_init.d directory: %m"); + pg_log_error("error while reading cdb_init.d directory: %m"); + closedir(dir); exit(1); } - if (readdir_errno != 0) + if (closedir(dir)) { - /* some kind of I/O error? */ - errno = readdir_errno; - pg_log_error("error while reading cdb_init.d directory: %m"); + pg_log_error("error while closing cdb_init.d directory: %m"); exit(1); }