On Wed, Feb 1, 2023 at 6:28 AM Justin Pryzby <pry...@telsasoft.com> wrote: > > I pushed the rmtree() change. Let's see if that helps, or tells us > > something new. > > I found a few failures since then: > > https://api.cirrus-ci.com/v1/artifact/task/6696942420361216/testrun/build/testrun/pg_upgrade/002_pg_upgrade/log/regress_log_002_pg_upgrade > > pg_upgrade: warning: could not remove directory > "C:/cirrus/build/testrun/pg_upgrade/002_pg_upgrade/data/t_002_pg_upgrade_new_node_data/pgdata/pg_upgrade_output.d/20230131T134931.720/log": > Directory not empty > pg_upgrade: warning: could not remove directory > "C:/cirrus/build/testrun/pg_upgrade/002_pg_upgrade/data/t_002_pg_upgrade_new_node_data/pgdata/pg_upgrade_output.d/20230131T134931.720": > Directory not empty
So no change: we didn't see "could not unlink file ...". So I think that means that it was rmtree() that unlinked the file for the *first* time, but someone else has it open. Even though Windows is at this point eroding my love of computers and making me consider a new career in, I dunno, carrot farming or something, I have one more idea. Check out this kluge in src/bin/pg_upgrade/exec.c: /* * "pg_ctl -w stop" might have reported that the server has stopped * because the postmaster.pid file has been removed, but "pg_ctl -w * start" might still be in the process of closing and might still be * holding its stdout and -l log file descriptors open. Therefore, * try to open the log file a few more times. */ I'm not sure about anything, but if that's what's happening here, then maybe the attached would help. In short, it would make the previous theory true (the idea of a second unlink() saving the day).
diff --git a/src/bin/pg_upgrade/util.c b/src/bin/pg_upgrade/util.c index 42dcbfc5b5..f214b7737f 100644 --- a/src/bin/pg_upgrade/util.c +++ b/src/bin/pg_upgrade/util.c @@ -68,7 +68,12 @@ cleanup_output_dirs(void) if (log_opts.retain) return; - (void) rmtree(log_opts.basedir, true); + /* + * Try twice. The second time might wait for files to be concurrently + * closed on Windows. + */ + if (!rmtree(log_opts.basedir, true)) + rmtree(log_opts.basedir, true); /* Remove pg_upgrade_output.d only if empty */ switch (pg_check_dir(log_opts.rootdir)) @@ -80,7 +85,12 @@ cleanup_output_dirs(void) case 1: /* exists and empty */ case 2: /* exists and contains only dot files */ - (void) rmtree(log_opts.rootdir, true); + /* + * Try twice. The second time might wait for files to be + * concurrently closed on Windows. + */ + if (!rmtree(log_opts.rootdir, true)) + rmtree(log_opts.rootdir, true); break; case 4: /* exists */