You've already forked pg_probackup
mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-09-16 09:26:30 +02:00
[Issue #237] Ignore EROFS when locking backup in shared mode
This commit is contained in:
@@ -36,6 +36,11 @@ static void unlock_backup(const char *backup_dir, const char *backup_id, bool ex
|
|||||||
static void release_excl_lock_file(const char *backup_dir);
|
static void release_excl_lock_file(const char *backup_dir);
|
||||||
static void release_shared_lock_file(const char *backup_dir);
|
static void release_shared_lock_file(const char *backup_dir);
|
||||||
|
|
||||||
|
#define LOCK_OK 0
|
||||||
|
#define LOCK_FAIL_TIMEOUT 1
|
||||||
|
#define LOCK_FAIL_ENOSPC 2
|
||||||
|
#define LOCK_FAIL_EROFS 3
|
||||||
|
|
||||||
typedef struct LockInfo
|
typedef struct LockInfo
|
||||||
{
|
{
|
||||||
char backup_id[10];
|
char backup_id[10];
|
||||||
@@ -187,18 +192,26 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
|
|||||||
|
|
||||||
rc = grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict);
|
rc = grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict);
|
||||||
|
|
||||||
if (rc == 1)
|
if (rc == LOCK_FAIL_TIMEOUT)
|
||||||
return false;
|
return false;
|
||||||
else if (rc == 2)
|
else if (rc == LOCK_FAIL_ENOSPC)
|
||||||
{
|
{
|
||||||
enospc_detected = true;
|
|
||||||
if (strict)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we failed to take exclusive lock due to ENOSPC,
|
* If we failed to take exclusive lock due to ENOSPC,
|
||||||
* then in lax mode treat such condition as if lock was taken.
|
* then in lax mode treat such condition as if lock was taken.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enospc_detected = true;
|
||||||
|
if (strict)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (rc == LOCK_FAIL_EROFS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we failed to take exclusive lock due to EROFS,
|
||||||
|
* then in shared mode treat such condition as if lock was taken.
|
||||||
|
*/
|
||||||
|
return !exclusive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -242,7 +255,7 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
|
|||||||
* freed some space on filesystem, thanks to unlinking of BACKUP_RO_LOCK_FILE.
|
* freed some space on filesystem, thanks to unlinking of BACKUP_RO_LOCK_FILE.
|
||||||
* If somebody concurrently acquired exclusive lock file first, then we should give up.
|
* If somebody concurrently acquired exclusive lock file first, then we should give up.
|
||||||
*/
|
*/
|
||||||
if (grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict) == 1)
|
if (grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict) == LOCK_FAIL_TIMEOUT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -271,18 +284,20 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock backup in exclusive mode
|
/*
|
||||||
|
* Lock backup in exclusive mode
|
||||||
* Result codes:
|
* Result codes:
|
||||||
* 0 Success
|
* LOCK_OK Success
|
||||||
* 1 Failed to acquire lock in lock_timeout time
|
* LOCK_FAIL_TIMEOUT Failed to acquire lock in lock_timeout time
|
||||||
* 2 Failed to acquire lock due to ENOSPC
|
* LOCK_FAIL_ENOSPC Failed to acquire lock due to ENOSPC
|
||||||
|
* LOCK_FAIL_EROFS Failed to acquire lock due to EROFS
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
|
grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
|
||||||
{
|
{
|
||||||
char lock_file[MAXPGPATH];
|
char lock_file[MAXPGPATH];
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
char buffer[MAXPGPATH * 2 + 256];
|
char buffer[256];
|
||||||
int ntries = LOCK_TIMEOUT;
|
int ntries = LOCK_TIMEOUT;
|
||||||
int empty_tries = LOCK_STALE_TIMEOUT;
|
int empty_tries = LOCK_STALE_TIMEOUT;
|
||||||
int len;
|
int len;
|
||||||
@@ -312,6 +327,14 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
|
|||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
break; /* Success; exit the retry loop */
|
break; /* Success; exit the retry loop */
|
||||||
|
|
||||||
|
/* read-only fs is a special case */
|
||||||
|
if (errno == EROFS)
|
||||||
|
{
|
||||||
|
elog(WARNING, "Could not create lock file \"%s\": %s",
|
||||||
|
lock_file, strerror(errno));
|
||||||
|
return LOCK_FAIL_EROFS;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Couldn't create the pid file. Probably it already exists.
|
* Couldn't create the pid file. Probably it already exists.
|
||||||
* If file already exists or we have some permission problem (???),
|
* If file already exists or we have some permission problem (???),
|
||||||
@@ -390,7 +413,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
|
|||||||
* exist.
|
* exist.
|
||||||
*/
|
*/
|
||||||
if (encoded_pid == my_pid)
|
if (encoded_pid == my_pid)
|
||||||
return 0;
|
return LOCK_OK;
|
||||||
|
|
||||||
if (kill(encoded_pid, 0) == 0)
|
if (kill(encoded_pid, 0) == 0)
|
||||||
{
|
{
|
||||||
@@ -437,7 +460,7 @@ grab_lock:
|
|||||||
|
|
||||||
/* Failed to acquire exclusive lock in time */
|
/* Failed to acquire exclusive lock in time */
|
||||||
if (fd <= 0)
|
if (fd <= 0)
|
||||||
return 1;
|
return LOCK_FAIL_TIMEOUT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Successfully created the file, now fill it.
|
* Successfully created the file, now fill it.
|
||||||
@@ -457,7 +480,7 @@ grab_lock:
|
|||||||
* Only delete command should be run in lax mode.
|
* Only delete command should be run in lax mode.
|
||||||
*/
|
*/
|
||||||
if (!strict && save_errno == ENOSPC)
|
if (!strict && save_errno == ENOSPC)
|
||||||
return 2;
|
return LOCK_FAIL_ENOSPC;
|
||||||
else
|
else
|
||||||
elog(ERROR, "Could not write lock file \"%s\": %s",
|
elog(ERROR, "Could not write lock file \"%s\": %s",
|
||||||
lock_file, strerror(save_errno));
|
lock_file, strerror(save_errno));
|
||||||
@@ -475,7 +498,7 @@ grab_lock:
|
|||||||
* Only delete command should be run in lax mode.
|
* Only delete command should be run in lax mode.
|
||||||
*/
|
*/
|
||||||
if (!strict && save_errno == ENOSPC)
|
if (!strict && save_errno == ENOSPC)
|
||||||
return 2;
|
return LOCK_FAIL_ENOSPC;
|
||||||
else
|
else
|
||||||
elog(ERROR, "Could not flush lock file \"%s\": %s",
|
elog(ERROR, "Could not flush lock file \"%s\": %s",
|
||||||
lock_file, strerror(save_errno));
|
lock_file, strerror(save_errno));
|
||||||
@@ -488,7 +511,7 @@ grab_lock:
|
|||||||
fio_unlink(lock_file, FIO_BACKUP_HOST);
|
fio_unlink(lock_file, FIO_BACKUP_HOST);
|
||||||
|
|
||||||
if (!strict && errno == ENOSPC)
|
if (!strict && errno == ENOSPC)
|
||||||
return 2;
|
return LOCK_FAIL_ENOSPC;
|
||||||
else
|
else
|
||||||
elog(ERROR, "Could not close lock file \"%s\": %s",
|
elog(ERROR, "Could not close lock file \"%s\": %s",
|
||||||
lock_file, strerror(save_errno));
|
lock_file, strerror(save_errno));
|
||||||
@@ -498,7 +521,7 @@ grab_lock:
|
|||||||
// base36enc(backup->start_time),
|
// base36enc(backup->start_time),
|
||||||
// LOCK_TIMEOUT - ntries + LOCK_STALE_TIMEOUT - empty_tries);
|
// LOCK_TIMEOUT - ntries + LOCK_STALE_TIMEOUT - empty_tries);
|
||||||
|
|
||||||
return 0;
|
return LOCK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until all shared lock owners are gone
|
/* Wait until all shared lock owners are gone
|
||||||
@@ -648,7 +671,12 @@ grab_shared_lock_file(pgBackup *backup)
|
|||||||
|
|
||||||
fp_out = fopen(lock_file_tmp, "w");
|
fp_out = fopen(lock_file_tmp, "w");
|
||||||
if (fp_out == NULL)
|
if (fp_out == NULL)
|
||||||
|
{
|
||||||
|
if (errno == EROFS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
elog(ERROR, "Cannot open temp lock file \"%s\": %s", lock_file_tmp, strerror(errno));
|
elog(ERROR, "Cannot open temp lock file \"%s\": %s", lock_file_tmp, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
/* add my own pid */
|
/* add my own pid */
|
||||||
buffer_len += snprintf(buffer+buffer_len, sizeof(buffer), "%u\n", my_pid);
|
buffer_len += snprintf(buffer+buffer_len, sizeof(buffer), "%u\n", my_pid);
|
||||||
@@ -679,7 +707,7 @@ unlock_backup(const char *backup_dir, const char *backup_id, bool exclusive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* To remove shared lock, we must briefly obtain exclusive lock, ... */
|
/* To remove shared lock, we must briefly obtain exclusive lock, ... */
|
||||||
if (grab_excl_lock_file(backup_dir, backup_id, false) != 0)
|
if (grab_excl_lock_file(backup_dir, backup_id, false) != LOCK_OK)
|
||||||
/* ... if it's not possible then leave shared lock */
|
/* ... if it's not possible then leave shared lock */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user