pgsql: Allow copydir() to be interrupted.

Started by Nonameover 15 years ago13 messages
#1Noname
rhaas@postgresql.org

Log Message:
-----------
Allow copydir() to be interrupted.

This makes ALTER DATABASE .. SET TABLESPACE and CREATE DATABASE more
sensitive to interrupts. Backpatch to 8.4, where ALTER DATABASE .. SET
TABLESPACE was introduced. We could go back further, but in the absence
of complaints about the CREATE DATABASE case it doesn't seem worth it.

Guillaume Lelarge, with a small correction by me.

Modified Files:
--------------
pgsql/src/port:
copydir.c (r1.36 -> r1.37)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/port/copydir.c?r1=1.36&r2=1.37)

#2Andrew Dunstan
andrew@dunslane.net
In reply to: Noname (#1)
Re: pgsql: Allow copydir() to be interrupted.

Robert Haas wrote:

Log Message:
-----------
Allow copydir() to be interrupted.

This makes ALTER DATABASE .. SET TABLESPACE and CREATE DATABASE more
sensitive to interrupts. Backpatch to 8.4, where ALTER DATABASE .. SET
TABLESPACE was introduced. We could go back further, but in the absence
of complaints about the CREATE DATABASE case it doesn't seem worth it.

Guillaume Lelarge, with a small correction by me.

Modified Files:
--------------
pgsql/src/port:
copydir.c (r1.36 -> r1.37)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/port/copydir.c?r1=1.36&r2=1.37)

This appears to have broken MinGW and Cygwin builds on the buildfarm.

cheers

andrew

