[pacman-dev] [PATCH v2] alpm: Add better logging when a command fails to execute correctly
Daan De Meyer
daan.j.demeyer at gmail.com
Sun May 24 15:06:41 UTC 2020
You have a point, maybe I'm not solving the right problem. To give a little
more context, While playing with systemd's mkosi (
https://github.com/systemd/mkosi), systemd's systemd-tmpfiles pacman hook
has been consistently failing with "error: command failed to execute
correctly". However, when looking at pacman's logs with `journalctl
_COMM=pacman` (mkosi has pacman log to syslog), there was absolutely no
further information on the failure. I've looked at systemd's source code
now and if stderr is not a tty, it logs separately to another medium
(syslog, journal, ...). To get the actual error from systemd-tmpfiles, I
first hacked this patch into pacman to know which command was actually
failing and even then I had to modify the file descriptor dupping to
directly have systemd inherit the pacman stderr fd before I could actually
get the error from systemd-tmpfiles.
So maybe, instead of this patch, we should force systemd-tmpfiles to output
to the console instead by setting the SYSTEMD_LOG_TARGET environment
variable in the corresponding pacman hook. On the other hand,
systemd-tmpfiles is a CLI tool so maybe it should be outputting to the
console even if it is not a tty. I'll open an issue with systemd as well to
discuss this. It's not intuitive that spawning a systemd CLI tool as a
child process with input redirected to pipes would suddenly cause the
logging output to go somewhere else.
On Sun, 24 May 2020 at 01:06, Andrew Gregory <andrew.gregory.8 at gmail.com>
wrote:
> On 05/23/20 at 02:04pm, Daan De Meyer wrote:
> > This makes debugging hook failures when running pacman less of a
> > hassle. Instead of a generic "command failed to execute correctly",
> > we now get the exact command and its arguments, as well as the exit
> > code of the command logged.
> >
> > Signed-off-by: Daan De Meyer <daan.j.demeyer at gmail.com>
> > ---
> >
> > Updated strv_join failure handling. I'm also not entirely sure what to
> > do with the translations. Do I update all the separate files with the
> > updated message identifier? I can fix some of the translations but
> > the Arabic ones are impossible for me to fix.
>
> No, translations are done separately through transifex.
>
> > lib/libalpm/util.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 44 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
> > index ead03004..22ae48f6 100644
> > --- a/lib/libalpm/util.c
> > +++ b/lib/libalpm/util.c
> > @@ -568,6 +568,42 @@ static void _alpm_reset_signals(void)
> > }
> > }
> >
> > +static char *strv_join(char *const *strv, const char *separator)
> > +{
> > + char *const *i;
> > + char *r, *p;
> > + size_t size = 0;
> > +
> > + if (!separator) {
> > + separator = " ";
> > + }
> > +
> > + for (i = strv; *i; i++) {
> > + if (i != strv) {
> > + size += strlen(separator);
> > + }
> > +
> > + size += strlen(*i);
> > + }
> > +
> > + r = malloc(size + 1);
> > + if (r == NULL) {
> > + return NULL;
> > + }
> > +
> > + p = r;
> > +
> > + for (i = strv; *i; i++) {
> > + if (i != strv) {
> > + p = stpcpy(p, separator);
> > + }
> > +
> > + p = stpcpy(p, *i);
> > + }
> > +
> > + return r;
> > +}
>
> We already have an almost identical function in pacman/util.c.
>
> > /** Execute a command with arguments in a chroot.
> > * @param handle the context handle
> > * @param cmd command to execute
> > @@ -745,7 +781,14 @@ int _alpm_run_chroot(alpm_handle_t *handle, const
> char *cmd, char *const argv[],
> > if(WIFEXITED(status)) {
> > _alpm_log(handle, ALPM_LOG_DEBUG, "call to waitpid
> succeeded\n");
> > if(WEXITSTATUS(status) != 0) {
> > - _alpm_log(handle, ALPM_LOG_ERROR,
> _("command failed to execute correctly\n"));
> > + char *argv_str = strv_join(argv, NULL);
> > + if (argv_str) {
> > + _alpm_log(handle, ALPM_LOG_ERROR,
> > + _("command \"%s\"
> failed to execute correctly: %i\n"),
> > + argv_str,
> WEXITSTATUS(status));
>
> I doubt that the exit status is generally going to be useful to the
> user, nor is it clear from the error message that that's even what is
> being printed.
>
> > + free(argv_str);
> > + }
>
> I don't know that this is the right approach. This is going to give
> pretty useless, and probably confusing, output for scriptlets. Hooks
> and scripts should really be printing appropriate error messages when
> they fail, so that our error message should really only matter in the
> rare occasions where the command fails to execute at all. I would be
> more inclined to point the user at the actual hook or script that
> failed.
>
> > +
> > retval = 1;
> > }
> > } else if(WIFSIGNALED(status) != 0) {
> > --
> > 2.26.2
>
More information about the pacman-dev
mailing list