Blame SOURCES/postgresql-pgupgrade-socketdir-option.patch

a0e397
Backport from PostgreSQL12
a0e397
a0e397
Upstream commit:
a0e397
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2d34ad84303181111c6f0747186857ff50106267
a0e397
a0e397
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
a0e397
index c74eb25e18..92a2ed5e4c 100644
a0e397
--- a/src/bin/pg_upgrade/option.c
a0e397
+++ b/src/bin/pg_upgrade/option.c
a0e397
@@ -21,8 +21,9 @@
a0e397
 
a0e397
 
a0e397
 static void usage(void);
a0e397
-static void check_required_directory(char **dirpath, char **configpath,
a0e397
-						 char *envVarName, char *cmdLineOption, char *description);
a0e397
+static void check_required_directory(char **dirpath,
a0e397
+						 const char *envVarName, bool useCwd,
a0e397
+						 const char *cmdLineOption, const char *description);
a0e397
 #define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
a0e397
 
a0e397
 
a0e397
@@ -52,6 +53,7 @@ parseCommandLine(int argc, char *argv[])
a0e397
 		{"link", no_argument, NULL, 'k'},
a0e397
 		{"retain", no_argument, NULL, 'r'},
a0e397
 		{"jobs", required_argument, NULL, 'j'},
a0e397
+		{"socketdir", required_argument, NULL, 's'},
a0e397
 		{"verbose", no_argument, NULL, 'v'},
a0e397
 		{NULL, 0, NULL, 0}
a0e397
 	};
a0e397
@@ -100,7 +102,7 @@ parseCommandLine(int argc, char *argv[])
a0e397
 	if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
a0e397
 		pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE);
a0e397
 
a0e397
-	while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
a0e397
+	while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rs:U:v",
a0e397
 								 long_options, &optindex)) != -1)
a0e397
 	{
a0e397
 		switch (option)
a0e397
@@ -119,12 +121,10 @@ parseCommandLine(int argc, char *argv[])
a0e397
 
a0e397
 			case 'd':
a0e397
 				old_cluster.pgdata = pg_strdup(optarg);
a0e397
-				old_cluster.pgconfig = pg_strdup(optarg);
a0e397
 				break;
a0e397
 
a0e397
 			case 'D':
a0e397
 				new_cluster.pgdata = pg_strdup(optarg);
a0e397
-				new_cluster.pgconfig = pg_strdup(optarg);
a0e397
 				break;
a0e397
 
a0e397
 			case 'j':
a0e397
@@ -186,6 +186,10 @@ parseCommandLine(int argc, char *argv[])
a0e397
 				log_opts.retain = true;
a0e397
 				break;
a0e397
 
a0e397
+			case 's':
a0e397
+				user_opts.socketdir = pg_strdup(optarg);
a0e397
+				break;
a0e397
+
a0e397
 			case 'U':
a0e397
 				pg_free(os_info.user);
a0e397
 				os_info.user = pg_strdup(optarg);
a0e397
@@ -238,14 +242,16 @@ parseCommandLine(int argc, char *argv[])
a0e397
 		pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);
a0e397
 
a0e397
 	/* Get values from env if not already set */
a0e397
-	check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b",
a0e397
-							 _("old cluster binaries reside"));
a0e397
-	check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B",
a0e397
-							 _("new cluster binaries reside"));
a0e397
-	check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig,
a0e397
-							 "PGDATAOLD", "-d", _("old cluster data resides"));
a0e397
-	check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig,
a0e397
-							 "PGDATANEW", "-D", _("new cluster data resides"));
a0e397
+	check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
a0e397
+							 "-b", _("old cluster binaries reside"));
a0e397
+	check_required_directory(&new_cluster.bindir, "PGBINNEW", false,
a0e397
+							 "-B", _("new cluster binaries reside"));
a0e397
+	check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false,
a0e397
+							 "-d", _("old cluster data resides"));
a0e397
+	check_required_directory(&new_cluster.pgdata, "PGDATANEW", false,
a0e397
+							 "-D", _("new cluster data resides"));
a0e397
+	check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true,
a0e397
+							 "-s", _("sockets will be created"));
a0e397
 
a0e397
 #ifdef WIN32
a0e397
 
a0e397
@@ -290,6 +296,7 @@ usage(void)
a0e397
 	printf(_("  -p, --old-port=PORT           old cluster port number (default %d)\n"), old_cluster.port);
a0e397
 	printf(_("  -P, --new-port=PORT           new cluster port number (default %d)\n"), new_cluster.port);
a0e397
 	printf(_("  -r, --retain                  retain SQL and log files after success\n"));
a0e397
+	printf(_("  -s, --socketdir=DIR           socket directory to use (default CWD)\n"));
a0e397
 	printf(_("  -U, --username=NAME           cluster superuser (default \"%s\")\n"), os_info.user);
a0e397
 	printf(_("  -v, --verbose                 enable verbose internal logging\n"));
a0e397
 	printf(_("  -V, --version                 display version information, then exit\n"));
a0e397
@@ -330,29 +337,32 @@ usage(void)
a0e397
  * check_required_directory()
a0e397
  *
a0e397
  * Checks a directory option.
a0e397
- *	dirpath		  - the directory name supplied on the command line
a0e397
- *	configpath	  - optional configuration directory
a0e397
+ *	dirpath		  - the directory name supplied on the command line, or NULL
a0e397
  *	envVarName	  - the name of an environment variable to get if dirpath is NULL
