aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c71
-rw-r--r--src/backend/utils/misc/tzparser.c33
2 files changed, 87 insertions, 17 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index f27a83e1f88..9f7aef1a93f 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.577 2009/04/05 04:19:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.578 2009/05/02 22:02:37 tgl Exp $
*
* NOTES
*
@@ -315,6 +315,7 @@ extern int optreset; /* might not be declared by system headers */
/*
* postmaster.c - function prototypes
*/
+static void getInstallationPaths(const char *argv0);
static void checkDataDir(void);
#ifdef USE_BONJOUR
@@ -493,11 +494,8 @@ PostmasterMain(int argc, char *argv[])
ALLOCSET_DEFAULT_MAXSIZE);
MemoryContextSwitchTo(PostmasterContext);
- if (find_my_exec(argv[0], my_exec_path) < 0)
- elog(FATAL, "%s: could not locate my own executable path",
- argv[0]);
-
- get_pkglib_path(my_exec_path, pkglib_path);
+ /* Initialize paths to installation files */
+ getInstallationPaths(argv[0]);
/*
* Options setup
@@ -690,15 +688,6 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(1);
}
-#ifdef EXEC_BACKEND
- /* Locate executable backend before we change working directory */
- if (find_other_exec(argv[0], "postgres", PG_BACKEND_VERSIONSTR,
- postgres_exec_path) < 0)
- ereport(FATAL,
- (errmsg("%s: could not locate matching postgres executable",
- progname)));
-#endif
-
/*
* Locate the proper configuration files and data directory, and read
* postgresql.conf for the first time.
@@ -1063,6 +1052,58 @@ PostmasterMain(int argc, char *argv[])
/*
+ * Compute and check the directory paths to files that are part of the
+ * installation (as deduced from the postgres executable's own location)
+ */
+static void
+getInstallationPaths(const char *argv0)
+{
+ DIR *pdir;
+
+ /* Locate the postgres executable itself */
+ if (find_my_exec(argv0, my_exec_path) < 0)
+ elog(FATAL, "%s: could not locate my own executable path", argv0);
+
+#ifdef EXEC_BACKEND
+ /* Locate executable backend before we change working directory */
+ if (find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
+ postgres_exec_path) < 0)
+ ereport(FATAL,
+ (errmsg("%s: could not locate matching postgres executable",
+ argv0)));
+#endif
+
+ /*
+ * Locate the pkglib directory --- this has to be set early in case we try
+ * to load any modules from it in response to postgresql.conf entries.
+ */
+ get_pkglib_path(my_exec_path, pkglib_path);
+
+ /*
+ * Verify that there's a readable directory there; otherwise the
+ * Postgres installation is incomplete or corrupt. (A typical cause
+ * of this failure is that the postgres executable has been moved or
+ * hardlinked to some directory that's not a sibling of the installation
+ * lib/ directory.)
+ */
+ pdir = AllocateDir(pkglib_path);
+ if (pdir == NULL)
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not open directory \"%s\": %m",
+ pkglib_path),
+ errhint("This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location.",
+ my_exec_path)));
+ FreeDir(pdir);
+
+ /*
+ * XXX is it worth similarly checking the share/ directory? If the
+ * lib/ directory is there, then share/ probably is too.
+ */
+}
+
+
+/*
* Validate the proposed data directory
*/
static void
diff --git a/src/backend/utils/misc/tzparser.c b/src/backend/utils/misc/tzparser.c
index f7d6c84514e..cc688dcaba1 100644
--- a/src/backend/utils/misc/tzparser.c
+++ b/src/backend/utils/misc/tzparser.c
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/tzparser.c,v 1.7 2009/01/01 17:23:53 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/tzparser.c,v 1.8 2009/05/02 22:02:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -326,12 +326,41 @@ ParseTzFile(const char *filename, int depth,
tzFile = AllocateFile(file_path, "r");
if (!tzFile)
{
- /* at level 0, if file doesn't exist, guc.c's complaint is enough */
+ /*
+ * Check to see if the problem is not the filename but the directory.
+ * This is worth troubling over because if the installation share/
+ * directory is missing or unreadable, this is likely to be the first
+ * place we notice a problem during postmaster startup.
+ */
+ int save_errno = errno;
+ DIR *tzdir;
+
+ snprintf(file_path, sizeof(file_path), "%s/timezonesets",
+ share_path);
+ tzdir = AllocateDir(file_path);
+ if (tzdir == NULL)
+ {
+ ereport(tz_elevel,
+ (errcode_for_file_access(),
+ errmsg("could not open directory \"%s\": %m",
+ file_path),
+ errhint("This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location.",
+ my_exec_path)));
+ return -1;
+ }
+ FreeDir(tzdir);
+ errno = save_errno;
+
+ /*
+ * otherwise, if file doesn't exist and it's level 0, guc.c's
+ * complaint is enough
+ */
if (errno != ENOENT || depth > 0)
ereport(tz_elevel,
(errcode_for_file_access(),
errmsg("could not read time zone file \"%s\": %m",
filename)));
+
return -1;
}