0 | 0 |
#!/bin/sh
|
1 | 1 |
|
2 | |
. /lib/partman/definitions.sh
|
3 | |
|
4 | |
# If you are curious why partman-auto is so slow, it is because
|
5 | |
# update-all is slow
|
6 | |
update_all () {
|
7 | |
local dev num id size type fs path name partitions
|
8 | |
for dev in $DEVICES/*; do
|
9 | |
[ -d "$dev" ] || continue
|
10 | |
cd $dev
|
11 | |
partitions=''
|
12 | |
open_dialog PARTITIONS
|
13 | |
while { read_line num id size type fs path name; [ "$id" ]; }; do
|
14 | |
partitions="$partitions $id"
|
15 | |
done
|
16 | |
close_dialog
|
17 | |
for id in $partitions; do
|
18 | |
update_partition $dev $id
|
19 | |
done
|
20 | |
done
|
21 | |
}
|
22 | |
|
23 | |
autopartitioning_failed () {
|
24 | |
db_fset partman-auto/autopartitioning_failed seen false
|
25 | |
db_input critical partman-auto/autopartitioning_failed || true
|
26 | |
db_go || true
|
27 | |
update_all
|
28 | |
exit 1
|
29 | |
}
|
30 | |
|
31 | |
unnamed=0
|
32 | |
|
33 | |
decode_recipe () {
|
34 | |
local ram line word min factor max fs -
|
35 | |
unnamed=$(($unnamed + 1))
|
36 | |
ram=$(cat /proc/meminfo | grep ^Mem: | { read x y z; echo $y; }) # in bytes
|
37 | |
ram=$(expr 000000"$ram" : '0*\(.*\)......$') # convert to megabytes
|
38 | |
name="Unnamed.${unnamed}"
|
39 | |
scheme=''
|
40 | |
line=''
|
41 | |
for word in $(cat $1); do
|
42 | |
case $word in
|
43 | |
:)
|
44 | |
name=$line
|
45 | |
line=''
|
46 | |
;;
|
47 | |
::)
|
48 | |
db_metaget $line description
|
49 | |
if [ "$RET" ]; then
|
50 | |
name=$RET
|
51 | |
else
|
52 | |
name="Unnamed.${unnamed}"
|
53 | |
fi
|
54 | |
line=''
|
55 | |
;;
|
56 | |
.)
|
57 | |
# we correct errors in order not to crash parted_server
|
58 | |
set -- $line
|
59 | |
if expr "$1" : '[0-9][0-9]*$' >/dev/null; then
|
60 | |
min=$1
|
61 | |
elif expr "$1" : '[0-9][0-9]*%$' >/dev/null; then
|
62 | |
min=$(($ram * ${1%?} / 100))
|
63 | |
else # error
|
64 | |
min=2200000000 # there is no so big storage device jet
|
65 | |
fi
|
66 | |
if expr "$2" : '[0-9][0-9]*%$' >/dev/null; then
|
67 | |
factor=$(($ram * ${2%?} / 100))
|
68 | |
elif expr "$2" : '[0-9][0-9]*$' >/dev/null; then
|
69 | |
factor=$2
|
70 | |
else # error
|
71 | |
factor=$min # do not enlarge the partition
|
72 | |
fi
|
73 | |
if [ "$factor" -lt "$min" ]; then
|
74 | |
factor="$min"
|
75 | |
fi
|
76 | |
if expr "$3" : '[0-9][0-9]*$' >/dev/null; then
|
77 | |
max=$3
|
78 | |
elif expr "$3" : '[0-9][0-9]*%$' >/dev/null; then
|
79 | |
max=$(($ram * ${3%?} / 100))
|
80 | |
else # error
|
81 | |
max=$min # do not enlarge the partition
|
82 | |
fi
|
83 | |
if [ "$max" -lt "$min" ]; then
|
84 | |
max="$min"
|
85 | |
fi
|
86 | |
case "$4" in # allow only valid file systems
|
87 | |
ext2|ext3|linux-swap|fat16|fat32)
|
88 | |
fs="$4"
|
89 | |
;;
|
90 | |
*)
|
91 | |
fs=ext2
|
92 | |
;;
|
93 | |
esac
|
94 | |
shift; shift; shift; shift
|
95 | |
line="$min $factor $max $fs $*"
|
96 | |
if [ "$scheme" ]; then
|
97 | |
scheme="${scheme}${NL}${line}"
|
98 | |
else
|
99 | |
scheme="$line"
|
100 | |
fi
|
101 | |
line=''
|
102 | |
;;
|
103 | |
*)
|
104 | |
if [ "$line" ]; then
|
105 | |
line="$line $word"
|
106 | |
else
|
107 | |
line="$word"
|
108 | |
fi
|
109 | |
esac
|
110 | |
done
|
111 | |
}
|
112 | |
|
113 | |
foreach_partition () {
|
114 | |
local - doing IFS partition former last
|
115 | |
doing=$1
|
116 | |
IFS="$NL"
|
117 | |
former=''
|
118 | |
for partition in $scheme; do
|
119 | |
restore_ifs
|
120 | |
if [ "$former" ]; then
|
121 | |
set -- $former
|
122 | |
last=no
|
123 | |
eval "$doing"
|
124 | |
fi
|
125 | |
former="$partition"
|
126 | |
done
|
127 | |
if [ "$former" ]; then
|
128 | |
set -- $former
|
129 | |
last=yes
|
130 | |
eval "$doing"
|
131 | |
fi
|
132 | |
}
|
133 | |
|
134 | |
min_size () {
|
135 | |
local size
|
136 | |
size=0
|
137 | |
foreach_partition '
|
138 | |
size=$(($size + $1))'
|
139 | |
echo $size
|
140 | |
}
|
141 | |
|
142 | |
factor_sum () {
|
143 | |
local factor
|
144 | |
factor=0
|
145 | |
foreach_partition '
|
146 | |
factor=$(($factor + $2))'
|
147 | |
echo $factor
|
148 | |
}
|
149 | |
|
150 | |
partition_before () {
|
151 | |
local num id size type fs path name result found
|
152 | |
result=''
|
153 | |
found=no
|
154 | |
open_dialog PARTITIONS
|
155 | |
while { read_line num id size type fs path name; [ "$id" ]; }; do
|
156 | |
if [ "$id" = "$1" ]; then
|
157 | |
found=yes
|
158 | |
fi
|
159 | |
if [ $found = no ]; then
|
160 | |
result=$id
|
161 | |
fi
|
162 | |
done
|
163 | |
close_dialog
|
164 | |
echo $result
|
165 | |
}
|
166 | |
|
167 | |
partition_after () {
|
168 | |
local num id size type fs path name result found
|
169 | |
result=''
|
170 | |
found=no
|
171 | |
open_dialog PARTITIONS
|
172 | |
while { read_line num id size type fs path name; [ "$id" ]; }; do
|
173 | |
if [ $found = yes -a -z "$result" ]; then
|
174 | |
result=$id
|
175 | |
fi
|
176 | |
if [ "$id" = "$1" ]; then
|
177 | |
found=yes
|
178 | |
fi
|
179 | |
done
|
180 | |
close_dialog
|
181 | |
echo $result
|
182 | |
}
|
183 | |
|
184 | |
pull_primary () {
|
185 | |
primary=''
|
186 | |
logical=''
|
187 | |
foreach_partition '
|
188 | |
if
|
189 | |
[ -z "$primary" ] \
|
190 | |
&& echo $* | grep '\''\$primary{'\'' >/dev/null
|
191 | |
then
|
192 | |
primary="$*"
|
193 | |
else
|
194 | |
if [ -z "$logical" ]; then
|
195 | |
logical="$*"
|
196 | |
else
|
197 | |
logical="${logical}${NL}$*"
|
198 | |
fi
|
199 | |
fi'
|
200 | |
}
|
201 | |
|
202 | |
setup_partition () {
|
203 | |
local id flags file line
|
204 | |
id=$1; shift
|
205 | |
while [ "$1" ]; do
|
206 | |
case "$1" in
|
207 | |
\$bootable{)
|
208 | |
while [ "$1" != '}' -a "$1" ]; do
|
209 | |
shift
|
210 | |
done
|
211 | |
open_dialog GET_FLAGS $id
|
212 | |
flags=$(read_paragraph)
|
213 | |
close_dialog
|
214 | |
open_dialog SET_FLAGS $id
|
215 | |
write_line "$flags"
|
216 | |
write_line boot
|
217 | |
write_line NO_MORE
|
218 | |
close_dialog
|
219 | |
;;
|
220 | |
\$*{)
|
221 | |
while [ "$1" != '}' -a "$1" ]; do
|
222 | |
shift
|
223 | |
done
|
224 | |
;;
|
225 | |
*{)
|
226 | |
file=${1%?}
|
227 | |
[ -d $id ] || mkdir $id
|
228 | |
>$id/$file
|
229 | |
shift
|
230 | |
line=''
|
231 | |
while [ "$1" != '}' -a "$1" ]; do
|
232 | |
if [ "$1" = ';' ]; then
|
233 | |
echo "$line" >>$id/$file
|
234 | |
else
|
235 | |
if [ "$line" ]; then
|
236 | |
line="$line $1"
|
237 | |
else
|
238 | |
line="$1"
|
239 | |
fi
|
240 | |
fi
|
241 | |
shift
|
242 | |
done
|
243 | |
echo "$line" >>$id/$file
|
244 | |
esac
|
245 | |
shift
|
246 | |
done
|
247 | |
return 0
|
248 | |
}
|
249 | |
|
250 | |
# Let us be safe and update the directories
|
251 | |
update_all
|
|
2 |
. /lib/partman/recipes.sh
|
252 | 3 |
|
253 | 4 |
dev=$1
|
254 | 5 |
free_space=$2
|
255 | 6 |
|
256 | 7 |
cd $dev
|
257 | 8 |
open_dialog PARTITION_INFO $free_space
|
258 | |
read_line x1 x2 free_size free_type x3 x4 x5
|
|
9 |
read_line x1 x2 free_size x3 x4 x5 x6
|
259 | 10 |
close_dialog
|
260 | |
|
261 | |
if [ "$free_type" = unusable ]; then
|
262 | |
db_fset partman-auto/unusable_space seen false
|
263 | |
db_input critical partman-auto/unusable_space || true
|
264 | |
db_go || true
|
265 | |
exit 1
|
266 | |
fi
|
267 | 11 |
|
268 | 12 |
free_size=$(expr 000000"$free_size" : '0*\(.*\)......$') # convert to megabytes
|
269 | 13 |
|
270 | |
choices=''
|
271 | |
for recipe in /lib/partman/recipes/*; do
|
272 | |
[ -f "$recipe" ] || continue
|
273 | |
decode_recipe $recipe
|
274 | |
if [ $(min_size) -le $free_size ]; then
|
275 | |
choices="${choices}${recipe}${TAB}${name}${NL}"
|
276 | |
fi
|
277 | |
done
|
|
14 |
choose_recipe "$free_size" || exit $?
|
278 | 15 |
|
279 | |
#db_metaget partman-auto/text/expert_recipe description
|
280 | |
#choices="${choices}expert${TAB}${RET}"
|
281 | |
|
282 | |
db_fset partman-auto/choose_recipe seen false
|
283 | |
debconf_select high partman-auto/choose_recipe "$choices" no_default
|
284 | |
if [ "$?" = 255 ]; then
|
285 | |
exit 0
|
286 | |
fi
|
287 | |
|
288 | |
case $RET in
|
289 | |
expert)
|
290 | |
db_fset partman-auto/expert_recipe seen false
|
291 | |
db_input critical partman-auto/expert_recipe || true
|
292 | |
if ! db_go; then
|
293 | |
exit 1
|
294 | |
fi
|
295 | |
decode_recipe $RET
|
296 | |
;;
|
297 | |
*)
|
298 | |
decode_recipe $RET
|
299 | |
;;
|
300 | |
esac
|
301 | |
|
302 | |
|
303 | |
# Make factors small numbers so we can multiply on them.
|
304 | |
# Also ensure that fact, max and fs are valid
|
305 | |
# (Ofcourse in valid recipes they must be valid.)
|
306 | |
factsum=$(($(factor_sum) - $(min_size)))
|
307 | |
scheme=$(
|
308 | |
foreach_partition '
|
309 | |
local min fact max fs
|
310 | |
min=$1
|
311 | |
fact=$((($2 - $min) * 100 / $factsum))
|
312 | |
max=$3
|
313 | |
fs=$4
|
314 | |
case "$fs" in
|
315 | |
ext2|ext3|linux-swap|fat16|fat32)
|
316 | |
true
|
317 | |
;;
|
318 | |
*)
|
319 | |
fs=ext2
|
320 | |
;;
|
321 | |
esac
|
322 | |
shift; shift; shift; shift
|
323 | |
echo $min $fact $max $fs $*'
|
324 | |
)
|
325 | |
|
326 | |
oldscheme=''
|
327 | |
while [ "$scheme" != "$oldscheme" ]; do
|
328 | |
oldscheme="$scheme"
|
329 | |
factsum=$(factor_sum)
|
330 | |
unallocated=$(($free_size - $(min_size)))
|
331 | |
if [ $unallocated -lt 0 ]; then
|
332 | |
unallocated=0
|
333 | |
fi
|
334 | |
scheme=$(
|
335 | |
foreach_partition '
|
336 | |
local min fact max newmin
|
337 | |
min=$1
|
338 | |
fact=$2
|
339 | |
max=$3
|
340 | |
shift; shift; shift
|
341 | |
newmin=$(($min + $unallocated * $fact / $factsum))
|
342 | |
if [ $newmin -le $max ]; then
|
343 | |
echo $newmin $fact $max $*
|
344 | |
else
|
345 | |
echo $max 0 $max $*
|
346 | |
fi'
|
347 | |
)
|
348 | |
done
|
349 | |
|
350 | |
while
|
351 | |
[ "$free_type" = pri/log ] \
|
352 | |
&& echo $scheme | grep '\$primary{' >/dev/null
|
353 | |
do
|
354 | |
pull_primary
|
355 | |
set -- $primary
|
356 | |
open_dialog NEW_PARTITION primary $4 $free_space beginning ${1}000001
|
357 | |
read_line num id size type fs path name
|
358 | |
close_dialog
|
359 | |
if [ -z "$id" ]; then
|
360 | |
autopartitioning_failed
|
361 | |
fi
|
362 | |
neighbour=$(partition_after $id)
|
363 | |
if [ "$neighbour" ]; then
|
364 | |
open_dialog PARTITION_INFO $neighbour
|
365 | |
read_line x1 new_free_space x2 new_free_type fs x3 x4
|
366 | |
close_dialog
|
367 | |
fi
|
368 | |
if
|
369 | |
[ -z "$neighbour" -o "$fs" != free \
|
370 | |
-o "$new_free_type" = primary -o "$new_free_type" = unusable ]
|
371 | |
then
|
372 | |
open_dialog DELETE_PARTITION $id
|
373 | |
close_dialog
|
374 | |
open_dialog NEW_PARTITION primary $4 $free_space end ${1}000001
|
375 | |
read_line num id size type fs path name
|
376 | |
close_dialog
|
377 | |
if [ -z "$id" ]; then
|
378 | |
autopartitioning_failed
|
379 | |
fi
|
380 | |
neighbour=$(partition_before $id)
|
381 | |
if [ "$neighbour" ]; then
|
382 | |
open_dialog PARTITION_INFO $neighbour
|
383 | |
read_line x1 new_free_space x2 new_free_type fs x3 x4
|
384 | |
close_dialog
|
385 | |
fi
|
386 | |
if
|
387 | |
[ -z "$neighbour" -o "$fs" != free -o "$new_free_type" = unusable ]
|
388 | |
then
|
389 | |
open_dialog DELETE_PARTITION $id
|
390 | |
close_dialog
|
391 | |
break
|
392 | |
fi
|
393 | |
fi
|
394 | |
shift; shift; shift; shift
|
395 | |
setup_partition $id $*
|
396 | |
primary=''
|
397 | |
scheme="$logical"
|
398 | |
free_space=$new_free_space
|
399 | |
free_type="$new_free_type"
|
400 | |
done
|
401 | |
|
402 | |
foreach_partition '
|
403 | |
if [ -z "$free_space" ]; then
|
404 | |
autopartitioning_failed
|
405 | |
fi
|
406 | |
open_dialog PARTITION_INFO $free_space
|
407 | |
read_line x1 free_space x2 free_type fs x3 x4
|
408 | |
close_dialog
|
409 | |
if [ "$fs" != free ]; then
|
410 | |
free_type=unusable
|
411 | |
fi
|
412 | |
case "$free_type" in
|
413 | |
primary|logical)
|
414 | |
type="$free_type"
|
415 | |
;;
|
416 | |
pri/log)
|
417 | |
type=logical
|
418 | |
;;
|
419 | |
unusable)
|
420 | |
autopartitioning_failed
|
421 | |
;;
|
422 | |
esac
|
423 | |
if [ "$last" = yes ]; then
|
424 | |
open_dialog NEW_PARTITION $type $4 $free_space full ${1}000001
|
425 | |
else
|
426 | |
open_dialog NEW_PARTITION $type $4 $free_space beginning ${1}000001
|
427 | |
fi
|
428 | |
read_line num id size type fs path name
|
429 | |
close_dialog
|
430 | |
if [ -z "$id" ]; then
|
431 | |
autopartitioning_failed
|
432 | |
fi
|
433 | |
shift; shift; shift; shift
|
434 | |
setup_partition $id $*
|
435 | |
free_space=$(partition_after $id)'
|
436 | |
|
437 | |
update_all
|
|
16 |
perform_recipe $dev $free_space $recipe || exit $?
|