Skip to content

Commit c30628c

Browse files
committed
[Issue #237] Ignore EROFS when locking backup in shared mode
1 parent 02a3665 commit c30628c

File tree

1 file changed

+46
-18
lines changed

1 file changed

+46
-18
lines changed

src/catalog.c

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ static void unlock_backup(const char *backup_dir, const char *backup_id, bool ex
3636
static void release_excl_lock_file(const char *backup_dir);
3737
static void release_shared_lock_file(const char *backup_dir);
3838

39+
#define LOCK_OK 0
40+
#define LOCK_FAIL_TIMEOUT 1
41+
#define LOCK_FAIL_ENOSPC 2
42+
#define LOCK_FAIL_EROFS 3
43+
3944
typedef struct LockInfo
4045
{
4146
char backup_id[10];
@@ -187,18 +192,26 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
187192

188193
rc = grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict);
189194

190-
if (rc == 1)
195+
if (rc == LOCK_FAIL_TIMEOUT)
191196
return false;
192-
else if (rc == 2)
197+
else if (rc == LOCK_FAIL_ENOSPC)
193198
{
199+
/*
200+
* If we failed to take exclusive lock due to ENOSPC,
201+
* then in lax mode treat such condition as if lock was taken.
202+
*/
203+
194204
enospc_detected = true;
195205
if (strict)
196206
return false;
197-
207+
}
208+
else if (rc == LOCK_FAIL_EROFS)
209+
{
198210
/*
199-
* If we failed to take exclusive lock due to ENOSPC,
200-
* then in lax mode treat such condition as if lock was taken.
211+
* If we failed to take exclusive lock due to EROFS,
212+
* then in shared mode treat such condition as if lock was taken.
201213
*/
214+
return !exclusive;
202215
}
203216

204217
/*
@@ -242,7 +255,7 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
242255
* freed some space on filesystem, thanks to unlinking of BACKUP_RO_LOCK_FILE.
243256
* If somebody concurrently acquired exclusive lock file first, then we should give up.
244257
*/
245-
if (grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict) == 1)
258+
if (grab_excl_lock_file(backup->root_dir, base36enc(backup->start_time), strict) == LOCK_FAIL_TIMEOUT)
246259
return false;
247260

248261
return true;
@@ -271,18 +284,20 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
271284
return true;
272285
}
273286

274-
/* Lock backup in exclusive mode
287+
/*
288+
* Lock backup in exclusive mode
275289
* Result codes:
276-
* 0 Success
277-
* 1 Failed to acquire lock in lock_timeout time
278-
* 2 Failed to acquire lock due to ENOSPC
290+
* LOCK_OK Success
291+
* LOCK_FAIL_TIMEOUT Failed to acquire lock in lock_timeout time
292+
* LOCK_FAIL_ENOSPC Failed to acquire lock due to ENOSPC
293+
* LOCK_FAIL_EROFS Failed to acquire lock due to EROFS
279294
*/
280295
int
281296
grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
282297
{
283298
char lock_file[MAXPGPATH];
284299
int fd = 0;
285-
char buffer[MAXPGPATH * 2 + 256];
300+
char buffer[256];
286301
int ntries = LOCK_TIMEOUT;
287302
int empty_tries = LOCK_STALE_TIMEOUT;
288303
int len;
@@ -312,6 +327,14 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
312327
if (fd >= 0)
313328
break; /* Success; exit the retry loop */
314329

330+
/* read-only fs is a special case */
331+
if (errno == EROFS)
332+
{
333+
elog(WARNING, "Could not create lock file \"%s\": %s",
334+
lock_file, strerror(errno));
335+
return LOCK_FAIL_EROFS;
336+
}
337+
315338
/*
316339
* Couldn't create the pid file. Probably it already exists.
317340
* 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)
390413
* exist.
391414
*/
392415
if (encoded_pid == my_pid)
393-
return 0;
416+
return LOCK_OK;
394417

395418
if (kill(encoded_pid, 0) == 0)
396419
{
@@ -437,7 +460,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
437460

438461
/* Failed to acquire exclusive lock in time */
439462
if (fd <= 0)
440-
return 1;
463+
return LOCK_FAIL_TIMEOUT;
441464

442465
/*
443466
* Successfully created the file, now fill it.
@@ -457,7 +480,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
457480
* Only delete command should be run in lax mode.
458481
*/
459482
if (!strict && save_errno == ENOSPC)
460-
return 2;
483+
return LOCK_FAIL_ENOSPC;
461484
else
462485
elog(ERROR, "Could not write lock file \"%s\": %s",
463486
lock_file, strerror(save_errno));
@@ -475,7 +498,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
475498
* Only delete command should be run in lax mode.
476499
*/
477500
if (!strict && save_errno == ENOSPC)
478-
return 2;
501+
return LOCK_FAIL_ENOSPC;
479502
else
480503
elog(ERROR, "Could not flush lock file \"%s\": %s",
481504
lock_file, strerror(save_errno));
@@ -488,7 +511,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
488511
fio_unlink(lock_file, FIO_BACKUP_HOST);
489512

490513
if (!strict && errno == ENOSPC)
491-
return 2;
514+
return LOCK_FAIL_ENOSPC;
492515
else
493516
elog(ERROR, "Could not close lock file \"%s\": %s",
494517
lock_file, strerror(save_errno));
@@ -498,7 +521,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
498521
// base36enc(backup->start_time),
499522
// LOCK_TIMEOUT - ntries + LOCK_STALE_TIMEOUT - empty_tries);
500523

501-
return 0;
524+
return LOCK_OK;
502525
}
503526

504527
/* Wait until all shared lock owners are gone
@@ -648,7 +671,12 @@ grab_shared_lock_file(pgBackup *backup)
648671

649672
fp_out = fopen(lock_file_tmp, "w");
650673
if (fp_out == NULL)
674+
{
675+
if (errno == EROFS)
676+
return 0;
677+
651678
elog(ERROR, "Cannot open temp lock file \"%s\": %s", lock_file_tmp, strerror(errno));
679+
}
652680

653681
/* add my own pid */
654682
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)
679707
}
680708

681709
/* To remove shared lock, we must briefly obtain exclusive lock, ... */
682-
if (grab_excl_lock_file(backup_dir, backup_id, false) != 0)
710+
if (grab_excl_lock_file(backup_dir, backup_id, false) != LOCK_OK)
683711
/* ... if it's not possible then leave shared lock */
684712
return;
685713

0 commit comments

Comments
 (0)