a0e397
- *	cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N)
a0e397
+ *	useCwd		  - true if OK to default to CWD
a0e397
+ *	cmdLineOption - the command line option for this directory
a0e397
  *	description   - a description of this directory option
a0e397
  *
a0e397
  * We use the last two arguments to construct a meaningful error message if the
a0e397
  * user hasn't provided the required directory name.
a0e397
  */
a0e397
 static void
a0e397
-check_required_directory(char **dirpath, char **configpath,
a0e397
-						 char *envVarName, char *cmdLineOption,
a0e397
-						 char *description)
a0e397
+check_required_directory(char **dirpath, const char *envVarName, bool useCwd,
a0e397
+						 const char *cmdLineOption, const char *description)
a0e397
 {
a0e397
 	if (*dirpath == NULL || strlen(*dirpath) == 0)
a0e397
 	{
a0e397
 		const char *envVar;
a0e397
 
a0e397
 		if ((envVar = getenv(envVarName)) && strlen(envVar))
a0e397
+ 			*dirpath = pg_strdup(envVar);
a0e397
+		else if (useCwd)
a0e397
 		{
a0e397
-			*dirpath = pg_strdup(envVar);
a0e397
-			if (configpath)
a0e397
-				*configpath = pg_strdup(envVar);
a0e397
+			char		cwd[MAXPGPATH];
a0e397
+
a0e397
+			if (!getcwd(cwd, MAXPGPATH))
a0e397
+				pg_fatal("could not determine current directory\n");
a0e397
+			*dirpath = pg_strdup(cwd);
a0e397
 		}
a0e397
 		else
a0e397
 			pg_fatal("You must identify the directory where the %s.\n"
a0e397
@@ -361,16 +371,10 @@ check_required_directory(char **dirpath, char **configpath,
a0e397
 	}
a0e397
 
a0e397
 	/*
a0e397
-	 * Trim off any trailing path separators because we construct paths by
a0e397
-	 * appending to this path.
a0e397
+	 * Clean up the path, in particular trimming any trailing path separators,
a0e397
+	 * because we construct paths by appending to this path.
a0e397
 	 */
a0e397
-#ifndef WIN32
a0e397
-	if ((*dirpath)[strlen(*dirpath) - 1] == '/')
a0e397
-#else
a0e397
-	if ((*dirpath)[strlen(*dirpath) - 1] == '/' ||
a0e397
-		(*dirpath)[strlen(*dirpath) - 1] == '\\')
a0e397
-#endif
a0e397
-		(*dirpath)[strlen(*dirpath) - 1] = 0;
a0e397
+	canonicalize_path(*dirpath);
a0e397
 }
a0e397
 
a0e397
 /*
a0e397
@@ -379,6 +383,10 @@ check_required_directory(char **dirpath, char **configpath,
a0e397
  * If a configuration-only directory was specified, find the real data dir
a0e397
  * by querying the running server.  This has limited checking because we
a0e397
  * can't check for a running server because we can't find postmaster.pid.
a0e397
+ *
a0e397
+ * On entry, cluster->pgdata has been set from command line or env variable,
a0e397
+ * but cluster->pgconfig isn't set.  We fill both variables with corrected
a0e397
+ * values.
a0e397
  */
a0e397
 void
a0e397
 adjust_data_dir(ClusterInfo *cluster)
a0e397
@@ -389,6 +397,9 @@ adjust_data_dir(ClusterInfo *cluster)
a0e397
 	FILE	   *fp,
a0e397
 			   *output;
a0e397
 
a0e397
+	/* Initially assume config dir and data dir are the same */
a0e397
+	cluster->pgconfig = pg_strdup(cluster->pgdata);
a0e397
+
a0e397
 	/* If there is no postgresql.conf, it can't be a config-only dir */
a0e397
 	snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
a0e397
 	if ((fp = fopen(filename, "r")) == NULL)
a0e397
@@ -455,12 +466,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
a0e397
 	if (GET_MAJOR_VERSION(cluster->major_version) >= 901)
a0e397
 	{
a0e397
 		if (!live_check)
a0e397
-		{
a0e397
-			/* Use the current directory for the socket */
a0e397
-			cluster->sockdir = pg_malloc(MAXPGPATH);
a0e397
-			if (!getcwd(cluster->sockdir, MAXPGPATH))
a0e397
-				pg_fatal("could not determine current directory\n");
a0e397
-		}
a0e397
+			cluster->sockdir = user_opts.socketdir;
a0e397
 		else
a0e397
 		{
a0e397
 			/*
a0e397
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
a0e397
index dccc3e3b63..65a9166414 100644
a0e397
--- a/src/bin/pg_upgrade/pg_upgrade.h
a0e397
+++ b/src/bin/pg_upgrade/pg_upgrade.h
a0e397
@@ -297,7 +297,8 @@ typedef struct
a0e397
 	bool		check;			/* TRUE -> ask user for permission to make
a0e397
 								 * changes */
a0e397
 	transferMode transfer_mode; /* copy files or link them? */
a0e397
-	int			jobs;
a0e397
+	int			jobs;			/* number of processes/threads to use */
a0e397
+	char	   *socketdir;		/* directory to use for Unix sockets */
a0e397
 } UserOpts;
a0e397
 
a0e397