aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/postmaster.c24
-rw-r--r--src/backend/storage/file/fd.c136
-rw-r--r--src/include/storage/fd.h3
3 files changed, 140 insertions, 23 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 96d7d1e3ad9..6334cdd7e37 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -28,7 +28,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.217 2001/06/07 04:50:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.218 2001/06/11 04:12:29 tgl Exp $
*
* NOTES
*
@@ -243,9 +243,14 @@ static void RandomSalt(char *salt);
static void SignalChildren(int signal);
static int CountChildren(void);
static bool CreateOptsFile(int argc, char *argv[]);
-static void postmaster_error(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
-
static pid_t SSDataBase(int xlop);
+#ifdef __GNUC__
+/* This checks the format string for consistency. */
+static void postmaster_error(const char *fmt, ...)
+ __attribute__((format(printf, 1, 2)));
+#else
+static void postmaster_error(const char *fmt, ...);
+#endif
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
@@ -253,7 +258,6 @@ static pid_t SSDataBase(int xlop);
#ifdef USE_SSL
static void InitSSL(void);
-
#endif
@@ -597,6 +601,12 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster(1);
/*
+ * Remove old temporary files. At this point there can be no other
+ * Postgres processes running in this directory, so this should be safe.
+ */
+ RemovePgTempFiles();
+
+ /*
* Establish input sockets.
*/
#ifdef USE_SSL
@@ -613,7 +623,8 @@ PostmasterMain(int argc, char *argv[])
if (NetServer)
{
status = StreamServerPort(AF_INET, VirtualHost,
- (unsigned short) PostPortNumber, UnixSocketDir,
+ (unsigned short) PostPortNumber,
+ UnixSocketDir,
&ServerSock_INET);
if (status != STATUS_OK)
{
@@ -624,7 +635,8 @@ PostmasterMain(int argc, char *argv[])
#ifdef HAVE_UNIX_SOCKETS
status = StreamServerPort(AF_UNIX, VirtualHost,
- (unsigned short) PostPortNumber, UnixSocketDir,
+ (unsigned short) PostPortNumber,
+ UnixSocketDir,
&ServerSock_UNIX);
if (status != STATUS_OK)
{
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 237ae0a4428..f37a9573df9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.80 2001/06/06 17:07:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.81 2001/06/11 04:12:29 tgl Exp $
*
* NOTES:
*
@@ -44,6 +44,7 @@
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
+#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
@@ -51,6 +52,12 @@
#include "miscadmin.h"
#include "storage/fd.h"
+
+/* Filename components for OpenTemporaryFile */
+#define PG_TEMP_FILES_DIR "pg_tempfiles"
+#define PG_TEMP_FILE_PREFIX "pg_temp"
+
+
/*
* Problem: Postgres does a system(ld...) to do dynamic loading.
* This will open several extra files in addition to those used by
@@ -189,7 +196,7 @@ static void FreeVfd(File file);
static int FileAccess(File file);
static File fileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
-static char *filepath(char *filename);
+static char *filepath(const char *filename);
static long pg_nofile(void);
/*
@@ -568,28 +575,27 @@ FreeVfd(File file)
/* filepath()
* Convert given pathname to absolute.
*
+ * Result is a palloc'd string.
+ *
* (Generally, this isn't actually necessary, considering that we
* should be cd'd into the database directory. Presently it is only
* necessary to do it in "bootstrap" mode. Maybe we should change
* bootstrap mode to do the cd, and save a few cycles/bytes here.)
*/
static char *
-filepath(char *filename)
+filepath(const char *filename)
{
char *buf;
- int len;
/* Not an absolute path name? Then fill in with database path... */
if (*filename != '/')
{
- len = strlen(DatabasePath) + strlen(filename) + 2;
- buf = (char *) palloc(len);
+ buf = (char *) palloc(strlen(DatabasePath) + strlen(filename) + 2);
sprintf(buf, "%s/%s", DatabasePath, filename);
}
else
{
- buf = (char *) palloc(strlen(filename) + 1);
- strcpy(buf, filename);
+ buf = pstrdup(filename);
}
#ifdef FILEDEBUG
@@ -742,21 +748,46 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
File
OpenTemporaryFile(void)
{
- char tempfilename[64];
+ char tempfilepath[128];
File file;
/*
* Generate a tempfile name that's unique within the current
- * transaction
+ * transaction and database instance.
*/
- snprintf(tempfilename, sizeof(tempfilename),
- "pg_sorttemp%d.%ld", MyProcPid, tempFileCounter++);
+ snprintf(tempfilepath, sizeof(tempfilepath),
+ "%s/%s%d.%ld", PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
+ MyProcPid, tempFileCounter++);
- /* Open the file */
- file = FileNameOpenFile(tempfilename,
- O_RDWR | O_CREAT | O_TRUNC | PG_BINARY, 0600);
+ /*
+ * Open the file. Note: we don't use O_EXCL, in case there is an
+ * orphaned temp file that can be reused.
+ */
+ file = FileNameOpenFile(tempfilepath,
+ O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
+ 0600);
if (file <= 0)
- elog(ERROR, "Failed to create temporary file %s", tempfilename);
+ {
+ char *dirpath;
+
+ /*
+ * We might need to create the pg_tempfiles subdirectory, if
+ * no one has yet done so.
+ *
+ * Don't check for error from mkdir; it could fail if someone else
+ * just did the same thing. If it doesn't work then we'll bomb out
+ * on the second create attempt, instead.
+ */
+ dirpath = filepath(PG_TEMP_FILES_DIR);
+ mkdir(dirpath, S_IRWXU);
+ pfree(dirpath);
+
+ file = FileNameOpenFile(tempfilepath,
+ O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
+ 0600);
+ if (file <= 0)
+ elog(ERROR, "Failed to create temporary file %s", tempfilepath);
+ }
/* Mark it for deletion at close or EOXact */
VfdCache[file].fdstate |= FD_TEMPORARY;
@@ -1203,3 +1234,76 @@ AtEOXact_Files(void)
*/
tempFileCounter = 0;
}
+
+
+/*
+ * Remove old temporary files
+ *
+ * This should be called during postmaster startup. It will forcibly
+ * remove any leftover files created by OpenTemporaryFile.
+ */
+void
+RemovePgTempFiles(void)
+{
+ char db_path[MAXPGPATH];
+ char temp_path[MAXPGPATH];
+ char rm_path[MAXPGPATH];
+ DIR *db_dir;
+ DIR *temp_dir;
+ struct dirent *db_de;
+ struct dirent *temp_de;
+
+ /*
+ * Cycle through pg_tempfiles for all databases
+ * and remove old temp files.
+ */
+ snprintf(db_path, sizeof(db_path), "%s/base", DataDir);
+ if ((db_dir = opendir(db_path)) != NULL)
+ {
+ while ((db_de = readdir(db_dir)) != NULL)
+ {
+ if (strcmp(db_de->d_name, ".") == 0 ||
+ strcmp(db_de->d_name, "..") == 0)
+ continue;
+
+ snprintf(temp_path, sizeof(temp_path),
+ "%s/%s/%s",
+ db_path, db_de->d_name,
+ PG_TEMP_FILES_DIR);
+ if ((temp_dir = opendir(temp_path)) != NULL)
+ {
+ while ((temp_de = readdir(temp_dir)) != NULL)
+ {
+ if (strcmp(temp_de->d_name, ".") == 0 ||
+ strcmp(temp_de->d_name, "..") == 0)
+ continue;
+
+ snprintf(rm_path, sizeof(temp_path),
+ "%s/%s/%s/%s",
+ db_path, db_de->d_name,
+ PG_TEMP_FILES_DIR,
+ temp_de->d_name);
+
+ if (strncmp(temp_de->d_name,
+ PG_TEMP_FILE_PREFIX,
+ strlen(PG_TEMP_FILE_PREFIX)) == 0)
+ {
+ unlink(rm_path);
+ }
+ else
+ {
+ /*
+ * would prefer to use elog here, but it's not
+ * up and running during postmaster startup...
+ */
+ fprintf(stderr,
+ "Unexpected file found in temporary-files directory: %s\n",
+ rm_path);
+ }
+ }
+ closedir(temp_dir);
+ }
+ }
+ closedir(db_dir);
+ }
+}
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 6bb690c3f57..f3e06978a67 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: fd.h,v 1.29 2001/05/25 15:45:34 momjian Exp $
+ * $Id: fd.h,v 1.30 2001/06/11 04:12:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,6 +70,7 @@ extern int BasicOpenFile(FileName fileName, int fileFlags, int fileMode);
/* Miscellaneous support routines */
extern void closeAllVfds(void);
extern void AtEOXact_Files(void);
+extern void RemovePgTempFiles(void);
extern int pg_fsync(int fd);
extern int pg_fdatasync(int fd);