@@ -53,13 +53,14 @@ unlink_lock_atexit(void)
5353 * If no backup matches, return NULL.
5454 */
5555pgBackup *
56- read_backup (time_t timestamp )
56+ read_backup (const char * instance_name , time_t timestamp )
5757{
5858 pgBackup tmp ;
5959 char conf_path [MAXPGPATH ];
6060
6161 tmp .start_time = timestamp ;
62- pgBackupGetPath (& tmp , conf_path , lengthof (conf_path ), BACKUP_CONTROL_FILE );
62+ pgBackupGetPathInInstance (instance_name , & tmp , conf_path ,
63+ lengthof (conf_path ), BACKUP_CONTROL_FILE , NULL );
6364
6465 return readBackupControlFile (conf_path );
6566}
@@ -71,11 +72,12 @@ read_backup(time_t timestamp)
7172 * status.
7273 */
7374void
74- write_backup_status (pgBackup * backup , BackupStatus status )
75+ write_backup_status (pgBackup * backup , BackupStatus status ,
76+ const char * instance_name )
7577{
7678 pgBackup * tmp ;
7779
78- tmp = read_backup (backup -> start_time );
80+ tmp = read_backup (instance_name , backup -> start_time );
7981 if (!tmp )
8082 {
8183 /*
@@ -302,19 +304,86 @@ IsDir(const char *dirpath, const char *entry, fio_location location)
302304 return fio_stat (path , & st , false, location ) == 0 && S_ISDIR (st .st_mode );
303305}
304306
307+ /*
308+ * Create list of instances in given backup catalog.
309+ *
310+ * Returns parray of "InstanceConfig" structures, filled with
311+ * actual config of each instance.
312+ */
313+ parray *
314+ catalog_get_instance_list (void )
315+ {
316+ char path [MAXPGPATH ];
317+ DIR * dir ;
318+ struct dirent * dent ;
319+ parray * instances ;
320+
321+ instances = parray_new ();
322+
323+ /* open directory and list contents */
324+ join_path_components (path , backup_path , BACKUPS_DIR );
325+ dir = opendir (path );
326+ if (dir == NULL )
327+ elog (ERROR , "Cannot open directory \"%s\": %s" ,
328+ path , strerror (errno ));
329+
330+ while (errno = 0 , (dent = readdir (dir )) != NULL )
331+ {
332+ char child [MAXPGPATH ];
333+ struct stat st ;
334+ InstanceConfig * instance ;
335+
336+ /* skip entries point current dir or parent dir */
337+ if (strcmp (dent -> d_name , "." ) == 0 ||
338+ strcmp (dent -> d_name , ".." ) == 0 )
339+ continue ;
340+
341+ join_path_components (child , path , dent -> d_name );
342+
343+ if (lstat (child , & st ) == -1 )
344+ elog (ERROR , "Cannot stat file \"%s\": %s" ,
345+ child , strerror (errno ));
346+
347+ if (!S_ISDIR (st .st_mode ))
348+ continue ;
349+
350+ instance = readInstanceConfigFile (dent -> d_name );
351+
352+ parray_append (instances , instance );
353+ }
354+
355+ /* TODO 3.0: switch to ERROR */
356+ if (parray_num (instances ) == 0 )
357+ elog (WARNING , "This backup catalog contains no backup instances. Backup instance can be added via 'add-instance' command." );
358+
359+ if (errno )
360+ elog (ERROR , "Cannot read directory \"%s\": %s" ,
361+ path , strerror (errno ));
362+
363+ if (closedir (dir ))
364+ elog (ERROR , "Cannot close directory \"%s\": %s" ,
365+ path , strerror (errno ));
366+
367+ return instances ;
368+ }
369+
305370/*
306371 * Create list of backups.
307372 * If 'requested_backup_id' is INVALID_BACKUP_ID, return list of all backups.
308373 * The list is sorted in order of descending start time.
309374 * If valid backup id is passed only matching backup will be added to the list.
310375 */
311376parray *
312- catalog_get_backup_list (time_t requested_backup_id )
377+ catalog_get_backup_list (const char * instance_name , time_t requested_backup_id )
313378{
314379 DIR * data_dir = NULL ;
315380 struct dirent * data_ent = NULL ;
316381 parray * backups = NULL ;
317382 int i ;
383+ char backup_instance_path [MAXPGPATH ];
384+
385+ sprintf (backup_instance_path , "%s/%s/%s" ,
386+ backup_path , BACKUPS_DIR , instance_name );
318387
319388 /* open backup instance backups directory */
320389 data_dir = fio_opendir (backup_instance_path , FIO_BACKUP_HOST );
@@ -420,6 +489,7 @@ catalog_get_backup_list(time_t requested_backup_id)
420489 * Create list of backup datafiles.
421490 * If 'requested_backup_id' is INVALID_BACKUP_ID, exit with error.
422491 * If valid backup id is passed only matching backup will be added to the list.
492+ * TODO this function only used once. Is it really needed?
423493 */
424494parray *
425495get_backup_filelist (pgBackup * backup )
@@ -1195,6 +1265,33 @@ pgBackupGetPath2(const pgBackup *backup, char *path, size_t len,
11951265 base36enc (backup -> start_time ), subdir1 , subdir2 );
11961266}
11971267
1268+ /*
1269+ * independent from global variable backup_instance_path
1270+ * Still depends from backup_path
1271+ */
1272+ void
1273+ pgBackupGetPathInInstance (const char * instance_name ,
1274+ const pgBackup * backup , char * path , size_t len ,
1275+ const char * subdir1 , const char * subdir2 )
1276+ {
1277+ char backup_instance_path [MAXPGPATH ];
1278+
1279+ sprintf (backup_instance_path , "%s/%s/%s" ,
1280+ backup_path , BACKUPS_DIR , instance_name );
1281+
1282+ /* If "subdir1" is NULL do not check "subdir2" */
1283+ if (!subdir1 )
1284+ snprintf (path , len , "%s/%s" , backup_instance_path ,
1285+ base36enc (backup -> start_time ));
1286+ else if (!subdir2 )
1287+ snprintf (path , len , "%s/%s/%s" , backup_instance_path ,
1288+ base36enc (backup -> start_time ), subdir1 );
1289+ /* "subdir1" and "subdir2" is not NULL */
1290+ else
1291+ snprintf (path , len , "%s/%s/%s/%s" , backup_instance_path ,
1292+ base36enc (backup -> start_time ), subdir1 , subdir2 );
1293+ }
1294+
11981295/*
11991296 * Check if multiple backups consider target backup to be their direct parent
12001297 */
0 commit comments