/[d-i]/trunk/partman/partman-auto/autopartition
ViewVC logotype

Contents of /trunk/partman/partman-auto/autopartition

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.5