Skip to content

Commit 2d34ad8

Browse files
committed
Add a --socketdir option to pg_upgrade.
This allows control of the directory in which the postmaster sockets are created for the temporary postmasters started by pg_upgrade. The default location remains the current working directory, which is typically fine, but if it is deeply nested then its pathname might be too long to be a socket name. In passing, clean up some messiness in pg_upgrade's option handling, particularly the confusing and undocumented way that configuration-only datadirs were handled. And fix check_required_directory's substantially under-baked cleanup of directory pathnames. Daniel Gustafsson, reviewed by Hironobu Suzuki, some code cleanup by me Discussion: https://postgr.es/m/E72DD5C3-2268-48A5-A907-ED4B34BEC223@yesql.se
1 parent 7d4524a commit 2d34ad8

File tree

3 files changed

+77
-44
lines changed

3 files changed

+77
-44
lines changed

doc/src/sgml/ref/pgupgrade.sgml

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,14 @@
163163
</para></listitem>
164164
</varlistentry>
165165

166+
<varlistentry>
167+
<term><option>-s</option> <replaceable>dir</replaceable></term>
168+
<term><option>--socketdir=</option><replaceable>dir</replaceable></term>
169+
<listitem><para>directory to use for postmaster sockets during upgrade;
170+
default is current working directory; environment
171+
variable <envar>PGSOCKETDIR</envar></para></listitem>
172+
</varlistentry>
173+
166174
<varlistentry>
167175
<term><option>-U</option> <replaceable>username</replaceable></term>
168176
<term><option>--username=</option><replaceable>username</replaceable></term>
@@ -709,11 +717,21 @@ psql --username=postgres --file=script.sql postgres
709717
<title>Notes</title>
710718

711719
<para>
712-
<application>pg_upgrade</application> does not support upgrading of databases
713-
containing table columns using these <type>reg*</type> OID-referencing system data types:
714-
<type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
715-
<type>regoperator</type>, <type>regconfig</type>, and
716-
<type>regdictionary</type>. (<type>regtype</type> can be upgraded.)
720+
<application>pg_upgrade</application> creates various working files, such
721+
as schema dumps, in the current working directory. For security, be sure
722+
that that directory is not readable or writable by any other users.
723+
</para>
724+
725+
<para>
726+
<application>pg_upgrade</application> launches short-lived postmasters in
727+
the old and new data directories. Temporary Unix socket files for
728+
communication with these postmasters are, by default, made in the current
729+
working directory. In some situations the path name for the current
730+
directory might be too long to be a valid socket name. In that case you
731+
can use the <option>-s</option> option to put the socket files in some
732+
directory with a shorter path name. For security, be sure that that
733+
directory is not readable or writable by any other users.
734+
(This is not relevant on Windows.)
717735
</para>
718736

719737
<para>
@@ -732,6 +750,14 @@ psql --username=postgres --file=script.sql postgres
732750
insert dummy data, and upgrade that.
733751
</para>
734752

753+
<para>
754+
<application>pg_upgrade</application> does not support upgrading of databases
755+
containing table columns using these <type>reg*</type> OID-referencing system data types:
756+
<type>regproc</type>, <type>regprocedure</type>, <type>regoper</type>,
757+
<type>regoperator</type>, <type>regconfig</type>, and
758+
<type>regdictionary</type>. (<type>regtype</type> can be upgraded.)
759+
</para>
760+
735761
<para>
736762
If you are upgrading a pre-<productname>PostgreSQL</productname> 9.2 cluster
737763
that uses a configuration-file-only directory, you must pass the

src/bin/pg_upgrade/option.c

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121

2222

2323
static void usage(void);
24-
static void check_required_directory(char **dirpath, char **configpath,
25-
const char *envVarName, const char *cmdLineOption, const char *description);
24+
static void check_required_directory(char **dirpath,
25+
const char *envVarName, bool useCwd,
26+
const char *cmdLineOption, const char *description);
2627
#define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false"
2728

2829

