@@ -36,6 +36,11 @@ static void unlock_backup(const char *backup_dir, const char *backup_id, bool ex
3636static void release_excl_lock_file (const char * backup_dir );
3737static 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+
3944typedef 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 */
280295int
281296grab_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