From e17e392b68011f9173ddaa9bc88009a8e5629c44 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Mon, 29 Jan 2024 08:27:48 +0000
Subject: [PATCH v10 3/4] add start_standby/stop_standby functions

---
 src/bin/pg_basebackup/pg_subscriber.c | 104 +++++++++++++++++---------
 1 file changed, 69 insertions(+), 35 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_subscriber.c b/src/bin/pg_basebackup/pg_subscriber.c
index df770f0fc8..f535e7160f 100644
--- a/src/bin/pg_basebackup/pg_subscriber.c
+++ b/src/bin/pg_basebackup/pg_subscriber.c
@@ -75,6 +75,9 @@ static void drop_subscription(PGconn *conn, LogicalRepInfo *dbinfo);
 static void set_replication_progress(PGconn *conn, LogicalRepInfo *dbinfo, const char *lsn);
 static void enable_subscription(PGconn *conn, LogicalRepInfo *dbinfo);
 
+static void start_standby(char *server_start_log);
+static void stop_standby(void);
+
 #define	USEC_PER_SEC	1000000
 #define	WAIT_INTERVAL	1		/* 1 second */
 
@@ -1363,6 +1366,68 @@ enable_subscription(PGconn *conn, LogicalRepInfo *dbinfo)
 	destroyPQExpBuffer(str);
 }
 
+/*
+ * Start a standby server with given logfile. This also decides filename if not
+ * determined yet. If the start is failed, the process exits with error
+ * messages.
+ */
+static void
+start_standby(char *server_start_log)
+{
+	int			rc;
+	char	   *pg_ctl_cmd;
+
+	Assert(server_start_log != NULL);
+
+	if (server_start_log[0] == '\0')
+	{
+		char		timebuf[128];
+		struct timeval time;
+		time_t		tt;
+		int			len;
+
+		/* append timestamp with ISO 8601 format. */
+		gettimeofday(&time, NULL);
+		tt = (time_t) time.tv_sec;
+		strftime(timebuf, sizeof(timebuf), "%Y%m%dT%H%M%S", localtime(&tt));
+		snprintf(timebuf + strlen(timebuf), sizeof(timebuf) - strlen(timebuf),
+				 ".%03d", (int) (time.tv_usec / 1000));
+
+		len = snprintf(server_start_log, MAXPGPATH,
+					   "%s/%s/server_start_%s.log", subscriber_dir,
+					   PGS_OUTPUT_DIR, timebuf);
+		if (len >= MAXPGPATH)
+		{
+			pg_log_error("log file path is too long");
+			exit(1);
+		}
+	}
+
+	pg_log_info("starting the standby server");
+	pg_ctl_cmd = psprintf("\"%s\" start -D \"%s\" -s -l \"%s\"", pg_ctl_path,
+						  subscriber_dir, server_start_log);
+	rc = system(pg_ctl_cmd);
+	pg_ctl_status(pg_ctl_cmd, rc, 1);
+}
+
+/*
+ * Stop a standby server. If the stop is failed, the process exits with error
+ * messages.
+ */
+static void
+stop_standby(void)
+{
+	int			rc;
+	char	   *pg_ctl_cmd;
+
+	pg_log_info("stopping the standby server");
+
+	pg_ctl_cmd = psprintf("\"%s\" stop -D \"%s\" -s", pg_ctl_path,
+						  subscriber_dir);
+	rc = system(pg_ctl_cmd);
+	pg_ctl_status(pg_ctl_cmd, rc, 0);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -1383,16 +1448,10 @@ main(int argc, char **argv)
 
 	int			c;
 	int			option_index;
-	int			rc;
-
-	char	   *pg_ctl_cmd;
 
 	char	   *base_dir;
-	char	   *server_start_log;
+	char		server_start_log[MAXPGPATH] = {0};
 
-	char		timebuf[128];
-	struct timeval time;
-	time_t		tt;
 	int			len;
 
 	char	   *pub_base_conninfo = NULL;
@@ -1638,9 +1697,7 @@ main(int argc, char **argv)
 		pg_log_info("standby is up and running");
 		pg_log_info("stopping the server to start the transformation steps");
 
-		pg_ctl_cmd = psprintf("\"%s\" stop -D \"%s\" -s", pg_ctl_path, subscriber_dir);
-		rc = system(pg_ctl_cmd);
-		pg_ctl_status(pg_ctl_cmd, rc, 0);
+		stop_standby();
 	}
 	else
 	{
@@ -1705,26 +1762,7 @@ main(int argc, char **argv)
 	/*
 	 * Start subscriber and wait until accepting connections.
 	 */
-	pg_log_info("starting the subscriber");
-
-	/* append timestamp with ISO 8601 format. */
-	gettimeofday(&time, NULL);
-	tt = (time_t) time.tv_sec;
-	strftime(timebuf, sizeof(timebuf), "%Y%m%dT%H%M%S", localtime(&tt));
-	snprintf(timebuf + strlen(timebuf), sizeof(timebuf) - strlen(timebuf),
-			 ".%03d", (int) (time.tv_usec / 1000));
-
-	server_start_log = (char *) pg_malloc0(MAXPGPATH);
-	len = snprintf(server_start_log, MAXPGPATH, "%s/%s/server_start_%s.log", subscriber_dir, PGS_OUTPUT_DIR, timebuf);
-	if (len >= MAXPGPATH)
-	{
-		pg_log_error("log file path is too long");
-		exit(1);
-	}
-
-	pg_ctl_cmd = psprintf("\"%s\" start -D \"%s\" -s -l \"%s\"", pg_ctl_path, subscriber_dir, server_start_log);
-	rc = system(pg_ctl_cmd);
-	pg_ctl_status(pg_ctl_cmd, rc, 1);
+	start_standby(server_start_log);
 
 	/*
 	 * Waiting the subscriber to be promoted.
@@ -1779,11 +1817,7 @@ main(int argc, char **argv)
 	/*
 	 * Stop the subscriber.
 	 */
-	pg_log_info("stopping the subscriber");
-
-	pg_ctl_cmd = psprintf("\"%s\" stop -D \"%s\" -s", pg_ctl_path, subscriber_dir);
-	rc = system(pg_ctl_cmd);
-	pg_ctl_status(pg_ctl_cmd, rc, 0);
+	stop_standby();
 
 	/*
 	 * Change system identifier.
-- 
2.43.0