@@ -52,6 +53,7 @@ parseCommandLine(int argc, char *argv[])
5253
{"link", no_argument, NULL, 'k'},
5354
{"retain", no_argument, NULL, 'r'},
5455
{"jobs", required_argument, NULL, 'j'},
56+
{"socketdir", required_argument, NULL, 's'},
5557
{"verbose", no_argument, NULL, 'v'},
5658
{"clone", no_argument, NULL, 1},
5759

@@ -102,7 +104,7 @@ parseCommandLine(int argc, char *argv[])
102104
if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
103105
pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE);
104106

105-
while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
107+
while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rs:U:v",
106108
long_options, &optindex)) != -1)
107109
{
108110
switch (option)
@@ -121,12 +123,10 @@ parseCommandLine(int argc, char *argv[])
121123

122124
case 'd':
123125
old_cluster.pgdata = pg_strdup(optarg);
124-
old_cluster.pgconfig = pg_strdup(optarg);
125126
break;
126127

127128
case 'D':
128129
new_cluster.pgdata = pg_strdup(optarg);
129-
new_cluster.pgconfig = pg_strdup(optarg);
130130
break;
131131

132132
case 'j':
@@ -188,6 +188,10 @@ parseCommandLine(int argc, char *argv[])
188188
log_opts.retain = true;
189189
break;
190190

191+
case 's':
192+
user_opts.socketdir = pg_strdup(optarg);
193+
break;
194+
191195
case 'U':
192196
pg_free(os_info.user);
193197
os_info.user = pg_strdup(optarg);
@@ -244,14 +248,16 @@ parseCommandLine(int argc, char *argv[])
244248
pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);
245249

246250
/* Get values from env if not already set */
247-
check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b",
248-
_("old cluster binaries reside"));
249-
check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B",
250-
_("new cluster binaries reside"));
251-
check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig,
252-
"PGDATAOLD", "-d", _("old cluster data resides"));
253-
check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig,
254-
"PGDATANEW", "-D", _("new cluster data resides"));
251+
check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
252+
"-b", _("old cluster binaries reside"));
253+
check_required_directory(&new_cluster.bindir, "PGBINNEW", false,
254+
"-B", _("new cluster binaries reside"));
255+
check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false,
256+
"-d", _("old cluster data resides"));
257+
check_required_directory(&new_cluster.pgdata, "PGDATANEW", false,
258+
"-D", _("new cluster data resides"));
259+
check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true,
260+
"-s", _("sockets will be created"));
255261

256262
#ifdef WIN32
257263

