~ago/partman-auto-loop/lupin-support

1 by Colin Watson
initial import
1
#! /bin/sh
2
41 by ago
Wait for /host partition to be mountmoved before checking for the existance of loopfiles
3
. /lib/partman/lib/base.sh
39 by ago
Fixed path of resize.sh and recipes.sh that have been moved
4
. /lib/partman/lib/resize.sh
5
. /lib/partman/lib/recipes.sh
1 by Colin Watson
initial import
6
21 by Colin Watson
* Use 'mount --move' outside d-i rather than 'mount -o move';
7
# busybox wants mount -o move; util-linux wants mount --move. Sigh.
8
if [ -d /lib/debian-installer ]; then
9
	mount_move='-o move'
10
else
11
	mount_move='--move'
12
fi
13
1 by Colin Watson
initial import
14
modprobe loop >/dev/null 2>&1 || true
15
16
# Set up working directory.
17
18
if type mktemp >/dev/null 2>&1; then
19
	recipe_dir="$(mktemp -d /tmp/partman-auto-loop.XXXXXX)"
20
	trap "rm -rf $recipe_dir" EXIT HUP INT QUIT TERM
21
else
22
	recipe_dir=/tmp
23
fi
24
25
# Fetch parameters.
26
27
disk="$1"
28
29
cd $disk
30
31
if ! db_get partman-auto-loop/partition || [ -z "$RET" ]; then
32
	logger -t partman-auto-loop "Error: No partition number specified in partman-auto-loop/partition"
33
	exit 1
34
fi
35
partition="$RET"
36
37
if ! db_get partman-auto-loop/recipe || [ -z "$RET" ]; then
38
	logger -t partman-auto-loop "Error: No recipe specified in partman-auto-loop/recipe"
39
	exit 1
40
fi
41
recipe="$RET"
42
echo "$recipe" >"$recipe_dir/loop_recipe"
43
44
# Find the requested partition.
45
46
db_progress START 0 5 partman-auto/text/automatically_partition
47
db_progress INFO partman-auto/progress/info
48
49
partition_id=
50
partition_fs=
51
open_dialog PARTITIONS
52
while { read_line num id size type fs path name; [ "$id" ]; }; do
53
	if [ "$num" = "$partition" ]; then
54
		partition_id="$id"
55
		partition_fs="$fs"
56
		# go ahead and read all remaining input
57
	fi
58
done
59
close_dialog
60
if [ -z "$partition_id" ]; then
61
	logger -t partman-auto-loop "Error: Partition number $partition not found in $disk"
62
	exit 1
