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 | #!/bin/bash
#
# http://pad.lv/1443542
## attempt to recreate bug / race between
## udevadm settle
## blockdev --rereadpt
## sfdisk
##
## that was seen in curtin
getsize() {
# return size of target in bytes
local target="$1"
if [ -b "$target" ]; then
_RET=$(blockdev --getsize64 "$target")
elif [ -f "$target" ]; then
_RET=$(stat "--format=%s" "$target")
else
return 1;
fi
}
error() { echo "$@" 1>&2; }
debug() { shift; echo "$@" 1>&2; }
wipedev() {
# wipe the front and end (gpt is at end also)
local target="$1" size="" out="" bs="" count="" seek="" mb=$((1024*1024))
local info=""
size="$SIZE"
# select a block size that evenly divides size. bigger is generally faster.
for bs in $mb 4096 1024 512 1; do
[ "$((size % bs))" = "0" ] && break
done
if [ "$bs" = "1" ]; then
error "WARN: odd sized '$target' ($size). not divisible by 512."
fi
[ "$size" -ge "$mb" ] && count=$((mb / bs)) || count=$((size / bs))
info="size=$size count=$count bs=$bs"
#debug 1 "wiping start of '$target' with ${info}."
# wipe the first MB (up to 'size')
out=$(dd if=/dev/zero conv=notrunc "of=$target" \
"bs=$bs" "count=$count" 2>&1) || {
error "wiping start of '$target' failed."
error " size=$size count=$count bs=$bs: $out"
return 1
}
if [ "$size" -gt "$mb" ]; then
# do the last 1MB
count=$((mb / bs))
seek=$(((size / bs) - $count))
info="size=$size count=$count bs=$bs seek=$seek"
#debug 1 "wiping end of '$target' with ${info}."
out=$(dd if=/dev/zero conv=notrunc "of=$target" "seek=$seek" \
"bs=$bs" "count=$count" 2>&1)
if [ $? -ne 0 ]; then
error "wiping end of '$target' failed."
error " size=$size count=$count seek=$seek bs=$bs: $out";
return 1;
fi
fi
if [ -b "$target" ]; then
blockdev --rereadpt "$target"
udevadm settle
fi
}
partition() {
local out="" ret=0
out=$(sfdisk --unit=S --force "$1" 2>&1 <<EOF
2048,
EOF
)
ret=$?
[ $ret -eq 0 ] || echo "$out"
return $ret
}
partition2() {
local n=$((1024*1024))
local out="" ret=""
out=$(sfdisk --unit=S --force "$1" 2>&1 <<EOF
2048,$n
$(($n+2048)),
EOF
)
ret=$?
[ $ret -eq 0 ] || echo "$out"
return $ret
}
waitfor() {
blockdev --rereadpt "$1" && udevadm settle
}
fail() { error "$@"; exit 1; }
dev=${1:-/dev/vdb}
pt1="${dev}1"
pt2=${dev}2
getsize "$dev" || fail "failed get size of $dev"
SIZE=${_RET}
n=0
while n=$(($n+1)); do
echo "run $n: ${SECONDS}"
wipedev "$dev" || fail "wipe failed"
for pt in $pt1 $pt2; do
[ -b "$pt" ] && fail "found $pt after wipe"
done
[ -b "$dev" ] || fail "$dev missing after wipe"
partition "$dev" || fail "partition failed"
waitfor "$dev" || fail "waitfor after partition failed"
[ -b "$pt1" ] || fail "$pt1 missing after partition1"
[ -b "$pt2" ] && fail "$pt2 found after partition1"
[ -b "${dev}" ] || fail "$dev missing after partition1"
partition2 "$dev" || fail "partition2 failed"
waitfor "$dev" || fail "waitfor after partition2 failed"
[ -b "$pt1" ] || fail "$pt1 missing after partition2"
[ -b "$pt2" ] || fail "$pt2 missing after partition2"
[ -b "${dev}" ] || fail "$dev missing after partition2"
done
|