mirror of
https://github.com/postgres/postgres.git
synced 2025-04-18 13:44:19 +03:00
Further cleanup for directory creation on pg_dump/pg_dumpall
Instead of two separate (and different) implementations, refactor to use a single common routine. Along the way, remove use of a hardcoded file permissions constant in favor of the common project setting for directory creation. Author: Mahendra Singh Thalor <mahi6run@gmail.com> Discussion: https://postgr.es/m/CAKYtNApihL8X1h7XO-zOjznc8Ca66Aevgvhc9zOTh6DBh2iaeA@mail.gmail.com
This commit is contained in:
parent
4909b38af0
commit
4170298b6e
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "common/file_perm.h"
|
||||||
|
#include "common/logging.h"
|
||||||
#include "dumputils.h"
|
#include "dumputils.h"
|
||||||
#include "fe_utils/string_utils.h"
|
#include "fe_utils/string_utils.h"
|
||||||
|
|
||||||
@ -884,3 +886,37 @@ makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
|||||||
|
|
||||||
pg_free(mine);
|
pg_free(mine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create_or_open_dir
|
||||||
|
*
|
||||||
|
* This will create a new directory with the given dirname. If there is
|
||||||
|
* already an empty directory with that name, then use it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
create_or_open_dir(const char *dirname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch ((ret = pg_check_dir(dirname)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
/* opendir failed but not with ENOENT */
|
||||||
|
pg_fatal("could not open directory \"%s\": %m", dirname);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
/* directory does not exist */
|
||||||
|
if (mkdir(dirname, pg_dir_create_mode) < 0)
|
||||||
|
pg_fatal("could not create directory \"%s\": %m", dirname);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* exists and is empty, fix perms */
|
||||||
|
if (chmod(dirname, pg_dir_create_mode) != 0)
|
||||||
|
pg_fatal("could not change permissions of directory \"%s\": %m",
|
||||||
|
dirname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* exists and is not empty */
|
||||||
|
pg_fatal("directory \"%s\" is not empty", dirname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -62,5 +62,6 @@ extern void makeAlterConfigCommand(PGconn *conn, const char *configitem,
|
|||||||
const char *type, const char *name,
|
const char *type, const char *name,
|
||||||
const char *type2, const char *name2,
|
const char *type2, const char *name2,
|
||||||
PQExpBuffer buf);
|
PQExpBuffer buf);
|
||||||
|
extern void create_or_open_dir(const char *dirname);
|
||||||
|
|
||||||
#endif /* DUMPUTILS_H */
|
#endif /* DUMPUTILS_H */
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include "common/file_utils.h"
|
#include "common/file_utils.h"
|
||||||
#include "compress_io.h"
|
#include "compress_io.h"
|
||||||
|
#include "dumputils.h"
|
||||||
#include "parallel.h"
|
#include "parallel.h"
|
||||||
#include "pg_backup_utils.h"
|
#include "pg_backup_utils.h"
|
||||||
|
|
||||||
@ -156,41 +157,8 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
|
|||||||
|
|
||||||
if (AH->mode == archModeWrite)
|
if (AH->mode == archModeWrite)
|
||||||
{
|
{
|
||||||
struct stat st;
|
|
||||||
bool is_empty = false;
|
|
||||||
|
|
||||||
/* we accept an empty existing directory */
|
/* we accept an empty existing directory */
|
||||||
if (stat(ctx->directory, &st) == 0 && S_ISDIR(st.st_mode))
|
create_or_open_dir(ctx->directory);
|
||||||
{
|
|
||||||
DIR *dir = opendir(ctx->directory);
|
|
||||||
|
|
||||||
if (dir)
|
|
||||||
{
|
|
||||||
struct dirent *d;
|
|
||||||
|
|
||||||
is_empty = true;
|
|
||||||
while (errno = 0, (d = readdir(dir)))
|
|
||||||
{
|
|
||||||
if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0)
|
|
||||||
{
|
|
||||||
is_empty = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errno)
|
|
||||||
pg_fatal("could not read directory \"%s\": %m",
|
|
||||||
ctx->directory);
|
|
||||||
|
|
||||||
if (closedir(dir))
|
|
||||||
pg_fatal("could not close directory \"%s\": %m",
|
|
||||||
ctx->directory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_empty && mkdir(ctx->directory, 0700) < 0)
|
|
||||||
pg_fatal("could not create directory \"%s\": %m",
|
|
||||||
ctx->directory);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* Read Mode */
|
{ /* Read Mode */
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -78,7 +77,6 @@ static void executeCommand(PGconn *conn, const char *query);
|
|||||||
static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
|
static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns,
|
||||||
SimpleStringList *names);
|
SimpleStringList *names);
|
||||||
static void read_dumpall_filters(const char *filename, SimpleStringList *pattern);
|
static void read_dumpall_filters(const char *filename, SimpleStringList *pattern);
|
||||||
static void create_or_open_dir(const char *dirname);
|
|
||||||
static ArchiveFormat parseDumpFormat(const char *format);
|
static ArchiveFormat parseDumpFormat(const char *format);
|
||||||
|
|
||||||
static char pg_dump_bin[MAXPGPATH];
|
static char pg_dump_bin[MAXPGPATH];
|
||||||
@ -1655,7 +1653,7 @@ dumpDatabases(PGconn *conn, ArchiveFormat archDumpFormat)
|
|||||||
snprintf(db_subdir, MAXPGPATH, "%s/databases", filename);
|
snprintf(db_subdir, MAXPGPATH, "%s/databases", filename);
|
||||||
|
|
||||||
/* Create a subdirectory with 'databases' name under main directory. */
|
/* Create a subdirectory with 'databases' name under main directory. */
|
||||||
if (mkdir(db_subdir, 0755) != 0)
|
if (mkdir(db_subdir, pg_dir_create_mode) != 0)
|
||||||
pg_fatal("could not create subdirectory \"%s\": %m", db_subdir);
|
pg_fatal("could not create subdirectory \"%s\": %m", db_subdir);
|
||||||
|
|
||||||
snprintf(map_file_path, MAXPGPATH, "%s/map.dat", filename);
|
snprintf(map_file_path, MAXPGPATH, "%s/map.dat", filename);
|
||||||
@ -1946,41 +1944,6 @@ read_dumpall_filters(const char *filename, SimpleStringList *pattern)
|
|||||||
filter_free(&fstate);
|
filter_free(&fstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* create_or_open_dir
|
|
||||||
*
|
|
||||||
* This will create a new directory with the given dirname. If there is
|
|
||||||
* already an empty directory with that name, then use it.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
create_or_open_dir(const char *dirname)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
switch ((ret = pg_check_dir(dirname)))
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
/* opendir failed but not with ENOENT */
|
|
||||||
pg_fatal("could not open directory \"%s\": %m", dirname);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
/* directory does not exist */
|
|
||||||
if (mkdir(dirname, pg_dir_create_mode) < 0)
|
|
||||||
pg_fatal("could not create directory \"%s\": %m", dirname);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* exists and is empty, fix perms */
|
|
||||||
if (chmod(dirname, pg_dir_create_mode) != 0)
|
|
||||||
pg_fatal("could not change permissions of directory \"%s\": %m",
|
|
||||||
dirname);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* exists and is not empty */
|
|
||||||
pg_fatal("directory \"%s\" is not empty", dirname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* parseDumpFormat
|
* parseDumpFormat
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user