@@ -28,7 +28,7 @@ static bool backup_lock_exit_hook_registered = false;
2828static parray * locks = NULL ;
2929
3030static 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 );
3232static int wait_shared_owners (pgBackup * backup );
3333
3434
@@ -231,7 +231,7 @@ lock_backup(pgBackup *backup, bool strict, bool exclusive)
231231 if (exclusive )
232232 rc = wait_shared_owners (backup );
233233 else
234- rc = grab_shared_lock_file (backup );
234+ rc = grab_shared_lock_file (backup -> root_dir );
235235
236236 if (rc != 0 )
237237 {
@@ -600,26 +600,21 @@ wait_shared_owners(pgBackup *backup)
600600 return 0 ;
601601}
602602
603+ #define FT_SLICE pid
604+ #define FT_SLICE_TYPE pid_t
605+ #include <ft_array.inc.h>
606+
603607/*
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.
607610 */
608- int
609- grab_shared_lock_file ( pgBackup * backup )
611+ static ft_arr_pid_t
612+ read_shared_lock_file ( const char * lock_file )
610613{
611614 FILE * fp_in = NULL ;
612- FILE * fp_out = NULL ;
613615 char buf_in [256 ];
614616 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 ();
623618
624619 /* open already existing lock files */
625620 fp_in = fopen (lock_file , "r" );
@@ -629,7 +624,7 @@ grab_shared_lock_file(pgBackup *backup)
629624 /* read PIDs of owners */
630625 while (fp_in && fgets (buf_in , sizeof (buf_in ), fp_in ))
631626 {
632- encoded_pid = atoi (buf_in );
627+ encoded_pid = ( pid_t ) atoll (buf_in );
633628 if (encoded_pid <= 0 )
634629 {
635630 elog (WARNING , "Bogus data in lock file \"%s\": \"%s\"" , lock_file , buf_in );
@@ -645,11 +640,11 @@ grab_shared_lock_file(pgBackup *backup)
645640 * Somebody is still using this backup in shared mode,
646641 * copy this pid into a new file.
647642 */
648- buffer_len += snprintf ( buffer + buffer_len , 4096 , "%llu\n" , ( long long ) encoded_pid );
643+ ft_arr_pid_push ( & pids , encoded_pid );
649644 }
650645 else if (errno != ESRCH )
651646 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 ));
653648 }
654649
655650 if (fp_in )
@@ -659,31 +654,69 @@ grab_shared_lock_file(pgBackup *backup)
659654 fclose (fp_in );
660655 }
661656
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+
662669 fp_out = fopen (lock_file_tmp , "w" );
663670 if (fp_out == NULL )
664671 {
665672 if (errno == EROFS )
666- return 0 ;
673+ return ;
667674
668675 elog (ERROR , "Cannot open temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
669676 }
670677
671- /* add my own pid */
672- buffer_len += snprintf (buffer + buffer_len , sizeof (buffer ), "%llu\n" , (long long )my_pid );
673-
674678 /* 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 );
676682
677683 if (ferror (fp_out ))
684+ {
685+ fclose (fp_out );
686+ remove (lock_file_tmp );
678687 elog (ERROR , "Cannot write to lock file: \"%s\"" , lock_file_tmp );
688+ }
679689
680690 if (fclose (fp_out ) != 0 )
691+ {
692+ remove (lock_file_tmp );
681693 elog (ERROR , "Cannot close temp lock file \"%s\": %s" , lock_file_tmp , strerror (errno ));
694+ }
682695
683696 if (rename (lock_file_tmp , lock_file ) < 0 )
684697 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+ }
686700
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 );
687720 return 0 ;
688721}
689722
@@ -723,87 +756,23 @@ release_excl_lock_file(const char *backup_dir)
723756void
724757release_shared_lock_file (const char * backup_dir )
725758{
726- FILE * fp_in = NULL ;
727- FILE * fp_out = NULL ;
728- char buf_in [256 ];
729- pid_t encoded_pid ;
730759 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 ;
735761
736762 join_path_components (lock_file , backup_dir , BACKUP_RO_LOCK_FILE );
737- snprintf (lock_file_tmp , MAXPGPATH , "%s%s" , lock_file , "tmp" );
738763
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 )
742767 {
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 )
785770 elog (ERROR , "Cannot remove shared lock file \"%s\": %s" , lock_file , strerror (errno ));
786771 return ;
787772 }
788773
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 );
807776}
808777
809778/*
0 commit comments