Re: BUG #16154: pg_ctl restart with a logfile fails sometimes (on Windows)

Alexander Lakhin <[email protected]>
Newsgroups gmane.comp.db.postgresql.bugs
Message-ID <[email protected]>
06.12.2019 18:14, Tom Lane wrote:
> Alexander Lakhin <[email protected]> writes:
>> If this file is still opened by the previous server shell (it can happen
>> when the previous server instance has unlinked it's pid file, but it's
>> CMD shell is still running), the next CMD start fails with the
>> aforementioned error message.
> Interesting.  I wonder whether this explains all of the remaining
> buildfarm failures of this sort that we've been seeing even after
> 0ba06e0bf.
>
>> To fix this issue I propose the attached patch
>> (fix_logfile_sharing_violation ).
> This seems like a pretty ugly hack ... please at least make it
> #ifdef WIN32, so that the rest of us don't have to deal with it.
> Also, if I read it correctly, it causes a pre-existing logfile
> to get truncated, which has never happened before.  Mode "a"
> would be a better choice.
This change should go under the following code:
#else                            /* WIN32 */

    /*
     * As with the Unix case, it's easiest to use the shell (CMD.EXE) to
     * handle redirection etc.  Unfortunately CMD.EXE lacks any
equivalent of
     * "exec", so we don't get to find out the postmaster's PID immediately.
     */
    PROCESS_INFORMATION pi;
    const char *comspec;

    /* Find CMD.EXE location using COMSPEC, if it's set */
    comspec = getenv("COMSPEC");
    if (comspec == NULL)
        comspec = "CMD";

So it should affect only Windows.
I've fixed the mode. Thanks for your review!

Best regards,
Alexander
fix_logfile_sharing_violation.patch (text/x-patch, 922 B)
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 65f9fb4c0a..9bc44b2de4 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -519,8 +519,21 @@ start_postmaster(void)
 		comspec = "CMD";
 
 	if (log_file != NULL)
+	{
+		/* Check the log file availability to prevent CMD.EXE failing with
+		 * ERROR_SHARING_VIOLATION, e.g. when the log file is still opened
+		 * by the previous server shell.
+		 */
+		FILE *fd = fopen(log_file, "a");
+		if (!fd) {
+			write_stderr(_("%s: could not access log file \"%s\": %s\n"),
+						 progname, log_file, strerror(errno));
+			exit(1);
+		}
+		fclose(fd);
 		snprintf(cmd, MAXPGPATH, "\"%s\" /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
 				 comspec, exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
+	}
 	else
 		snprintf(cmd, MAXPGPATH, "\"%s\" /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
 				 comspec, exec_path, pgdata_opt, post_opts, DEVNULL);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.