1#!/bin/sh
2
3## $FreeBSD$
4## Created by: Miroslav Lachman <000.fbsd@quip.cz>
5
6## Backup of disk partitions layout, useful for gpart restore.
7## Data are stored on local filesystem, in /var/backup.
8## It is recommended to copy those files to off-site storage.
9
10
11## If there is a global system configuration file, suck it in.
12##
13if [ -r /etc/defaults/periodic.conf ]
14then
15	. /etc/defaults/periodic.conf
16	source_periodic_confs
17fi
18
19bak_dir=/var/backups
20
21rotate() {
22	base_name=$1
23	show_diff=$2
24	file="$bak_dir/$base_name"
25
26	if [ -f "${file}.bak" ] ; then
27		rc=0
28		if cmp -s "${file}.bak" "${file}.tmp"; then
29			rm "${file}.tmp"
30		else
31			rc=1
32			[ -n "$show_diff" ] && diff "${file}.bak" "${file}.tmp"
33			mv "${file}.bak" "${file}.bak2" || rc=3
34			mv "${file}.tmp" "${file}.bak" || rc=3
35		fi
36	else
37		rc=1
38		mv "${file}.tmp" "${file}.bak" || rc=3
39		[ -n "$show_diff" ] && cat "${file}.bak"
40	fi
41}
42
43case "$daily_backup_gpart_verbose" in
44	[Yy][Ee][Ss]) show="YES"
45esac
46
47case "$daily_backup_gpart_enable" in
48	[Yy][Ee][Ss])
49
50	echo ""
51	echo "Dump of kern.geom.conftxt:";
52	sysctl -n kern.geom.conftxt > "$bak_dir/kern.geom.conftxt.tmp"
53	rotate "kern.geom.conftxt" $show
54
55	gpart_devs=$(gpart show | awk '$1 == "=>" { print $4 }')
56	if [ -n "$daily_backup_gpart_exclude" ]; then
57		gpart_devs=$(echo "${gpart_devs}" | grep -E -v "${daily_backup_gpart_exclude}")
58	fi
59
60	if [ -z "$gpart_devs"  ]; then
61		echo '$daily_backup_gpart_enable is set but no disk probed by kernel.' \
62		"perhaps NFS diskless client."
63		rc=2
64	else
65		echo ""
66		echo "Backup of partitions information for:";
67
68		for d in ${gpart_devs}; do
69			echo "$d"
70			safe_name=$(echo "gpart.${d}" | tr -cs ".[:alnum:]\n" "_")
71			gpart backup "$d" > "$bak_dir/$safe_name.tmp"
72			rotate "$safe_name" $show
73		done
74
75		gpart_show=$(gpart show -p)
76		boot_part=$(echo "$gpart_show" | awk '$4 ~ /(bios|freebsd)-boot/ { print $3 }')
77		if [ -n "$boot_part" ]; then
78			echo ""
79			echo "Backup of boot partition content:"
80			for b in ${boot_part}; do
81				echo "$b"
82				safe_name=$(echo "boot.${b}" | tr -cs ".[:alnum:]\n" "_")
83				dd if="/dev/${b}" of="$bak_dir/$safe_name.tmp" 2> /dev/null
84				rotate "$safe_name"
85			done
86		fi
87
88		mbr_part=$(echo "$gpart_show" | awk '$1 == "=>" && $5 == "MBR" { print $4 }')
89		if [ -n "$mbr_part" ]; then
90			echo ""
91			echo "Backup of MBR record:"
92			for mb in ${mbr_part}; do
93				echo "$mb"
94				safe_name=$(echo "boot.${mb}" | tr -cs ".[:alnum:]\n" "_")
95				dd if="/dev/${mb}" of="$bak_dir/$safe_name.tmp" bs=512 count=1 2> /dev/null
96				rotate "$safe_name"
97			done
98		fi
99
100	fi
101	;;
102
103	*)  rc=0
104	;;
105esac
106
107case "$daily_backup_efi_enable" in
108    [Yy][Ee][Ss])
109
110    efi_part=$(gpart show -p | awk '$4 ~ /efi/ {print $3}')
111    if [ -n "$efi_part" ]; then
112        echo ""
113        echo "Backup of EFI partition content:"
114        for efi in ${efi_part}; do
115            echo "$efi"
116            safe_name=$(echo "efi.${efi}" | tr -cs ".[:alnum:]\n" "_")
117            dd if="/dev/${efi}" of="$bak_dir/$safe_name.tmp" 2> /dev/null
118            rotate "$safe_name"
119        done
120    fi
121    ;;
122esac
123
124exit $rc
125