blob: 7f2ad112a6285db3690a14c709d5f9cb8fde1742 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/sh
Brad Bishopc342db32019-05-15 21:57:59 -04002#
3# SPDX-License-Identifier: GPL-2.0-only
4#
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005
Patrick Williamsc124f4f2015-09-15 14:41:29 -05006# 1MB blocksize
7BLOCKSIZE=1048576
8
9usage() {
10 echo "Usage: $(basename $0) IMAGE DEVICE"
11}
12
13image_details() {
14 IMG=$1
15 echo "Image details"
16 echo "============="
17 echo " image: $(basename $IMG)"
18 # stat format is different on Mac OS and Linux
19 if [ "$(uname)" = "Darwin" ]; then
20 echo " size: $(stat -L -f '%z bytes' $IMG)"
21 echo " modified: $(stat -L -f '%Sm' $IMG)"
22 else
23 echo " size: $(stat -L -c '%s bytes' $IMG)"
24 echo " modified: $(stat -L -c '%y' $IMG)"
25 fi
26 echo " type: $(file -L -b $IMG)"
27 echo ""
28}
29
30device_details() {
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031 BLOCK_SIZE=512
32
33 echo "Device details"
34 echo "=============="
35
36 # Collect disk info using diskutil on Mac OS
37 if [ "$(uname)" = "Darwin" ]; then
38 diskutil info $DEVICE | egrep "(Device Node|Media Name|Total Size)"
39 return
40 fi
41
42 # Default / Linux information collection
Brad Bishop96ff1982019-08-19 13:50:42 -040043 ACTUAL_DEVICE=`readlink -f $DEVICE`
44 DEV=`basename $ACTUAL_DEVICE`
45 if [ "$ACTUAL_DEVICE" != "$DEVICE" ] ; then
46 echo " device: $DEVICE -> $ACTUAL_DEVICE"
47 else
48 echo " device: $DEVICE"
49 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -050050 if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
51 echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
52 else
Brad Bishop96ff1982019-08-19 13:50:42 -040053 echo " vendor: UNKNOWN"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050054 fi
55 if [ -f "/sys/class/block/$DEV/device/model" ]; then
56 echo " model: $(cat /sys/class/block/$DEV/device/model)"
57 else
58 echo " model: UNKNOWN"
59 fi
60 if [ -f "/sys/class/block/$DEV/size" ]; then
61 echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
62 else
63 echo " size: UNKNOWN"
64 fi
65 echo ""
66}
67
Brad Bishop96ff1982019-08-19 13:50:42 -040068check_mount_device() {
69 if cat /proc/self/mounts | awk '{ print $1 }' | grep /dev/ | grep -q -E "^$1$" ; then
70 return 0
71 fi
72 return 1
73}
74
75is_mounted() {
76 if [ "$(uname)" = "Darwin" ]; then
77 if df | awk '{ print $1 }' | grep /dev/ | grep -q -E "^$1(s[0-9]+)?$" ; then
78 return 0
79 fi
80 else
81 if check_mount_device $1 ; then
82 return 0
83 fi
84 DEV=`basename $1`
85 if [ -d /sys/class/block/$DEV/ ] ; then
86 PARENT_BLKDEV=`basename $(readlink -f "/sys/class/block/$DEV/..")`
87 if [ "$PARENT_BLKDEV" != "block" ] ; then
88 if check_mount_device $PARENT_BLKDEV ; then
89 return 0
90 fi
91 fi
92 for CHILD_BLKDEV in `find /sys/class/block/$DEV/ -mindepth 1 -maxdepth 1 -name "$DEV*" -type d`
93 do
94 if check_mount_device /dev/`basename $CHILD_BLKDEV` ; then
95 return 0
96 fi
97 done
98 fi
99 fi
100 return 1
101}
102
103is_inuse() {
104 HOLDERS_DIR="/sys/class/block/`basename $1`/holders"
105 if [ -d $HOLDERS_DIR ] && [ `ls -A $HOLDERS_DIR` ] ; then
106 return 0
107 fi
108 return 1
109}
110
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111if [ $# -ne 2 ]; then
112 usage
113 exit 1
114fi
115
116IMAGE=$1
117DEVICE=$2
118
119if [ ! -e "$IMAGE" ]; then
120 echo "ERROR: Image $IMAGE does not exist"
121 usage
122 exit 1
123fi
124
Brad Bishop96ff1982019-08-19 13:50:42 -0400125if [ ! -e "$DEVICE" ]; then
126 echo "ERROR: Device $DEVICE does not exist"
127 usage
128 exit 1
129fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500130
Brad Bishop96ff1982019-08-19 13:50:42 -0400131if [ "$(uname)" = "Darwin" ]; then
132 # readlink doesn't support -f on MacOS, just assume it isn't a symlink
133 ACTUAL_DEVICE=$DEVICE
134else
135 ACTUAL_DEVICE=`readlink -f $DEVICE`
136fi
137if is_mounted $ACTUAL_DEVICE ; then
138 echo "ERROR: Device $DEVICE is currently mounted - check if this is the right device, and unmount it first if so"
139 device_details
140 exit 1
141fi
142if is_inuse $ACTUAL_DEVICE ; then
143 echo "ERROR: Device $DEVICE is currently in use (possibly part of LVM) - check if this is the right device!"
144 device_details
145 exit 1
146fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147
148if [ ! -w "$DEVICE" ]; then
Brad Bishop96ff1982019-08-19 13:50:42 -0400149 echo "ERROR: Device $DEVICE is not writable - possibly use sudo?"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500150 usage
151 exit 1
152fi
153
154image_details $IMAGE
Brad Bishop96ff1982019-08-19 13:50:42 -0400155device_details
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500156
157printf "Write $IMAGE to $DEVICE [y/N]? "
158read RESPONSE
159if [ "$RESPONSE" != "y" ]; then
160 echo "Write aborted"
161 exit 0
162fi
163
164echo "Writing image..."
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600165if which pv >/dev/null 2>&1; then
166 pv "$IMAGE" | dd of="$DEVICE" bs="$BLOCKSIZE"
167else
168 dd if="$IMAGE" of="$DEVICE" bs="$BLOCKSIZE"
169fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500170sync