You've already forked pg_probackup
							
							
				mirror of
				https://github.com/postgrespro/pg_probackup.git
				synced 2025-10-31 00:17:52 +02:00 
			
		
		
		
	Clean up the snapshot related stuff
This is not really part of the core of pg_rman, rather better to focus on incremental backup or stuff like that.
This commit is contained in:
		
							
								
								
									
										230
									
								
								backup.c
									
									
									
									
									
								
							
							
						
						
									
										230
									
								
								backup.c
									
									
									
									
									
								
							| @@ -57,14 +57,6 @@ static void delete_online_wal_backup(void); | |||||||
|  |  | ||||||
| static bool dirExists(const char *path); | static bool dirExists(const char *path); | ||||||
|  |  | ||||||
| static void execute_freeze(void); |  | ||||||
| static void execute_unfreeze(void); |  | ||||||
| static void execute_split(parray *tblspc_list); |  | ||||||
| static void execute_resync(void); |  | ||||||
| static void execute_mount(parray *tblspcmp_list); |  | ||||||
| static void execute_umount(void); |  | ||||||
| static void execute_script(const char *mode, bool is_cleanup, parray *output); |  | ||||||
| static void snapshot_cleanup(bool fatal, void *userdata); |  | ||||||
| static void add_files(parray *files, const char *root, bool add_root, bool is_pgdata); | static void add_files(parray *files, const char *root, bool add_root, bool is_pgdata); | ||||||
| static int strCompare(const void *str1, const void *str2); | static int strCompare(const void *str1, const void *str2); | ||||||
| static void create_file_list(parray *files, const char *root, const char *prefix, bool is_append); | static void create_file_list(parray *files, const char *root, const char *prefix, bool is_append); | ||||||
| @@ -241,20 +233,6 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt) | |||||||
| 		for (i = 0; pgdata_exclude[i]; i++);	/* find first empty slot */ | 		for (i = 0; pgdata_exclude[i]; i++);	/* find first empty slot */ | ||||||
| 		pgdata_exclude[i] = PG_TBLSPC_DIR; | 		pgdata_exclude[i] = PG_TBLSPC_DIR; | ||||||
|  |  | ||||||
| 		/* set the error processing for the snapshot */ |  | ||||||
| 		pgut_atexit_push(snapshot_cleanup, cleanup_list); |  | ||||||
|  |  | ||||||
| 		/* create snapshot volume */ |  | ||||||
| 		if (!check) |  | ||||||
| 		{ |  | ||||||
| 			/* freeze I/O of the file-system */ |  | ||||||
| 			execute_freeze(); |  | ||||||
| 			/* create the snapshot, and obtain the name of TABLESPACE backup from snapshot */ |  | ||||||
| 			execute_split(tblspc_list); |  | ||||||
| 			/* unfreeze I/O of the file-system */ |  | ||||||
| 			execute_unfreeze(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		/* | 		/* | ||||||
| 		 * when DB cluster is not contained in the backup from the snapshot, | 		 * when DB cluster is not contained in the backup from the snapshot, | ||||||
| 		 * DB cluster is added to the backup file list from non-snapshot. | 		 * DB cluster is added to the backup file list from non-snapshot. | ||||||
| @@ -315,10 +293,6 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt) | |||||||
| 		/* create file list of non-snapshot objects */ | 		/* create file list of non-snapshot objects */ | ||||||
| 		create_file_list(files, pgdata, NULL, false); | 		create_file_list(files, pgdata, NULL, false); | ||||||
|  |  | ||||||
| 		/* mount snapshot volume to file-system, and obtain that mounted directory */ |  | ||||||
| 		if (!check) |  | ||||||
| 			execute_mount(tblspcmp_list); |  | ||||||
|  |  | ||||||
| 		/* backup files from snapshot volume */ | 		/* backup files from snapshot volume */ | ||||||
| 		for (i = 0; i < parray_num(tblspcmp_list); i++) | 		for (i = 0; i < parray_num(tblspcmp_list); i++) | ||||||
| 		{ | 		{ | ||||||
| @@ -414,17 +388,7 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt) | |||||||
| 		parray_walk(tblspcmp_list, free); | 		parray_walk(tblspcmp_list, free); | ||||||
| 		parray_free(tblspcmp_list); | 		parray_free(tblspcmp_list); | ||||||
|  |  | ||||||
| 		/* snapshot became unnecessary, annul the snapshot */ |  | ||||||
| 		if (!check) |  | ||||||
| 		{ |  | ||||||
| 			/* unmount directory of mounted snapshot volume */ |  | ||||||
| 			execute_umount(); |  | ||||||
| 			/* annul the snapshot */ |  | ||||||
| 			execute_resync(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		/* unset the error processing for the snapshot */ |  | ||||||
| 		pgut_atexit_pop(snapshot_cleanup, cleanup_list); |  | ||||||
| 		/* don't use 'parray_walk'. element of parray not allocate memory by malloc */ | 		/* don't use 'parray_walk'. element of parray not allocate memory by malloc */ | ||||||
| 		parray_free(cleanup_list); | 		parray_free(cleanup_list); | ||||||
| 		PQclear(tblspc_res); | 		PQclear(tblspc_res); | ||||||
| @@ -1557,200 +1521,6 @@ delete_arclog_link(void) | |||||||
| 	parray_free(files); | 	parray_free(files); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'freeze' of snapshot-script. |  | ||||||
|  * When the command ends normally, 'unfreeze' is added to the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_freeze(void) |  | ||||||
| { |  | ||||||
| 	/* append 'unfreeze' command to cleanup list */ |  | ||||||
| 	parray_append(cleanup_list, SNAPSHOT_UNFREEZE); |  | ||||||
|  |  | ||||||
| 	/* execute 'freeze' command */ |  | ||||||
| 	execute_script(SNAPSHOT_FREEZE, false, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'unfreeze' of snapshot-script. |  | ||||||
|  * Remove 'unfreeze' from the cleanup list before executing the command |  | ||||||
|  * when 'unfreeze' is included in the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_unfreeze(void) |  | ||||||
| { |  | ||||||
| 	int	i; |  | ||||||
|  |  | ||||||
| 	/* remove 'unfreeze' command from cleanup list */ |  | ||||||
| 	for (i = 0; i < parray_num(cleanup_list); i++) |  | ||||||
| 	{ |  | ||||||
| 		char	*mode; |  | ||||||
|  |  | ||||||
| 		mode = (char *) parray_get(cleanup_list, i); |  | ||||||
| 		if (strcmp(mode,SNAPSHOT_UNFREEZE) == 0) |  | ||||||
| 		{ |  | ||||||
| 			parray_remove(cleanup_list, i); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	/* execute 'unfreeze' command */ |  | ||||||
| 	execute_script(SNAPSHOT_UNFREEZE, false, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'split' of snapshot-script. |  | ||||||
|  * When the command ends normally, 'resync' is added to the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_split(parray *tblspc_list) |  | ||||||
| { |  | ||||||
| 	/* append 'resync' command to cleanup list */ |  | ||||||
| 	parray_append(cleanup_list, SNAPSHOT_RESYNC); |  | ||||||
|  |  | ||||||
| 	/* execute 'split' command */ |  | ||||||
| 	execute_script(SNAPSHOT_SPLIT, false, tblspc_list); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'resync' of snapshot-script. |  | ||||||
|  * Remove 'resync' from the cleanup list before executing the command |  | ||||||
|  * when 'resync' is included in the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_resync(void) |  | ||||||
| { |  | ||||||
| 	int	i; |  | ||||||
|  |  | ||||||
| 	/* remove 'resync' command from cleanup list */ |  | ||||||
| 	for (i = 0; i < parray_num(cleanup_list); i++) |  | ||||||
| 	{ |  | ||||||
| 		char *mode; |  | ||||||
|  |  | ||||||
| 		mode = (char *) parray_get(cleanup_list, i); |  | ||||||
| 		if (strcmp(mode, SNAPSHOT_RESYNC) == 0) |  | ||||||
| 		{ |  | ||||||
| 			parray_remove(cleanup_list, i); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	/* execute 'resync' command */ |  | ||||||
| 	execute_script(SNAPSHOT_RESYNC, false, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'mount' of snapshot-script. |  | ||||||
|  * When the command ends normally, 'umount' is added to the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_mount(parray *tblspcmp_list) |  | ||||||
| { |  | ||||||
| 	/* append 'umount' command to cleanup list */ |  | ||||||
| 	parray_append(cleanup_list, SNAPSHOT_UMOUNT); |  | ||||||
|  |  | ||||||
| 	/* execute 'mount' command */ |  | ||||||
| 	execute_script(SNAPSHOT_MOUNT, false, tblspcmp_list); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the command 'umount' of snapshot-script. |  | ||||||
|  * Remove 'umount' from the cleanup list before executing the command |  | ||||||
|  * when 'umount' is included in the cleanup list. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_umount(void) |  | ||||||
| { |  | ||||||
| 	int	i; |  | ||||||
|  |  | ||||||
| 	/* remove 'umount' command from cleanup list */ |  | ||||||
| 	for (i = 0; i < parray_num(cleanup_list); i++) |  | ||||||
| 	{ |  | ||||||
| 		char *mode = (char *) parray_get(cleanup_list, i); |  | ||||||
|  |  | ||||||
| 		if (strcmp(mode, SNAPSHOT_UMOUNT) == 0) |  | ||||||
| 		{ |  | ||||||
| 			parray_remove(cleanup_list, i); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	/* execute 'umount' command */ |  | ||||||
| 	execute_script(SNAPSHOT_UMOUNT, false, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Execute the snapshot-script in the specified mode. |  | ||||||
|  * A standard output of snapshot-script is stored in the array given to the parameter. |  | ||||||
|  * If is_cleanup is TRUE, processing is continued. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| execute_script(const char *mode, bool is_cleanup, parray *output) |  | ||||||
| { |  | ||||||
| 	char	 ss_script[MAXPGPATH]; |  | ||||||
| 	char	 command[1024]; |  | ||||||
| 	char	 fline[2048]; |  | ||||||
| 	int		 num; |  | ||||||
| 	FILE	*out; |  | ||||||
| 	parray	*lines; |  | ||||||
|  |  | ||||||
| 	/* obtain the path of snapshot-script. */ |  | ||||||
| 	join_path_components(ss_script, backup_path, SNAPSHOT_SCRIPT_FILE); |  | ||||||
| 	snprintf(command, sizeof(command), |  | ||||||
| 		"%s %s %s", ss_script, mode, is_cleanup ? "cleanup" : ""); |  | ||||||
|  |  | ||||||
| 	/* execute snapshot-script */ |  | ||||||
| 	out = popen(command, "r"); |  | ||||||
| 	if (out == NULL) |  | ||||||
| 		elog(ERROR_SYSTEM, _("could not execute snapshot-script: %s\n"), strerror(errno)); |  | ||||||
|  |  | ||||||
| 	/* read STDOUT and store into the array each line */ |  | ||||||
| 	lines = parray_new(); |  | ||||||
| 	while (fgets(fline, sizeof(fline), out) != NULL) |  | ||||||
| 	{ |  | ||||||
| 		/* remove line separator */ |  | ||||||
| 		if (fline[strlen(fline) - 1] == '\n') |  | ||||||
| 			fline[strlen(fline) - 1] = '\0'; |  | ||||||
| 		parray_append(lines, pgut_strdup(fline)); |  | ||||||
| 	} |  | ||||||
| 	pclose(out); |  | ||||||
|  |  | ||||||
| 	/* |  | ||||||
| 	 * status of the command is obtained from the last element of the array |  | ||||||
| 	 * if last element is not 'SUCCESS', that means ERROR. |  | ||||||
| 	 */ |  | ||||||
| 	num = parray_num(lines); |  | ||||||
| 	if (num <= 0 || strcmp((char *) parray_get(lines, num - 1), "SUCCESS") != 0) |  | ||||||
| 		elog(is_cleanup ? WARNING : ERROR_SYSTEM, _("snapshot-script failed: %s"), mode); |  | ||||||
|  |  | ||||||
| 	/* if output is not NULL, concat array. */ |  | ||||||
| 	if (output) |  | ||||||
| 	{ |  | ||||||
| 		parray_remove(lines, num -1);	/* remove last element, that is command status */ |  | ||||||
| 		parray_concat(output, lines); |  | ||||||
| 	} |  | ||||||
| 	/* if output is NULL, clear directory list */ |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		parray_walk(lines, free); |  | ||||||
| 		parray_free(lines); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  * Delete the unnecessary object created by snapshot-script. |  | ||||||
|  * The command necessary for the deletion is given from the parameter. |  | ||||||
|  * When the error occurs, this function is called. |  | ||||||
|  */ |  | ||||||
| static void |  | ||||||
| snapshot_cleanup(bool fatal, void *userdata) |  | ||||||
| { |  | ||||||
| 	parray	*cleanup_list; |  | ||||||
| 	int		 i; |  | ||||||
|  |  | ||||||
| 	/* Execute snapshot-script for cleanup */ |  | ||||||
| 	cleanup_list = (parray *) userdata; |  | ||||||
| 	for (i = parray_num(cleanup_list) - 1; i >= 0; i--) |  | ||||||
| 		execute_script((char *) parray_get(cleanup_list, i), true, NULL); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Append files to the backup list array. |  * Append files to the backup list array. | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -1,306 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| ############################################################################# |  | ||||||
| #  Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION |  | ||||||
| ############################################################################# |  | ||||||
|  |  | ||||||
| CMD_SUDO="/usr/bin/sudo" |  | ||||||
| CMD_LVCREATE="${CMD_SUDO} /usr/sbin/lvcreate" |  | ||||||
| CMD_LVREMOVE="${CMD_SUDO} /usr/sbin/lvremove" |  | ||||||
| CMD_MOUNT="${CMD_SUDO} /bin/mount" |  | ||||||
| CMD_UMOUNT="${CMD_SUDO} /bin/umount" |  | ||||||
|  |  | ||||||
| INFO=-2 |  | ||||||
| WARNING=-1 |  | ||||||
| ERROR=0 |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # Please set the information necessary for the snapshot acquisition |  | ||||||
| # to each array. |  | ||||||
| #  |  | ||||||
| # The following arrays are one sets. |  | ||||||
| #  |  | ||||||
| # SNAPSHOT_NAME .... name for snapshot volume |  | ||||||
| # SNAPSHOT_SIZE .... size to allocate for snapshot volume |  | ||||||
| # SNAPSHOT_VG ...... volume group to which logical volume to create snapshot belongs |  | ||||||
| # SNAPSHOT_LV ...... logical volume to create snapshot |  | ||||||
| # SNAPSHOT_MOUNT ... mount point to file-system of snapshot volume |  | ||||||
| #  |  | ||||||
| # increase and decrease the slot in proportion to the number of acquisition |  | ||||||
| # of snapshots. |  | ||||||
| #  |  | ||||||
| # example: |  | ||||||
| # |  | ||||||
| # SNAPSHOT_NAME[0]="snap00" |  | ||||||
| # SNAPSHOT_SIZE[0]="2G" |  | ||||||
| # SNAPSHOT_VG[0]="/dev/VolumeGroup00"  |  | ||||||
| # SNAPSHOT_LV[0]="/dev/VolumeGroup00/LogicalVolume00" |  | ||||||
| # SNAPSHOT_MOUNT[0]="/mnt/pgdata" |  | ||||||
| # |  | ||||||
| # SNAPSHOT_NAME[1]="snap01" |  | ||||||
| # SNAPSHOT_SIZE[1]="2G" |  | ||||||
| # SNAPSHOT_VG[1]="/dev/VolumeGroup00"  |  | ||||||
| # SNAPSHOT_LV[1]="/dev/VolumeGroup00/LogicalVolume01" |  | ||||||
| # SNAPSHOT_MOUNT[1]="/mnt/tblspc/account" |  | ||||||
| # |  | ||||||
| #SNAPSHOT_NAME[0]="" |  | ||||||
| #SNAPSHOT_SIZE[0]="" |  | ||||||
| #SNAPSHOT_VG[0]=""  |  | ||||||
| #SNAPSHOT_LV[0]="" |  | ||||||
| #SNAPSHOT_MOUNT[0]="" |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # Please set the tablespace name and tablespace storage path in snapshot  |  | ||||||
| # to each array. |  | ||||||
| #  |  | ||||||
| # The following arrays are one sets. |  | ||||||
| #  |  | ||||||
| # SNAPSHOT_TBLSPC ........ name of tablespace in snapshot volume |  | ||||||
| # SNAPSHOT_TBLSPC_DIR .... stored directory of tablespace in snapshot volume |  | ||||||
| # |  | ||||||
| # Note: set 'PG-DATA' to SNAPSHOT_TBLSPC when PGDATA in snapshot volume. |  | ||||||
| # |  | ||||||
| # increase and decrease the slot in proportion to the number of acquisition |  | ||||||
| # of tablespace. |  | ||||||
| #  |  | ||||||
| # example: |  | ||||||
| # |  | ||||||
| # SNAPSHOT_TBLSPC[0]="PG-DATA" |  | ||||||
| # SNAPSHOT_TBLSPC_DIR[0]="/mnt/pgdata/pgdata" |  | ||||||
| # SNAPSHOT_TBLSPC[1]="custom" |  | ||||||
| # SNAPSHOT_TBLSPC_DIR[1]="/mnt/tblspc_custom/tblspc/custom" |  | ||||||
| # SNAPSHOT_TBLSPC[2]="account" |  | ||||||
| # SNAPSHOT_TBLSPC_DIR[2]="/mnt/tblspc_account/tblspc/account" |  | ||||||
| # |  | ||||||
| #SNAPSHOT_TBLSPC[0]="" |  | ||||||
| #SNAPSHOT_TBLSPC_DIR[0]="" |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # argument of the command. |  | ||||||
| # this variables are set by set_args(). |  | ||||||
| # |  | ||||||
| ARGS_SS_NAME=""  # SNAPSHOT_NAME[N] |  | ||||||
| ARGS_SS_SIZE=""  # SNAPSHOT_SIZE[N] |  | ||||||
| ARGS_SS_VG=""    # SNAPSHOT_VG[N] |  | ||||||
| ARGS_SS_LV=""    # SNAPSHOT_LV[N] |  | ||||||
| ARGS_SS_MOUNT="" # SNAPSHOT_MOUNT[N] |  | ||||||
|  |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'freeze'. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| # |  | ||||||
| function freeze() |  | ||||||
| { |  | ||||||
| 	# nothing to do |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'unfreeze'. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| # |  | ||||||
| function unfreeze() |  | ||||||
| { |  | ||||||
| 	# nothing to do |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'split'. |  | ||||||
| # create a snapshot volume from the setting of the specified slot. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| #  |  | ||||||
| function split() |  | ||||||
| { |  | ||||||
| 	local i=0 |  | ||||||
| 	 |  | ||||||
| 	for ss_name in "${SNAPSHOT_NAME[@]}" |  | ||||||
| 	do |  | ||||||
| 		set_args "${ss_name}" "${SNAPSHOT_SIZE[${i}]}" "" "${SNAPSHOT_LV[${i}]}" "" |  | ||||||
| 		execute_split |  | ||||||
| 		i=$(expr ${i} + 1) |  | ||||||
| 	done |  | ||||||
| 	 |  | ||||||
| 	# print tablespace name |  | ||||||
| 	i=0 |  | ||||||
| 	for tblspc in "${SNAPSHOT_TBLSPC[@]}" |  | ||||||
| 	do |  | ||||||
| 		local tblspc="${SNAPSHOT_TBLSPC[${i}]}" |  | ||||||
| 		 |  | ||||||
| 		echo "${tblspc}" |  | ||||||
| 		i=$(expr ${i} + 1) |  | ||||||
| 	done |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'resync'. |  | ||||||
| # remove a snapshot volume from the setting of the specified slot. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| # |  | ||||||
| function resync() |  | ||||||
| { |  | ||||||
| 	local i=0 |  | ||||||
| 	 |  | ||||||
| 	for ss_name in "${SNAPSHOT_NAME[@]}" |  | ||||||
| 	do |  | ||||||
| 		set_args "${ss_name}" "" "${SNAPSHOT_VG[${i}]}" "" "" |  | ||||||
| 		execute_resync |  | ||||||
| 		i=$(expr ${i} + 1) |  | ||||||
| 	done |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'mount'. |  | ||||||
| # create mount point of the snapshot volume to the file-system. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| # |  | ||||||
| function mount() |  | ||||||
| { |  | ||||||
| 	local i=0 |  | ||||||
| 	 |  | ||||||
| 	for ss_name in "${SNAPSHOT_NAME[@]}" |  | ||||||
| 	do |  | ||||||
| 		set_args "${ss_name}" "" "${SNAPSHOT_VG[${i}]}" "" "${SNAPSHOT_MOUNT[${i}]}" |  | ||||||
| 		execute_mount |  | ||||||
| 		i=$(expr ${i} + 1) |  | ||||||
| 	done |  | ||||||
| 	 |  | ||||||
| 	# print tablespace name and stored directory |  | ||||||
| 	i=0 |  | ||||||
| 	for tblspc in "${SNAPSHOT_TBLSPC[@]}" |  | ||||||
| 	do |  | ||||||
| 		local tblspc_mp="${SNAPSHOT_TBLSPC_DIR[${i}]}" |  | ||||||
| 		 |  | ||||||
| 		echo "${tblspc}=${tblspc_mp}" |  | ||||||
| 		i=$(expr ${i} + 1) |  | ||||||
| 	done |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # implement of interface 'umount'. |  | ||||||
| # remove mount point of the snapshot volume from the file-system. |  | ||||||
| # don't remove this function even if there is no necessity. |  | ||||||
| # |  | ||||||
| function umount() |  | ||||||
| { |  | ||||||
| 	for ss_mp in "${SNAPSHOT_MOUNT[@]}" |  | ||||||
| 	do |  | ||||||
| 		set_args "" "" "" "" "${ss_mp}" |  | ||||||
| 		execute_umount |  | ||||||
| 	done |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # create the snapshot volume. |  | ||||||
| # |  | ||||||
| function execute_split() |  | ||||||
| { |  | ||||||
| 	${CMD_LVCREATE} --snapshot --size=${ARGS_SS_SIZE} --name="${ARGS_SS_NAME}" "${ARGS_SS_LV}" > /dev/null |  | ||||||
| 	[ ${?} -ne 0 ] && \ |  | ||||||
| 		print_log ${ERROR} "${CMD_LVCREATE} command failed: ${ARGS_SS_LV}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # remove the snapshot volume. |  | ||||||
| # |  | ||||||
| function execute_resync() |  | ||||||
| { |  | ||||||
| 	${CMD_LVREMOVE} -f "${ARGS_SS_VG}/${ARGS_SS_NAME}" > /dev/null |  | ||||||
| 	[ ${?} -ne 0 ] && \ |  | ||||||
| 		print_log ${ERROR} "${CMD_LVREMOVE} command failed: ${ARGS_SS_VG}/${ARGS_SS_NAME}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # mount the snapshot volume to file-system. |  | ||||||
| # |  | ||||||
| function execute_mount() |  | ||||||
| { |  | ||||||
| 	${CMD_MOUNT} "${ARGS_SS_VG}/${ARGS_SS_NAME}" "${ARGS_SS_MOUNT}" > /dev/null |  | ||||||
| 	[ ${?} -ne 0 ] && \ |  | ||||||
| 		print_log ${ERROR} "${CMD_MOUNT} command failed: ${ARGS_SS_MOUNT}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # unmount the directory from file-system in snapshot volume. |  | ||||||
| # |  | ||||||
| function execute_umount() |  | ||||||
| { |  | ||||||
| 	${CMD_UMOUNT} "${ARGS_SS_MOUNT}" > /dev/null |  | ||||||
| 	[ ${?} -ne 0 ] && \ |  | ||||||
| 		print_log ${ERROR} "${CMD_UMOUNT} command failed: ${ARGS_SS_MOUNT}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # set argument of command to execute. |  | ||||||
| # |  | ||||||
| set_args() |  | ||||||
| { |  | ||||||
| 	ARGS_SS_NAME="${1}" |  | ||||||
| 	ARGS_SS_SIZE="${2}" |  | ||||||
| 	ARGS_SS_VG="${3}" |  | ||||||
| 	ARGS_SS_LV="${4}" |  | ||||||
| 	ARGS_SS_MOUNT="${5}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # output the log message and abort the script when level <= ERROR |  | ||||||
| # |  | ||||||
| function print_log() |  | ||||||
| { |  | ||||||
| 	local level="${1}" |  | ||||||
| 	local message="${2}" |  | ||||||
| 	 |  | ||||||
| 	# if cleanup enable change ERROR to WARNING |  | ||||||
| 	[ -n "${cleanup}" -a ${level} -ge 0 ] && \ |  | ||||||
| 		level=${WARNING} |  | ||||||
| 	 |  | ||||||
| 	case "${level}" in |  | ||||||
| 		${INFO} ) # INFO |  | ||||||
| 			echo "INFO: ${message}" 1>&2 |  | ||||||
| 		;; |  | ||||||
| 		${WARNING} ) # WARNING |  | ||||||
| 			echo "WARNING: ${message}" 1>&2 |  | ||||||
| 		;; |  | ||||||
| 		${ERROR} ) # ERROR |  | ||||||
| 			echo "ERROR: ${message}" 1>&2 |  | ||||||
| 		;; |  | ||||||
| 	esac |  | ||||||
| 	[ ${level} -ge 0 ] && exit |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # main |  | ||||||
| # |  | ||||||
| command="${1}" |  | ||||||
| cleanup="${2}" |  | ||||||
|  |  | ||||||
| case "${command}" in |  | ||||||
| 	"freeze" ) |  | ||||||
| 		freeze |  | ||||||
| 	;; |  | ||||||
| 	"unfreeze" ) |  | ||||||
| 		unfreeze |  | ||||||
| 	;; |  | ||||||
| 	"split" ) |  | ||||||
| 		split |  | ||||||
| 	;; |  | ||||||
| 	"resync" ) |  | ||||||
| 		resync |  | ||||||
| 	;; |  | ||||||
| 	"mount" ) |  | ||||||
| 		mount |  | ||||||
| 	;; |  | ||||||
| 	"umount" ) |  | ||||||
| 		umount |  | ||||||
| 	;; |  | ||||||
| 	* ) |  | ||||||
| 		print_log ${ERROR} "specified invalid command: ${command} (internal error)" |  | ||||||
| 	;; |  | ||||||
| esac |  | ||||||
|  |  | ||||||
| echo "SUCCESS" |  | ||||||
| exit |  | ||||||
		Reference in New Issue
	
	Block a user