#3Robert Haas
robertmhaas@gmail.com
In reply to: Andrew Dunstan (#2)
Re: pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 8:10 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

Robert Haas wrote:

Log Message:
-----------
Allow copydir() to be interrupted.

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now. I'm wondering if
this is a link-ordering problem of some kind.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#4Magnus Hagander
magnus@hagander.net
In reply to: Robert Haas (#3)
Re: pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 2:13 PM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 8:10 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

Robert Haas wrote:

Log Message:
-----------
Allow copydir() to be interrupted.

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

We've seen something like this before, but I don't recall what it was.
It's probably something getting resolved too early when it's built
into libpgport_srv.a. That would explain why it's working fine on MSVC
- we don't actually bother building a server-side .lib there, we just
link the object files directly into postgres.exe. (We do build the
library for client side, of course, since it's used in many different
binaries)

--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/

#5Robert Haas
robertmhaas@gmail.com
In reply to: Magnus Hagander (#4)
Re: pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 9:19 AM, Magnus Hagander <magnus@hagander.net> wrote:

On Fri, Jul 2, 2010 at 2:13 PM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 8:10 AM, Andrew Dunstan <andrew@dunslane.net> wrote:

Robert Haas wrote:

Log Message:
-----------
Allow copydir() to be interrupted.

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

We've seen something like this before, but I don't recall what it was.
It's probably something getting resolved too early when it's built
into libpgport_srv.a. That would explain why it's working fine on MSVC
- we don't actually bother building a server-side .lib there, we just
link the object files directly into postgres.exe. (We do build the
library for client side, of course, since it's used in many different
binaries)

I wonder if we should just move copydir.c to someplace within the
backend, perhaps backend/storage/file or backend/utils/misc. It's
already backend-specific code anyway, so I'm not sure there's much
point in having it in src/port.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#5)
Re: pgsql: Allow copydir() to be interrupted.

Robert Haas <robertmhaas@gmail.com> writes:

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now. �I'm wondering if
this is a link-ordering problem of some kind.

Possibly an #ifndef FRONTEND will fix it.

regards, tom lane

#7Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#6)
Re: pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 10:18 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

Possibly an #ifndef FRONTEND will fix it.

What's failing to link is postgres.exe

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#8Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#7)
1 attachment(s)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 10:21 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 10:18 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

Possibly an #ifndef FRONTEND will fix it.

What's failing to link is postgres.exe

I suspect that moving copydir.c into the backend will fix this, but I
don't have an appropriate build environment to test. Can someone
please test the attached patch?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

Attachments:

copydir-to-backend.patchapplication/octet-stream; name=copydir-to-backend.patchDownload
diff --git a/src/backend/storage/file/Makefile b/src/backend/storage/file/Makefile
index 24fb246..c3d507c 100644
--- a/src/backend/storage/file/Makefile
+++ b/src/backend/storage/file/Makefile
@@ -12,6 +12,6 @@ subdir = src/backend/storage/file
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = fd.o buffile.o
+OBJS = fd.o buffile.o copydir.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c
new file mode 100644
index 0000000..2dbc461
--- /dev/null
+++ b/src/backend/storage/file/copydir.c
@@ -0,0 +1,272 @@
+/*-------------------------------------------------------------------------
+ *
+ * copydir.c
+ *	  copies a directory
+ *
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *	While "xcopy /e /i /q" works fine for copying directories, on Windows XP
+ *	it requires a Window handle which prevents it from working when invoked
+ *	as a service.
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL$
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "storage/fd.h"
+#include "miscadmin.h"
+
+/*
+ *	On Windows, call non-macro versions of palloc; we can't reference
+ *	CurrentMemoryContext in this file because of PGDLLIMPORT conflict.
+ */
+#if defined(WIN32) || defined(__CYGWIN__)
+#undef palloc
+#undef pstrdup
+#define palloc(sz)		pgport_palloc(sz)
+#define pstrdup(str)	pgport_pstrdup(str)
+#endif
+
+
+static void copy_file(char *fromfile, char *tofile);
+static void fsync_fname(char *fname, bool isdir);
+
+
+/*
+ * copydir: copy a directory
+ *
+ * If recurse is false, subdirectories are ignored.  Anything that's not
+ * a directory or a regular file is ignored.
+ */
+void
+copydir(char *fromdir, char *todir, bool recurse)
+{
+	DIR		   *xldir;
+	struct dirent *xlde;
+	char		fromfile[MAXPGPATH];
+	char		tofile[MAXPGPATH];
+
+	if (mkdir(todir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not create directory \"%s\": %m", todir)));
+
+	xldir = AllocateDir(fromdir);
+	if (xldir == NULL)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not open directory \"%s\": %m", fromdir)));
+
+	while ((xlde = ReadDir(xldir, fromdir)) != NULL)
+	{
+		struct stat fst;
+
+        /* If we got a cancel signal during the copy of the directory, quit */
+        CHECK_FOR_INTERRUPTS();
+
+		if (strcmp(xlde->d_name, ".") == 0 ||
+			strcmp(xlde->d_name, "..") == 0)
+			continue;
+
+		snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
+		snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
+
+		if (lstat(fromfile, &fst) < 0)
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not stat file \"%s\": %m", fromfile)));
+
+		if (S_ISDIR(fst.st_mode))
+		{
+			/* recurse to handle subdirectories */
+			if (recurse)
+				copydir(fromfile, tofile, true);
+		}
+		else if (S_ISREG(fst.st_mode))
+			copy_file(fromfile, tofile);
+	}
+	FreeDir(xldir);
+
+	/*
+	 * Be paranoid here and fsync all files to ensure the copy is really done.
+	 */
+	xldir = AllocateDir(todir);
+	if (xldir == NULL)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not open directory \"%s\": %m", todir)));
+
+	while ((xlde = ReadDir(xldir, todir)) != NULL)
+	{
+		struct stat fst;
+
+		if (strcmp(xlde->d_name, ".") == 0 ||
+			strcmp(xlde->d_name, "..") == 0)
+			continue;
+
+		snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
+
+		/*
+		 * We don't need to sync subdirectories here since the recursive
+		 * copydir will do it before it returns
+		 */
+		if (lstat(tofile, &fst) < 0)
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not stat file \"%s\": %m", tofile)));
+
+		if (S_ISREG(fst.st_mode))
+			fsync_fname(tofile, false);
+	}
+	FreeDir(xldir);
+
+	/*
+	 * It's important to fsync the destination directory itself as individual
+	 * file fsyncs don't guarantee that the directory entry for the file is
+	 * synced. Recent versions of ext4 have made the window much wider but
+	 * it's been true for ext3 and other filesystems in the past.
+	 */
+	fsync_fname(todir, true);
+}
+
+/*
+ * copy one file
+ */
+static void
+copy_file(char *fromfile, char *tofile)
+{
+	char	   *buffer;
+	int			srcfd;
+	int			dstfd;
+	int			nbytes;
+	off_t		offset;
+
+	/* Use palloc to ensure we get a maxaligned buffer */
+#define COPY_BUF_SIZE (8 * BLCKSZ)
+
+	buffer = palloc(COPY_BUF_SIZE);
+
+	/*
+	 * Open the files
+	 */
+	srcfd = BasicOpenFile(fromfile, O_RDONLY | PG_BINARY, 0);
+	if (srcfd < 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not open file \"%s\": %m", fromfile)));
+
+	dstfd = BasicOpenFile(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
+						  S_IRUSR | S_IWUSR);
+	if (dstfd < 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not create file \"%s\": %m", tofile)));
+
+	/*
+	 * Do the data copying.
+	 */
+	for (offset = 0;; offset += nbytes)
+	{
+        /* If we got a cancel signal during the copy of the file, quit */
+        CHECK_FOR_INTERRUPTS();
+
+		nbytes = read(srcfd, buffer, COPY_BUF_SIZE);
+		if (nbytes < 0)
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not read file \"%s\": %m", fromfile)));
+		if (nbytes == 0)
+			break;
+		errno = 0;
+		if ((int) write(dstfd, buffer, nbytes) != nbytes)
+		{
+			/* if write didn't set errno, assume problem is no disk space */
+			if (errno == 0)
+				errno = ENOSPC;
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not write to file \"%s\": %m", tofile)));
+		}
+
+		/*
+		 * We fsync the files later but first flush them to avoid spamming the
+		 * cache and hopefully get the kernel to start writing them out before
+		 * the fsync comes.
+		 */
+		pg_flush_data(dstfd, offset, nbytes);
+	}
+
+	if (close(dstfd))
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not close file \"%s\": %m", tofile)));
+
+	close(srcfd);
+
+	pfree(buffer);
+}
+
+
+/*
+ * fsync a file
+ *
+ * Try to fsync directories but ignore errors that indicate the OS
+ * just doesn't allow/require fsyncing directories.
+ */
+static void
+fsync_fname(char *fname, bool isdir)
+{
+	int			fd;
+	int 		returncode;
+
+	/*
+	 * Some OSs require directories to be opened read-only whereas
+	 * other systems don't allow us to fsync files opened read-only; so
+	 * we need both cases here 
+	 */
+	if (!isdir)
+		fd = BasicOpenFile(fname,
+						   O_RDWR | PG_BINARY,
+						   S_IRUSR | S_IWUSR);
+	else
+		fd = BasicOpenFile(fname,
+						   O_RDONLY | PG_BINARY,
+						   S_IRUSR | S_IWUSR);
+
+	/*
+	 * Some OSs don't allow us to open directories at all 
+	 * (Windows returns EACCES) 
+	 */
+	if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
+		return;
+
+	else if (fd < 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not open file \"%s\": %m", fname)));
+
+	returncode = pg_fsync(fd);
+	
+	/* Some OSs don't allow us to fsync directories at all */
+	if (returncode != 0 && isdir && errno == EBADF)
+	{
+		close(fd);
+		return;
+	}
+
+	if (returncode != 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not fsync file \"%s\": %m", fname)));
+
+	close(fd);
+}
diff --git a/src/port/Makefile b/src/port/Makefile
index d507b94..9ef9491 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -30,7 +30,7 @@ include $(top_builddir)/src/Makefile.global
 override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
 LIBS += $(PTHREAD_LIBS)
 
