@@ -124,16 +124,11 @@ static char dir_check_file(pgFile *file);
124124static void dir_list_file_internal (parray * files , pgFile * parent , bool exclude ,
125125 bool omit_symlink , parray * black_list ,
126126 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 );
131127static void opt_path_map (ConfigOption * opt , const char * arg ,
132128 TablespaceList * list , const char * type );
133129
134130/* Tablespace mapping */
135131static TablespaceList tablespace_dirs = {NULL , NULL };
136- static TablespaceCreatedList tablespace_created_dirs = {NULL , NULL };
137132/* Extra directories mapping */
138133static TablespaceList external_remap_list = {NULL , NULL };
139134
@@ -840,108 +835,6 @@ dir_list_file_internal(parray *files, pgFile *parent, bool exclude,
840835 fio_closedir (dir );
841836}
842837
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-
945838/*
946839 * Retrieve tablespace path, either relocated or original depending on whether
947840 * -T was passed or not.
@@ -960,21 +853,6 @@ get_tablespace_mapping(const char *dir)
960853 return dir ;
961854}
962855
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-
978856/*
979857 * Split argument into old_dir and new_dir and append to mapping
980858 * list.
@@ -1052,15 +930,15 @@ opt_externaldir_map(ConfigOption *opt, const char *arg)
1052930}
1053931
1054932/*
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**.
1057934 *
1058935 * If **extract_tablespaces** is true then try to extract tablespace data
1059936 * directories into their initial path using tablespace_map file.
937+ * Use **backup_dir** for tablespace_map extracting.
1060938 *
1061939 * 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?
1064942 *
1065943 * TODO: symlink handling. If user located symlink in PG_TBLSPC_DIR, it will
1066944 * be restored as directory.
@@ -1071,27 +949,35 @@ create_data_directories(parray *dest_files, const char *data_dir, const char *ba
1071949{
1072950 int i ;
1073951 parray * links = NULL ;
1074- mode_t pg_tablespace_mode ;
952+ mode_t pg_tablespace_mode = 0 ;
1075953 char to_path [MAXPGPATH ];
1076954
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+ */
1078958 for (i = 0 ; i < parray_num (dest_files ); i ++ )
1079959 {
1080960 pgFile * file = (pgFile * ) parray_get (dest_files , i );
1081961
1082962 if (!S_ISDIR (file -> mode ))
1083963 continue ;
1084964
965+ /* skip external directory content */
966+ if (file -> external_dir_num != 0 )
967+ continue ;
968+
969+ /* look for 'pg_tblspc' directory */
1085970 if (strcmp (file -> rel_path , PG_TBLSPC_DIR ) == 0 )
1086971 {
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 ;
1092974 }
1093975 }
1094976
977+ /* sanity */
978+ if (!pg_tablespace_mode )
979+ pg_tablespace_mode = DIR_PERMISSION ;
980+
1095981 /* get tablespace map */
1096982 if (extract_tablespaces )
1097983 {
@@ -1101,19 +987,12 @@ create_data_directories(parray *dest_files, const char *data_dir, const char *ba
1101987 parray_qsort (links , pgFileCompareName );
1102988 }
1103989
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.
1117996 */
1118997
1119998 elog (LOG , "Restore directories and symlinks..." );
0 commit comments