@@ -124,16 +124,11 @@ static char dir_check_file(pgFile *file);
124
124
static void dir_list_file_internal (parray * files , pgFile * parent , bool exclude ,
125
125
bool omit_symlink , parray * black_list ,
126
126
int external_dir_num , fio_location location );
127
-
128
- static void list_data_directories (parray * files , const char * root ,
129
- const char * rel_path , bool exclude ,
130
- fio_location location );
131
127
static void opt_path_map (ConfigOption * opt , const char * arg ,
132
128
TablespaceList * list , const char * type );
133
129
134
130
/* Tablespace mapping */
135
131
static TablespaceList tablespace_dirs = {NULL , NULL };
136
- static TablespaceCreatedList tablespace_created_dirs = {NULL , NULL };
137
132
/* Extra directories mapping */
138
133
static TablespaceList external_remap_list = {NULL , NULL };
139
134
@@ -840,108 +835,6 @@ dir_list_file_internal(parray *files, pgFile *parent, bool exclude,
840
835
fio_closedir (dir );
841
836
}
842
837
843
- /*
844
- * List data directories excluding directories from pgdata_exclude_dir array.
845
- *
846
- * We exclude first level of directories and on the first level we check all
847
- * files and directories.
848
- */
849
- static void
850
- list_data_directories (parray * files , const char * root , const char * rel_path ,
851
- bool exclude , fio_location location )
852
- {
853
- char full_path [MAXPGPATH ];
854
- DIR * dir ;
855
- struct dirent * dent ;
856
- int prev_errno ;
857
- bool has_child_dirs = false;
858
-
859
- join_path_components (full_path , root , rel_path );
860
-
861
- /* open directory and list contents */
862
- dir = fio_opendir (full_path , location );
863
- if (dir == NULL )
864
- elog (ERROR , "Cannot open directory \"%s\": %s" , full_path ,
865
- strerror (errno ));
866
-
867
- errno = 0 ;
868
- while ((dent = fio_readdir (dir )))
869
- {
870
- char child [MAXPGPATH ];
871
- bool skip = false;
872
- struct stat st ;
873
-
874
- /* skip entries point current dir or parent dir */
875
- if (strcmp (dent -> d_name , "." ) == 0 ||
876
- strcmp (dent -> d_name , ".." ) == 0 )
877
- continue ;
878
-
879
- /* Make full child path */
880
- join_path_components (child , full_path , dent -> d_name );
881
-
882
- if (fio_stat (child , & st , false, location ) == -1 )
883
- elog (ERROR , "Cannot stat file \"%s\": %s" , child , strerror (errno ));
884
-
885
- if (!S_ISDIR (st .st_mode ))
886
- continue ;
887
-
888
- /* Check for exclude for the first level of listing */
889
- if (exclude && rel_path [0 ] == '\0' )
890
- {
891
- int i ;
892
-
893
- for (i = 0 ; pgdata_exclude_dir [i ]; i ++ )
894
- {
895
- if (strcmp (dent -> d_name , pgdata_exclude_dir [i ]) == 0 )
896
- {
897
- skip = true;
898
- break ;
899
- }
900
- }
901
- }
902
- if (skip )
903
- continue ;
904
-
905
- has_child_dirs = true;
906
- /* Make relative child path */
907
- join_path_components (child , rel_path , dent -> d_name );
908
- list_data_directories (files , root , child , exclude , location );
909
- }
910
-
911
- /* List only full and last directories */
912
- if (rel_path [0 ] != '\0' && !has_child_dirs )
913
- parray_append (files ,
914
- pgFileNew (full_path , rel_path , false, 0 , location ));
915
-
916
- prev_errno = errno ;
917
- fio_closedir (dir );
918
-
919
- if (prev_errno && prev_errno != ENOENT )
920
- elog (ERROR , "Cannot read directory \"%s\": %s" ,
921
- full_path , strerror (prev_errno ));
922
- }
923
-
924
- /*
925
- * Save create directory path into memory. We can use it in next page restore to
926
- * not raise the error "restore tablespace destination is not empty" in
927
- * create_data_directories().
928
- */
929
- static void
930
- set_tablespace_created (const char * link , const char * dir )
931
- {
932
- TablespaceCreatedListCell * cell = pgut_new (TablespaceCreatedListCell );
933
-
934
- strcpy (cell -> link_name , link );
935
- strcpy (cell -> linked_dir , dir );
936
- cell -> next = NULL ;
937
-
938
- if (tablespace_created_dirs .tail )
939
- tablespace_created_dirs .tail -> next = cell ;
940
- else
941
- tablespace_created_dirs .head = cell ;
942
- tablespace_created_dirs .tail = cell ;
943
- }
944
-
945
838
/*
946
839
* Retrieve tablespace path, either relocated or original depending on whether
947
840
* -T was passed or not.
@@ -960,21 +853,6 @@ get_tablespace_mapping(const char *dir)
960
853
return dir ;
961
854
}
962
855
963
- /*
964
- * Is directory was created when symlink was created in restore_directories().
965
- */
966
- static const char *
967
- get_tablespace_created (const char * link )
968
- {
969
- TablespaceCreatedListCell * cell ;
970
-
971
- for (cell = tablespace_created_dirs .head ; cell ; cell = cell -> next )
972
- if (strcmp (link , cell -> link_name ) == 0 )
973
- return cell -> linked_dir ;
974
-
975
- return NULL ;
976
- }
977
-
978
856
/*
979
857
* Split argument into old_dir and new_dir and append to mapping
980
858
* list.
@@ -1052,15 +930,15 @@ opt_externaldir_map(ConfigOption *opt, const char *arg)
1052
930
}
1053
931
1054
932
/*
1055
- * Create backup directories from **backup_dir** to **data_dir**. Doesn't raise
1056
- * an error if target directories exist.
933
+ * Create directories from **dest_files** in **data_dir**.
1057
934
*
1058
935
* If **extract_tablespaces** is true then try to extract tablespace data
1059
936
* directories into their initial path using tablespace_map file.
937
+ * Use **backup_dir** for tablespace_map extracting.
1060
938
*
1061
939
* Enforce permissions from backup_content.control. The only
1062
- * problem now is with PGDATA itself, we must preserve PGDATA permissions
1063
- * somewhere.
940
+ * problem now is with PGDATA itself.
941
+ * TODO: we must preserve PGDATA permissions somewhere. Is it actually a problem?
1064
942
*
1065
943
* TODO: symlink handling. If user located symlink in PG_TBLSPC_DIR, it will
1066
944
* be restored as directory.
@@ -1071,27 +949,35 @@ create_data_directories(parray *dest_files, const char *data_dir, const char *ba
1071
949
{
1072
950
int i ;
1073
951
parray * links = NULL ;
1074
- mode_t pg_tablespace_mode ;
952
+ mode_t pg_tablespace_mode = 0 ;
1075
953
char to_path [MAXPGPATH ];
1076
954
1077
- /* Ugly: get PG_TBLSPC_DIR pemission mask */
955
+ /* Ugly: get PG_TBLSPC_DIR pemission mask.
956
+ * We will use it to set permissions for tablespace directories.
957
+ */
1078
958
for (i = 0 ; i < parray_num (dest_files ); i ++ )
1079
959
{
1080
960
pgFile * file = (pgFile * ) parray_get (dest_files , i );
1081
961
1082
962
if (!S_ISDIR (file -> mode ))
1083
963
continue ;
1084
964
965
+ /* skip external directory content */
966
+ if (file -> external_dir_num != 0 )
967
+ continue ;
968
+
969
+ /* look for 'pg_tblspc' directory */
1085
970
if (strcmp (file -> rel_path , PG_TBLSPC_DIR ) == 0 )
1086
971
{
1087
- if (file -> external_dir_num == 0 )
1088
- {
1089
- pg_tablespace_mode = file -> mode ;
1090
- break ;
1091
- }
972
+ pg_tablespace_mode = file -> mode ;
973
+ break ;
1092
974
}
1093
975
}
1094
976
977
+ /* sanity */
978
+ if (!pg_tablespace_mode )
979
+ pg_tablespace_mode = DIR_PERMISSION ;
980
+
1095
981
/* get tablespace map */
1096
982
if (extract_tablespaces )
1097
983
{
@@ -1101,19 +987,12 @@ create_data_directories(parray *dest_files, const char *data_dir, const char *ba
1101
987
parray_qsort (links , pgFileCompareName );
1102
988
}
1103
989
1104
- /* Fun part is that backup_content.control is from beginning
1105
- * of a backup, and tablespace_map is from the end
1106
- * of a backup.
1107
- * If we trust tablspace_map, we would have to we create first
1108
- * tablespaces from it, then the start creating directories and files
1109
- * from backup_content.
1110
- * The problem if that backup_content could contain files from
1111
- * deleted tablespaces and so would have to
1112
- * check every file and directory if it comes from tablespace,
1113
- * not presented in tablespace_map and skip it restoring if it
1114
- * is not.
1115
- * Trusting backup_content.control is safest way, there is no risk
1116
- * of not restoring something.
990
+ /*
991
+ * We iterate over dest_files and for every directory with parent 'pg_tblspc'
992
+ * we must lookup this directory name in tablespace map.
993
+ * If we got a match, we treat this directory as tablespace.
994
+ * It means that we create directory specified in tablespace_map and
995
+ * original directory created as symlink to it.
1117
996
*/
1118
997
1119
998
elog (LOG , "Restore directories and symlinks..." );
0 commit comments