From 120d7e18e7df28f91bfec8dad759b098842b4d61 Mon Sep 17 00:00:00 2001 From: Magnus Hagander <magnus@hagander.net> Date: Thu, 20 Dec 2007 20:27:53 +0000 Subject: [PATCH] On win32, loop when opening files if sharing- och lock-violation errors occur. Hopefully, this will make it possible to recover from broken antivirus and/or backup software that locks our files. --- src/port/open.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/port/open.c b/src/port/open.c index 526897d1681..ef097416273 100644 --- a/src/port/open.c +++ b/src/port/open.c @@ -6,14 +6,18 @@ * * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/port/open.c,v 1.22 2007/11/30 11:16:43 mha Exp $ + * $PostgreSQL: pgsql/src/port/open.c,v 1.23 2007/12/20 20:27:53 mha Exp $ * *------------------------------------------------------------------------- */ #ifdef WIN32 -#include "c.h" +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include <windows.h> #include <fcntl.h> @@ -58,8 +62,9 @@ int pgwin32_open(const char *fileName, int fileFlags,...) { int fd; - HANDLE h; + HANDLE h = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa; + int loops = 0; /* Check that we can handle the request */ assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND | @@ -71,7 +76,7 @@ pgwin32_open(const char *fileName, int fileFlags,...) sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; - if ((h = CreateFile(fileName, + while ((h = CreateFile(fileName, /* cannot use O_RDONLY, as it == 0 */ (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) : ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ), @@ -88,7 +93,32 @@ pgwin32_open(const char *fileName, int fileFlags,...) ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0), NULL)) == INVALID_HANDLE_VALUE) { - _dosmaperr(GetLastError()); + /* + * Sharing violation or locking error can indicate antivirus, backup + * or similar software that's locking the file. Try again for 30 seconds + * before giving up. + */ + DWORD err = GetLastError(); + if (err == ERROR_SHARING_VIOLATION || + err == ERROR_LOCK_VIOLATION) + { + pg_usleep(100000); + loops++; + +#ifndef FRONTEND + if (loops == 50) + ereport(LOG, + (errmsg("could not open file \"%s\": %s", fileName, + (err == ERROR_SHARING_VIOLATION)?_("sharing violation"):_("lock violation")), + errdetail("Continuing to retry for 30 seconds."), + errhint("You may have antivirus, backup or similar software interfering with the database."))); +#endif + + if (loops < 300) + continue; + } + + _dosmaperr(err); return -1; } -- GitLab