Improve capture of pg_rewind stderr output

As it seems redirecting stderr to stdin (2>&1) when executing
system commands results in a SIGPIPE (141) return code, making
it impossible to determine the actual return code, redirect
stderr to a temporary file and collate the output from that.

There are possibly better ways of doing this which could
be revisited at a future date.
This commit is contained in:
Ian Barwick
2020-10-15 14:00:59 +09:00
parent 725e9f9851
commit ac2feba380
2 changed files with 57 additions and 6 deletions

View File

@@ -2843,7 +2843,7 @@ do_node_rejoin(void)
if (ret == false)
{
log_error(_("unable to execute pg_rewind"));
log_error(_("pg_rewind execution failed"));
log_detail("%s", command_output.data);
termPQExpBuffer(&command_output);

View File

@@ -57,27 +57,56 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
char output[MAXLEN];
int retval = 0;
bool success;
char tmpfile_path[MAXPGPATH];
const char *tmpdir = getenv("TMPDIR");
int fd;
PQExpBufferData command_final;
log_verbose(LOG_DEBUG, "executing:\n %s", command);
if (!tmpdir)
tmpdir = "/tmp";
maxpath_snprintf(tmpfile_path, "%s/repmgr_command.XXXXXX",
tmpdir);
fd = mkstemp(tmpfile_path);
if (fd < 1)
{
log_error(_("unable to open temporary file"));
return false;
}
initPQExpBuffer(&command_final);
appendPQExpBufferStr(&command_final, command);
appendPQExpBuffer(&command_final, " 2>%s", tmpfile_path);
log_verbose(LOG_DEBUG, "executing:\n %s", command_final.data);
if (outputbuf == NULL)
{
retval = system(command);
retval = system(command_final.data);
termPQExpBuffer(&command_final);
if (return_value != NULL)
*return_value = WEXITSTATUS(retval);
close(fd);
return (retval == 0) ? true : false;
}
fp = popen(command, "r");
fp = popen(command_final.data, "r");
if (fp == NULL)
{
log_error(_("unable to execute local command:\n%s"), command);
log_error(_("unable to execute local command:\n%s"), command_final.data);
termPQExpBuffer(&command_final);
close(fd);
return false;
}
termPQExpBuffer(&command_final);
while (fgets(output, MAXLEN, fp) != NULL)
{
@@ -91,11 +120,32 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
retval = pclose(fp);
/* */
/* 141 = SIGPIPE */
success = (WEXITSTATUS(retval) == 0 || WEXITSTATUS(retval) == 141) ? true : false;
log_verbose(LOG_DEBUG, "result of command was %i (%i)", WEXITSTATUS(retval), retval);
/*
* Append any captured STDERR output
*/
fp = fopen(tmpfile_path, "r");
/*
* Not critical if we can't open the file
*/
if (fp != NULL)
{
while (fgets(output, MAXLEN, fp) != NULL)
{
appendPQExpBufferStr(outputbuf, output);
}
fclose(fp);
}
unlink(tmpfile_path);
if (return_value != NULL)
*return_value = WEXITSTATUS(retval);
@@ -104,6 +154,7 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
else
log_verbose(LOG_DEBUG, "local_command(): no output returned");
return success;
}