diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index c7f5bd5..46096e6 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -125,6 +125,7 @@ static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr);
 static void XLogWalRcvFlush(bool dying);
 static void XLogWalRcvSendReply(void);
 static void XLogWalRcvSendHSFeedback(void);
+static void XLogWalRcvSendInfo(void);
 
 /* Signal handlers */
 static void WalRcvSigHupHandler(SIGNAL_ARGS);
@@ -276,6 +277,9 @@ WalReceiverMain(void)
 	walrcv_connect(conninfo, startpoint);
 	DisableWalRcvImmediateExit();
 
+	/* Give the primary our identification and configuration information */
+	XLogWalRcvSendInfo();
+
 	/* Loop until end-of-streaming or error */
 	for (;;)
 	{
@@ -305,6 +309,7 @@ WalReceiverMain(void)
 		{
 			got_SIGHUP = false;
 			ProcessConfigFile(PGC_SIGHUP);
+			XLogWalRcvSendInfo();
 		}
 
 		/* Wait a while for data to arrive */
@@ -702,3 +707,26 @@ XLogWalRcvSendHSFeedback(void)
 	memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage));
 	walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1);
 }
+
+/*
+ * Send info message to primary.
+ */
+static void
+XLogWalRcvSendInfo(void)
+{
+	char		buf[sizeof(StandbyInfoMessage) + 1];
+	StandbyInfoMessage	info_message;
+
+	/* Get current timestamp. */
+	info_message.sendTime = GetCurrentTimestamp();
+	strncpy(info_message.servername, ServerName, strlen(ServerName));
+	info_message.servername[strlen(ServerName)] = '\0';
+
+	elog(DEBUG2, "sending standby info servername \"%s\"",
+				 info_message.servername);
+
+	/* Prepend with the message type and send it. */
+	buf[0] = 'i';
+	memcpy(&buf[1], &info_message, sizeof(StandbyInfoMessage));
+	walrcv_send(buf, sizeof(StandbyInfoMessage) + 1);
+}
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index e04d59e..43e47d9 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -119,6 +119,7 @@ static void StartReplication(StartReplicationCmd * cmd);
 static void ProcessStandbyMessage(void);
 static void ProcessStandbyReplyMessage(void);
 static void ProcessStandbyHSFeedbackMessage(void);
+static void ProcessStandbyInfoMessage(void);
 static void ProcessRepliesIfAny(void);
 
 
@@ -537,6 +538,10 @@ ProcessStandbyMessage(void)
 			ProcessStandbyHSFeedbackMessage();
 			break;
 
+		case 'i':
+			ProcessStandbyInfoMessage();
+			break;
+
 		default:
 			ereport(COMMERROR,
 					(errcode(ERRCODE_PROTOCOL_VIOLATION),
@@ -655,6 +660,16 @@ ProcessStandbyHSFeedbackMessage(void)
 	}
 }
 
+static void
+ProcessStandbyInfoMessage(void)
+{
+	StandbyInfoMessage	info;
+
+	pq_copymsgbytes(&reply_message, (char *) &info, sizeof(StandbyInfoMessage));
+
+	elog(DEBUG2, "server name %s", info.servername);
+}
+
 /* Main loop of walsender process */
 static int
 WalSndLoop(void)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 55cbf75..fd733e0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -186,6 +186,7 @@ static const char *assign_pgstat_temp_directory(const char *newval, bool doit, G
 static const char *assign_application_name(const char *newval, bool doit, GucSource source);
 static const char *show_unix_socket_permissions(void);
 static const char *show_log_file_mode(void);
+static const char *assign_server_name(const char *newval, bool doit, GucSource source);
 
 static char *config_enum_get_options(struct config_enum * record,
 						const char *prefix, const char *suffix,
@@ -405,6 +406,9 @@ int			tcp_keepalives_idle;
 int			tcp_keepalives_interval;
 int			tcp_keepalives_count;
 
+char		*ServerName = NULL;
+
+
 /*
  * These variables are all dummies that don't do anything, except in some
  * cases provide the value for SHOW to display.  The real state is elsewhere
@@ -2365,6 +2369,15 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"server_name", PGC_POSTMASTER, CLIENT_CONN_STATEMENT,
+			gettext_noop("Allows setting of a unique name for this server."),
+			NULL
+		},
+		&ServerName,
+		"", assign_server_name, NULL
+	},
+
+	{
 		{"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT,
 			gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."),
 			NULL,
@@ -8184,4 +8197,29 @@ show_log_file_mode(void)
 	return buf;
 }
 
+static const char *
+assign_server_name(const char *newval, bool doit, GucSource source)
+{
+	char	   *p;
+
+#define MAX_LEN_SERVERNAME 64
+	/* Limit the maximum length of the server name */
+	if (strlen(newval) > MAX_LEN_SERVERNAME)
+		ereport(GUC_complaint_elevel(source),
+			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+			 errmsg("\"server_name\" maximum length is %d characters",
+						MAX_LEN_SERVERNAME)));
+
+	/* Only allow clean ASCII chars in the application name */
+	for (p = (char *) newval; *p; p++)
+	{
+		if (*p < 32 || *p > 126)
+			ereport(GUC_complaint_elevel(source),
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("\"server_name\" must only contain ASCII characters")));
+	}
+
+	return newval;
+}
+
 #include "guc-file.c"
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 6726733..cbe6fb2 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -56,6 +56,7 @@
 
 # - Connection Settings -
 
+#server_name = ''	# optional server name for use when clustering servers
 #listen_addresses = 'localhost'		# what IP address(es) to listen on;
 					# comma-separated list of addresses;
 					# defaults to 'localhost', '*' = all
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index aa8cce5..bf6c262 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -218,6 +218,7 @@ extern int	CTimeZone;
 
 #define MAXTZLEN		10		/* max TZ name len, not counting tr. null */
 
+extern char	*ServerName;
 extern bool enableFsync;
 extern bool allowSystemTableMods;
 extern PGDLLIMPORT int work_mem;
diff --git a/src/include/replication/walprotocol.h b/src/include/replication/walprotocol.h
index 9baca94..5f16371 100644
--- a/src/include/replication/walprotocol.h
+++ b/src/include/replication/walprotocol.h
@@ -81,6 +81,20 @@ typedef struct
 } StandbyHSFeedbackMessage;
 
 /*
+ * Info message from standby (message type 'i').  This is wrapped within
+ * a CopyData message at the FE/BE protocol level.
+ *
+ * Note that the data length is not specified here.
+ */
+typedef struct
+{
+	char		servername[65];		/* Must match MAX_LEN_SERVERNAME + 1*/
+
+	/* Sender's system clock at the time of transmission */
+	TimestampTz sendTime;
+} StandbyInfoMessage;
+
+/*
  * Maximum data payload in a WAL data message.	Must be >= XLOG_BLCKSZ.
  *
  * We don't have a good idea of what a good value would be; there's some
