From 1a6a73565c36bac45b84ddf1b9718062c13d69cd Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 15 Mar 2016 14:50:48 +0100 Subject: [PATCH 1/3] Make rename() calls for log files in adminpack durable As mentioned in 1d4a0ab1, rename() is not a durable operation in case of crashes, causing renames to be potentially lost in such unfortunate scenarios. The functions of adminpack are not critical code paths so they do not induce any data loss, still it may be annoying for the upper application layer like pgadmin to see inconsistent log files should a server restart after a crash. --- contrib/adminpack/adminpack.c | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c index ea781a0..9136b79 100644 --- a/contrib/adminpack/adminpack.c +++ b/contrib/adminpack/adminpack.c @@ -209,44 +209,27 @@ pg_file_rename(PG_FUNCTION_ARGS) fn3 ? fn3 : fn2))); } + /* + * Should a third file name be defined, use it as a temporary switch + * that allows reverting back to the initial point should an error + * occur. + */ if (fn3) { - if (rename(fn2, fn3) != 0) - { - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not rename \"%s\" to \"%s\": %m", - fn2, fn3))); - } - if (rename(fn1, fn2) != 0) - { - ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not rename \"%s\" to \"%s\": %m", - fn1, fn2))); + /* durable_rename produces already a log entry */ + durable_rename(fn2, fn3, ERROR); - if (rename(fn3, fn2) != 0) - { - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not rename \"%s\" back to \"%s\": %m", - fn3, fn2))); - } - else - { + if (durable_rename(fn1, fn2, WARNING) != 0) + { + if (durable_rename(fn3, fn2, ERROR) == 0) ereport(ERROR, (ERRCODE_UNDEFINED_FILE, errmsg("renaming \"%s\" to \"%s\" was reverted", fn2, fn3))); - } } } - else if (rename(fn1, fn2) != 0) - { - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not rename \"%s\" to \"%s\": %m", fn1, fn2))); - } + else + durable_rename(fn1, fn2, ERROR); PG_RETURN_BOOL(true); } -- 2.7.3