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 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 int strCompare(const void *str1, const void *str2); | ||||
| 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 */ | ||||
| 		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, | ||||
| 		 * 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(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 */ | ||||
| 		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_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 */ | ||||
| 		parray_free(cleanup_list); | ||||
| 		PQclear(tblspc_res); | ||||
| @@ -1557,200 +1521,6 @@ delete_arclog_link(void) | ||||
| 	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. | ||||
|  */ | ||||
|   | ||||
| @@ -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