mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-26 16:46:28 +00:00
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:
@@ -2843,7 +2843,7 @@ do_node_rejoin(void)
|
|||||||
|
|
||||||
if (ret == false)
|
if (ret == false)
|
||||||
{
|
{
|
||||||
log_error(_("unable to execute pg_rewind"));
|
log_error(_("pg_rewind execution failed"));
|
||||||
log_detail("%s", command_output.data);
|
log_detail("%s", command_output.data);
|
||||||
|
|
||||||
termPQExpBuffer(&command_output);
|
termPQExpBuffer(&command_output);
|
||||||
|
|||||||
61
sysutils.c
61
sysutils.c
@@ -57,27 +57,56 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
|
|||||||
char output[MAXLEN];
|
char output[MAXLEN];
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
bool success;
|
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)
|
if (outputbuf == NULL)
|
||||||
{
|
{
|
||||||
retval = system(command);
|
retval = system(command_final.data);
|
||||||
|
termPQExpBuffer(&command_final);
|
||||||
|
|
||||||
if (return_value != NULL)
|
if (return_value != NULL)
|
||||||
*return_value = WEXITSTATUS(retval);
|
*return_value = WEXITSTATUS(retval);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
return (retval == 0) ? true : false;
|
return (retval == 0) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = popen(command, "r");
|
fp = popen(command_final.data, "r");
|
||||||
|
|
||||||
if (fp == NULL)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
termPQExpBuffer(&command_final);
|
||||||
|
|
||||||
while (fgets(output, MAXLEN, fp) != NULL)
|
while (fgets(output, MAXLEN, fp) != NULL)
|
||||||
{
|
{
|
||||||
@@ -91,11 +120,32 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
|
|||||||
|
|
||||||
retval = pclose(fp);
|
retval = pclose(fp);
|
||||||
|
|
||||||
/* */
|
/* 141 = SIGPIPE */
|
||||||
success = (WEXITSTATUS(retval) == 0 || WEXITSTATUS(retval) == 141) ? true : false;
|
success = (WEXITSTATUS(retval) == 0 || WEXITSTATUS(retval) == 141) ? true : false;
|
||||||
|
|
||||||
log_verbose(LOG_DEBUG, "result of command was %i (%i)", WEXITSTATUS(retval), retval);
|
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)
|
if (return_value != NULL)
|
||||||
*return_value = WEXITSTATUS(retval);
|
*return_value = WEXITSTATUS(retval);
|
||||||
|
|
||||||
@@ -104,6 +154,7 @@ _local_command(const char *command, PQExpBufferData *outputbuf, bool simple, int
|
|||||||
else
|
else
|
||||||
log_verbose(LOG_DEBUG, "local_command(): no output returned");
|
log_verbose(LOG_DEBUG, "local_command(): no output returned");
|
||||||
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user