Codebase list partman-auto / af5e448
Divide the autopartition in smaler pieces. Autopartition the whole drive doesn't create new partition table too early. r9663 Anton Zinoviev 20 years ago
4 changed file(s) with 28 addition(s) and 431 deletion(s). Raw diff Collapse all Expand all
00 #!/bin/sh
11
2 . /lib/partman/definitions.sh
2 . /lib/partman/recipes.sh
33
44 dev=$1
5
6 [ -f $dev/size ] || exit 1
7 free_size=$(cat $dev/size)
8 free_size=$(expr 000000"$free_size" : '0*\(.*\)......$') # convert to megabytes
9
10 choose_recipe "$free_size" || exit $?
511
612 cd $dev
713 open_dialog NEW_LABEL msdos # FIXME: defaults for non-i386
1521 rm visuals
1622 fi
1723
18 myfreespace=''
24 free_space=''
1925 open_dialog PARTITIONS
2026 while { read_line num id size type fs path name; [ "$id" ]; }; do
2127 if [ "$fs" = free ]; then
22 myfreespace=$id
28 free_space=$id
29 free_size=$size
2330 fi
2431 done
2532 close_dialog
2633
27 autopartition $dev $myfreespace
28
34 perform_recipe $dev $free_space $recipe || exit $?
00 #!/bin/sh
11
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
2523
2534 dev=$1
2545 free_space=$2
2556
2567 cd $dev
2578 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
25910 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
26711
26812 free_size=$(expr 000000"$free_size" : '0*\(.*\)......$') # convert to megabytes
26913
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 $?
27815
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 $?
99
1010 * Joey Hess
1111 - Use a different question for the initial autopartitioning.
12
12 * Anton Zinoviev
13 - new files: perform_recipe and recipes.sh
14 - extract most parts of autopartition to perform_recipe and
15 recipes.sh
16 - perform_recipe: remove all old method files. Closes: #235194.
17 - recipes.sh: new function choose_recipe
18 - automatically_partition/some_device/do_option: use directly
19 choose_recipe and perform_recipe instead of autopartition. Create
20 new partition table only when the user has already chosen a recipe.
21 Closes: #235377.
22
1323 -- Christian Perrier <[email protected]> Wed, 3 Mar 2004 09:07:10 +0100
1424
1525 partman-auto (6) unstable; urgency=low
2828 dh_testroot
2929 dh_clean -k
3030 dh_install autopartition bin
31 dh_install perform_recipe bin
32 dh_install recipes.sh lib/partman
3133 debian/install-rc recipes
3234 debian/install-rc choose_partition
3335 debian/install-rc free_space