From: "Clément Lassieur" <clement@lassieur.org>
To: Christopher Baines <mail@cbaines.net>
Cc: 30701@debbugs.gnu.org
Subject: [bug#30701] [PATCH 2/4] services: Use a external pid file for PostgreSQL.
Date: Mon, 05 Mar 2018 13:15:36 +0100 [thread overview]
Message-ID: <87bmg2zpjr.fsf@lassieur.org> (raw)
In-Reply-To: <87k1uroru8.fsf@cbaines.net>
Christopher Baines <mail@cbaines.net> writes:
> Clément Lassieur <clement@lassieur.org> writes:
>
>> Christopher Baines <mail@cbaines.net> writes:
>>
>>> * gnu/services/databases.scm (postgresql-pid-file-for-version): New procedure.
>>> (<postgresql-config-file>): Add a new external-pid-file field.
>>> (postgresql-config-file-compiler): Add support for the external-pid-file.
>>> (postgresql-activation): Create the directory for the pid file.
>>> (postgresql-shepherd-service): Use the pid-file when starting the service.
>>> ---
>>> gnu/services/databases.scm | 48 ++++++++++++++++++++++++++++++++++------------
>>> 1 file changed, 36 insertions(+), 12 deletions(-)
>>
>> ...
>>
>>> +(define (postgresql-pid-file-for-version version)
>>> + (string-append "/var/run/postgresql/"
>>> + (version-major+minor version)
>>> + "-main.pid"))
>>> +
>>> (define-record-type* <postgresql-config-file>
>>> postgresql-config-file make-postgresql-config-file
>>> postgresql-config-file?
>>> - (log-destination postgresql-config-file-log-destination
>>> - (default "syslog"))
>>> - (hba-file postgresql-config-file-hba-file
>>> - (default %default-postgres-hba))
>>> - (ident-file postgresql-config-file-ident-file
>>> - (default %default-postgres-ident))
>>> - (extra-config postgresql-config-file-extra-config
>>> - (default '())))
>>> + (log-destination postgresql-config-file-log-destination
>>> + (default "syslog"))
>>> + (hba-file postgresql-config-file-hba-file
>>> + (default %default-postgres-hba))
>>> + (ident-file postgresql-config-file-ident-file
>>> + (default %default-postgres-ident))
>>> + (external-pid-file postgresql-config-file-external-pid-file
>>> + (default (postgresql-pid-file-for-version
>>> + (package-version postgresql))))
>>
>> Why does external-pid-file have a default value. It's optional, and the
>> user already has access to $DATA/postmaster.pid anyway.
>
> I ended up adding this as I was writing the system test. I was coping
> previous tests that I have written, in which I've been checking that the
> shepherd gets the PID back when it starts the process.
>
> Before I set out in writing this, I didn't realise that PostgreSQL
> stores the PID in the data directory by default, or that pg_ctl waits
> for actions to complete by default either.
>
> I'm not particularly attached to this patch, I guess it mostly offers
> consistency with other services.
>
>>> @@ -140,6 +153,9 @@ host all all ::1/128 trust"))
>>> (default 5432))
>>> (locale postgresql-configuration-locale
>>> (default "en_US.utf8"))
>>> + (pid-file postgresql-configuration-pid-file
>>> + (default (postgresql-pid-file-for-version
>>> + (package-version postgresql))))
>>
>> The main PID file is chosen by Postgres, and put at
>> $DATA/postmaster.pid. I don't think it's customizable. This setting
>> (pid-file) probably doesn't affect the daemon the way you think it does.
>
> This part of the configuration is just meant to be where the Guix part
> of the service expects to find the pid-file (if one is used, and it's
> not #f).
>
>>> (config-file postgresql-configuration-file
>>> (default (postgresql-config-file)))
>>> (data-directory postgresql-configuration-data-directory
>>> @@ -157,7 +173,8 @@ host all all ::1/128 trust"))
>>>
>>> + ;; Create a directory for the pid file
>>> + (mkdir-p #$(dirname pid-file))
>>> + (chown #$(dirname pid-file) (passwd:uid user) (passwd:gid user))
>>
>> I think it would make more sense to create the directory for the
>> external-pid-file.
>
> As far as I understand it, this is what this does.
>
>>> (define postgresql-shepherd-service
>>> (match-lambda
>>> - (($ <postgresql-configuration> postgresql port locale config-file data-directory)
>>> + (($ <postgresql-configuration> postgresql port locale pid-file
>>> + config-file data-directory)
>>> (let* ((pg_ctl-wrapper
>>> ;; Wrapper script that switches to the 'postgres' user before
>>> ;; launching daemon.
>>> @@ -221,7 +243,9 @@ host all all ::1/128 trust"))
>>> (provision '(postgres))
>>> (documentation "Run the PostgreSQL daemon.")
>>> (requirement '(user-processes loopback syslogd))
>>> - (start (action "start"))
>>> + (start #~(make-forkexec-constructor
>>> + '(#$pg_ctl-wrapper "start")
>>> + #:pid-file #$pid-file))
>>> (stop (action "stop"))))))))
>>
>> If pid-file != external-pid-file, Sherpherd will wait for a file that
>> doesn't exist won't it? Because Postgresql will never be aware of that
>> pid-file.
>
> Yep.
>
>> Plus, there is no reason to use make-forkexec-constructor on pg_ctl
>> because pg_ctl returns after it has checked that the daemon is running.
>> For the same reason, Shepherd doesn't need to know about Postgres' PID.
>> All the hard work is done by pg_ctl.
>
> As the comment I made at the top, I did this when I was writing the
> system test. If you remove this patch, when you call (start-service
> 'postgres), it will return #f if the service starts successfully. If you
> tweak the service to make it fail to start (e.g. by changing the "start"
> action to something else), you get the same observable behaviour,
> start-service returns #f.
>
> The way this works for other services, normally through
> make-forkexec-constructor is that calling start-service will return the
> PID.
>
> While the system test does still add some value even without checking if
> the service has started, doing so would be really good. Even if it's not
> using the PID file approach, maybe the exit code of pg_ctl could be
> used? I'm not really sure why it isn't working like that already, as
> invoke usually returns either #t or #f...
The PID approch only makes sense when the executable run by Shepherd
doesn't return; i.e. it blocks. Then Shepherd needs to fork a child
process (with make-forkexec-constructor), so that it doesn't block. And
the only way to know if the daemon has started is to find a "proof",
which is the PID file. That's the point of the #:pid-file parameter of
make-forkexec-constructor.
But the PostgreSQL package is more elaborate: it provides an 'pg_ctl'
executable that does all the hard work:
- starting the daemon,
- checking its PID to make sure the daemon is running,
- exiting with 0 if the daemon is running.
So Shepherd doesn't need to fork, it just checks the return value of
pg_ctl.
Conclusion: (start-service 'postgres) returning #t means that pg_ctl
exit code is 0, which means that the daemon is running. I hope it makes
more sense :-)
next prev parent reply other threads:[~2018-03-05 12:16 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-04 19:10 [bug#30701] [PATCH 0/4] PostgreSQL service changes (add record type, and system test) Christopher Baines
2018-03-04 19:16 ` [bug#30701] [PATCH 1/4] services: Rework the PostgreSQL config file to use a record type Christopher Baines
2018-03-04 19:16 ` [bug#30701] [PATCH 2/4] services: Use a external pid file for PostgreSQL Christopher Baines
2018-03-05 0:32 ` Clément Lassieur
2018-03-05 8:21 ` Christopher Baines
2018-03-05 8:27 ` Christopher Baines
2018-03-05 12:15 ` Clément Lassieur [this message]
2018-03-04 19:16 ` [bug#30701] [PATCH 3/4] tests: databases: Add a system test " Christopher Baines
2018-03-05 0:32 ` Clément Lassieur
2018-03-05 8:34 ` Christopher Baines
2018-03-04 19:16 ` [bug#30701] [PATCH 4/4] services: databases: Add postgresql-configuration record exports Christopher Baines
2018-03-05 12:16 ` Clément Lassieur
2018-03-05 19:37 ` Christopher Baines
2018-03-05 0:32 ` [bug#30701] [PATCH 1/4] services: Rework the PostgreSQL config file to use a record type Clément Lassieur
2018-03-05 7:52 ` Christopher Baines
2018-03-05 8:52 ` Clément Lassieur
2018-03-05 9:35 ` Clément Lassieur
2018-03-05 8:39 ` [bug#30701] [PATCH 1/3] " Christopher Baines
2018-03-05 8:39 ` [bug#30701] [PATCH 2/3] tests: databases: Add a system test for PostgreSQL Christopher Baines
2018-03-05 11:54 ` Clément Lassieur
2018-03-05 19:25 ` Christopher Baines
2018-03-05 8:39 ` [bug#30701] [PATCH 3/3] services: databases: Add postgresql-configuration record exports Christopher Baines
2018-03-05 19:37 ` [bug#30701] [PATCH 1/3] services: Rework the PostgreSQL config file to use a record type Christopher Baines
2018-03-05 19:37 ` [bug#30701] [PATCH 2/3] tests: databases: Add a system test for PostgreSQL Christopher Baines
2018-03-05 19:37 ` [bug#30701] [PATCH 3/3] services: databases: Add postgresql-configuration record exports Christopher Baines
2018-03-05 21:33 ` [bug#30701] [PATCH 1/3] services: Rework the PostgreSQL config file to use a record type Clément Lassieur
2018-03-13 17:37 ` bug#30701: " Christopher Baines
2018-03-14 17:37 ` [bug#30701] " Clément Lassieur
2018-03-17 20:35 ` Christopher Baines
2018-03-18 0:34 ` Clément Lassieur
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bmg2zpjr.fsf@lassieur.org \
--to=clement@lassieur.org \
--cc=30701@debbugs.gnu.org \
--cc=mail@cbaines.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.