-OBJS = $(LIBOBJS) chklocale.o copydir.o dirmod.o exec.o noblock.o path.o \
+OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o noblock.o path.o \
 	pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o
 ifneq (,$(filter $(PORTNAME),cygwin win32))
 OBJS += pipe.o
diff --git a/src/port/copydir.c b/src/port/copydir.c
deleted file mode 100644
index 2dbc461..0000000
--- a/src/port/copydir.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * copydir.c
- *	  copies a directory
- *
- * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *	While "xcopy /e /i /q" works fine for copying directories, on Windows XP
- *	it requires a Window handle which prevents it from working when invoked
- *	as a service.
- *
- * IDENTIFICATION
- *	  $PostgreSQL$
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "storage/fd.h"
-#include "miscadmin.h"
-
-/*
- *	On Windows, call non-macro versions of palloc; we can't reference
- *	CurrentMemoryContext in this file because of PGDLLIMPORT conflict.
- */
-#if defined(WIN32) || defined(__CYGWIN__)
-#undef palloc
-#undef pstrdup
-#define palloc(sz)		pgport_palloc(sz)
-#define pstrdup(str)	pgport_pstrdup(str)
-#endif
-
-
-static void copy_file(char *fromfile, char *tofile);
-static void fsync_fname(char *fname, bool isdir);
-
-
-/*
- * copydir: copy a directory
- *
- * If recurse is false, subdirectories are ignored.  Anything that's not
- * a directory or a regular file is ignored.
- */
-void
-copydir(char *fromdir, char *todir, bool recurse)
-{
-	DIR		   *xldir;
-	struct dirent *xlde;
-	char		fromfile[MAXPGPATH];
-	char		tofile[MAXPGPATH];
-
-	if (mkdir(todir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not create directory \"%s\": %m", todir)));
-
-	xldir = AllocateDir(fromdir);
-	if (xldir == NULL)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not open directory \"%s\": %m", fromdir)));
-
-	while ((xlde = ReadDir(xldir, fromdir)) != NULL)
-	{
-		struct stat fst;
-
-        /* If we got a cancel signal during the copy of the directory, quit */
-        CHECK_FOR_INTERRUPTS();
-
-		if (strcmp(xlde->d_name, ".") == 0 ||
-			strcmp(xlde->d_name, "..") == 0)
-			continue;
-
-		snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
-		snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
-
-		if (lstat(fromfile, &fst) < 0)
-			ereport(ERROR,
-					(errcode_for_file_access(),
-					 errmsg("could not stat file \"%s\": %m", fromfile)));
-
-		if (S_ISDIR(fst.st_mode))
-		{
-			/* recurse to handle subdirectories */
-			if (recurse)
-				copydir(fromfile, tofile, true);
-		}
-		else if (S_ISREG(fst.st_mode))
-			copy_file(fromfile, tofile);
-	}
-	FreeDir(xldir);
-
-	/*
-	 * Be paranoid here and fsync all files to ensure the copy is really done.
-	 */
-	xldir = AllocateDir(todir);
-	if (xldir == NULL)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not open directory \"%s\": %m", todir)));
-
-	while ((xlde = ReadDir(xldir, todir)) != NULL)
-	{
-		struct stat fst;
-
-		if (strcmp(xlde->d_name, ".") == 0 ||
-			strcmp(xlde->d_name, "..") == 0)
-			continue;
-
-		snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
-
-		/*
-		 * We don't need to sync subdirectories here since the recursive
-		 * copydir will do it before it returns
-		 */
-		if (lstat(tofile, &fst) < 0)
-			ereport(ERROR,
-					(errcode_for_file_access(),
-					 errmsg("could not stat file \"%s\": %m", tofile)));
-
-		if (S_ISREG(fst.st_mode))
-			fsync_fname(tofile, false);
-	}
-	FreeDir(xldir);
-
-	/*
-	 * It's important to fsync the destination directory itself as individual
-	 * file fsyncs don't guarantee that the directory entry for the file is
-	 * synced. Recent versions of ext4 have made the window much wider but
-	 * it's been true for ext3 and other filesystems in the past.
-	 */
-	fsync_fname(todir, true);
-}
-
-/*
- * copy one file
- */
-static void
-copy_file(char *fromfile, char *tofile)
-{
-	char	   *buffer;
-	int			srcfd;
-	int			dstfd;
-	int			nbytes;
-	off_t		offset;
-
-	/* Use palloc to ensure we get a maxaligned buffer */
-#define COPY_BUF_SIZE (8 * BLCKSZ)
-
-	buffer = palloc(COPY_BUF_SIZE);
-
-	/*
-	 * Open the files
-	 */
-	srcfd = BasicOpenFile(fromfile, O_RDONLY | PG_BINARY, 0);
-	if (srcfd < 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not open file \"%s\": %m", fromfile)));
-
-	dstfd = BasicOpenFile(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
-						  S_IRUSR | S_IWUSR);
-	if (dstfd < 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not create file \"%s\": %m", tofile)));
-
-	/*
-	 * Do the data copying.
-	 */
-	for (offset = 0;; offset += nbytes)
-	{
-        /* If we got a cancel signal during the copy of the file, quit */
-        CHECK_FOR_INTERRUPTS();
-
-		nbytes = read(srcfd, buffer, COPY_BUF_SIZE);
-		if (nbytes < 0)
-			ereport(ERROR,
-					(errcode_for_file_access(),
-					 errmsg("could not read file \"%s\": %m", fromfile)));
-		if (nbytes == 0)
-			break;
-		errno = 0;
-		if ((int) write(dstfd, buffer, nbytes) != nbytes)
-		{
-			/* if write didn't set errno, assume problem is no disk space */
-			if (errno == 0)
-				errno = ENOSPC;
-			ereport(ERROR,
-					(errcode_for_file_access(),
-					 errmsg("could not write to file \"%s\": %m", tofile)));
-		}
-
-		/*
-		 * We fsync the files later but first flush them to avoid spamming the
-		 * cache and hopefully get the kernel to start writing them out before
-		 * the fsync comes.
-		 */
-		pg_flush_data(dstfd, offset, nbytes);
-	}
-
-	if (close(dstfd))
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not close file \"%s\": %m", tofile)));
-
-	close(srcfd);
-
-	pfree(buffer);
-}
-
-
-/*
- * fsync a file
- *
- * Try to fsync directories but ignore errors that indicate the OS
- * just doesn't allow/require fsyncing directories.
- */
-static void
-fsync_fname(char *fname, bool isdir)
-{
-	int			fd;
-	int 		returncode;
-
-	/*
-	 * Some OSs require directories to be opened read-only whereas
-	 * other systems don't allow us to fsync files opened read-only; so
-	 * we need both cases here 
-	 */
-	if (!isdir)
-		fd = BasicOpenFile(fname,
-						   O_RDWR | PG_BINARY,
-						   S_IRUSR | S_IWUSR);
-	else
-		fd = BasicOpenFile(fname,
-						   O_RDONLY | PG_BINARY,
-						   S_IRUSR | S_IWUSR);
-
-	/*
-	 * Some OSs don't allow us to open directories at all 
-	 * (Windows returns EACCES) 
-	 */
-	if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
-		return;
-
-	else if (fd < 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not open file \"%s\": %m", fname)));
-
-	returncode = pg_fsync(fd);
-	
-	/* Some OSs don't allow us to fsync directories at all */
-	if (returncode != 0 && isdir && errno == EBADF)
-	{
-		close(fd);
-		return;
-	}
-
-	if (returncode != 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not fsync file \"%s\": %m", fname)));
-
-	close(fd);
-}
#9Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#8)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 11:07 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 10:21 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 10:18 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