63
fi
64
65
# Set up the requested partition in partman.
66
67
existing=no
68
for j in $(
69
	for i in /lib/partman/valid_filesystems/*; do
70
		[ -x $i ] || continue
71
		$i $disk $partition_id existing
72
	done
73
); do
74
	if [ "$j" = "$partition_fs" ]; then
75
		existing=yes
76
	fi
77
done
78
79
if [ "$existing" = no ]; then
80
	logger -t partman-auto-loop "Error: No filesystem on $disk/$partition_id"
81
	exit 1
82
fi
83
84
echo keep >$partition_id/method
85
rm -f $partition_id/format
86
>$partition_id/use_filesystem
87
echo $partition_fs >$partition_id/filesystem
88
mkdir -p $partition_id/options
89
echo / >$partition_id/mountpoint
90
update_partition $disk $partition_id
91
92
# Is there enough space to perform the recipe?
93
94
dev="$disk"
95
oldid="$partition_id"
96
40 by ago
Skip free space calculation if file images are pre-generated
97
recipe_new=
98
firstword=
99
imagepaths=
100
for word in $(cat "$recipe_dir/loop_recipe"); do
101
	case $word in
102
		.)
103
			recipe_new="${recipe_new:+$recipe_new }\$imagepath{ $firstword } $word"
104
			firstword=
105
			;;
106
		*)
107
			if [ "$firstword" ]; then
108
				recipe_new="${recipe_new:+$recipe_new }$word"
109
			else
110
				firstword="$word"
111
				imagepaths="${imagepaths:+$imagepaths }$word"
112
			fi
113
			;;
114
	esac
115
done
116
echo "$recipe_new" >"$recipe_dir/loop_recipe_new"
117
decode_recipe "$recipe_dir/loop_recipe_new" loop
118
1 by Colin Watson
initial import
119
db_progress STEP 1
120
121
fstab="$(
122
	for i in /lib/partman/fstab.d/*; do
123
		[ -x "$i" ] || continue
124
		$i
125
	done |
126
	while read fs mp type options dump pass; do
127
		case $mp in
128
			(/)
129
				echo $fs $mp $type $options $dump $pass
130
				;;
131
		esac
132
	done
133
)"
134
135
if [ -z "$fstab" ]; then
136
	logger -t partman-auto-loop "Error: No fstab output for $disk/$partition_id"
137
	exit 1
138
fi
139
140
mkdir -p /target
141
28 by Colin Watson
* Use an existing mountpoint for /host if there is one.
142
mountpoint="$(grep "^${fstab%% *} [^ ]* [^ ]* [^ ]*rw" /proc/mounts | cut -d ' ' -f2)" || mountpoint=
143
if [ "$mountpoint" = /target ]; then
144
	# nothing to do
145
	:
146
elif [ "$mountpoint" ]; then
31 by Colin Watson
* Use $mount_move for existing mountpoints too (thanks, Agostino Russo).
147
	if ! mount $mount_move "$mountpoint" /target; then
28 by Colin Watson
* Use an existing mountpoint for /host if there is one.
148
		logger -t partman-auto-loop "Error: Failed to move $mountpoint to /target"
149
		exit 1
1 by Colin Watson
initial import
150
	fi
28 by Colin Watson
* Use an existing mountpoint for /host if there is one.
151
	unmount_cmd='umount /target'
152
else
153
	for m in /lib/partman/mount.d/*; do
154
		[ -x "$m" ] || continue
155
156
		unmount_cmd="$($m "$fstab")"
157
		if [ "$?" = 0 ]; then
158
			break
159
		fi
160
	done
161
fi
29 by Colin Watson
* Prevent ntfs-3g processes from being killed by /etc/init.d/sendsigs.
162
if [ -d /var/run ]; then
36 by ago
Allow disk images to be created externally (LP: #176019).
163
	pidof /sbin/mount.ntfs >> /var/run/sendsigs.omit
164
	pidof /sbin/mount.ntfs-3g >> /var/run/sendsigs.omit
29 by Colin Watson
* Prevent ntfs-3g processes from being killed by /etc/init.d/sendsigs.
165
fi
28 by Colin Watson
* Use an existing mountpoint for /host if there is one.
166
1 by Colin Watson
initial import
167
# TODO: handle errors if no mount succeeded
168
mkdir -p /host
21 by Colin Watson
* Use 'mount --move' outside d-i rather than 'mount -o move';
169
mount $mount_move /target /host # TODO error handling
1 by Colin Watson
initial import
170
24 by Colin Watson
* Remove the 'mountpoint' file for the partition mounted on /host so that
171
# Don't try to mount this again later.
172
rm -f $partition_id/mountpoint
173
41 by ago
Wait for /host partition to be mountmoved before checking for the existance of loopfiles
174
#Ensure there is enough free space
175
check_free_space=false
176
requires_disk_space(){
177
    [ "$1" != 0 ] || return
178
	path="$(echo "$*" | sed 's/.*\$imagepath{  *\([^ }]*\) *}.*/\1/')"
179
	[ "$path" != "$*" ] || return
180
    case $path in
181
		/*)	;;
182
		*)	path="/$path" ;;
183
    esac
184
    [ -f "/host$path" ] && return 
185
    check_free_space=true
186
}
187
foreach_partition 'requires_disk_space $*' 
188
#skip resize_range check if images are already created
189
if [ $check_free_space = true ]; then #TBD check if images are already created
190
    case $partition_fs in
191
	linux-swap|fat16|fat32|hfs|hfs+|hfsx)
192
		get_resize_range
193
		;;
194
	ext2|ext3)
195
		if ! search-path tune2fs; then
196
			logger -t partman-auto-loop "Error: tune2fs not found"
197
			exit 1
198
		fi
199
		if ! search-path resize2fs; then
200
			logger -t partman-auto-loop "Error: resize2fs not found"
201
			exit 1
202
		fi
203
		if ! get_ext2_resize_range; then
204
			logger -t partman-auto-loop "Error: Failed to get ext2 resize range for $disk/$partition_id"
205
			exit 1
206
		fi
207
		;;
208
	ntfs)
209
		if ! search-path ntfsresize; then
210
			logger -t partman-auto-loop "Error: ntfsresize not found"
211
			exit 1
212
		fi
213
		if ! get_ntfs_resize_range; then
214
			db_input critical partman-auto-loop/unclean_ntfs || true
215
			db_go || true
216
			logger -t partman-auto-loop "Error: Failed to get NTFS resize range for $disk/$partition_id"
217
			reboot
218
			exit 1
219
		fi
220
		;;
221
	*)
222
		logger -t partman-auto-loop "Cannot calculate free space on filesystems of type $partition_fs"
223
		exit 1
224
		;;
225
    esac
226
    free_size="$(expr \( "$cursize" - "$minsize" \) \* 9 / 10)"
227
    # convert to megabytes
228
    free_size="$(expr 0000000"$free_size" : '0*\(..*\)......$')"
229
    if [ $(min_size) -gt $free_size ]; then
230
        logger -t partman-auto-loop "Error: partman-auto-loop/recipe too large ($(min_size) > $free_size)"
231
        exit 1
232
    fi
233
fi
234
36 by ago
Allow disk images to be created externally (LP: #176019).
235
# Ensure that no old loop images are present and mountable.
236
mkdir -p /tmpmountpoint
11 by Colin Watson
* Bail out if any of the specified image paths already exist.
237
for path in $imagepaths; do
238
	case $path in
239
		/*)	;;
240
		*)	path="/$path" ;;
241
	esac
242
	if [ -e "/host$path" ]; then
36 by ago
Allow disk images to be created externally (LP: #176019).
243
		if mount -t auto -o loop,ro /host$path /tmpmountpoint 2>/dev/null; then
244
			db_progress STOP
245
			db_subst partman-auto-loop/unclean_host PARTITION "$partition"
246
			db_subst partman-auto-loop/unclean_host DISK "$disk"
247
			db_subst partman-auto-loop/unclean_host IMAGES "$path"
248
			db_input critical partman-auto-loop/unclean_host || true
249
			db_capb
250
			db_go || true
251
			db_capb backup
252
			umount /tmpmountpoint || true
253
			rmdir /tmpmountpoint || true
254
			umount /host || true
255
			exit 1
256
		fi
11 by Colin Watson
* Bail out if any of the specified image paths already exist.
257
	fi
258
done
259
1 by Colin Watson
initial import
260
db_progress STEP 1
261
262
expand_scheme
263
264
db_progress STEP 1
265
266
clean_method
267
268
db_progress STEP 1
269
270
setup_loop () {
17 by Colin Watson
* Skip any zero-sized partitions resulting from recipe expansion.
271
	[ "$1" != 0 ] || return
1 by Colin Watson
initial import
272
	path="$(echo "$*" | sed 's/.*\$imagepath{  *\([^ }]*\) *}.*/\1/')"
273
	[ "$path" != "$*" ] || return
41 by ago
Wait for /host partition to be mountmoved before checking for the existance of loopfiles
274
	fs="$4"
1 by Colin Watson
initial import
275
276
	case $path in
277
		/*)	;;
278
		*)	path="/$path" ;;
279
	esac
41 by ago
Wait for /host partition to be mountmoved before checking for the existance of loopfiles
280
	if [ ! -f "/host$path" ] && [ "$1" -gt 0 ];then	
36 by ago
Allow disk images to be created externally (LP: #176019).
281
		mkdir -p "/host${path%/*}"
41 by ago
Wait for /host partition to be mountmoved before checking for the existance of loopfiles
282
		if [ "$fs" = "linux-swap" ]; then	
36 by ago
Allow disk images to be created externally (LP: #176019).
283
		    #swap requires a file with no holes
284
			dd if=/dev/zero of="/host$path" bs="1MB" count="$1"
285
		else
286
			dd if=/dev/zero of="/host$path" bs="1MB" seek="$1" count=0
287
		fi	
288
	fi
289
	if [ ! -f "/host$path" ] || ! losetup -f "/host$path"; then
1 by Colin Watson
initial import
290
		shift
291
		continue
292
	fi
14 by Colin Watson
* Create ordinary swap files rather than creating swap partitions on top
293
	if [ "$4" = linux-swap ]; then
294
		loops="/host$path"
295
	else
296
		loops="$(echo /dev/loop* /dev/loop/*)"
297
	fi
298
	for loop in $loops; do
1 by Colin Watson
initial import
299
		[ -e "$loop" ] || continue
14 by Colin Watson
* Create ordinary swap files rather than creating swap partitions on top
300
		case $loop in
301
			/dev/loop*)
302
				loopfile="$(losetup "$loop")" || continue
303
				# The following works with both busybox's
304
				# losetup and util-linux's losetup. Yes,
305
				# this is ugly.
306
				loopfile="$(echo "$loopfile" | sed 's,.*\(/host/[^)]*\).*,\1,')"
307
				;;
308
			*)
309
				loopfile="$loop"
310
				;;
311
		esac
1 by Colin Watson
initial import
312
		[ "$loopfile" = "/host$path" ] || continue
313
314
		dirname="$(echo "$loop" | sed 's:/:=:g')"
315
		dev="$DEVICES/$dirname"
316
317
		rm -rf "$dev"
318
		mkdir "$dev" || autopartitioning_failed
319
		printf "%s" "$loop" >"$dev/device"
22 by Colin Watson
* Actually write the size to the partition's 'size' file, not the type!
320
		printf "%s" "$1" >"$dev/size"
1 by Colin Watson
initial import
321
		echo "Loopback on $loopfile" >"$dev/model"
322
		echo "$loopfile" >"$dev/loop"
323
324
		cd "$dev"
325
		open_dialog OPEN "$(cat "$dev/device")"
326
		read_line response
327
		close_dialog
328
		if [ "$response" = failed ]; then
329
			cd /
330
			rm -rf "$dev"
331
			autopartitioning_failed
332
		fi
333
334
		open_dialog NEW_LABEL loop
335
		close_dialog
336
337
		# find the free space
338
		open_dialog PARTITIONS
339
		free_space=
340
		while { read_line num id size type fs path name; [ "$id" ]; }; do
341
			if [ "$fs" = free ]; then
342
				free_space=$id
343
				free_size=$size
344
			fi
345
		done
346
		close_dialog
347
348
		# create partition in the free space
349
		[ "$free_space" ] || autopartitioning_failed
350
		open_dialog NEW_PARTITION primary $4 $free_space full ${1}000001
351
		read_line num id size type fs path name
352
		close_dialog
353
354
		shift; shift; shift; shift
355
		setup_partition $id $*
356
		break
357
	done
358
}
359
360
foreach_partition 'setup_loop $*'
361
362
db_progress STEP 1
363
364
update_all
365
15 by Colin Watson
* apt-install lupin-support.
366
apt-install lupin-support
367
1 by Colin Watson
initial import
368
db_progress STOP
369
370
exit 0