-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfactory_reset.sh
161 lines (144 loc) · 4.77 KB
/
factory_reset.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/bin/sh
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This runs from the factory install/reset shim. This MUST be run
# from USB, in developer mode. This script will wipe OQC activity and
# put the system back into factory fresh/shippable state.
# Preserve files in the CRX cache. Largely copied from clobber-state.
# TODO(dgarrett,jsalz): Consolidate.
#
. "/usr/share/misc/chromeos-common.sh"
. "$(dirname "$0")/factory_common.sh"
. "$(dirname "$0")/secure-wipe.sh"
# CUTOFF_DIR is provided from platform/factory/sh/cutoff, repacked by ebuild.
CUTOFF_DIR="/usr/share/cutoff"
CUTOFF_SCRIPT="${CUTOFF_DIR}/cutoff.sh"
INFORM_SHOPFLOOR_SCRIPT="${CUTOFF_DIR}/inform_shopfloor.sh"
usage() {
echo "Usage: $0 disk [wipe|secure|verify]."
echo "disk: device to operate on [for instance /dev/sda]"
echo "If no argument, do a factory reset. Otherwise:"
echo "wipe: write 0's on every LBA [backward compatibility]"
echo "secure: use internal erase command in the device"
echo " and write a pattern on the disk"
echo "verify: verify the disk has been erased properly"
exit 1
}
# Note that some variables are shared with restore_crx_cache.
preserve_crx_cache() {
PRESERVED_TAR="/tmp/preserve.tar"
PRESERVED_FILES=""
STATE_PATH="/mnt/stateful_partition"
mkdir -p "${STATE_PATH}"
mount "${STATE_DEV}" "${STATE_PATH}"
IMPORT_FILES="$(cd ${STATE_PATH};
echo unencrypted/import_extensions/extensions/*.crx)"
if [ "${IMPORT_FILES}" != \
"unencrypted/import_extensions/extensions/*.crx" ]; then
PRESERVED_FILES="${PRESERVED_FILES} ${IMPORT_FILES}"
fi
PRESERVED_LIST=""
if [ -n "${PRESERVED_FILES}" ]; then
# We want to preserve permissions and recreate the directory structure
# for all of the files in the PRESERVED_FILES variable. In order to do
# so we run tar --no-recurison and specify the names of each of the
# parent directories. For example for home/.shadow/install_attributes.pb
# we pass to tar home home/.shadow home/.shadow/install_attributes.pb
for file in ${PRESERVED_FILES}; do
if [ ! -e "${STATE_PATH}/${file}" ]; then
continue
fi
path="${file}"
while [ "${path}" != '.' ]; do
PRESERVED_LIST="${path} ${PRESERVED_LIST}"
path=$(dirname "${path}")
done
done
tar cf ${PRESERVED_TAR} -C ${STATE_PATH} --no-recursion -- ${PRESERVED_LIST}
fi
# Try a few times to unmount the stateful partition.
local unmounted=false
for i in $(seq 5); do
if umount ${STATE_DEV}; then
unmounted=true
break
fi
sleep 1
done
if ! ${unmounted}; then
# Bail out: we may not be able to successfully mkfs.
echo "Unable to unmount stateful partition. Aborting."
exit 1
fi
}
# Restores files previously preserved by preserve_crx_cache.
restore_crx_cache() {
if [ -n "${PRESERVED_LIST}" ]; then
# Copy files back to stateful partition
mount ${STATE_DEV} ${STATE_PATH}
tar xfp ${PRESERVED_TAR} -C ${STATE_PATH}
sync # Try as best we can, in case umount fails
umount ${STATE_PATH}
# Sleep for a bit, since we will shut down soon and want to give
# the drive a chance to flush everything
sleep 3
fi
}
do_cutoff() {
# inform_shopfloor will load shopfloor URL from lsb-factory, and ignore the
# request if SHOPFLOOR_URL is not set.
"${INFORM_SHOPFLOOR_SCRIPT}" "" "factory_reset" || exit 1
"${CUTOFF_SCRIPT}"
}
main() {
if [ "$#" -lt 1 ]; then
usage
fi
DEV="$1"
if [ ! -b "${DEV}" ]; then
echo "Invalid root disk ${DEV}."
exit 1
fi
STATE_DEV=$(make_partition_dev "${DEV}" "1")
DEV_SIZE=$(blockdev --getsize64 "${DEV}")
shift
# Tcsd will bring up the tpm and de-own it,
# as we are in developer/recovery mode.
start tcsd || true
if [ $# -eq 1 ]; then
case "$1" in
wipe)
# Nuke the disk.
pv -etpr -s ${DEV_SIZE} -B 8M /dev/zero |
dd bs=8M of="${DEV}" oflag=dsync iflag=fullblock
;;
secure)
# Erase using firmware feature first.
secure_erase ${DEV} || exit 1
perform_fio_op "${DEV}" "${DEV_SIZE}" "write" || exit 1
;;
verify)
perform_fio_op "${DEV}" "${DEV_SIZE}" "verify" || exit 1
;;
*)
usage
esac
else
echo "Factory reset"
if [ ! -b "${STATE_DEV}" ]; then
echo "Failed to find stateful partition."
exit 1
fi
# TODO(hungte) This should do same thing as what clobber-state did.
preserve_crx_cache
# Just wipe the start of the partition and remake the fs on
# the stateful partition.
dd bs=4M count=1 if=/dev/zero of=${STATE_DEV}
/sbin/mkfs.ext4 "${STATE_DEV}"
restore_crx_cache
fi
do_cutoff
echo "Done"
}
main "$@"