From 5cc52ace3e31f9492fe6f2e4441f386c2b21837e Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Fri, 10 Aug 2018 12:54:05 +0530
Subject: [PATCH 4/4] Handle EMSGSIZE on macOS.  Fix misleading error message.

Also zero-initialize a couple of structs passed to the kernel just in case
there is padding on some system somewhere that could be a problem (based on
a rumor about EMSGSIZE errors which didn't turn out to help).
---
 src/backend/postmaster/checkpointer.c | 15 +++++++++++++--
 src/backend/storage/file/fd.c         |  3 ++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 16a57090fe7..714f1522f15 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -1321,8 +1321,19 @@ SendFsyncRequest(CheckpointerRequest *request, int fd)
 				elog(FATAL, "unexpected short write to fsync request socket");
 			break;
 		}
-		else if (errno == EWOULDBLOCK || errno == EAGAIN)
+		else if (errno == EWOULDBLOCK || errno == EAGAIN
+#ifdef __darwin__
+				 || errno == EMSGSIZE || errno == ENOBUFS
+#endif
+				)
 		{
+			/*
+			 * Testing on macOS 10.13 showed occasional EMSGSIZE or
+			 * ENOBUFS errors, which could be handled by retrying.  Unless
+			 * the problem also shows up on other systems, let's handle those
+			 * only for that OS.
+			 */
+
 			/* blocked on write - wait for socket to become readable */
 			rc = WaitLatchOrSocket(NULL,
 								   WL_SOCKET_WRITEABLE | WL_POSTMASTER_DEATH,
@@ -1331,6 +1342,6 @@ SendFsyncRequest(CheckpointerRequest *request, int fd)
 				exit(1);
 		}
 		else
-			ereport(FATAL, (errmsg("could not receive fsync request: %m")));
+			ereport(FATAL, (errmsg("could not send fsync request: %m")));
 	}
 }
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 7135a57df57..d45e15a9e41 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -3642,7 +3642,7 @@ pg_uds_send_with_fd(int sock, void *buf, ssize_t buflen, int fd)
 {
 	ssize_t     size;
 	struct msghdr   msg = {0};
-	struct iovec    iov;
+	struct iovec    iov = {0};
 	/* cmsg header, union for correct alignment */
 	union
 	{
@@ -3651,6 +3651,7 @@ pg_uds_send_with_fd(int sock, void *buf, ssize_t buflen, int fd)
 	} cmsgu;
 	struct cmsghdr  *cmsg;
 
+	memset(&cmsgu, 0, sizeof(cmsgu));
 	iov.iov_base = buf;
 	iov.iov_len = buflen;
 
-- 
2.17.0

