Skip to content

Commit 071d9f0

Browse files
committed
pg_upgrade: throw an error for non-existent tablespace directories
Non-existent tablespace directory references can occur if user tablespaces are created inside data directories and the data directory is renamed in preparation for running pg_upgrade, and the symbolic links are not updated. Backpatch to 9.3.
1 parent 95aa823 commit 071d9f0

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

contrib/pg_upgrade/tablespace.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include "pg_upgrade.h"
1313

14+
#include <sys/types.h>
15+
1416
static void get_tablespace_paths(void);
1517
static void set_tablespace_directory_suffix(ClusterInfo *cluster);
1618

@@ -66,9 +68,39 @@ get_tablespace_paths(void)
6668
i_spclocation = PQfnumber(res, "spclocation");
6769

6870
for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
71+
{
72+
struct stat statBuf;
73+
6974
os_info.old_tablespaces[tblnum] = pg_strdup(
7075
PQgetvalue(res, tblnum, i_spclocation));
7176

77+
/*
78+
* Check that the tablespace path exists and is a directory.
79+
* Effectively, this is checking only for tables/indexes in
80+
* non-existent tablespace directories. Databases located in
81+
* non-existent tablespaces already throw a backend error.
82+
* Non-existent tablespace directories can occur when a data
83+
* directory that contains user tablespaces is moved as part
84+
* of pg_upgrade preparation and the symbolic links are not
85+
* updated.
86+
*/
87+
if (stat(os_info.old_tablespaces[tblnum], &statBuf) != 0)
88+
{
89+
if (errno == ENOENT)
90+
report_status(PG_FATAL,
91+
"tablespace directory \"%s\" does not exist\n",
92+
os_info.old_tablespaces[tblnum]);
93+
else
94+
report_status(PG_FATAL,
95+
"cannot stat() tablespace directory \"%s\": %s\n",
96+
os_info.old_tablespaces[tblnum], getErrorText(errno));
97+
}
98+
if (!S_ISDIR(statBuf.st_mode))
99+
report_status(PG_FATAL,
100+
"tablespace path \"%s\" is not a directory\n",
101+
os_info.old_tablespaces[tblnum]);
102+
}
103+
72104
PQclear(res);
73105

74106
PQfinish(conn);

0 commit comments

Comments
 (0)