Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(432)

Side by Side Diff: scripts/image_signing/common.sh

Issue 6294002: Split common.sh into bash-only and dash-only sections (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: change resign_firmwarefd to only use dashisms Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | scripts/image_signing/common_minimal.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/bash 1 #!/bin/bash
2 2 #
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 3 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 # Globals 7 . "$(dirname "$0")/common_minimal.sh"
8 # ----------------------------------------------------------------------------
9
10 # Determine script directory
11 SCRIPT_DIR=$(dirname $0)
12 PROG=$(basename $0)
13 GPT=cgpt
14
15 # The tag when the rootfs is changed.
16 TAG_NEEDS_TO_BE_SIGNED="/root/.need_to_be_signed"
17
18 # List of Temporary files and mount points.
19 TEMP_FILE_LIST=$(mktemp)
20 TEMP_DIR_LIST=$(mktemp)
21 8
22 # Array of actions that are executed during the clean up process. 9 # Array of actions that are executed during the clean up process.
23 declare -a cleanup_actions 10 declare -a cleanup_actions
24 11
25 # Adds an action to be executed during the clean up process. 12 # Adds an action to be executed during the clean up process.
26 # Actions are executed in the reverse order of when they were added. 13 # Actions are executed in the reverse order of when they were added.
27 # ARGS: ACTION 14 # ARGS: ACTION
28 add_cleanup_action() { 15 add_cleanup_action() {
29 cleanup_actions[${#cleanup_actions[*]}]=$1 16 cleanup_actions[${#cleanup_actions[*]}]=$1
30 } 17 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 68 }
82 69
83 # Prints an error message and exit with an error code. 70 # Prints an error message and exit with an error code.
84 # Taken from src/scripts/common.sh. 71 # Taken from src/scripts/common.sh.
85 # Args: MESSAGE 72 # Args: MESSAGE
86 die() { 73 die() {
87 error "$1" 74 error "$1"
88 exit 1 75 exit 1
89 } 76 }
90 77
91 # Finds and loads the 'shflags' library, or return as failed. 78 # This will override the trap set in common_minmal.sh
92 load_shflags() {
93 # Load shflags
94 if [ -f /usr/lib/shflags ]; then
95 . /usr/lib/shflags
96 elif [ -f "${SCRIPT_DIR}/shflags" ]; then
97 . "${SCRIPT_DIR}/shflags"
98 elif [ -f "${SCRIPT_DIR}/lib/shflags/shflags" ]; then
99 . "${SCRIPT_DIR}/lib/shflags/shflags"
100 else
101 echo "ERROR: Cannot find the required shflags library."
102 return 1
103 fi
104
105 # Add debug option for debug output below
106 DEFINE_boolean debug $FLAGS_FALSE "Provide debug messages" "d"
107 }
108
109 # Functions for debug output
110 # ----------------------------------------------------------------------------
111
112 # Reports error message and exit(1)
113 # Args: error message
114 err_die() {
115 echo "ERROR: $*" 1>&2
116 exit 1
117 }
118
119 # Returns true if we're running in debug mode.
120 #
121 # Note that if you don't set up shflags by calling load_shflags(), you
122 # must set $FLAGS_debug and $FLAGS_TRUE yourself. The default
123 # behavior is that debug will be off if you define neither $FLAGS_TRUE
124 # nor $FLAGS_debug.
125 is_debug_mode() {
126 [ "${FLAGS_debug:-not$FLAGS_TRUE}" = "$FLAGS_TRUE" ]
127 }
128
129 # Prints messages (in parameters) in debug mode
130 # Args: debug message
131 debug_msg() {
132 if is_debug_mode; then
133 echo "DEBUG: $*" 1>&2
134 fi
135 }
136
137 # Functions for temporary files and directories
138 # ----------------------------------------------------------------------------
139
140 # Create a new temporary file and return its name.
141 # File is automatically cleaned when cleanup_temps_and_mounts() is called.
142 make_temp_file() {
143 local tempfile=$(mktemp)
144 echo "$tempfile" >> $TEMP_FILE_LIST
145 echo $tempfile
146 }
147
148 # Create a new temporary directory and return its name.
149 # Directory is automatically deleted and any filesystem mounted on it unmounted
150 # when cleanup_temps_and_mounts() is called.
151 make_temp_dir() {
152 local tempdir=$(mktemp -d)
153 echo "$tempdir" >> $TEMP_DIR_LIST
154 echo $tempdir
155 }
156
157 cleanup_temps_and_mounts() {
158 for i in $(cat $TEMP_FILE_LIST); do
159 rm -f $i
160 done
161 set +e # umount may fail for unmounted directories
162 for i in $(cat $TEMP_DIR_LIST); do
163 if [ -n "$i" ]; then
164 if has_needs_to_be_resigned_tag "$i"; then
165 echo "Warning: image may be modified. Please resign image."
166 fi
167 sudo umount -d $i 2>/dev/null
168 rm -rf $i
169 fi
170 done
171 set -e
172 rm -rf $TEMP_DIR_LIST $TEMP_FILE_LIST
173 }
174
175 trap "cleanup_temps_and_mounts" EXIT
176
177 # Functions for partition management
178 # ----------------------------------------------------------------------------
179
180 # Read GPT table to find the starting location of a specific partition.
181 # Args: DEVICE PARTNUM
182 # Returns: offset (in sectors) of partition PARTNUM
183 partoffset() {
184 sudo $GPT show -b -i $2 $1
185 }
186
187 # Read GPT table to find the size of a specific partition.
188 # Args: DEVICE PARTNUM
189 # Returns: size (in sectors) of partition PARTNUM
190 partsize() {
191 sudo $GPT show -s -i $2 $1
192 }
193
194 # Tags a file system as "needs to be resigned".
195 # Args: MOUNTDIRECTORY
196 tag_as_needs_to_be_resigned() {
197 local mount_dir="$1"
198 sudo touch "$mount_dir/$TAG_NEEDS_TO_BE_SIGNED"
199 }
200
201 # Determines if the target file system has the tag for resign
202 # Args: MOUNTDIRECTORY
203 # Returns: true if the tag is there otherwise false
204 has_needs_to_be_resigned_tag() {
205 local mount_dir="$1"
206 [ -f "$mount_dir/$TAG_NEEDS_TO_BE_SIGNED" ]
207 }
208
209 # Determines if the target file system is a Chrome OS root fs
210 # Args: MOUNTDIRECTORY
211 # Returns: true if MOUNTDIRECTORY looks like root fs, otherwise false
212 is_rootfs_partition() {
213 local mount_dir="$1"
214 [ -f "$mount_dir/$(dirname "$TAG_NEEDS_TO_BE_SIGNED")" ]
215 }
216
217 # Mount a partition read-only from an image into a local directory
218 # Args: IMAGE PARTNUM MOUNTDIRECTORY
219 mount_image_partition_ro() {
220 local image=$1
221 local partnum=$2
222 local mount_dir=$3
223 local offset=$(partoffset "$image" "$partnum")
224 sudo mount -o loop,ro,offset=$((offset * 512)) "$image" "$mount_dir"
225 }
226
227 # Mount a partition from an image into a local directory
228 # Args: IMAGE PARTNUM MOUNTDIRECTORY
229 mount_image_partition() {
230 local image=$1
231 local partnum=$2
232 local mount_dir=$3
233 local offset=$(partoffset "$image" "$partnum")
234 # Forcibly call enable_rw_mount. It should fail on unsupported filesystems
235 # and be idempotent on ext*.
236 enable_rw_mount "$image" $((offset * 512)) 2> /dev/null
237 sudo mount -o loop,offset=$((offset * 512)) "$image" "$mount_dir"
238 if is_rootfs_partition "$mount_dir"; then
239 tag_as_needs_to_be_resigned "$mount_dir"
240 fi
241 }
242
243 # Extract a partition to a file
244 # Args: IMAGE PARTNUM OUTPUTFILE
245 extract_image_partition() {
246 local image=$1
247 local partnum=$2
248 local output_file=$3
249 local offset=$(partoffset "$image" "$partnum")
250 local size=$(partsize "$image" "$partnum")
251 dd if=$image of=$output_file bs=512 skip=$offset count=$size conv=notrunc >/de v/null 2>&1
252 }
253
254 # Replace a partition in an image from file
255 # Args: IMAGE PARTNUM INPUTFILE
256 replace_image_partition() {
257 local image=$1
258 local partnum=$2
259 local input_file=$3
260 local offset=$(partoffset "$image" "$partnum")
261 local size=$(partsize "$image" "$partnum")
262 dd if=$input_file of=$image bs=512 seek=$offset count=$size conv=notrunc
263 }
264
265 # For details, see crosutils.git/common.sh
266 enable_rw_mount() {
267 local rootfs="$1"
268 local offset="${2-0}"
269
270 # Make sure we're checking an ext2 image
271 if ! is_ext2 "$rootfs" $offset; then
272 echo "enable_rw_mount called on non-ext2 filesystem: $rootfs $offset" 1>&2
273 return 1
274 fi
275
276 local ro_compat_offset=$((0x464 + 3)) # Set 'highest' byte
277 # Dash can't do echo -ne, but it can do printf "\NNN"
278 # We could use /dev/zero here, but this matches what would be
279 # needed for disable_rw_mount (printf '\377').
280 printf '\000' |
281 sudo dd of="$rootfs" seek=$((offset + ro_compat_offset)) \
282 conv=notrunc count=1 bs=1
283 }
284
285 # For details, see crosutils.git/common.sh
286 is_ext2() {
287 local rootfs="$1"
288 local offset="${2-0}"
289
290 # Make sure we're checking an ext2 image
291 local sb_magic_offset=$((0x438))
292 local sb_value=$(sudo dd if="$rootfs" skip=$((offset + sb_magic_offset)) \
293 count=2 bs=1 2>/dev/null)
294 local expected_sb_value=$(printf '\123\357')
295 if [ "$sb_value" = "$expected_sb_value" ]; then
296 return 0
297 fi
298 return 1
299 }
300
301 disable_rw_mount() {
302 local rootfs="$1"
303 local offset="${2-0}"
304
305 # Make sure we're checking an ext2 image
306 if ! is_ext2 "$rootfs" $offset; then
307 echo "disable_rw_mount called on non-ext2 filesystem: $rootfs $offset" 1>&2
308 return 1
309 fi
310
311 local ro_compat_offset=$((0x464 + 3)) # Set 'highest' byte
312 # Dash can't do echo -ne, but it can do printf "\NNN"
313 # We could use /dev/zero here, but this matches what would be
314 # needed for disable_rw_mount (printf '\377').
315 printf '\377' |
316 sudo dd of="$rootfs" seek=$((offset + ro_compat_offset)) \
317 conv=notrunc count=1 bs=1
318 }
319
320 rw_mount_disabled() {
321 local rootfs="$1"
322 local offset="${2-0}"
323
324 # Make sure we're checking an ext2 image
325 if ! is_ext2 "$rootfs" $offset; then
326 return 2
327 fi
328
329 local ro_compat_offset=$((0x464 + 3)) # Set 'highest' byte
330 local ro_value=$(sudo dd if="$rootfs" skip=$((offset + ro_compat_offset)) \
331 count=1 bs=1 2>/dev/null)
332 local expected_ro_value=$(printf '\377')
333 if [ "$ro_value" = "$expected_ro_value" ]; then
334 return 0
335 fi
336 return 1
337 }
338
339 # Misc functions
340 # ----------------------------------------------------------------------------
341
342 # Returns true if all files in parameters exist.
343 # Args: List of files
344 ensure_files_exist() {
345 local filename return_value=0
346 for filename in "$@"; do
347 if [ ! -f "$filename" -a ! -b "$filename" ]; then
348 echo "ERROR: Cannot find required file: $filename"
349 return_value=1
350 fi
351 done
352
353 return $return_value
354 }
355
356 # Check if the 'chronos' user already has a password
357 # Args: rootfs
358 no_chronos_password() {
359 local rootfs=$1
360 sudo grep -q '^chronos:\*:' "$rootfs/etc/shadow"
361 }
362
363 trap "cleanup" INT TERM EXIT 79 trap "cleanup" INT TERM EXIT
364 80
365 add_cleanup_action "cleanup_temps_and_mounts" 81 add_cleanup_action "cleanup_temps_and_mounts"
OLDNEW
« no previous file with comments | « no previous file | scripts/image_signing/common_minimal.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698