@@ -28,7 +28,7 @@ static bool backup_lock_exit_hook_registered = false;
28
28
static parray * locks = NULL ;
29
29
30
30
static int grab_excl_lock_file (const char * backup_dir , const char * backup_id , bool strict );
31
- static int grab_shared_lock_file (pgBackup * backup );
31
+ static int grab_shared_lock_file (const char * backup_dir );
32
32
static int wait_shared_owners (pgBackup * backup );
33
33
34
34
@@ -231,7 +231,7 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
231
231
if (exclusive )
232
232
rc = wait_shared_owners (backup );
233
233
else
234
- rc = grab_shared_lock_file (backup );
234
+ rc = grab_shared_lock_file (backup -> root_dir );
235
235
236
236
if (rc != 0 )
237
237
{
@@ -600,26 +600,21 @@ wait_shared_owners(pgBackup *backup)
600
600
return 0 ;
601
601
}
602
602
603
+ #define FT_SLICE pid
604
+ #define FT_SLICE_TYPE pid_t
605
+ #include <ft_array.inc.h>
606
+
603
607
/*
604
- * Lock backup in shared mode
605
- * 0 - successs
606
- * 1 - fail
608
+ * returns array of pids stored in shared lock file and still alive.
609
+ * It excludes our own pid, so no need to exclude it explicitely.
607
610
*/
608
- int
609
- grab_shared_lock_file ( pgBackup * backup )
611
+ static ft_arr_pid_t
612
+ read_shared_lock_file ( const char * lock_file )
610
613
{
611
614
FILE * fp_in = NULL ;
612
- FILE * fp_out = NULL ;
613
615
char buf_in [256 ];
614
616
pid_t encoded_pid ;
615
- char lock_file [MAXPGPATH ];
616
-
617
- char buffer [8192 ]; /*TODO: should be enough, but maybe malloc+realloc is better ? */
618
- char lock_file_tmp [MAXPGPATH ];
619
- int buffer_len = 0 ;
620
-
621
- join_path_components (lock_file , backup -> root_dir , BACKUP_RO_LOCK_FILE );
622
- snprintf (lock_file_tmp , MAXPGPATH , "%s%s" , lock_file , "tmp" );
617
+ ft_arr_pid_t pids = ft_arr_init ();
623
618
624
619
/* open already existing lock files */
625
620
fp_in = fopen (lock_file , "r" );
@@ -629,7 +624,7 @@ grab_shared_lock_file(pgBackup *backup)
629
624
/* read PIDs of owners */
630
625
while (fp_in && fgets (buf_in , sizeof (buf_in ), fp_in ))
631
626
{
632
- encoded_pid = atoi (buf_in );
627
+ encoded_pid = ( pid_t ) atoll (buf_in );
633
628
if (encoded_pid <= 0 )
634
629
{
635
630
elog (WARNING , "Bogus data in lock file \"%s\": \"%s\"" , lock_file , buf_in );
@@ -645,11 +640,11 @@ grab_shared_lock_file(pgBackup *backup)
645
640
* Somebody is still using this backup in shared mode,
646
641
* copy this pid into a new file.
647
642
*/
648
- buffer_len += snprintf ( buffer + buffer_len , 4096 , "%llu\n" , ( long long ) encoded_pid );
643
+ ft_arr_pid_push ( & pids , encoded_pid );
649
644
}
650
645
else if (errno != ESRCH )
651
646
elog (ERROR , "Failed to send signal 0 to a process %lld: %s" ,
652
- (long long )encoded_pid , strerror (errno ));
647
+ (long long )encoded_pid , strerror (errno ));
653
648
}
654
649
655
650
if (fp_in )
@@ -659,31 +654,69 @@ grab_shared_lock_file(pgBackup *backup)
659
654
fclose (fp_in );
660
655
}
661
656
657
+ return pids ;
658
+ }
659
+
660
+ static void
661
+ write_shared_lock_file (const char * lock_file , ft_arr_pid_t pids )
662
+ {
663
+ FILE * fp_out = NULL ;
664
+ char lock_file_tmp [MAXPGPATH ];
665
+ ssize_t i ;
666
+
667
+ snprintf (lock_file_tmp , MAXPGPATH , "%s%s" , lock_file , "tmp" );
668
+
662
669
fp_out = fopen (lock_file_tmp , "w" );
663
670
if (fp_out == NULL )
664
671
{
665
672
if (errno == EROFS )
666
- return 0 ;
673
+ return ;
667
674
668
675
elog (ERROR , "Cannot open temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
669
676
}
670
677
671
- /* add my own pid */
672
- buffer_len += snprintf (buffer + buffer_len , sizeof (buffer ), "%llu\n" , (long long )my_pid );
673
-
674
678
/* write out the collected PIDs to temp lock file */
675
- fwrite (buffer , 1 , buffer_len , fp_out );
679
+ for (i = 0 ; i < pids .len ; i ++ )
680
+ fprintf (fp_out , "%lld\n" , (long long )ft_arr_pid_at (& pids , i ));
681
+ fflush (fp_out );
676
682
677
683
if (ferror (fp_out ))
684
+ {
685
+ fclose (fp_out );
686
+ remove (lock_file_tmp );
678
687
elog (ERROR , "Cannot write to lock file: \"%s\"" , lock_file_tmp );
688
+ }
679
689
680
690
if (fclose (fp_out ) != 0 )
691
+ {
692
+ remove (lock_file_tmp );
681
693
elog (ERROR , "Cannot close temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
694
+ }
682
695
683
696
if (rename (lock_file_tmp , lock_file ) < 0 )
684
697
elog (ERROR , "Cannot rename file \"%s\" to \"%s\": %s" ,
685
- lock_file_tmp , lock_file , strerror (errno ));
698
+ lock_file_tmp , lock_file , strerror (errno ));
699
+ }
686
700
701
+ /*
702
+ * Lock backup in shared mode
703
+ * 0 - successs
704
+ * 1 - fail
705
+ */
706
+ int
707
+ grab_shared_lock_file (const char * backup_dir )
708
+ {
709
+ char lock_file [MAXPGPATH ];
710
+ ft_arr_pid_t pids ;
711
+
712
+ join_path_components (lock_file , backup_dir , BACKUP_RO_LOCK_FILE );
713
+
714
+ pids = read_shared_lock_file (lock_file );
715
+ /* add my own pid */
716
+ ft_arr_pid_push (& pids , my_pid );
717
+
718
+ write_shared_lock_file (lock_file , pids );
719
+ ft_arr_pid_free (& pids );
687
720
return 0 ;
688
721
}
689
722
@@ -723,87 +756,23 @@ release_excl_lock_file(const char *backup_dir)
723
756
void
724
757
release_shared_lock_file (const char * backup_dir )
725
758
{
726
- FILE * fp_in = NULL ;
727
- FILE * fp_out = NULL ;
728
- char buf_in [256 ];
729
- pid_t encoded_pid ;
730
759
char lock_file [MAXPGPATH ];
731
-
732
- char buffer [8192 ]; /*TODO: should be enough, but maybe malloc+realloc is better ? */
733
- char lock_file_tmp [MAXPGPATH ];
734
- int buffer_len = 0 ;
760
+ ft_arr_pid_t pids ;
735
761
736
762
join_path_components (lock_file , backup_dir , BACKUP_RO_LOCK_FILE );
737
- snprintf (lock_file_tmp , MAXPGPATH , "%s%s" , lock_file , "tmp" );
738
763
739
- /* open lock file */
740
- fp_in = fopen ( lock_file , "r" );
741
- if (fp_in == NULL )
764
+ pids = read_shared_lock_file ( lock_file );
765
+ /* read_shared_lock_file already had deleted my own pid */
766
+ if (pids . len == 0 )
742
767
{
743
- if (errno == ENOENT )
744
- return ;
745
- else
746
- elog (ERROR , "Cannot open lock file \"%s\": %s" , lock_file , strerror (errno ));
747
- }
748
-
749
- /* read PIDs of owners */
750
- while (fgets (buf_in , sizeof (buf_in ), fp_in ))
751
- {
752
- encoded_pid = atoi (buf_in );
753
-
754
- if (encoded_pid <= 0 )
755
- {
756
- elog (WARNING , "Bogus data in lock file \"%s\": \"%s\"" , lock_file , buf_in );
757
- continue ;
758
- }
759
-
760
- /* remove my pid */
761
- if (encoded_pid == my_pid )
762
- continue ;
763
-
764
- if (kill (encoded_pid , 0 ) == 0 )
765
- {
766
- /*
767
- * Somebody is still using this backup in shared mode,
768
- * copy this pid into a new file.
769
- */
770
- buffer_len += snprintf (buffer + buffer_len , 4096 , "%llu\n" , (long long )encoded_pid );
771
- }
772
- else if (errno != ESRCH )
773
- elog (ERROR , "Failed to send signal 0 to a process %lld: %s" ,
774
- (long long )encoded_pid , strerror (errno ));
775
- }
776
-
777
- if (ferror (fp_in ))
778
- elog (ERROR , "Cannot read from lock file: \"%s\"" , lock_file );
779
- fclose (fp_in );
780
-
781
- /* if there is no active pid left, then there is nothing to do */
782
- if (buffer_len == 0 )
783
- {
784
- if (fio_remove (FIO_BACKUP_HOST , lock_file , false) != 0 )
768
+ ft_arr_pid_free (& pids );
769
+ if (remove (lock_file ) != 0 )
785
770
elog (ERROR , "Cannot remove shared lock file \"%s\": %s" , lock_file , strerror (errno ));
786
771
return ;
787
772
}
788
773
789
- fp_out = fopen (lock_file_tmp , "w" );
790
- if (fp_out == NULL )
791
- elog (ERROR , "Cannot open temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
792
-
793
- /* write out the collected PIDs to temp lock file */
794
- fwrite (buffer , 1 , buffer_len , fp_out );
795
-
796
- if (ferror (fp_out ))
797
- elog (ERROR , "Cannot write to lock file: \"%s\"" , lock_file_tmp );
798
-
799
- if (fclose (fp_out ) != 0 )
800
- elog (ERROR , "Cannot close temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
801
-
802
- if (rename (lock_file_tmp , lock_file ) < 0 )
803
- elog (ERROR , "Cannot rename file \"%s\" to \"%s\": %s" ,
804
- lock_file_tmp , lock_file , strerror (errno ));
805
-
806
- return ;
774
+ write_shared_lock_file (lock_file , pids );
775
+ ft_arr_pid_free (& pids );
807
776
}
808
777
809
778
/*
0 commit comments