Possibly an #ifndef FRONTEND will fix it.

What's failing to link is postgres.exe

I suspect that moving copydir.c into the backend will fix this, but I
don't have an appropriate build environment to test.  Can someone
please test the attached patch?

Andrew confirms that this works on mingw, so I'm going to go ahead and
check it in and see what happens.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#10Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#9)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 12:38 PM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 11:07 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 10:21 AM, Robert Haas <robertmhaas@gmail.com> wrote:

On Fri, Jul 2, 2010 at 10:18 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

This appears to have broken MinGW and Cygwin builds on the buildfarm.

Well, that's not awesome. IM-ing with Magnus now.  I'm wondering if
this is a link-ordering problem of some kind.

Possibly an #ifndef FRONTEND will fix it.

What's failing to link is postgres.exe

I suspect that moving copydir.c into the backend will fix this, but I
don't have an appropriate build environment to test.  Can someone
please test the attached patch?

Andrew confirms that this works on mingw, so I'm going to go ahead and
check it in and see what happens.

hamerkop [Windows Server 2008 R2 (64bit) Visual C++ 2005 AMD64] is not
happy with this.

http://pgbuildfarm.org/cgi-bin/show_log.pl?nm=hamerkop&amp;dt=2010-07-02%2018:45:44

I don't really understand most of the log messages, but the problem
seems to be here (some garbage removed for clarity):

