@@ -36,6 +36,11 @@ static void unlock_backup(const char *backup_dir, const char *backup_id, bool ex
36
36
static void release_excl_lock_file (const char * backup_dir );
37
37
static void release_shared_lock_file (const char * backup_dir );
38
38
39
+ #define LOCK_OK 0
40
+ #define LOCK_FAIL_TIMEOUT 1
41
+ #define LOCK_FAIL_ENOSPC 2
42
+ #define LOCK_FAIL_EROFS 3
43
+
39
44
typedef struct LockInfo
40
45
{
41
46
char backup_id [10 ];
@@ -187,18 +192,26 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
187
192
188
193
rc = grab_excl_lock_file (backup -> root_dir , base36enc (backup -> start_time ), strict );
189
194
190
- if (rc == 1 )
195
+ if (rc == LOCK_FAIL_TIMEOUT )
191
196
return false;
192
- else if (rc == 2 )
197
+ else if (rc == LOCK_FAIL_ENOSPC )
193
198
{
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
+
194
204
enospc_detected = true;
195
205
if (strict )
196
206
return false;
197
-
207
+ }
208
+ else if (rc == LOCK_FAIL_EROFS )
209
+ {
198
210
/*
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.
201
213
*/
214
+ return !exclusive ;
202
215
}
203
216
204
217
/*
@@ -242,7 +255,7 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
242
255
* freed some space on filesystem, thanks to unlinking of BACKUP_RO_LOCK_FILE.
243
256
* If somebody concurrently acquired exclusive lock file first, then we should give up.
244
257
*/
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 )
246
259
return false;
247
260
248
261
return true;
@@ -271,18 +284,20 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
271
284
return true;
272
285
}
273
286
274
- /* Lock backup in exclusive mode
287
+ /*
288
+ * Lock backup in exclusive mode
275
289
* 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
279
294
*/
280
295
int
281
296
grab_excl_lock_file (const char * root_dir , const char * backup_id , bool strict )
282
297
{
283
298
char lock_file [MAXPGPATH ];
284
299
int fd = 0 ;
285
- char buffer [MAXPGPATH * 2 + 256 ];
300
+ char buffer [256 ];
286
301
int ntries = LOCK_TIMEOUT ;
287
302
int empty_tries = LOCK_STALE_TIMEOUT ;
288
303
int len ;
@@ -312,6 +327,14 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
312
327
if (fd >= 0 )
313
328
break ; /* Success; exit the retry loop */
314
329
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
+
315
338
/*
316
339
* Couldn't create the pid file. Probably it already exists.
317
340
* 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)
390
413
* exist.
391
414
*/
392
415
if (encoded_pid == my_pid )
393
- return 0 ;
416
+ return LOCK_OK ;
394
417
395
418
if (kill (encoded_pid , 0 ) == 0 )
396
419
{
@@ -437,7 +460,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
437
460
438
461
/* Failed to acquire exclusive lock in time */
439
462
if (fd <= 0 )
440
- return 1 ;
463
+ return LOCK_FAIL_TIMEOUT ;
441
464
442
465
/*
443
466
* 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)
457
480
* Only delete command should be run in lax mode.
458
481
*/
459
482
if (!strict && save_errno == ENOSPC )
460
- return 2 ;
483
+ return LOCK_FAIL_ENOSPC ;
461
484
else
462
485
elog (ERROR , "Could not write lock file \"%s\": %s" ,
463
486
lock_file , strerror (save_errno ));
@@ -475,7 +498,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
475
498
* Only delete command should be run in lax mode.
476
499
*/
477
500
if (!strict && save_errno == ENOSPC )
478
- return 2 ;
501
+ return LOCK_FAIL_ENOSPC ;
479
502
else
480
503
elog (ERROR , "Could not flush lock file \"%s\": %s" ,
481
504
lock_file , strerror (save_errno ));
@@ -488,7 +511,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
488
511
fio_unlink (lock_file , FIO_BACKUP_HOST );
489
512
490
513
if (!strict && errno == ENOSPC )
491
- return 2 ;
514
+ return LOCK_FAIL_ENOSPC ;
492
515
else
493
516
elog (ERROR , "Could not close lock file \"%s\": %s" ,
494
517
lock_file , strerror (save_errno ));
@@ -498,7 +521,7 @@ grab_excl_lock_file(const char *root_dir, const char *backup_id, bool strict)
498
521
// base36enc(backup->start_time),
499
522
// LOCK_TIMEOUT - ntries + LOCK_STALE_TIMEOUT - empty_tries);
500
523
501
- return 0 ;
524
+ return LOCK_OK ;
502
525
}
503
526
504
527
/* Wait until all shared lock owners are gone
@@ -648,7 +671,12 @@ grab_shared_lock_file(pgBackup *backup)
648
671
649
672
fp_out = fopen (lock_file_tmp , "w" );
650
673
if (fp_out == NULL )
674
+ {
675
+ if (errno == EROFS )
676
+ return 0 ;
677
+
651
678
elog (ERROR , "Cannot open temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
679
+ }
652
680
653
681
/* add my own pid */
654
682
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)
679
707
}
680
708
681
709
/* 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 )
683
711
/* ... if it's not possible then leave shared lock */
684
712
return ;
685
713
0 commit comments