From bd7c4252fc907c7406aa4ca0438e74f494b2d3c3 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Tue, 9 Oct 2018 15:01:30 +0200 Subject: [PATCH] Support custom socket directory during upgrades The upgrade process will use CWD as the location for sockets dir, which is limited by the sockaddr_un structure to around 100 bytes. In order to avoid hitting the limit, support an optional command line parameter for overriding the socket directory. --- doc/src/sgml/ref/pgupgrade.sgml | 8 ++++++++ src/bin/pg_upgrade/option.c | 26 +++++++++++++++++++++----- src/bin/pg_upgrade/pg_upgrade.h | 2 ++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index d51146d641..750f080282 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -163,6 +163,14 @@ + + + dir + directory to use for sockets during upgrade, default is + current working directory + + + username username diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 9dbc9225a6..84ee7edab8 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -52,6 +52,7 @@ parseCommandLine(int argc, char *argv[]) {"link", no_argument, NULL, 'k'}, {"retain", no_argument, NULL, 'r'}, {"jobs", required_argument, NULL, 'j'}, + {"socketdir", required_argument, NULL, 's'}, {"verbose", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; @@ -64,6 +65,8 @@ parseCommandLine(int argc, char *argv[]) user_opts.transfer_mode = TRANSFER_MODE_COPY; + user_opts.socketdir = NULL; + os_info.progname = get_progname(argv[0]); /* Process libpq env. variables; load values here for usage() output */ @@ -100,7 +103,7 @@ parseCommandLine(int argc, char *argv[]) if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL) pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE); - while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v", + while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rs:U:v", long_options, &optindex)) != -1) { switch (option) @@ -186,6 +189,10 @@ parseCommandLine(int argc, char *argv[]) log_opts.retain = true; break; + case 's': + user_opts.socketdir = pg_strdup(optarg); + break; + case 'U': pg_free(os_info.user); os_info.user = pg_strdup(optarg); @@ -291,6 +298,7 @@ usage(void) printf(_(" -P, --new-port=PORT new cluster port number (default %d)\n"), new_cluster.port); printf(_(" -r, --retain retain SQL and log files after success\n")); printf(_(" -U, --username=NAME cluster superuser (default \"%s\")\n"), os_info.user); + printf(_(" -s, --socketdir=DIR socket directory during upgrades (default CWD)\n")); printf(_(" -v, --verbose enable verbose internal logging\n")); printf(_(" -V, --version display version information, then exit\n")); printf(_(" -?, --help show this help, then exit\n")); @@ -456,10 +464,18 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) { if (!live_check) { - /* Use the current directory for the socket */ - cluster->sockdir = pg_malloc(MAXPGPATH); - if (!getcwd(cluster->sockdir, MAXPGPATH)) - pg_fatal("could not determine current directory\n"); + if (user_opts.socketdir) + cluster->sockdir = user_opts.socketdir; + else + { + /* + * If the user hasn't requested a specific path, use the + * current directory for the socket + */ + cluster->sockdir = pg_malloc(MAXPGPATH); + if (!getcwd(cluster->sockdir, MAXPGPATH)) + pg_log(PG_FATAL, "cannot find current directory\n"); + } } else { diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index f83a3eeb67..d745ee101c 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -298,6 +298,8 @@ typedef struct * changes */ transferMode transfer_mode; /* copy files or link them? */ int jobs; + char *socketdir; /* directory to use for sockets, NULL means + * using the default of CWD */ } UserOpts; typedef struct -- 2.14.1.145.gb3622a4ee