#include "sys/mman.h"
#endif
+#include "catalog/catalog.h"
#include "common/username.h"
#include "mb/pg_wchar.h"
#include "getaddrinfo.h"
static char **readfile(const char *path);
static void writefile(char *path, char **lines);
static void walkdir(char *path, void (*action) (char *fname, bool isdir));
+static void walktblspc_links(char *path, void (*action) (char *fname, bool isdir));
static void pre_sync_fname(char *fname, bool isdir);
static void fsync_fname(char *fname, bool isdir);
static FILE *popen_check(const char *command, const char *mode);
(*action) (path, true);
}
+/*
+ * walktblspc_links: call walkdir on each entry under the given
+ * pg_tblspc directory, or do nothing if pg_tblspc doesn't exist.
+ */
+static void
+walktblspc_links(char *path, void (*action) (char *fname, bool isdir))
+{
+ DIR *dir;
+ struct dirent *direntry;
+ char subpath[MAXPGPATH];
+
+ dir = opendir(path);
+ if (dir == NULL)
+ {
+ if (errno == ENOENT)
+ return;
+ fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
+ progname, path, strerror(errno));
+ exit_nicely();
+ }
+
+ while (errno = 0, (direntry = readdir(dir)) != NULL)
+ {
+ if (strcmp(direntry->d_name, ".") == 0 ||
+ strcmp(direntry->d_name, "..") == 0)
+ continue;
+
+ /* fsync the version specific tablespace subdirectory */
+ snprintf(subpath, sizeof(subpath), "%s/%s/%s",
+ path, direntry->d_name, TABLESPACE_VERSION_DIRECTORY);
+
+ walkdir(subpath, action);
+ }
+
+ if (errno)
+ {
+ fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
+ progname, path, strerror(errno));
+ exit_nicely();
+ }
+
+ if (closedir(dir))
+ {
+ fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
+ progname, path, strerror(errno));
+ exit_nicely();
+ }
+}
+
/*
* Hint to the OS that it should get ready to fsync() this file.
*/
perform_fsync(void)
{
char pdir[MAXPGPATH];
+ char pg_tblspc[MAXPGPATH];
fputs(_("syncing data to disk ... "), stdout);
fflush(stdout);
/* first the parent of the PGDATA directory */
pre_sync_fname(pdir, true);
- /* then recursively through the directory */
+ /* then recursively through the data directory */
walkdir(pg_data, pre_sync_fname);
+ /* now do the same thing for everything under pg_tblspc */
+ snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pg_data);
+ walktblspc_links(pg_tblspc, pre_sync_fname);
+
/*
* Now, do the fsync()s in the same order.
*/
/* first the parent of the PGDATA directory */
fsync_fname(pdir, true);
- /* then recursively through the directory */
+ /* then recursively through the data directory */
walkdir(pg_data, fsync_fname);
+ /* and now the same for all tablespaces */
+ walktblspc_links(pg_tblspc, fsync_fname);
+
check_ok();
}