aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/fd.c
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2018-04-07 17:45:39 -0400
committerStephen Frost <sfrost@snowman.net>2018-04-07 17:45:39 -0400
commitda9b580d89903fee871cf54845ffa2b26bda2e11 (patch)
treec2538c675c15e973c662e58a94fdecd77aa06b2a /src/backend/storage/file/fd.c
parent499be013de65242235ebdde06adb08db887f0ea5 (diff)
downloadpostgresql-da9b580d89903fee871cf54845ffa2b26bda2e11.tar.gz
postgresql-da9b580d89903fee871cf54845ffa2b26bda2e11.zip
Refactor dir/file permissions
Consolidate directory and file create permissions for tools which work with the PG data directory by adding a new module (common/file_perm.c) that contains variables (pg_file_create_mode, pg_dir_create_mode) and constants to initialize them (0600 for files and 0700 for directories). Convert mkdir() calls in the backend to MakePGDirectory() if the original call used default permissions (always the case for regular PG directories). Add tests to make sure permissions in PGDATA are set correctly by the tools which modify the PG data directory. Authors: David Steele <david@pgmasters.net>, Adam Brightwell <adam.brightwell@crunchydata.com> Reviewed-By: Michael Paquier, with discussion amongst many others. Discussion: https://postgr.es/m/ad346fe6-b23e-59f1-ecb7-0e08390ad629%40pgmasters.net
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r--src/backend/storage/file/fd.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index d30a725f900..36eea9d11d0 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -84,6 +84,7 @@
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/pg_tablespace.h"
+#include "common/file_perm.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "storage/fd.h"
@@ -125,12 +126,6 @@
#define FD_MINFREE 10
/*
- * Default mode for created files, unless something else is specified using
- * the *Perm() function variants.
- */
-#define PG_FILE_MODE_DEFAULT (S_IRUSR | S_IWUSR)
-
-/*
* A number of platforms allow individual processes to open many more files
* than they can really support when *many* processes do the same thing.
* This GUC parameter lets the DBA limit max_safe_fds to something less than
@@ -937,7 +932,7 @@ set_max_safe_fds(void)
int
BasicOpenFile(const char *fileName, int fileFlags)
{
- return BasicOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
+ return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
}
/*
@@ -1356,7 +1351,7 @@ FileInvalidate(File file)
File
PathNameOpenFile(const char *fileName, int fileFlags)
{
- return PathNameOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
+ return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
}
/*
@@ -1434,7 +1429,7 @@ PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
void
PathNameCreateTemporaryDir(const char *basedir, const char *directory)
{
- if (mkdir(directory, S_IRWXU) < 0)
+ if (MakePGDirectory(directory) < 0)
{
if (errno == EEXIST)
return;
@@ -1444,14 +1439,14 @@ PathNameCreateTemporaryDir(const char *basedir, const char *directory)
* EEXIST to close a race against another process following the same
* algorithm.
*/
- if (mkdir(basedir, S_IRWXU) < 0 && errno != EEXIST)
+ if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("cannot create temporary directory \"%s\": %m",
basedir)));
/* Try again. */
- if (mkdir(directory, S_IRWXU) < 0 && errno != EEXIST)
+ if (MakePGDirectory(directory) < 0 && errno != EEXIST)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("cannot create temporary subdirectory \"%s\": %m",
@@ -1601,11 +1596,11 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
* We might need to create the tablespace's tempfile directory, 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.
+ * Don't check for an error from MakePGDirectory; 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.
*/
- mkdir(tempdirpath, S_IRWXU);
+ (void) MakePGDirectory(tempdirpath);
file = PathNameOpenFile(tempfilepath,
O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
@@ -2401,7 +2396,7 @@ TryAgain:
int
OpenTransientFile(const char *fileName, int fileFlags)
{
- return OpenTransientFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
+ return OpenTransientFilePerm(fileName, fileFlags, pg_file_create_mode);
}
/*
@@ -3554,3 +3549,27 @@ fsync_parent_path(const char *fname, int elevel)
return 0;
}
+
+/*
+ * Create a PostgreSQL data sub-directory
+ *
+ * The data directory itself, along with most other directories, are created at
+ * initdb-time, but we do have some occations where we create directories from
+ * the backend (CREATE TABLESPACE, for example). In those cases, we want to
+ * make sure that those directories are created consistently. Today, that means
+ * making sure that the created directory has the correct permissions, which is
+ * what pg_dir_create_mode tracks for us.
+ *
+ * Note that we also set the umask() based on what we understand the correct
+ * permissions to be (see file_perm.c).
+ *
+ * For permissions other than the default mkdir() can be used directly, but be
+ * sure to consider carefully such cases -- a directory with incorrect
+ * permissions in a PostgreSQL data directory could cause backups and other
+ * processes to fail.
+ */
+int
+MakePGDirectory(const char *directoryName)
+{
+ return mkdir(directoryName, pg_dir_create_mode);
+}