LINK : fatal error LNK1104: '.\Release\postgres\src_port_copydir.obj'
LIB : fatal error LNK1181: '.\Release\libpgport\copydir.obj'

What doesn't make sense about that is that that file should not have
existed in the snapshot hamerkop ran against.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#11Andrew Dunstan
andrew@dunslane.net
In reply to: Robert Haas (#10)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

Robert Haas wrote:

I suspect that moving copydir.c into the backend will fix this, but I
don't have an appropriate build environment to test. Can someone
please test the attached patch?

Andrew confirms that this works on mingw, so I'm going to go ahead and
check it in and see what happens.

hamerkop [Windows Server 2008 R2 (64bit) Visual C++ 2005 AMD64] is not
happy with this.

http://pgbuildfarm.org/cgi-bin/show_log.pl?nm=hamerkop&amp;dt=2010-07-02%2018:45:44

I don't really understand most of the log messages, but the problem
seems to be here (some garbage removed for clarity):

LINK : fatal error LNK1104: '.\Release\postgres\src_port_copydir.obj'
LIB : fatal error LNK1181: '.\Release\libpgport\copydir.obj'

What doesn't make sense about that is that that file should not have
existed in the snapshot hamerkop ran against.

MSVC was looking for it and not finding it. I have committed a fix that
I hope will fix the MSVC builds, by removing it from the list of files
in libpgport.

cheers

andrew

#12Robert Haas
robertmhaas@gmail.com
In reply to: Andrew Dunstan (#11)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

On Fri, Jul 2, 2010 at 7:30 PM, Andrew Dunstan <andrew@dunslane.net> wrote:

MSVC was looking for it and not finding it. I have committed a fix that I
hope will fix the MSVC builds, by removing it from the list of files in
libpgport.

You'll need to do the same thing in 8.4...

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

#13Andrew Dunstan
andrew@dunslane.net
In reply to: Robert Haas (#12)
Re: [COMMITTERS] pgsql: Allow copydir() to be interrupted.

Robert Haas wrote:

On Fri, Jul 2, 2010 at 7:30 PM, Andrew Dunstan <andrew@dunslane.net> wrote:

MSVC was looking for it and not finding it. I have committed a fix that I
hope will fix the MSVC builds, by removing it from the list of files in
libpgport.

You'll need to do the same thing in 8.4...

Darn. Ok, done.

cheers

andrew