Commit fbcfa90b authored by Bruce Momjian's avatar Bruce Momjian

Fix pg_upgrade file share violation on Windows created by the commit

4741e9af.  This was done by adding an
optional second log file parameter to exec_prog(), and closing and
reopening the log file between system() calls.

Backpatch to 9.2.
parent 3a42a3ff
...@@ -183,7 +183,7 @@ issue_warnings(char *sequence_script_file_name) ...@@ -183,7 +183,7 @@ issue_warnings(char *sequence_script_file_name)
if (sequence_script_file_name) if (sequence_script_file_name)
{ {
prep_status("Adjusting sequences"); prep_status("Adjusting sequences");
exec_prog(true, true, UTILITY_LOG_FILE, exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/psql\" --echo-queries " SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on " "--set ON_ERROR_STOP=on "
"--no-psqlrc --port %d --username \"%s\" " "--no-psqlrc --port %d --username \"%s\" "
......
...@@ -23,7 +23,7 @@ generate_old_dump(void) ...@@ -23,7 +23,7 @@ generate_old_dump(void)
* --binary-upgrade records the width of dropped columns in pg_class, and * --binary-upgrade records the width of dropped columns in pg_class, and
* restores the frozenid's for databases and relations. * 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\" " SYSTEMQUOTE "\"%s/pg_dumpall\" --port %d --username \"%s\" "
"--schema-only --binary-upgrade %s > \"%s\" 2>> \"%s\"" "--schema-only --binary-upgrade %s > \"%s\" 2>> \"%s\""
SYSTEMQUOTE, new_cluster.bindir, old_cluster.port, os_info.user, SYSTEMQUOTE, new_cluster.bindir, old_cluster.port, os_info.user,
......
...@@ -33,18 +33,19 @@ static int win32_check_directory_write_permissions(void); ...@@ -33,18 +33,19 @@ static int win32_check_directory_write_permissions(void);
* line to be executed is saved to the specified log file. * line to be executed is saved to the specified log file.
* *
* If throw_error is TRUE, this function will throw a PG_FATAL error * 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 int
exec_prog(bool throw_error, bool is_priv, exec_prog(bool throw_error, bool is_priv, const char *log_file,
const char *log_file, const char *fmt,...) const char *opt_log_file, const char *fmt,...)
{ {
va_list args; va_list args;
int result; int result;
int retval; int retval;
char cmd[MAXPGPATH]; char cmd[MAXPGPATH];
mode_t old_umask = 0; mode_t old_umask = 0;
FILE *log = fopen(log_file, "a+"); FILE *log;
if (is_priv) if (is_priv)
old_umask = umask(S_IRWXG | S_IRWXO); old_umask = umask(S_IRWXG | S_IRWXO);
...@@ -53,9 +54,15 @@ exec_prog(bool throw_error, bool is_priv, ...@@ -53,9 +54,15 @@ exec_prog(bool throw_error, bool is_priv,
vsnprintf(cmd, MAXPGPATH, fmt, args); vsnprintf(cmd, MAXPGPATH, fmt, args);
va_end(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); pg_log(PG_VERBOSE, "%s\n", cmd);
fprintf(log, "command: %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); result = system(cmd);
...@@ -64,18 +71,28 @@ exec_prog(bool throw_error, bool is_priv, ...@@ -64,18 +71,28 @@ exec_prog(bool throw_error, bool is_priv,
if (result != 0) 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*"); report_status(PG_REPORT, "*failure*");
fflush(stdout); fflush(stdout);
pg_log(PG_VERBOSE, "There were problems executing \"%s\"\n", cmd); pg_log(PG_VERBOSE, "There were problems executing \"%s\"\n", cmd);
pg_log(throw_error ? PG_FATAL : PG_REPORT, 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", "the probable cause of the failure.\n",
log_file); log_file, opt_string);
retval = 1; retval = 1;
} }
else else
retval = 0; 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"); fprintf(log, "\n\n");
fclose(log); fclose(log);
......
...@@ -140,7 +140,7 @@ main(int argc, char **argv) ...@@ -140,7 +140,7 @@ main(int argc, char **argv)
* because there is no need to have the schema load use new oids. * because there is no need to have the schema load use new oids.
*/ */
prep_status("Setting next OID for new cluster"); 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 "\"%s/pg_resetxlog\" -o %u \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE, SYSTEMQUOTE,
new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid, new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid,
...@@ -211,7 +211,7 @@ prepare_new_cluster(void) ...@@ -211,7 +211,7 @@ prepare_new_cluster(void)
* --analyze so autovacuum doesn't update statistics later * --analyze so autovacuum doesn't update statistics later
*/ */
prep_status("Analyzing all rows in the new cluster"); 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\" " SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
"--all --analyze %s >> \"%s\" 2>&1" SYSTEMQUOTE, "--all --analyze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
new_cluster.bindir, new_cluster.port, os_info.user, new_cluster.bindir, new_cluster.port, os_info.user,
...@@ -225,7 +225,7 @@ prepare_new_cluster(void) ...@@ -225,7 +225,7 @@ prepare_new_cluster(void)
* later. * later.
*/ */
prep_status("Freezing all rows on the new cluster"); 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\" " SYSTEMQUOTE "\"%s/vacuumdb\" --port %d --username \"%s\" "
"--all --freeze %s >> \"%s\" 2>&1" SYSTEMQUOTE, "--all --freeze %s >> \"%s\" 2>&1" SYSTEMQUOTE,
new_cluster.bindir, new_cluster.port, os_info.user, new_cluster.bindir, new_cluster.port, os_info.user,
...@@ -263,7 +263,7 @@ prepare_new_databases(void) ...@@ -263,7 +263,7 @@ prepare_new_databases(void)
* support functions in template1 but pg_dumpall creates database using * support functions in template1 but pg_dumpall creates database using
* the template0 template. * the template0 template.
*/ */
exec_prog(true, true, RESTORE_LOG_FILE, exec_prog(true, true, RESTORE_LOG_FILE, NULL,
SYSTEMQUOTE "\"%s/psql\" --echo-queries " SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on " "--set ON_ERROR_STOP=on "
/* --no-psqlrc prevents AUTOCOMMIT=off */ /* --no-psqlrc prevents AUTOCOMMIT=off */
...@@ -296,7 +296,7 @@ create_new_objects(void) ...@@ -296,7 +296,7 @@ create_new_objects(void)
check_ok(); check_ok();
prep_status("Restoring database schema to new cluster"); 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 " SYSTEMQUOTE "\"%s/psql\" --echo-queries "
"--set ON_ERROR_STOP=on " "--set ON_ERROR_STOP=on "
"--no-psqlrc --port %d --username \"%s\" " "--no-psqlrc --port %d --username \"%s\" "
...@@ -331,7 +331,7 @@ copy_subdir_files(char *subdir) ...@@ -331,7 +331,7 @@ copy_subdir_files(char *subdir)
prep_status("Copying old %s to new server", subdir); 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 #ifndef WIN32
SYSTEMQUOTE "%s \"%s\" \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE, SYSTEMQUOTE "%s \"%s\" \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
"cp -Rf", "cp -Rf",
...@@ -353,7 +353,7 @@ copy_clog_xlog_xid(void) ...@@ -353,7 +353,7 @@ copy_clog_xlog_xid(void)
/* set the next transaction id of the new cluster */ /* set the next transaction id of the new cluster */
prep_status("Setting next transaction ID for 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 SYSTEMQUOTE
"\"%s/pg_resetxlog\" -f -x %u \"%s\" >> \"%s\" 2>&1" "\"%s/pg_resetxlog\" -f -x %u \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE, new_cluster.bindir, SYSTEMQUOTE, new_cluster.bindir,
...@@ -363,7 +363,7 @@ copy_clog_xlog_xid(void) ...@@ -363,7 +363,7 @@ copy_clog_xlog_xid(void)
/* now reset the wal archives in the new cluster */ /* now reset the wal archives in the new cluster */
prep_status("Resetting WAL archives"); prep_status("Resetting WAL archives");
exec_prog(true, true, UTILITY_LOG_FILE, exec_prog(true, true, UTILITY_LOG_FILE, NULL,
SYSTEMQUOTE SYSTEMQUOTE
"\"%s/pg_resetxlog\" -l %s \"%s\" >> \"%s\" 2>&1" "\"%s/pg_resetxlog\" -l %s \"%s\" >> \"%s\" 2>&1"
SYSTEMQUOTE, new_cluster.bindir, SYSTEMQUOTE, new_cluster.bindir,
......
...@@ -317,9 +317,9 @@ void split_old_dump(void); ...@@ -317,9 +317,9 @@ void split_old_dump(void);
/* exec.c */ /* exec.c */
int int
exec_prog(bool throw_error, bool is_priv, exec_prog(bool throw_error, bool is_priv, const char *log_file,
const char *log_file, const char *cmd,...) const char *opt_log_file, const char *cmd,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 5, 6)));
void verify_directories(void); void verify_directories(void);
bool is_server_running(const char *datadir); bool is_server_running(const char *datadir);
......
...@@ -171,11 +171,10 @@ start_postmaster(ClusterInfo *cluster) ...@@ -171,11 +171,10 @@ start_postmaster(ClusterInfo *cluster)
* Don't throw an error right away, let connecting throw the error because * Don't throw an error right away, let connecting throw the error because
* it might supply a reason for the failure. * 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 */ /* pass both file names if the differ */
(strcmp(SERVER_LOG_FILE, SERVER_START_LOG_FILE) == 0) ? (strcmp(SERVER_LOG_FILE, SERVER_START_LOG_FILE) != 0) ?
SERVER_LOG_FILE : SERVER_LOG_FILE : NULL,
SERVER_LOG_FILE " or " SERVER_START_LOG_FILE,
"%s", cmd); "%s", cmd);
/* Check to see if we can connect to the server; if not, report it. */ /* Check to see if we can connect to the server; if not, report it. */
...@@ -220,7 +219,7 @@ stop_postmaster(bool fast) ...@@ -220,7 +219,7 @@ stop_postmaster(bool fast)
cluster->pgopts ? cluster->pgopts : "", cluster->pgopts ? cluster->pgopts : "",
fast ? "-m fast" : "", SERVER_STOP_LOG_FILE); 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; os_info.running_cluster = NULL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment