HEX
Server: Apache/2.2.34 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141
System: Linux Kou-Etsu-Dou 4.4.59+ #25556 SMP PREEMPT Thu Mar 4 18:03:46 CST 2021 x86_64
User: hosam (1026)
PHP: 7.2.29
Disabled: NONE
Upload Files
File: //usr/syno/bin/synospace.sh
#!/bin/sh
#
# Synology space utility.
#
# Copyright (c) 2003-2013 Synology Inc. All rights reserved.
#
# Support to parse synology space*.xml and generate the correspond
# mdadm rebuild command, ref: <DSM> #45470.

Usage()
{
	echo "Copyright (c) 2003-2013 Synology Inc. All rights reserved."
	echo
	echo "Usage: $CMD [OPTIONS] [FILES]"
	echo
	echo "Option:"
	echo "    -p,--parse        Parse the space.xml to generate the correspond mdadm command."
	echo
}

getToken()
{
	awk '/<raid/,/raid>/' $1 | \
	awk '
	BEGIN { numRaid=0; }
	{
		if ("<raid" == $1) {
			for (i=2; i<=NF; i++) {
				if ("path=" == substr($i, 0, 5)) {
					if (0 != numRaid) {
						printf "END %d\n", numRaid;
					}

					numRaid++;
					printf "BEGIN %d\n", numRaid;
					printf "%s \"%d\"\n", $i, -2;
				}
				if ("level=" == substr($i, 0, 6)) {
					printf "%s \"%d\"\n", $i, -1;
				}
			}
		}
		if ("<disk" == $1) {
			path="";
			slot=-999;
			for (i=2; i<=NF; i++) {
				if ("dev_path=" == substr($i, 0, 9)) {
					path=$i;
				}
				if ("slot=" == substr($i, 0, 5)) {
					slot=$i;
				}
			}
			printf "%s %s\n", path, slot;
		}
	}
	END { printf "END %d\n", numRaid; }'
}

sortToken()
{
	echo "$@" | \
	sort -t '"' -k 4 -n | cut -d ' ' -f 1
}

blockToken()
{
	local block=""
	local numBlock=0
	echo "$@" | while read line; do
		if [ "BEGIN" == "`echo $line | head -c5`" ]; then
			block=""
			numBlock=`echo $line | cut -d' ' -f2`
		elif [ "END" == "`echo $line | head -c3`" ]; then
			output=`echo -e "$block"`
			echo ======= block token $numBlock  >&2
			echo "$output"                      >&2
			output=$(sortToken "$output")
			echo ======= sorted token $numBlock >&2
			echo "$output"                      >&2
			# real return
			echo "$output"
		else
			block="$block$line\n"
		fi
	done
}

assembleCMD()
{
	echo "$@" | \
	awk -F'"' '
	# for syntax escape"
	function output() {
		printf "%s -n %d --assume-clean %s\n", cmd, numDisk, disks;
	}
	# Check device exist or not
	# 0: exist
	# 1: not exist
	function exists(device) {
		line=0;
		if ((getline line < device) > 0) {
			return 0;
		}
		return 1;
	}

	BEGIN{ cmd=""; }
	{
		if ("path=" == $1) {
			if ("" != cmd) {		# handle previous raid section
				output();
			}

			# Initial all vars.
			numDisk=0; disks="";
			cmd="mdadm -C " $2 " -R ";
		}
		if ("level=" == $1) {
			cmd=cmd "-l " $2;
		}
		if ("dev_path=" == $1) {
			numDisk++;
			if (0 == exists($2)) {
				disks = disks $2 " ";
			} else {
				disks = disks "missing ";
			}
		}
	}
	END{ output(); }'
}

ParseXML()
{
	echo "========= get token"    >&2
	tok=$(getToken "$1")

	echo "$tok"                   >&2
	btok=$(blockToken "$tok")

	echo "========= asm command"  >&2
	cmd=$(assembleCMD "$btok")

	echo "$cmd"
}

CMD=$(basename "$0")
ARGS=`getopt -o "p:" -l "parse:" -n "$CMD" -- "$@"`

if [ $? -ne 0 -o $# -eq 0 ]; then
	Usage
	exit 1
fi


doParse=""
xmlFile=""
while [ -n "$1" ]; do
	case "$1" in
	-p | --parse)
		doParse=true
		xmlFile="$2"
		shift
		shift
		continue;;
	*)
		Usage
		exit 1;;
	esac
done

if [ -n "$doParse" ] ; then
	if [ -f $xmlFile -a -r $xmlFile ] ; then
		# turn on/off debug info
		exec 2>/dev/null
		ParseXML $xmlFile
	else
		echo "Error: File $xmlFile read failed."
		exit 1
	fi
fi

exit 0