1996-08-27 21:59:28 -04:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
*
|
1999-02-13 18:22:53 -05:00
|
|
|
* fd.h
|
1997-09-07 01:04:48 -04:00
|
|
|
* Virtual file descriptor definitions.
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
|
|
|
|
*
|
2014-01-07 16:05:30 -05:00
|
|
|
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
|
2000-01-26 00:58:53 -05:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
2010-09-20 16:08:53 -04:00
|
|
|
* src/include/storage/fd.h
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
1999-10-13 11:02:32 -04:00
|
|
|
|
1996-08-27 21:59:28 -04:00
|
|
|
/*
|
|
|
|
|
* calls:
|
1997-09-07 01:04:48 -04:00
|
|
|
*
|
2004-05-30 23:48:10 -04:00
|
|
|
* File {Close, Read, Write, Seek, Tell, Sync}
|
Add OpenTransientFile, with automatic cleanup at end-of-xact.
Files opened with BasicOpenFile or PathNameOpenFile are not automatically
cleaned up on error. That puts unnecessary burden on callers that only want
to keep the file open for a short time. There is AllocateFile, but that
returns a buffered FILE * stream, which in many cases is not the nicest API
to work with. So add function called OpenTransientFile, which returns a
unbuffered fd that's cleaned up like the FILE* returned by AllocateFile().
This plugs a few rare fd leaks in error cases:
1. copy_file() - fixed by by using OpenTransientFile instead of BasicOpenFile
2. XLogFileInit() - fixed by adding close() calls to the error cases. Can't
use OpenTransientFile here because the fd is supposed to persist over
transaction boundaries.
3. lo_import/lo_export - fixed by using OpenTransientFile instead of
PathNameOpenFile.
In addition to plugging those leaks, this replaces many BasicOpenFile() calls
with OpenTransientFile() that were not leaking, because the code meticulously
closed the file on error. That wasn't strictly necessary, but IMHO it's good
for robustness.
The same leaks exist in older versions, but given the rarity of the issues,
I'm not backpatching this. Not yet, anyway - it might be good to backpatch
later, after this mechanism has had some more testing in master branch.
2012-11-27 03:25:50 -05:00
|
|
|
* {Path Name Open, Allocate, Free} File
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
|
|
|
|
* These are NOT JUST RENAMINGS OF THE UNIX ROUTINES.
|
1999-05-08 20:52:08 -04:00
|
|
|
* Use them for all file activity...
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
1997-09-07 01:04:48 -04:00
|
|
|
* File fd;
|
Add OpenTransientFile, with automatic cleanup at end-of-xact.
Files opened with BasicOpenFile or PathNameOpenFile are not automatically
cleaned up on error. That puts unnecessary burden on callers that only want
to keep the file open for a short time. There is AllocateFile, but that
returns a buffered FILE * stream, which in many cases is not the nicest API
to work with. So add function called OpenTransientFile, which returns a
unbuffered fd that's cleaned up like the FILE* returned by AllocateFile().
This plugs a few rare fd leaks in error cases:
1. copy_file() - fixed by by using OpenTransientFile instead of BasicOpenFile
2. XLogFileInit() - fixed by adding close() calls to the error cases. Can't
use OpenTransientFile here because the fd is supposed to persist over
transaction boundaries.
3. lo_import/lo_export - fixed by using OpenTransientFile instead of
PathNameOpenFile.
In addition to plugging those leaks, this replaces many BasicOpenFile() calls
with OpenTransientFile() that were not leaking, because the code meticulously
closed the file on error. That wasn't strictly necessary, but IMHO it's good
for robustness.
The same leaks exist in older versions, but given the rarity of the issues,
I'm not backpatching this. Not yet, anyway - it might be good to backpatch
later, after this mechanism has had some more testing in master branch.
2012-11-27 03:25:50 -05:00
|
|
|
* fd = PathNameOpenFile("foo", O_RDONLY, 0600);
|
1996-08-27 21:59:28 -04:00
|
|
|
*
|
1997-09-07 01:04:48 -04:00
|
|
|
* AllocateFile();
|
|
|
|
|
* FreeFile();
|
1999-05-08 20:52:08 -04:00
|
|
|
*
|
|
|
|
|
* Use AllocateFile, not fopen, if you need a stdio file (FILE*); then
|
|
|
|
|
* use FreeFile, not fclose, to close it. AVOID using stdio for files
|
|
|
|
|
* that you intend to hold open for any length of time, since there is
|
|
|
|
|
* no way for them to share kernel file descriptors with other files.
|
2004-02-23 18:03:10 -05:00
|
|
|
*
|
|
|
|
|
* Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate
|
Add OpenTransientFile, with automatic cleanup at end-of-xact.
Files opened with BasicOpenFile or PathNameOpenFile are not automatically
cleaned up on error. That puts unnecessary burden on callers that only want
to keep the file open for a short time. There is AllocateFile, but that
returns a buffered FILE * stream, which in many cases is not the nicest API
to work with. So add function called OpenTransientFile, which returns a
unbuffered fd that's cleaned up like the FILE* returned by AllocateFile().
This plugs a few rare fd leaks in error cases:
1. copy_file() - fixed by by using OpenTransientFile instead of BasicOpenFile
2. XLogFileInit() - fixed by adding close() calls to the error cases. Can't
use OpenTransientFile here because the fd is supposed to persist over
transaction boundaries.
3. lo_import/lo_export - fixed by using OpenTransientFile instead of
PathNameOpenFile.
In addition to plugging those leaks, this replaces many BasicOpenFile() calls
with OpenTransientFile() that were not leaking, because the code meticulously
closed the file on error. That wasn't strictly necessary, but IMHO it's good
for robustness.
The same leaks exist in older versions, but given the rarity of the issues,
I'm not backpatching this. Not yet, anyway - it might be good to backpatch
later, after this mechanism has had some more testing in master branch.
2012-11-27 03:25:50 -05:00
|
|
|
* open directories (DIR*), and OpenTransientFile/CloseTransient File for an
|
|
|
|
|
* unbuffered file descriptor.
|
1996-08-27 21:59:28 -04:00
|
|
|
*/
|
1997-09-07 01:04:48 -04:00
|
|
|
#ifndef FD_H
|
1996-08-27 21:59:28 -04:00
|
|
|
#define FD_H
|
|
|
|
|
|
2004-02-23 18:03:10 -05:00
|
|
|
#include <dirent.h>
|
|
|
|
|
|
|
|
|
|
|
1996-08-27 21:59:28 -04:00
|
|
|
/*
|
|
|
|
|
* FileSeek uses the standard UNIX lseek(2) flags.
|
|
|
|
|
*/
|
|
|
|
|
|
1997-09-07 22:41:22 -04:00
|
|
|
typedef char *FileName;
|
1996-08-27 21:59:28 -04:00
|
|
|
|
1997-09-07 22:41:22 -04:00
|
|
|
typedef int File;
|
1996-08-27 21:59:28 -04:00
|
|
|
|
2001-09-30 14:57:45 -04:00
|
|
|
|
|
|
|
|
/* GUC parameter */
|
2017-12-05 09:24:12 -05:00
|
|
|
extern PGDLLIMPORT int max_files_per_process;
|
2001-09-30 14:57:45 -04:00
|
|
|
|
2012-03-29 01:19:11 -04:00
|
|
|
/*
|
|
|
|
|
* This is private to fd.c, but exported for save/restore_backend_variables()
|
|
|
|
|
*/
|
|
|
|
|
extern int max_safe_fds;
|
|
|
|
|
|
2001-09-30 14:57:45 -04:00
|
|
|
|
1996-08-27 21:59:28 -04:00
|
|
|
/*
|
|
|
|
|
* prototypes for functions in fd.c
|
|
|
|
|
*/
|
1999-05-08 20:52:08 -04:00
|
|
|
|
|
|
|
|
/* Operations on virtual Files --- equivalent to Unix kernel file ops */
|
1997-09-07 22:41:22 -04:00
|
|
|
extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode);
|
2007-06-07 15:19:57 -04:00
|
|
|
extern File OpenTemporaryFile(bool interXact);
|
1997-09-07 22:41:22 -04:00
|
|
|
extern void FileClose(File file);
|
2009-01-12 00:10:45 -05:00
|
|
|
extern int FilePrefetch(File file, off_t offset, int amount);
|
1997-09-07 22:41:22 -04:00
|
|
|
extern int FileRead(File file, char *buffer, int amount);
|
|
|
|
|
extern int FileWrite(File file, char *buffer, int amount);
|
2004-05-30 23:48:10 -04:00
|
|
|
extern int FileSync(File file);
|
2008-03-10 16:06:27 -04:00
|
|
|
extern off_t FileSeek(File file, off_t offset, int whence);
|
|
|
|
|
extern int FileTruncate(File file, off_t offset);
|
2009-08-05 14:01:54 -04:00
|
|
|
extern char *FilePathName(File file);
|
1999-05-08 20:52:08 -04:00
|
|
|
|
|
|
|
|
/* Operations that allow use of regular stdio --- USE WITH CAUTION */
|
2006-03-04 16:32:47 -05:00
|
|
|
extern FILE *AllocateFile(const char *name, const char *mode);
|
2004-02-23 18:03:10 -05:00
|
|
|
extern int FreeFile(FILE *file);
|
|
|
|
|
|
Add support for piping COPY to/from an external program.
This includes backend "COPY TO/FROM PROGRAM '...'" syntax, and corresponding
psql \copy syntax. Like with reading/writing files, the backend version is
superuser-only, and in the psql version, the program is run in the client.
In the passing, the psql \copy STDIN/STDOUT syntax is subtly changed: if you
the stdin/stdout is quoted, it's now interpreted as a filename. For example,
"\copy foo from 'stdin'" now reads from a file called 'stdin', not from
standard input. Before this, there was no way to specify a filename called
stdin, stdout, pstdin or pstdout.
This creates a new function in pgport, wait_result_to_str(), which can
be used to convert the exit status of a process, as returned by wait(3),
to a human-readable string.
Etsuro Fujita, reviewed by Amit Kapila.
2013-02-27 11:17:21 -05:00
|
|
|
/* Operations that allow use of pipe streams (popen/pclose) */
|
|
|
|
|
extern FILE *OpenPipeStream(const char *command, const char *mode);
|
|
|
|
|
extern int ClosePipeStream(FILE *file);
|
|
|
|
|
|
2004-02-23 18:03:10 -05:00
|
|
|
/* Operations to allow use of the <dirent.h> library routines */
|
|
|
|
|
extern DIR *AllocateDir(const char *dirname);
|
2005-06-19 17:34:03 -04:00
|
|
|
extern struct dirent *ReadDir(DIR *dir, const char *dirname);
|
Clean up assorted messiness around AllocateDir() usage.
This patch fixes a couple of low-probability bugs that could lead to
reporting an irrelevant errno value (and hence possibly a wrong SQLSTATE)
concerning directory-open or file-open failures. It also fixes places
where we took shortcuts in reporting such errors, either by using elog
instead of ereport or by using ereport but forgetting to specify an
errcode. And it eliminates a lot of just plain redundant error-handling
code.
In service of all this, export fd.c's formerly-static function
ReadDirExtended, so that external callers can make use of the coding
pattern
dir = AllocateDir(path);
while ((de = ReadDirExtended(dir, path, LOG)) != NULL)
if they'd like to treat directory-open failures as mere LOG conditions
rather than errors. Also fix FreeDir to be a no-op if we reach it
with dir == NULL, as such a coding pattern would cause.
Then, remove code at many call sites that was throwing an error or log
message for AllocateDir failure, as ReadDir or ReadDirExtended can handle
that job just fine. Aside from being a net code savings, this gets rid of
a lot of not-quite-up-to-snuff reports, as mentioned above. (In some
places these changes result in replacing a custom error message such as
"could not open tablespace directory" with more generic wording "could not
open directory", but it was agreed that the custom wording buys little as
long as we report the directory name.) In some other call sites where we
can't just remove code, change the error reports to be fully
project-style-compliant.
Also reorder code in restoreTwoPhaseData that was acquiring a lock
between AllocateDir and ReadDir; in the unlikely but surely not
impossible case that LWLockAcquire changes errno, AllocateDir failures
would be misreported. There is no great value in opening the directory
before acquiring TwoPhaseStateLock, so just do it in the other order.
Also fix CheckXLogRemoved to guarantee that it preserves errno,
as quite a number of call sites are implicitly assuming. (Again,
it's unlikely but I think not impossible that errno could change
during a SpinLockAcquire. If so, this function was broken for its
own purposes as well as breaking callers.)
And change a few places that were using not-per-project-style messages,
such as "could not read directory" when "could not open directory" is
more correct.
Back-patch the exporting of ReadDirExtended, in case we have occasion
to back-patch some fix that makes use of it; it's not needed right now
but surely making it global is pretty harmless. Also back-patch the
restoreTwoPhaseData and CheckXLogRemoved fixes. The rest of this is
essentially cosmetic and need not get back-patched.
Michael Paquier, with a bit of additional work by me
Discussion: https://postgr.es/m/CAB7nPqRpOCxjiirHmebEFhXVTK7V5Jvw4bz82p7Oimtsm3TyZA@mail.gmail.com
2017-12-04 17:02:52 -05:00
|
|
|
extern struct dirent *ReadDirExtended(DIR *dir, const char *dirname,
|
|
|
|
|
int elevel);
|
2004-02-23 18:03:10 -05:00
|
|
|
extern int FreeDir(DIR *dir);
|
1999-05-08 20:52:08 -04:00
|
|
|
|
Add OpenTransientFile, with automatic cleanup at end-of-xact.
Files opened with BasicOpenFile or PathNameOpenFile are not automatically
cleaned up on error. That puts unnecessary burden on callers that only want
to keep the file open for a short time. There is AllocateFile, but that
returns a buffered FILE * stream, which in many cases is not the nicest API
to work with. So add function called OpenTransientFile, which returns a
unbuffered fd that's cleaned up like the FILE* returned by AllocateFile().
This plugs a few rare fd leaks in error cases:
1. copy_file() - fixed by by using OpenTransientFile instead of BasicOpenFile
2. XLogFileInit() - fixed by adding close() calls to the error cases. Can't
use OpenTransientFile here because the fd is supposed to persist over
transaction boundaries.
3. lo_import/lo_export - fixed by using OpenTransientFile instead of
PathNameOpenFile.
In addition to plugging those leaks, this replaces many BasicOpenFile() calls
with OpenTransientFile() that were not leaking, because the code meticulously
closed the file on error. That wasn't strictly necessary, but IMHO it's good
for robustness.
The same leaks exist in older versions, but given the rarity of the issues,
I'm not backpatching this. Not yet, anyway - it might be good to backpatch
later, after this mechanism has had some more testing in master branch.
2012-11-27 03:25:50 -05:00
|
|
|
/* Operations to allow use of a plain kernel FD, with automatic cleanup */
|
|
|
|
|
extern int OpenTransientFile(FileName fileName, int fileFlags, int fileMode);
|
|
|
|
|
extern int CloseTransientFile(int fd);
|
|
|
|
|
|
2000-06-01 23:58:34 -04:00
|
|
|
/* If you've really really gotta have a plain kernel FD, use this */
|
|
|
|
|
extern int BasicOpenFile(FileName fileName, int fileFlags, int fileMode);
|
|
|
|
|
|
1999-05-08 20:52:08 -04:00
|
|
|
/* Miscellaneous support routines */
|
2005-08-07 23:12:16 -04:00
|
|
|
extern void InitFileAccess(void);
|
2004-02-23 15:45:59 -05:00
|
|
|
extern void set_max_safe_fds(void);
|
1997-09-07 22:41:22 -04:00
|
|
|
extern void closeAllVfds(void);
|
2007-06-07 15:19:57 -04:00
|
|
|
extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces);
|
|
|
|
|
extern bool TempTablespacesAreSet(void);
|
|
|
|
|
extern Oid GetNextTempTableSpace(void);
|
1999-05-08 20:52:08 -04:00
|
|
|
extern void AtEOXact_Files(void);
|
2004-09-16 12:58:44 -04:00
|
|
|
extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid,
|
2005-10-14 22:49:52 -04:00
|
|
|
SubTransactionId parentSubid);
|
2001-06-11 00:12:29 -04:00
|
|
|
extern void RemovePgTempFiles(void);
|
2007-06-07 15:19:57 -04:00
|
|
|
|
2000-12-08 17:21:33 -05:00
|
|
|
extern int pg_fsync(int fd);
|
2005-05-20 10:53:26 -04:00
|
|
|
extern int pg_fsync_no_writethrough(int fd);
|
|
|
|
|
extern int pg_fsync_writethrough(int fd);
|
2001-02-17 23:39:42 -05:00
|
|
|
extern int pg_fdatasync(int fd);
|
2010-02-25 21:01:40 -05:00
|
|
|
extern int pg_flush_data(int fd, off_t offset, off_t amount);
|
2016-03-09 21:53:54 -05:00
|
|
|
extern void fsync_fname(const char *fname, bool isdir);
|
|
|
|
|
extern int durable_rename(const char *oldfile, const char *newfile, int loglevel);
|
|
|
|
|
extern int durable_link_or_rename(const char *oldfile, const char *newfile, int loglevel);
|
Fix fsync-at-startup code to not treat errors as fatal.
Commit 2ce439f3379aed857517c8ce207485655000fc8e introduced a rather serious
regression, namely that if its scan of the data directory came across any
un-fsync-able files, it would fail and thereby prevent database startup.
Worse yet, symlinks to such files also caused the problem, which meant that
crash restart was guaranteed to fail on certain common installations such
as older Debian.
After discussion, we agreed that (1) failure to start is worse than any
consequence of not fsync'ing is likely to be, therefore treat all errors
in this code as nonfatal; (2) we should not chase symlinks other than
those that are expected to exist, namely pg_xlog/ and tablespace links
under pg_tblspc/. The latter restriction avoids possibly fsync'ing a
much larger part of the filesystem than intended, if the user has left
random symlinks hanging about in the data directory.
This commit takes care of that and also does some code beautification,
mainly moving the relevant code into fd.c, which seems a much better place
for it than xlog.c, and making sure that the conditional compilation for
the pre_sync_fname pass has something to do with whether pg_flush_data
works.
I also relocated the call site in xlog.c down a few lines; it seems a
bit silly to be doing this before ValidateXLOGDirectoryStructure().
The similar logic in initdb.c ought to be made to match this, but that
change is noncritical and will be dealt with separately.
Back-patch to all active branches, like the prior commit.
Abhijit Menon-Sen and Tom Lane
2015-05-28 17:33:03 -04:00
|
|
|
extern void SyncDataDirectory(void);
|
2001-10-28 01:26:15 -05:00
|
|
|
|
2003-12-20 12:31:21 -05:00
|
|
|
/* Filename components for OpenTemporaryFile */
|
|
|
|
|
#define PG_TEMP_FILES_DIR "pgsql_tmp"
|
|
|
|
|
#define PG_TEMP_FILE_PREFIX "pgsql_tmp"
|
|
|
|
|
|
2001-11-05 12:46:40 -05:00
|
|
|
#endif /* FD_H */
|