Support custom socket directory in pg_upgrade

Started by Daniel Gustafssonover 7 years ago20 messageshackers
Jump to latest
#1Daniel Gustafsson
daniel@yesql.se

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

cheers ./daniel

Attachments:

pg_upgrade_sockdir.patchapplication/octet-stream; name=pg_upgrade_sockdir.patch; x-unix-mode=0644Download+31-6
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Gustafsson (#1)
Re: Support custom socket directory in pg_upgrade

Daniel Gustafsson <daniel@yesql.se> writes:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

I think you could simplify matters if you installed the CWD default value
during option processing.

regards, tom lane

#3Daniel Gustafsson
daniel@yesql.se
In reply to: Tom Lane (#2)
Re: Support custom socket directory in pg_upgrade

On 9 Oct 2018, at 16:22, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Daniel Gustafsson <daniel@yesql.se> writes:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

I think you could simplify matters if you installed the CWD default value
during option processing.

The attached v2 tries to make the socketdir more like the other configurable
directories in pg_upgrade (adding an envvar for it etc). Is that more in line
with what you were suggesting? make -C src/bin/pg_upgrade check passes with
this, both unmodified and with a -s in the test script to override it. Also
fixed incorrect syntax in the docs part from v1.

cheers ./daniel

Attachments:

pg_upgrade_sockdir-v2.patchapplication/octet-stream; name=pg_upgrade_sockdir-v2.patch; x-unix-mode=0644Download+23-8
#4Hironobu SUZUKI
hironobu@interdb.jp
In reply to: Daniel Gustafsson (#3)
Re: Support custom socket directory in pg_upgrade

Hi,

I reviewed `pg_upgrade_sockdir-v2.patch`.

I checked `-s` option on OSX. I confirmed that all tools, which are
internally invoked such as pg_dumpall and pg_restore, used the specified
socket and pg_upgrade worked as expected.

I think this patch is fine.

Best regards,

Show quoted text

On 2018/10/09 21:26, Daniel Gustafsson wrote:

On 9 Oct 2018, at 16:22, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Daniel Gustafsson <daniel@yesql.se> writes:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

I think you could simplify matters if you installed the CWD default value
during option processing.

The attached v2 tries to make the socketdir more like the other configurable
directories in pg_upgrade (adding an envvar for it etc). Is that more in line
with what you were suggesting? make -C src/bin/pg_upgrade check passes with
this, both unmodified and with a -s in the test script to override it. Also
fixed incorrect syntax in the docs part from v1.

cheers ./daniel

#5Thomas Munro
thomas.munro@gmail.com
In reply to: Daniel Gustafsson (#3)
Re: Support custom socket directory in pg_upgrade

On Wed, Oct 10, 2018 at 9:27 AM Daniel Gustafsson <daniel@yesql.se> wrote:

On 9 Oct 2018, at 16:22, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Daniel Gustafsson <daniel@yesql.se> writes:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

I think you could simplify matters if you installed the CWD default value
during option processing.

The attached v2 tries to make the socketdir more like the other configurable
directories in pg_upgrade (adding an envvar for it etc). Is that more in line
with what you were suggesting? make -C src/bin/pg_upgrade check passes with
this, both unmodified and with a -s in the test script to override it. Also
fixed incorrect syntax in the docs part from v1.

I think PGSOCKETDIR should be mentioned in the documentation like the
other environment variables, and also I'm wondering if it actually
works: you set it to the current working directory first, then parse
the command line option if present, and then read the env var only if
not already set: but it's always going to be, isn't it? Perhaps you
should use getcwd() only if all else fails?

--
Thomas Munro
http://www.enterprisedb.com

#6Peter Eisentraut
peter_e@gmx.net
In reply to: Daniel Gustafsson (#1)
Re: Support custom socket directory in pg_upgrade

On 09/10/2018 15:09, Daniel Gustafsson wrote:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

Why not always create a temporary directory and put it there. Then we
don't need an option. It's not like the current directory is a
particularly good choice anyway.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#7Daniel Gustafsson
daniel@yesql.se
In reply to: Thomas Munro (#5)
Re: Support custom socket directory in pg_upgrade

On 6 Nov 2018, at 09:19, Thomas Munro <thomas.munro@enterprisedb.com> wrote:

On Wed, Oct 10, 2018 at 9:27 AM Daniel Gustafsson <daniel@yesql.se <mailto:daniel@yesql.se>> wrote:

On 9 Oct 2018, at 16:22, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Daniel Gustafsson <daniel@yesql.se> writes:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

I think you could simplify matters if you installed the CWD default value
during option processing.

The attached v2 tries to make the socketdir more like the other configurable
directories in pg_upgrade (adding an envvar for it etc). Is that more in line
with what you were suggesting? make -C src/bin/pg_upgrade check passes with
this, both unmodified and with a -s in the test script to override it. Also
fixed incorrect syntax in the docs part from v1.

I think PGSOCKETDIR should be mentioned in the documentation like the
other environment variables,

Of course, fixed.

and also I'm wondering if it actually
works: you set it to the current working directory first, then parse
the command line option if present, and then read the env var only if
not already set: but it's always going to be, isn't it? Perhaps you
should use getcwd() only if all else fails?

Yes, you’re right, I had a thinko in my patch as well as in the testing of it.
The attached version sets cwd as the default in case all else fails. Extending
check_required_directory() to do this may not be to everyones liking, but it
seemed the cleanest option to me.

cheers ./daniel

Attachments:

pg_upgrade_sockdir-v3.patchapplication/octet-stream; name=pg_upgrade_sockdir-v3.patch; x-unix-mode=0644Download+41-19
#8Daniel Gustafsson
daniel@yesql.se
In reply to: Peter Eisentraut (#6)
Re: Support custom socket directory in pg_upgrade

On 7 Nov 2018, at 08:23, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:

On 09/10/2018 15:09, Daniel Gustafsson wrote:

Having hit the maximum socketdir length error a number of times in pg_upgrade,
especially when running tests in a deep directory hierarchy, I figured it was
time to see if anyone else has had the same problem? The attached patch is
what I run with locally to avoid the issue, it adds a --socketdir=PATH option
to pg_upgrade which overrides the default use of CWD. Is that something that
could be considered?

Why not always create a temporary directory and put it there. Then we
don't need an option. It's not like the current directory is a
particularly good choice anyway.

I agree that cwd isn’t a terribly good default, but is there a good way to
identify a suitable temporary directory to use across all platforms (mostly
thinking about Windows)? Overloading PGDATA/base/pgsql_tmp (or similar) in
either the new or old datadir seems ugly, and risks running into the sockdir
limitation this patch is intending to solve.

cheers ./daniel

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Gustafsson (#8)
Re: Support custom socket directory in pg_upgrade

Daniel Gustafsson <daniel@yesql.se> writes:

On 7 Nov 2018, at 08:23, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote:
Why not always create a temporary directory and put it there. Then we
don't need an option. It's not like the current directory is a
particularly good choice anyway.

I agree that cwd isn’t a terribly good default, but is there a good way to
identify a suitable temporary directory to use across all platforms (mostly
thinking about Windows)?

Windows isn't a problem because it doesn't do Unix-style sockets anyway.
However, I agree that Peter's proposal is just begging the question of
how we'd identify a better default choice than cwd.

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work. For example, one idea is to make
a temporary directory under the installation's normal socket directory
(thus, /tmp/pgXXXX/ or some such). But, if the normal socket directory
is not /tmp, we might find that pg_upgrade can't write there.

So I'm inclined to think that a --socketdir option is a reasonable
feature independently of whether someone comes up with a different
proposal for the default location.

regards, tom lane

#10Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#9)
Re: Support custom socket directory in pg_upgrade

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work. For example, one idea is to make
a temporary directory under the installation's normal socket directory
(thus, /tmp/pgXXXX/ or some such). But, if the normal socket directory
is not /tmp, we might find that pg_upgrade can't write there.

We do exactly that in pg_regress and it's never been a problem.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#10)
Re: Support custom socket directory in pg_upgrade

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work. For example, one idea is to make
a temporary directory under the installation's normal socket directory
(thus, /tmp/pgXXXX/ or some such). But, if the normal socket directory
is not /tmp, we might find that pg_upgrade can't write there.

We do exactly that in pg_regress and it's never been a problem.

Yeah, but pg_upgrade is used by a much wider variety of people
than pg_regress.

regards, tom lane

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#11)
Re: Support custom socket directory in pg_upgrade

I wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work. For example, one idea is to make
a temporary directory under the installation's normal socket directory
(thus, /tmp/pgXXXX/ or some such). But, if the normal socket directory
is not /tmp, we might find that pg_upgrade can't write there.

We do exactly that in pg_regress and it's never been a problem.

Yeah, but pg_upgrade is used by a much wider variety of people
than pg_regress.

Further point about that: pg_regress's method of creating a temp
directory under /tmp is secure only on machines with the stickybit
set on /tmp; otherwise it's possible for an attacker to rename the
temp dir out of the way and inject his own socket. We agreed that
that was an okay risk to take for testing purposes, but I'm much
less willing to assume that it's okay for production use with
pg_upgrade. So I think we should keep the default situation being
that we put the socket in cwd, which we're already assuming is
secure because that's where we put the transient dump files.
That implies that we need this switch for use-cases where cwd
isn't workable due to long pathname or permissions considerations.

regards, tom lane

#13Daniel Gustafsson
daniel@yesql.se
In reply to: Tom Lane (#12)
Re: Support custom socket directory in pg_upgrade

On 15 Nov 2018, at 22:42, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Further point about that: pg_regress's method of creating a temp
directory under /tmp is secure only on machines with the stickybit
set on /tmp; otherwise it's possible for an attacker to rename the
temp dir out of the way and inject his own socket. We agreed that
that was an okay risk to take for testing purposes, but I'm much
less willing to assume that it's okay for production use with
pg_upgrade.

That’s a good point, it’s not an assumption I’d be comfortable with when it
deals with system upgrades.

cheers ./daniel

#14Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Tom Lane (#11)
Re: Support custom socket directory in pg_upgrade

On 2018-Nov-12, Tom Lane wrote:

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work. For example, one idea is to make
a temporary directory under the installation's normal socket directory
(thus, /tmp/pgXXXX/ or some such). But, if the normal socket directory
is not /tmp, we might find that pg_upgrade can't write there.

We do exactly that in pg_regress and it's never been a problem.

Yeah, but pg_upgrade is used by a much wider variety of people
than pg_regress.

Surely they can just set TMPDIR if /tmp is not writable? If TMPDIR is
set and not writable, bark at the user for it.

--
�lvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#15Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alvaro Herrera (#14)
Re: Support custom socket directory in pg_upgrade

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work.

Surely they can just set TMPDIR if /tmp is not writable? If TMPDIR is
set and not writable, bark at the user for it.

(1) There was nothing about TMPDIR in Peter's proposal, nor would an
implementation based on mkdtemp(3) automatically do that for us.

(2) If you accept the proposition that we must provide a user knob of
some sort, why shouldn't it be a command line switch rather than an
environment variable? The former are much easier to document and to
discover.

regards, tom lane

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Daniel Gustafsson (#7)
Re: Support custom socket directory in pg_upgrade

Daniel Gustafsson <daniel@yesql.se> writes:

[ pg_upgrade_sockdir-v3.patch ]

BTW, I notice that cfbot doesn't like this now that Thomas is running it
with -Werror:

option.c: In function ‘parseCommandLine’:
option.c:265:8: error: ignoring return value of ‘getcwd’, declared with attribute warn_unused_result [-Werror=unused-result]
getcwd(default_sockdir, MAXPGPATH);
^
cc1: all warnings being treated as errors

Failing to check a syscall's result isn't per project style even if
the tools would let you get away with it. Other places in that same
file do

if (!getcwd(cwd, MAXPGPATH))
pg_fatal("could not determine current directory\n");

regards, tom lane

#17Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#15)
Re: Support custom socket directory in pg_upgrade

I wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> writes:

On 12/11/2018 20:00, Tom Lane wrote:

Also, even if we had an arguably-better idea, I suspect that there would
always be cases where it didn't work.

Surely they can just set TMPDIR if /tmp is not writable? If TMPDIR is
set and not writable, bark at the user for it.

(1) There was nothing about TMPDIR in Peter's proposal, nor would an
implementation based on mkdtemp(3) automatically do that for us.
(2) If you accept the proposition that we must provide a user knob of
some sort, why shouldn't it be a command line switch rather than an
environment variable? The former are much easier to document and to
discover.

So we seem to be at an impasse here. By my count, three people have
expressed support for the patch's approach of adding a socket-directory
option, while two people seem to prefer the idea of putting pg_upgrade's
socket under /tmp (possibly with a way to override that). That's not
enough of a consensus to proceed with either approach, really, but
we ought to do something because the problem is real.

Given that we have a patch for this approach, and no patch has been
offered for the /tmp approach, I'm kind of inclined to exercise
committer's discretion and proceed with this patch. Will anybody
be seriously annoyed if I do?

regards, tom lane

#18Peter Eisentraut
peter_e@gmx.net
In reply to: Tom Lane (#17)
Re: Support custom socket directory in pg_upgrade

On 30/11/2018 17:58, Tom Lane wrote:

So we seem to be at an impasse here. By my count, three people have
expressed support for the patch's approach of adding a socket-directory
option, while two people seem to prefer the idea of putting pg_upgrade's
socket under /tmp (possibly with a way to override that). That's not
enough of a consensus to proceed with either approach, really, but
we ought to do something because the problem is real.

Given that we have a patch for this approach, and no patch has been
offered for the /tmp approach, I'm kind of inclined to exercise
committer's discretion and proceed with this patch. Will anybody
be seriously annoyed if I do?

I think it's fair to proceed and leave open that someone submits a
(possibly) better patch for a different approach in the future.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Peter Eisentraut (#18)
Re: Support custom socket directory in pg_upgrade

Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:

On 30/11/2018 17:58, Tom Lane wrote:

Given that we have a patch for this approach, and no patch has been
offered for the /tmp approach, I'm kind of inclined to exercise
committer's discretion and proceed with this patch. Will anybody
be seriously annoyed if I do?

I think it's fair to proceed and leave open that someone submits a
(possibly) better patch for a different approach in the future.

I don't think we'd be able to remove the --socketdir switch once added,
but certainly it doesn't preclude changing the algorithm for default
socket placement.

Pushed with minor code cleanup.

regards, tom lane

#20Noah Misch
noah@leadboat.com
In reply to: Daniel Gustafsson (#13)
Re: Support custom socket directory in pg_upgrade

On Sat, Nov 17, 2018 at 10:15:08PM +0100, Daniel Gustafsson wrote:

On 15 Nov 2018, at 22:42, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Further point about that: pg_regress's method of creating a temp
directory under /tmp is secure only on machines with the stickybit
set on /tmp; otherwise it's possible for an attacker to rename the
temp dir out of the way and inject his own socket. We agreed that
that was an okay risk to take for testing purposes, but I'm much
less willing to assume that it's okay for production use with
pg_upgrade.

That’s a good point, it’s not an assumption I’d be comfortable with when it
deals with system upgrades.

As in /messages/by-id/flat/20140329222934.GC170273@tornado.leadboat.com, I
maintain that insecure /tmp is not worth worrying about in any part of
PostgreSQL.