You've already forked pg_probackup
							
							
				mirror of
				https://github.com/postgrespro/pg_probackup.git
				synced 2025-10-31 00:17:52 +02:00 
			
		
		
		
	git-svn-id: http://pg-rman.googlecode.com/svn/trunk@70 182aca00-e38e-11de-a668-6fd11605f5ce
		
			
				
	
	
		
			174 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*-------------------------------------------------------------------------
 | |
|  *
 | |
|  * init.c: manage backup catalog.
 | |
|  *
 | |
|  * Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
 | |
|  *
 | |
|  *-------------------------------------------------------------------------
 | |
|  */
 | |
| 
 | |
| #include "pg_rman.h"
 | |
| 
 | |
| #include <unistd.h>
 | |
| #include <dirent.h>
 | |
| 
 | |
| static void parse_postgresql_conf(const char *path, char **log_directory,
 | |
| 								  char **archive_command);
 | |
| 
 | |
| /*
 | |
|  * selects function for scandir.
 | |
|  */
 | |
| static int selects(const struct dirent *dir)
 | |
| {
 | |
|   return dir->d_name[0] != '.';
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Initialize backup catalog.
 | |
|  */
 | |
| int
 | |
| do_init(void)
 | |
| {
 | |
| 	char	path[MAXPGPATH];
 | |
| 	char   *log_directory = NULL;
 | |
| 	char   *archive_command = NULL;
 | |
| 	FILE   *fp;
 | |
| 
 | |
| 	struct dirent **dp;
 | |
| 	int results;
 | |
| 	if (access(backup_path, F_OK) == 0){
 | |
| 		results = scandir(backup_path, &dp, selects, NULL);
 | |
| 		if(results != 0){
 | |
| 			elog(ERROR, _("backup catalog already exist. and it's not empty."));
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/* create backup catalog root directory */
 | |
| 	dir_create_dir(backup_path, DIR_PERMISSION);
 | |
| 
 | |
| 	/* create directories for backup of online files */
 | |
| 	join_path_components(path, backup_path, RESTORE_WORK_DIR);
 | |
| 	dir_create_dir(path, DIR_PERMISSION);
 | |
| 	snprintf(path, lengthof(path), "%s/%s/%s", backup_path, RESTORE_WORK_DIR,
 | |
| 		PG_XLOG_DIR);
 | |
| 	dir_create_dir(path, DIR_PERMISSION);
 | |
| 	snprintf(path, lengthof(path), "%s/%s/%s", backup_path, RESTORE_WORK_DIR,
 | |
| 		SRVLOG_DIR);
 | |
| 	dir_create_dir(path, DIR_PERMISSION);
 | |
| 
 | |
| 	/* create directory for timeline history files */
 | |
| 	join_path_components(path, backup_path, TIMELINE_HISTORY_DIR);
 | |
| 	dir_create_dir(path, DIR_PERMISSION);
 | |
| 
 | |
| 	/* read postgresql.conf */
 | |
| 	if (pgdata)
 | |
| 	{
 | |
| 		join_path_components(path, pgdata, "postgresql.conf");
 | |
| 		parse_postgresql_conf(path, &log_directory, &archive_command);
 | |
| 	}
 | |
| 
 | |
| 	/* create pg_rman.ini */
 | |
| 	join_path_components(path, backup_path, PG_RMAN_INI_FILE);
 | |
| 	fp = fopen(path, "wt");
 | |
| 	if (fp == NULL)
 | |
| 		elog(ERROR_SYSTEM, _("can't create pg_rman.ini: %s"), strerror(errno));
 | |
| 
 | |
| 	/* set ARCLOG_PATH refered with log_directory */
 | |
| 	if (arclog_path == NULL && archive_command && archive_command[0])
 | |
| 	{
 | |
| 		char *command = pgut_strdup(archive_command);
 | |
| 		char *begin;
 | |
| 		char *end;
 | |
| 		char *fname;
 | |
| 
 | |
| 		/* example: 'cp "%p" /path/to/arclog/"%f"' */
 | |
| 		for (begin = command; *begin;)
 | |
| 		{
 | |
| 			begin = begin + strspn(begin, " \n\r\t\v");
 | |
| 			end = begin + strcspn(begin, " \n\r\t\v");
 | |
| 			*end = '\0';
 | |
| 
 | |
| 			if ((fname = strstr(begin, "%f")) != NULL)
 | |
| 			{
 | |
| 				while (strchr(" \n\r\t\v\"'", *begin))
 | |
| 					begin++;
 | |
| 				fname--;
 | |
| 				while (fname > begin && strchr(" \n\r\t\v\"'/", fname[-1]))
 | |
| 					fname--;
 | |
| 				*fname = '\0';
 | |
| 
 | |
| 				if (is_absolute_path(begin))
 | |
| 					arclog_path = pgut_strdup(begin);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			begin = end + 1;
 | |
| 		}
 | |
| 
 | |
| 		free(command);
 | |
| 	}
 | |
| 	if (arclog_path)
 | |
| 	{
 | |
| 		fprintf(fp, "ARCLOG_PATH='%s'\n", arclog_path);
 | |
| 		elog(INFO, "ARCLOG_PATH is set to '%s'", arclog_path);
 | |
| 	}
 | |
| 	else if (archive_command && archive_command[0])
 | |
| 		elog(WARNING, "ARCLOG_PATH is not set because failed to parse archive_command '%s'."
 | |
| 				"Please set ARCLOG_PATH in pg_rman.ini or environmental variable", archive_command);
 | |
| 	else
 | |
| 		elog(WARNING, "ARCLOG_PATH is not set because archive_command is empty."
 | |
| 				"Please set ARCLOG_PATH in pg_rman.ini or environmental variable");
 | |
| 
 | |
| 	/* set SRVLOG_PATH refered with log_directory */
 | |
| 	if (srvlog_path == NULL)
 | |
| 	{
 | |
| 		if (log_directory)
 | |
| 		{
 | |
| 			if (is_absolute_path(log_directory))
 | |
| 				srvlog_path = pgut_strdup(log_directory);
 | |
| 			else
 | |
| 			{
 | |
| 				srvlog_path = pgut_malloc(MAXPGPATH);
 | |
| 				join_path_components(srvlog_path, pgdata, log_directory);
 | |
| 			}
 | |
| 		}
 | |
| 		else if (pgdata)
 | |
| 		{
 | |
| 			/* default: log_directory = 'pg_log' */
 | |
| 			srvlog_path = pgut_malloc(MAXPGPATH);
 | |
| 			join_path_components(srvlog_path, pgdata, "pg_log");
 | |
| 		}
 | |
| 	}
 | |
| 	if (srvlog_path)
 | |
| 	{
 | |
| 		fprintf(fp, "SRVLOG_PATH='%s'\n", srvlog_path);
 | |
| 		elog(INFO, "SRVLOG_PATH is set to '%s'", srvlog_path);
 | |
| 	}
 | |
| 
 | |
| 	fprintf(fp, "\n");
 | |
| 	fclose(fp);
 | |
| 
 | |
| 	free(archive_command);
 | |
| 	free(log_directory);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static void
 | |
| parse_postgresql_conf(const char *path,
 | |
| 					  char **log_directory,
 | |
| 					  char **archive_command)
 | |
| {
 | |
| 	pgut_option options[] =
 | |
| 	{
 | |
| 		{ 's', 0, "log_directory"		, NULL, SOURCE_ENV },
 | |
| 		{ 's', 0, "archive_command"		, NULL, SOURCE_ENV },
 | |
| 		{ 0 }
 | |
| 	};
 | |
| 
 | |
| 	options[0].var = log_directory;
 | |
| 	options[1].var = archive_command;
 | |
| 
 | |
| 	pgut_readopt(path, options, LOG);	/* ignore unknown options */
 | |
| }
 |