Project

General

Profile

Download (4.73 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/bin/sh
2
#-
3
# Copyright (c) 2017 Rubicon Communications, LLC
4
# All rights reserved.
5
#
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions
8
# are met:
9
# 1. Redistributions of source code must retain the above copyright
10
#    notice, this list of conditions and the following disclaimer.
11
# 2. Redistributions in binary form must reproduce the above copyright
12
#    notice, this list of conditions and the following disclaimer in the
13
#    documentation and/or other materials provided with the distribution.
14
#
15
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
# SUCH DAMAGE.
26
#
27
# $FreeBSD$
28

    
29
# Recover config.xml
30
# 
31
# in freebsd-src repo, usr.sbin/bsdinstall/scripts/auto
32
# - Add line to call file which will copy recovered config.xml
33

    
34
# Create a mount point and a place to store the recovered configuration
35
recovery_mount=/tmp/mnt_recovery
36
recovery_dir=/tmp/recovered_config
37
mkdir -p ${recovery_mount}
38
mkdir -p ${recovery_dir}
39

    
40
# Find list of potential target disks, which must be FreeBSD and either UFS or ZFS
41
target_disks=`/sbin/gpart show -p | /usr/bin/awk '/(freebsd-ufs|freebsd-zfs)/ {print $3;}'`
42

    
43
target_list=""
44
for try_device in ${target_disks} ; do
45
	# Add filesystem details (type and size)
46
	fs_details="`/sbin/gpart show -p | /usr/bin/grep \"[[:space:]]${try_device}[[:space:]]\" | /usr/bin/awk '{print $4, $5;}'`"
47

    
48
	# Add this disk to the list of potential targets
49
	target_list="${target_list} \"${try_device}\" \"${fs_details}\""
50
done
51

    
52
# Display a menu with all of the disk choices located above
53
if [ -n "${target_list}" ]; then
54
	exec 3>&1
55
	recover_disk_choice=`echo ${target_list} | xargs dialog --backtitle "pfSense Installer" \
56
		--title "Recover config.xml" \
57
		--menu "Select the partition containing config.xml" \
58
		0 0 0 2>&1 1>&3` || exit 1
59
	exec 3>&-
60
else
61
	echo "No suitable disk partitions found."
62
fi
63

    
64
recover_disk=${recover_disk_choice}
65

    
66
# If the user made a choice, try to recover
67
if [ -n "${recover_disk}" ] ; then
68
	# Find the filesystem type of the selected partition
69
	fs_type="`/sbin/gpart show -p | /usr/bin/grep \"[[:space:]]${recover_disk}[[:space:]]\" | /usr/bin/awk '{print $4;}'`"
70
	# Remove "freebsd-", leaving us with either "ufs" or "zfs".
71
	fs_type=${fs_type#freebsd-}
72

    
73
	echo "Attempting to recover config.xml from ${recover_disk}."
74
	if [ "${fs_type}" == "ufs" ]; then
75
		# UFS Recovery, attempt to mount but also attempt cleanup if it fails.
76

    
77
		mount_command="/sbin/mount -t ${fs_type} /dev/${recover_disk} ${recovery_mount}"
78
		${mount_command} 2>/dev/null
79
		mount_rc=$?
80
		attempts=0
81

    
82
		# Try to run fsck up to 10 times and remount, in case the parition is dirty and needs cleanup
83
		while [ ${mount_rc} -ne 0 -a ${attempts} -lt 10 ]; do
84
			echo "Unable to mount ${recover_disk}, running a disk check and retrying."
85
			/sbin/fsck -y -t ${fs_type} ${recover_disk}
86
			${mount_command} 2>/dev/null
87
			mount_rc=$?
88
			attempts=$((attempts+1))
89
		done
90
		if [ ${mount_rc} -ne 0 ]; then
91
			echo "Unable to mount ${recover_disk} for config.xml recovery."
92
			exit 1
93
		fi
94
	else
95
		# ZFS Recovery works different than UFS, needs special handling
96
		if [ "${fs_type}" == "zfs" ]; then
97
			# Load KLD for ZFS support
98
			/sbin/kldload zfs
99
			# Import pool (name=zroot) with alternate mount
100
			/sbin/zpool import -R ${recovery_mount} -f zroot
101
			# Mount the default root directory of the previous install
102
			/sbin/mount -t zfs zroot/ROOT/default ${recovery_mount}
103
		fi
104
	fi
105

    
106
	# In either FS type case, the previous root is now mounted under ${recovery_mount}, so check for a config
107
	if [ -r ${recovery_mount}/cf/conf/config.xml -a -s ${recovery_mount}/cf/conf/config.xml ]; then
108
		/bin/cp ${recovery_mount}/cf/conf/config.xml ${recovery_dir}/config.xml
109
		echo "Recovered config.xml from ${recover_disk}, stored in ${recovery_dir}."
110
	else
111
		echo "${recover_disk} does not contain a readable config.xml for recovery."
112
		exit 1
113
	fi
114

    
115
	# Cleanup. Unmount the disk partition.
116
	/sbin/umount ${recovery_mount}
117

    
118
	# ZFS cleanup, export the pool and then unload ZFS KLD.
119
	if [ "${fs_type}" == "zfs" ]; then
120
		/sbin/zpool export -f zroot
121
		/sbin/kldunload zfs
122
	fi
123
fi
    (1-1/1)