if (sequence_script_file_name)
{
prep_status("Adjusting sequences");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on "
"--no-psqlrc --port %d --username \"%s\" "
* --binary-upgrade records the width of dropped columns in pg_class, and
* restores the frozenid's for databases and relations.
*/
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/pg_dumpall\" --port %d --username \"%s\" "
"--schema-only --binary-upgrade %s > \"%s\" 2>> \"%s\""
SYSTEMQUOTE, new_cluster.bindir, old_cluster.port, os_info.user,
* line to be executed is saved to the specified log file.
*
* If throw_error is TRUE, this function will throw a PG_FATAL error
- * instead of returning should an error occur.
+ * instead of returning should an error occur. The command it appended
+ * to log_file; opt_log_file is used in error messages.
*/
int
-exec_prog(bool throw_error, bool is_priv,
- const char *log_file, const char *fmt,...)
+exec_prog(bool throw_error, bool is_priv, const char *log_file,
+ const char *opt_log_file, const char *fmt,...)
{
va_list args;
int result;
int retval;
char cmd[MAXPGPATH];
mode_t old_umask = 0;
- FILE *log = fopen(log_file, "a+");
+ FILE *log;
if (is_priv)
old_umask = umask(S_IRWXG | S_IRWXO);
vsnprintf(cmd, MAXPGPATH, fmt, args);
va_end(args);
+ if ((log = fopen_priv(log_file, "a+")) == NULL)
+ pg_log(PG_FATAL, "cannot write to log file %s\n", log_file);
pg_log(PG_VERBOSE, "%s\n", cmd);
fprintf(log, "command: %s\n", cmd);
- fflush(log);
+ /*
+ * In Windows, we must close then reopen the log file so the file is
+ * not open while the command is running, or we get a share violation.
+ */
+ fclose(log);
result = system(cmd);
if (result != 0)
{
+ char opt_string[MAXPGPATH];
+
+ /* Create string for optional second log file */
+ if (opt_log_file)
+ snprintf(opt_string, sizeof(opt_string), " or \"%s\"", opt_log_file);
+ else
+ opt_string[0] = '\0';
+
report_status(PG_REPORT, "*failure*");
fflush(stdout);
pg_log(PG_VERBOSE, "There were problems executing \"%s\"\n", cmd);
pg_log(throw_error ? PG_FATAL : PG_REPORT,
- "Consult the last few lines of \"%s\" for\n"
+ "Consult the last few lines of \"%s\"%s for\n"
"the probable cause of the failure.\n",
- log_file);
+ log_file, opt_string);
retval = 1;
}
else
retval = 0;
+ if ((log = fopen_priv(log_file, "a+")) == NULL)
+ pg_log(PG_FATAL, "cannot write to log file %s\n", log_file);
fprintf(log, "\n\n");
fclose(log);
* because there is no need to have the schema load use new oids.
*/
prep_status("Setting next OID for new cluster");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/pg_resetxlog\" -o %u \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE,
new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid,
* --analyze so autovacuum doesn't update statistics later
*/
prep_status("Analyzing all rows in the new cluster");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
"--all --analyze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
new_cluster.bindir, new_cluster.port, os_info.user,
* later.
*/
prep_status("Freezing all rows on the new cluster");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
"--all --freeze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
new_cluster.bindir, new_cluster.port, os_info.user,
* support functions in template1 but pg_dumpall creates database using
* the template0 template.
*/
- exec_prog(true, true, RESTORE_LOG_FILE,
+ exec_prog(true, true, RESTORE_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on "
/* --no-psqlrc prevents AUTOCOMMIT=off */
check_ok();
prep_status("Restoring database schema to new cluster");
- exec_prog(true, true, RESTORE_LOG_FILE,
+ exec_prog(true, true, RESTORE_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on "
"--no-psqlrc --port %d --username \"%s\" "
prep_status("Copying old %s to new server", subdir);
- exec_prog(true, false, UTILITY_LOG_FILE,
+ exec_prog(true, false, UTILITY_LOG_FILE, NULL,
#ifndef WIN32
SYSTEMQUOTE "%s \"%s\" \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
"cp -Rf",
/* set the next transaction id of the new cluster */
prep_status("Setting next transaction ID for new cluster");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE
"\"%s/pg_resetxlog\" -f -x %u \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE, new_cluster.bindir,
/* now reset the wal archives in the new cluster */
prep_status("Resetting WAL archives");
- exec_prog(true, true, UTILITY_LOG_FILE,
+ exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE
"\"%s/pg_resetxlog\" -l %s \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE, new_cluster.bindir,
/* exec.c */
int
-exec_prog(bool throw_error, bool is_priv,
- const char *log_file, const char *cmd,...)
-__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
+exec_prog(bool throw_error, bool is_priv, const char *log_file,
+ const char *opt_log_file, const char *cmd,...)
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 5, 6)));
void verify_directories(void);
bool is_server_running(const char *datadir);
* Don't throw an error right away, let connecting throw the error because
* it might supply a reason for the failure.
*/
- pg_ctl_return = exec_prog(false, true,
+ pg_ctl_return = exec_prog(false, true, SERVER_START_LOG_FILE,
/* pass both file names if the differ */
- (strcmp(SERVER_LOG_FILE, SERVER_START_LOG_FILE) == 0) ?
- SERVER_LOG_FILE :
- SERVER_LOG_FILE " or " SERVER_START_LOG_FILE,
+ (strcmp(SERVER_LOG_FILE, SERVER_START_LOG_FILE) != 0) ?
+ SERVER_LOG_FILE : NULL,
"%s", cmd);
/* Check to see if we can connect to the server; if not, report it. */
cluster->pgopts ? cluster->pgopts : "",
fast ? "-m fast" : "", SERVER_STOP_LOG_FILE);
- exec_prog(fast ? false : true, true, SERVER_STOP_LOG_FILE, "%s", cmd);
+ exec_prog(fast ? false : true, true, SERVER_STOP_LOG_FILE, NULL, "%s", cmd);
os_info.running_cluster = NULL;
}