Re: [BUGS] BUG #8177: initscript should create /var/run/postgresql - Mailing list pgsql-pkg-debian

From Chris Nehren
Subject Re: [BUGS] BUG #8177: initscript should create /var/run/postgresql
Date
Msg-id 20140530170316.GC13595@behemoth
Whole thread Raw
In response to Re: [BUGS] BUG #8177: initscript should create /var/run/postgresql  (Christoph Berg <myon@debian.org>)
Responses Re: [BUGS] BUG #8177: initscript should create /var/run/postgresql  (Chris Nehren <cnehren+pgsql-pkg-debian@pobox.com>)
List pgsql-pkg-debian
> On Mon, 2013-05-27 at 09:27 +0000, stronny@celestia.ru wrote:
> > The following bug has been logged on the website:
> >
> > Bug reference:      8177
> > Logged by:          stronny
> > Email address:      stronny@celestia.ru
> > PostgreSQL version: 9.2.4
> > Operating system:   wheezy
> > Description:
> >
> > When installed from apt.postgresql.org Postgres fails to start on system
> > boot.
> >
> > Wheezy changed /var/run to become memory-based so initscript should create
> > /var/run/postgresql if necessary.
>
> start() {
>     # create socket directory
>     if [ -d /var/run/postgresql ]; then
>         chmod 2775 /var/run/postgresql
>     else
>         install -d -m 2775 -o postgres -g postgres /var/run/postgresql
>     fi
>
>     do_ctl_all start "$1" "Starting PostgreSQL $1 database server"
> }
>
> We create the directory, what specifically doesn't work for you?

I've been able to reproduce this as well, and have found the root
cause.  Presently, the init script itself
(/etc/init.d/postgresql) does this:

    start|stop|restart|reload)
        if [ -z "`pg_lsclusters -h`" ]; then
            log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
            exit 0
        fi

pg_lsclusters is a Perl application that gets most of its logic
from PgCommon.pm.  Its entry point into PgCommon.pm (the one we
care about, anyway) is the subroutine &cluster_info.
&cluster_info, at line 575, calls &get_cluster_socketdir.  This
subroutine, at line 360, gets the 'unix_socket_directories' value
from the configuration file. If the value is defined in the
configuration file (the default), it immediately returns that
value to &cluster_info.  This is important.  If the value is
*not* defined, then &get_cluster_socketdir defaults it to
'/var/run/postgresql' and attempts to stat() this directory.  As
'/var/run' is now a tmpfs in Debian, this fails, because no
attempt has been made to create that directory before the stat()
runs.

There are actually two bugs here.  The first is attempting to
stat() a directory that the code has not ensured exists, which is
what this bug is about.  The second, more general, is that the
code makes no attempts at creating or even verifying the
existence of any unix_socket_{directory,directories} before
returning.  I've attached a patch to the init script that ensures
/var/run/postgresql actually exists before the code tries to
stat() it.

The reproduction steps for this bug are as follows:

1. install fresh Debian wheezy machine
2. Add official Postgres mirror to apt, installing the keyring
for same
3. Install the Postgres server
4. Remove any unix_socket_{directory,directories} directive from
/etc/postgresql/9.?/main/postgresql.conf
5. Reboot, observe Postgres startup failure

I've been able to reproduce this 100% of the time with the above
steps.

--
Chris Nehren

Attachment

pgsql-pkg-debian by date:

Previous
From: apt.postgresql.org repository
Date:
Subject: psqlodbc updated to version 1:09.03.0300-1.pgdg+1
Next
From: Chris Nehren
Date:
Subject: Re: [BUGS] BUG #8177: initscript should create /var/run/postgresql