From 616af29a17c0d18b3c9681855f54cead0d2f66ae 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, with an associated environment variable for overriding the socket directory. --- doc/src/sgml/ref/pgupgrade.sgml | 8 +++++++ src/bin/pg_upgrade/option.c | 49 ++++++++++++++++++++++++++--------------- src/bin/pg_upgrade/pg_upgrade.h | 2 ++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index d51146d641..31a4144207 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; environment variable PGSOCKETDIR + + + username username diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 9dbc9225a6..9c58125972 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -22,7 +22,8 @@ static void usage(void); static void check_required_directory(char **dirpath, char **configpath, - const char *envVarName, const char *cmdLineOption, const char *description); + const char *envVarName, const char *cmdLineOption, + const char *description, const char *defaultValue); #define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false" @@ -52,6 +53,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} }; @@ -61,6 +63,7 @@ parseCommandLine(int argc, char *argv[]) FILE *fp; char **filename; time_t run_time = time(NULL); + char default_sockdir[MAXPGPATH]; user_opts.transfer_mode = TRANSFER_MODE_COPY; @@ -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,11 @@ parseCommandLine(int argc, char *argv[]) log_opts.retain = true; break; + case 's': + user_opts.socketdir = pg_malloc0(MAXPGPATH); + strlcpy(user_opts.socketdir, optarg, MAXPGPATH); + break; + case 'U': pg_free(os_info.user); os_info.user = pg_strdup(optarg); @@ -239,13 +247,18 @@ parseCommandLine(int argc, char *argv[]) /* Get values from env if not already set */ check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b", - _("old cluster binaries reside")); + _("old cluster binaries reside"), NULL); check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B", - _("new cluster binaries reside")); + _("new cluster binaries reside"), NULL); check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig, - "PGDATAOLD", "-d", _("old cluster data resides")); + "PGDATAOLD", "-d", _("old cluster data resides"), + NULL); check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig, - "PGDATANEW", "-D", _("new cluster data resides")); + "PGDATANEW", "-D", _("new cluster data resides"), + NULL); + getcwd(default_sockdir, MAXPGPATH); + check_required_directory(&user_opts.socketdir, NULL, "PGSOCKETDIR", "-s", + _("sockets will be created"), default_sockdir); #ifdef WIN32 @@ -291,6 +304,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")); @@ -335,29 +349,33 @@ usage(void) * envVarName - the name of an environment variable to get if dirpath is NULL * cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N) * description - a description of this directory option + * defaultValue - a default value to assign in case the environment variable + * isn't set * * We use the last two arguments to construct a meaningful error message if the - * user hasn't provided the required directory name. + * user hasn't provided the required directory name, and a default isn't + * specified. */ static void check_required_directory(char **dirpath, char **configpath, const char *envVarName, const char *cmdLineOption, - const char *description) + const char *description, const char *defaultValue) { if (*dirpath == NULL || strlen(*dirpath) == 0) { const char *envVar; if ((envVar = getenv(envVarName)) && strlen(envVar)) - { *dirpath = pg_strdup(envVar); - if (configpath) - *configpath = pg_strdup(envVar); - } + else if (defaultValue) + *dirpath = pg_strdup(defaultValue); else pg_fatal("You must identify the directory where the %s.\n" "Please use the %s command-line option or the %s environment variable.\n", description, cmdLineOption, envVarName); + + if (configpath) + *configpath = pg_strdup(*dirpath); } /* @@ -455,12 +473,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) if (GET_MAJOR_VERSION(cluster->major_version) >= 901) { 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"); - } + cluster->sockdir = user_opts.socketdir; 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