@@ -23,7 +23,7 @@ static pgBackup* get_closest_backup(timelineInfo *tlinfo);
2323static pgBackup * get_oldest_backup (timelineInfo * tlinfo );
2424static const char * backupModes [] = {"" , "PAGE" , "PTRACK" , "DELTA" , "FULL" };
2525static pgBackup * readBackupControlFile (const char * path );
26- static void create_backup_dir (pgBackup * backup , const char * backup_instance_path );
26+ static int create_backup_dir (pgBackup * backup , const char * backup_instance_path );
2727
2828static bool backup_lock_exit_hook_registered = false;
2929static parray * locks = NULL ;
@@ -969,6 +969,7 @@ catalog_get_backup_list(InstanceState *instanceState, time_t requested_backup_id
969969 }
970970 else if (strcmp (base36enc (backup -> start_time ), data_ent -> d_name ) != 0 )
971971 {
972+ /* TODO there is no such guarantees */
972973 elog (WARNING , "backup ID in control file \"%s\" doesn't match name of the backup folder \"%s\"" ,
973974 base36enc (backup -> start_time ), backup_conf_path );
974975 }
@@ -1411,22 +1412,34 @@ get_multi_timeline_parent(parray *backup_list, parray *tli_list,
14111412 return NULL ;
14121413}
14131414
1414- /* Create backup directory in $BACKUP_PATH
1415- * Note, that backup_id attribute is updated,
1416- * so it is possible to get diffrent values in
1415+ /*
1416+ * Create backup directory in $BACKUP_PATH
1417+ * (with proposed backup->backup_id)
1418+ * and initialize this directory.
1419+ * If creation of directory fails, then
1420+ * backup_id will be cleared (set to INVALID_BACKUP_ID).
1421+ * It is possible to get diffrent values in
14171422 * pgBackup.start_time and pgBackup.backup_id.
14181423 * It may be ok or maybe not, so it's up to the caller
14191424 * to fix it or let it be.
14201425 */
14211426
14221427void
1423- pgBackupCreateDir (pgBackup * backup , InstanceState * instanceState , time_t start_time )
1428+ pgBackupInitDir (pgBackup * backup , const char * backup_instance_path )
14241429{
1425- int i ;
1426- parray * subdirs = parray_new ();
1427- parray * backups ;
1428- pgBackup * target_backup ;
1430+ int i ;
1431+ char temp [MAXPGPATH ];
1432+ parray * subdirs ;
14291433
1434+ /* Try to create backup directory at first */
1435+ if (create_backup_dir (backup , backup_instance_path ) != 0 )
1436+ {
1437+ /* Clear backup_id as indication of error */
1438+ backup -> backup_id = INVALID_BACKUP_ID ;
1439+ return ;
1440+ }
1441+
1442+ subdirs = parray_new ();
14301443 parray_append (subdirs , pg_strdup (DATABASE_DIR ));
14311444
14321445 /* Add external dirs containers */
@@ -1438,38 +1451,13 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14381451 false);
14391452 for (i = 0 ; i < parray_num (external_list ); i ++ )
14401453 {
1441- char temp [MAXPGPATH ];
14421454 /* Numeration of externaldirs starts with 1 */
14431455 makeExternalDirPathByNum (temp , EXTERNAL_DIR , i + 1 );
14441456 parray_append (subdirs , pg_strdup (temp ));
14451457 }
14461458 free_dir_list (external_list );
14471459 }
14481460
1449- /* Get list of all backups*/
1450- backups = catalog_get_backup_list (instanceState , INVALID_BACKUP_ID );
1451- if (parray_num (backups ) > 0 )
1452- {
1453- target_backup = (pgBackup * ) parray_get (backups , 0 );
1454- if (start_time > target_backup -> backup_id )
1455- {
1456- backup -> backup_id = start_time ;
1457- create_backup_dir (backup , instanceState -> instance_backup_subdir_path );
1458- }
1459- else
1460- {
1461- elog (ERROR , "Cannot create directory for older backup" );
1462- }
1463- }
1464- else
1465- {
1466- backup -> backup_id = start_time ;
1467- create_backup_dir (backup , instanceState -> instance_backup_subdir_path );
1468- }
1469-
1470- if (backup -> backup_id == 0 )
1471- elog (ERROR , "Cannot create backup directory: %s" , strerror (errno ));
1472-
14731461 backup -> database_dir = pgut_malloc (MAXPGPATH );
14741462 join_path_components (backup -> database_dir , backup -> root_dir , DATABASE_DIR );
14751463
@@ -1479,10 +1467,8 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14791467 /* create directories for actual backup files */
14801468 for (i = 0 ; i < parray_num (subdirs ); i ++ )
14811469 {
1482- char path [MAXPGPATH ];
1483-
1484- join_path_components (path , backup -> root_dir , parray_get (subdirs , i ));
1485- fio_mkdir (path , DIR_PERMISSION , FIO_BACKUP_HOST );
1470+ join_path_components (temp , backup -> root_dir , parray_get (subdirs , i ));
1471+ fio_mkdir (temp , DIR_PERMISSION , FIO_BACKUP_HOST );
14861472 }
14871473
14881474 free_dir_list (subdirs );
@@ -1491,34 +1477,26 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14911477/*
14921478 * Create root directory for backup,
14931479 * update pgBackup.root_dir if directory creation was a success
1480+ * Return values (same as dir_create_dir()):
1481+ * 0 - ok
1482+ * -1 - error (warning message already emitted)
14941483 */
1495- void
1484+ int
14961485create_backup_dir (pgBackup * backup , const char * backup_instance_path )
14971486{
1498- int attempts = 10 ;
1487+ int rc ;
1488+ char path [MAXPGPATH ];
14991489
1500- while (attempts -- )
1501- {
1502- int rc ;
1503- char path [MAXPGPATH ];
1504-
1505- join_path_components (path , backup_instance_path , base36enc (backup -> backup_id ));
1490+ join_path_components (path , backup_instance_path , base36enc (backup -> backup_id ));
15061491
1507- /* TODO: add wrapper for remote mode */
1508- rc = dir_create_dir (path , DIR_PERMISSION , true);
1509-
1510- if (rc == 0 )
1511- {
1512- backup -> root_dir = pgut_strdup (path );
1513- return ;
1514- }
1515- else
1516- {
1517- elog (WARNING , "Cannot create directory \"%s\": %s" , path , strerror (errno ));
1518- sleep (1 );
1519- }
1520- }
1492+ /* TODO: add wrapper for remote mode */
1493+ rc = dir_create_dir (path , DIR_PERMISSION , true);
15211494
1495+ if (rc == 0 )
1496+ backup -> root_dir = pgut_strdup (path );
1497+ else
1498+ elog (WARNING , "Cannot create directory \"%s\": %s" , path , strerror (errno ));
1499+ return rc ;
15221500}
15231501
15241502/*
0 commit comments