@@ -53,13 +53,14 @@ unlink_lock_atexit(void)
53
53
* If no backup matches, return NULL.
54
54
*/
55
55
pgBackup *
56
- read_backup (time_t timestamp )
56
+ read_backup (const char * instance_name , time_t timestamp )
57
57
{
58
58
pgBackup tmp ;
59
59
char conf_path [MAXPGPATH ];
60
60
61
61
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 );
63
64
64
65
return readBackupControlFile (conf_path );
65
66
}
@@ -71,11 +72,12 @@ read_backup(time_t timestamp)
71
72
* status.
72
73
*/
73
74
void
74
- write_backup_status (pgBackup * backup , BackupStatus status )
75
+ write_backup_status (pgBackup * backup , BackupStatus status ,
76
+ const char * instance_name )
75
77
{
76
78
pgBackup * tmp ;
77
79
78
- tmp = read_backup (backup -> start_time );
80
+ tmp = read_backup (instance_name , backup -> start_time );
79
81
if (!tmp )
80
82
{
81
83
/*
@@ -302,19 +304,86 @@ IsDir(const char *dirpath, const char *entry, fio_location location)
302
304
return fio_stat (path , & st , false, location ) == 0 && S_ISDIR (st .st_mode );
303
305
}
304
306
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
+
305
370
/*
306
371
* Create list of backups.
307
372
* If 'requested_backup_id' is INVALID_BACKUP_ID, return list of all backups.
308
373
* The list is sorted in order of descending start time.
309
374
* If valid backup id is passed only matching backup will be added to the list.
310
375
*/
311
376
parray *
312
- catalog_get_backup_list (time_t requested_backup_id )
377
+ catalog_get_backup_list (const char * instance_name , time_t requested_backup_id )
313
378
{
314
379
DIR * data_dir = NULL ;
315
380
struct dirent * data_ent = NULL ;
316
381
parray * backups = NULL ;
317
382
int i ;
383
+ char backup_instance_path [MAXPGPATH ];
384
+
385
+ sprintf (backup_instance_path , "%s/%s/%s" ,
386
+ backup_path , BACKUPS_DIR , instance_name );
318
387
319
388
/* open backup instance backups directory */
320
389
data_dir = fio_opendir (backup_instance_path , FIO_BACKUP_HOST );
@@ -420,6 +489,7 @@ catalog_get_backup_list(time_t requested_backup_id)
420
489
* Create list of backup datafiles.
421
490
* If 'requested_backup_id' is INVALID_BACKUP_ID, exit with error.
422
491
* 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?
423
493
*/
424
494
parray *
425
495
get_backup_filelist (pgBackup * backup )
@@ -1195,6 +1265,33 @@ pgBackupGetPath2(const pgBackup *backup, char *path, size_t len,
1195
1265
base36enc (backup -> start_time ), subdir1 , subdir2 );
1196
1266
}
1197
1267
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
+
1198
1295
/*
1199
1296
* Check if multiple backups consider target backup to be their direct parent
1200
1297
*/
0 commit comments