@@ -296,6 +302,7 @@ usage(void)
296302
printf(_(" -p, --old-port=PORT old cluster port number (default %d)\n"), old_cluster.port);
297303
printf(_(" -P, --new-port=PORT new cluster port number (default %d)\n"), new_cluster.port);
298304
printf(_(" -r, --retain retain SQL and log files after success\n"));
305+
printf(_(" -s, --socketdir=DIR socket directory to use (default CWD)\n"));
299306
printf(_(" -U, --username=NAME cluster superuser (default \"%s\")\n"), os_info.user);
300307
printf(_(" -v, --verbose enable verbose internal logging\n"));
301308
printf(_(" -V, --version display version information, then exit\n"));
@@ -337,29 +344,32 @@ usage(void)
337344
* check_required_directory()
338345
*
339346
* Checks a directory option.
340-
* dirpath - the directory name supplied on the command line
341-
* configpath - optional configuration directory
347+
* dirpath - the directory name supplied on the command line, or NULL
342348
* envVarName - the name of an environment variable to get if dirpath is NULL
343-
* cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N)
349+
* useCwd - true if OK to default to CWD
350+
* cmdLineOption - the command line option for this directory
344351
* description - a description of this directory option
345352
*
346353
* We use the last two arguments to construct a meaningful error message if the
347354
* user hasn't provided the required directory name.
348355
*/
349356
static void
350-
check_required_directory(char **dirpath, char **configpath,
351-
const char *envVarName, const char *cmdLineOption,
352-
const char *description)
357+
check_required_directory(char **dirpath, const char *envVarName, bool useCwd,
358+
const char *cmdLineOption, const char *description)
353359
{
354360
if (*dirpath == NULL || strlen(*dirpath) == 0)
355361
{
356362
const char *envVar;
357363

358364
if ((envVar = getenv(envVarName)) && strlen(envVar))
359-
{
360365
*dirpath = pg_strdup(envVar);
361-
if (configpath)
362-
*configpath = pg_strdup(envVar);
366+
else if (useCwd)
367+
{
368+
char cwd[MAXPGPATH];
369+
370+
if (!getcwd(cwd, MAXPGPATH))
371+
pg_fatal("could not determine current directory\n");
372+
*dirpath = pg_strdup(cwd);
363373
}
364374
else
365375
pg_fatal("You must identify the directory where the %s.\n"
@@ -368,16 +378,10 @@ check_required_directory(char **dirpath, char **configpath,
368378
}
369379

370380
/*
371-
* Trim off any trailing path separators because we construct paths by
372-
* appending to this path.
381+
* Clean up the path, in particular trimming any trailing path separators,
382+
* because we construct paths by appending to this path.
373383
*/
374-
#ifndef WIN32
375-
if ((*dirpath)[strlen(*dirpath) - 1] == '/')
376-
#else
377-
if ((*dirpath)[strlen(*dirpath) - 1] == '/' ||
378-
(*dirpath)[strlen(*dirpath) - 1] == '\\')
379-
#endif
380-
(*dirpath)[strlen(*dirpath) - 1] = 0;
384+
canonicalize_path(*dirpath);
381385
}
382386

383387
/*
@@ -386,6 +390,10 @@ check_required_directory(char **dirpath, char **configpath,
386390
* If a configuration-only directory was specified, find the real data dir
387391
* by querying the running server. This has limited checking because we
388392
* can't check for a running server because we can't find postmaster.pid.
393+
*
394+
* On entry, cluster->pgdata has been set from command line or env variable,
395+
* but cluster->pgconfig isn't set. We fill both variables with corrected
396+
* values.
389397
*/
390398
void
391399
adjust_data_dir(ClusterInfo *cluster)
@@ -396,6 +404,9 @@ adjust_data_dir(ClusterInfo *cluster)
396404
FILE *fp,
397405
*output;
398406

407+
/* Initially assume config dir and data dir are the same */
408+
cluster->pgconfig = pg_strdup(cluster->pgdata);
409+
399410
/* If there is no postgresql.conf, it can't be a config-only dir */
400411
snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
401412
if ((fp = fopen(filename, "r")) == NULL)
@@ -462,12 +473,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check)
462473
if (GET_MAJOR_VERSION(cluster->major_version) >= 901)
463474
{
464475
if (!live_check)
465-
{
466-
/* Use the current directory for the socket */
467-
cluster->sockdir = pg_malloc(MAXPGPATH);
468-
if (!getcwd(cluster->sockdir, MAXPGPATH))
469-
pg_fatal("could not determine current directory\n");
470-
}
476+
cluster->sockdir = user_opts.socketdir;
471477
else
472478
{
473479
/*

src/bin/pg_upgrade/pg_upgrade.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ typedef struct
298298
bool check; /* true -> ask user for permission to make
299299
* changes */
300300
transferMode transfer_mode; /* copy files or link them? */
301-
int jobs;
301+
int jobs; /* number of processes/threads to use */
302+
char *socketdir; /* directory to use for Unix sockets */
302303
} UserOpts;
303304

304305
typedef struct
@@ -374,7 +375,7 @@ bool pid_lock_file_exists(const char *datadir);
374375
/* file.c */
375376

376377
void cloneFile(const char *src, const char *dst,
377-
const char *schemaName, const char *relName);
378+
const char *schemaName, const char *relName);
378379
void copyFile(const char *src, const char *dst,
379380
const char *schemaName, const char *relName);
380381
void linkFile(const char *src, const char *dst,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy