recipes: tools/ntfs-3g: Added version 2021.8.22
[dragora.git] / patches / os-prober / os-prober-btrfsfix.patch
blob1047d249f92905c1ab9d77b356a4fba0575ec473
1 diff --git a/common.sh b/common.sh
2 index c2c5f46..8fb3c5f 100644
3 --- a/common.sh
4 +++ b/common.sh
5 @@ -155,6 +155,7 @@ parse_proc_mounts () {
6 done
9 +# add forth parameter to pickup btrfs subvol info
10 parsefstab () {
11 while read -r line; do
12 case "$line" in
13 @@ -165,12 +166,22 @@ parsefstab () {
14 set -f
15 set -- $line
16 set +f
17 - printf '%s %s %s\n' "$1" "$2" "$3"
18 + printf '%s %s %s %s\n' "$1" "$2" "$3" "$4"
20 esac
21 done
24 +#check_btrfs_mounted $bootsv $bootuuid)
25 +check_btrfs_mounted () {
26 + bootsv="$1"
27 + bootuuid="$2"
28 + bootdev=$(blkid | grep "$bootuuid" | cut -d ':' -f 1)
29 + bindfrom=$(grep " btrfs " /proc/self/mountinfo |
30 + grep " $bootdev " | grep " /$bootsv " | cut -d ' ' -f 5)
31 + printf "%s" "$bindfrom"
34 unescape_mount () {
35 printf %s "$1" | \
36 sed 's/\\011/ /g; s/\\012/\n/g; s/\\040/ /g; s/\\134/\\/g'
37 diff --git a/linux-boot-prober b/linux-boot-prober
38 index e32dc84..2a60fa2 100755
39 --- a/linux-boot-prober
40 +++ b/linux-boot-prober
41 @@ -5,16 +5,143 @@ set -e
43 newns "$@"
44 require_tmpdir
45 +ERR="n"
47 +tmpmnt=/var/lib/os-prober/mount
48 +if [ ! -d "$tmpmnt" ]; then
49 + mkdir "$tmpmnt"
50 +fi
52 +mounted=
53 +bootmnt=
54 +bootsv=
55 +bootuuid=
57 grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true
59 -partition="$1"
60 +if [ -z "$1" ]; then
61 + ERR=y
62 +elif [ "$1" = btrfs -a -z "$2" ]; then
63 + ERR=y
64 +elif [ "$1" = btrfs -a -z "$3" ]; then
65 + ERR=y
66 +elif [ "$1" = btrfs ]; then
67 + type=btrfs
68 + echo "$2" | grep -q "^UUID=" || ERR=y
69 + echo "$3" | grep -q "^subvol=" || ERR=y
70 + export "$2"
71 + export "$3"
72 + partition=$(blkid | grep "$UUID" | cut -d ':' -f 1 | tr '\n' ' ' | cut -d ' ' -f 1)
73 + debug "btrfs: partition=$partition, UUID=$UUID, subvol=$subvol"
74 +else
75 + partition="$1"
76 + type=other
77 +fi
79 -if [ -z "$partition" ]; then
80 +if [ "x$ERR" != xn ]; then
81 echo "usage: linux-boot-prober partition" >&2
82 + echo " linux-boot-prober btrfs UUID=<> subvol=<>" >&2
83 exit 1
86 +if [ "$type" = btrfs ]; then
87 + # handle all of the btrfs stuff here
88 + if [ ! -e "/proc/self/mountinfo" ]; then
89 + warn "/proc/self/mountinfo does not exist, exiting"
90 + umount "$tmpmnt" 2>/dev/null
91 + rmdir "$tmpmnt" 2>/dev/null
92 + exit 1
93 + fi
94 + mpoint=$(grep "btrfs" /proc/self/mountinfo | grep " /$subvol " | grep " $partition " | cut -d ' ' -f 5)
95 + if [ "$mpoint" = "/" ]; then
96 + warn "specifying active root not valid, exiting"
97 + umount "$tmpmnt" 2>/dev/null
98 + rmdir "$tmpmnt" 2>/dev/null
99 + exit 1
100 + fi
101 + if [ "$mpoint" = "$tmpmnt" ]; then
102 + warn "btrfs subvol=$subvool, UUID=$UUID, already mounted on $tmpmnt **ERROR**"
103 + umount "$tmpmnt" 2>/dev/null
104 + rmdir "$tmpmnt" 2>/dev/null
105 + exit 1
106 + fi
107 + if [ -z "$mpoint" ]; then
108 + # mount the btrfs root
109 + if ! mount -o subvol=$subvol -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then
110 + warn "error mounting btrfs subvol=$subvol UUID=$UUID"
111 + umount "$tmpmnt/boot" 2>/dev/null
112 + umount "$tmpmnt" 2>/dev/null
113 + rmdir "$tmpmnt" 2>/dev/null
114 + exit 1
115 + fi
116 + else
117 + # bind-mount
118 + if ! mount -o bind "$mpoint" "$tmpmnt" 2>/dev/null; then
119 + warn "error mounting btrfs bindfrom=$mpoint subvol=$subvol UUID=$UUID"
120 + umount "$tmpmnt/boot" 2>/dev/null
121 + umount "$tmpmnt" 2>/dev/null
122 + rmdir "$tmpmnt" 2>/dev/null
123 + exit 1
124 + fi
125 + fi
126 + debug "mounted btrfs $partition, subvol=$subvol on $tmpmnt"
127 + if [ ! -e "$tmpmnt/etc/fstab" ]; then
128 + warn "btrfs subvol=$subvol not root"
129 + umount "$tmpmnt" 2>/dev/null
130 + rmdir "$tmpmnt" 2>/dev/null
131 + exit 1
132 + fi
133 + bootmnt=$(parsefstab < "$tmpmnt/etc/fstab" | grep " /boot ") || true
134 + if [ -z "$bootmnt" ]; then
135 + # /boot is part of the root
136 + bootpart="$partition"
137 + bootsv="$subvol"
138 + elif echo "$bootmnt" | cut -d ' ' -f 3 | grep -q "btrfs"; then
139 + # separate btrfs /boot subvolume
140 + bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | grep "^subvol=" | sed "s/subvol=//" )
141 + bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | grep "^UUID=" | sed "s/UUID=//" )
142 + debug "mounting btrfs $tmpmnt/boot UUID=$bootuuid subvol=$bootsv"
143 + bindfrom=$(check_btrfs_mounted $bootsv $bootuuid)
144 + if [ -n "$bindfrom" ]; then
145 + # already mounted some place
146 + if ! mount -o bind $bindfrom "$tmpmnt/boot" 2>/dev/null; then
147 + warn "error bind mounting btrfs boot subvol=$bootsv, from=$bindfrom"
148 + umount "$tmpmnt/boot" 2>/dev/null
149 + umount "$tmpmnt" 2>/dev/null
150 + rmdir "$tmpmnt" 2>/dev/null
151 + exit 1
152 + fi
153 + elif ! mount -o subvol=$bootsv -t btrfs -U $bootuuid "$tmpmnt/boot" 2>/dev/null; then
154 + warn "error mounting btrfs boot partition subvol=$bootsv, UUID=$bootuuid"
155 + umount "$tmpmnt/boot" 2>/dev/null
156 + umount "$tmpmnt" 2>/dev/null
157 + rmdir "$tmpmnt" 2>/dev/null
158 + exit 1
159 + fi
160 + bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " /$bootsv " | cut -d ' ' -f 10)
161 + else
162 + # non-btrfs partition or logical volume
163 + linux_mount_boot $partition $tmpmnt
164 + bootpart="${mountboot%% *}"
165 + bootsv=
166 + fi
168 + test="/usr/lib/linux-boot-probes/mounted/40grub2"
169 + if [ -f $test ] && [ -x $test ]; then
170 + debug "running $test $partition $bootpart $tmpmnt $type $subvol $bootsv"
171 + if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvol" "$bootsv"; then
172 + debug "$test succeeded"
173 + fi
174 + fi
175 + umount "$tmpmnt/boot" 2>/dev/null || true
176 + if ! umount "$tmpmnt" 2>/dev/null; then
177 + warn "problem umount $tmpmnt"
178 + fi
179 + rmdir "$tmpmnt" 2>/dev/null || true
181 + exit 0
184 if ! mapped="$(mapdevfs "$partition")"; then
185 log "Device '$partition' does not exist; skipping"
186 continue
187 @@ -22,8 +149,8 @@ fi
189 if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map"; then
190 for test in /usr/lib/linux-boot-probes/*; do
191 - debug "running $test"
192 if [ -x $test ] && [ -f $test ]; then
193 + debug "running $test"
194 if $test "$partition"; then
195 debug "linux detected by $test"
196 break
197 diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
198 index 885614e..db5cbfd 100755
199 --- a/linux-boot-probes/mounted/common/40grub2
200 +++ b/linux-boot-probes/mounted/common/40grub2
201 @@ -2,17 +2,30 @@
202 . /usr/share/os-prober/common.sh
203 set -e
205 +# add support for btrfs with no separate /boot
206 +# that is, rootsv = bootsv
207 partition="$1"
208 bootpart="$2"
209 mpoint="$3"
210 type="$4"
211 +rootsv="$5"
212 +bootsv="$6"
214 found_item=0
216 entry_result () {
217 + if [ "x$type" = "xbtrfs" -a "$partition" = "$bootpart" ]; then
218 + # trim off the leading subvol
219 + kernelfile=$(echo "$kernel" | cut -d '/' -f 2- | cut -d '/' -f 2-)
220 + if [ "x$rootsv" != "x$bootsv" ]; then
221 + kernelfile="/boot/$kernelfile"
222 + fi
223 + else
224 + kernelfile=$kernel
225 + fi
226 if [ "$ignore_item" = 0 ] && \
227 [ -n "$kernel" ] && \
228 - [ -e "$mpoint/$kernel" ]; then
229 + [ -e "$mpoint/$kernelfile" ]; then
230 result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
231 found_item=1
233 diff --git a/os-prober b/os-prober
234 index 8852887..482c3c2 100755
235 --- a/os-prober
236 +++ b/os-prober
237 @@ -76,9 +76,12 @@ partitions () {
239 # Also detect OSes on LVM volumes (assumes LVM is active)
240 if type lvs >/dev/null 2>&1; then
241 - echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name |
242 + echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name 2>/dev/null |
243 sed "s|-|--|g;s|^[[:space:]]*\(.*\):\(.*\)$|/dev/mapper/\1-\2|")"
246 + # now lets make sure we got all of the btrfs partitions and disks
247 + blkid | grep 'TYPE="btrfs"' | cut -d ':' -f 1
250 parse_proc_swaps () {
251 @@ -136,6 +139,8 @@ if [ -f /proc/mdstat ] ; then
252 grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true
255 +: >"$OS_PROBER_TMP/btrfs-vols"
257 for partition in $(partitions); do
258 if ! mapped="$(mapdevfs "$partition")"; then
259 log "Device '$partition' does not exist; skipping"
260 @@ -154,7 +159,26 @@ for partition in $(partitions); do
261 continue
264 - if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
265 + # do btrfs processing here; both mounted and unmounted will
266 + # be handled by 50mounted-tests so we can do a subvol only once.
267 + type=$(blkid -o value -s TYPE $mapped || true)
268 + if [ "$type" = btrfs ]; then
269 + uuid=$(blkid -o value -s UUID $mapped)
270 + if grep -q "^$uuid" "$OS_PROBER_TMP/btrfs-vols" ; then
271 + continue
272 + fi
273 + debug "btrfs volume uuid=$uuid partition=$partition"
274 + echo "$uuid" >>"$OS_PROBER_TMP/btrfs-vols"
275 + test="/usr/lib/os-probes/50mounted-tests"
276 + if [ -f "$test" ] && [ -x "$test" ]; then
277 + debug "running $test on btrfs $partition"
278 + if "$test" btrfs "$uuid" "$partition"; then
279 + debug "os detected by $test"
280 + continue
281 + fi
282 + fi
284 + elif ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
285 for test in /usr/lib/os-probes/*; do
286 if [ -f "$test" ] && [ -x "$test" ]; then
287 debug "running $test on $partition"
288 diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests
289 index 2951ef9..e33eb82 100755
290 --- a/os-probes/common/50mounted-tests
291 +++ b/os-probes/common/50mounted-tests
292 @@ -19,19 +19,31 @@ do_unmount() {
293 rmdir "$tmpmnt" || true
296 -types="$(fs_type "$partition")"
297 +if [ "x$1" = xbtrfs ]; then
298 + types=btrfs
299 + if [ -z "$2" -o -z "$3" ]; then
300 + debug "missing btrfs parameters, exiting"
301 + exit 1
302 + fi
303 + UUID="$2"
304 + BTRFSDEV="$3"
305 +else
306 + partition="$1"
307 + types="$(fs_type "$partition")" || types=NOT-DETECTED
310 if [ "$types" = NOT-DETECTED ]; then
311 debug "$1 type not recognised; skipping"
312 - exit 0
313 + exit 1
314 elif [ "$types" = swap ]; then
315 debug "$1 is a swap partition; skipping"
316 - exit 0
317 + exit 1
318 elif [ "$types" = crypto_LUKS ]; then
319 debug "$1 is a LUKS partition; skipping"
320 - exit 0
321 + exit 1
322 elif [ "$types" = LVM2_member ]; then
323 debug "$1 is an LVM member; skipping"
324 - exit 0
325 + exit 1
326 elif [ "$types" = ntfs ]; then
327 if type ntfs-3g >/dev/null 2>&1; then
328 types='ntfs-3g ntfs'
329 @@ -40,7 +52,7 @@ elif [ -z "$types" ]; then
330 if type cryptsetup >/dev/null 2>&1 && \
331 cryptsetup luksDump "$partition" >/dev/null 2>&1; then
332 debug "$1 is a LUKS partition; skipping"
333 - exit 0
334 + exit 1
336 for type in $(grep -v nodev /proc/filesystems); do
337 # hfsplus filesystems are mountable as hfs. Try hfs last so
338 @@ -63,6 +75,108 @@ if [ ! -d "$tmpmnt" ]; then
341 mounted=
343 +# all btrfs processing here. Handle both unmounted and
344 +# mounted subvolumes.
345 +if [ "$types" = btrfs ]; then
346 + partition="$BTRFSDEV"
347 + debug "begin btrfs processing for $UUID"
348 + # note that the btrfs volume must not be mounted ro
349 + if mount -t btrfs -U "$UUID" "$tmpmnt" 2>/dev/null; then
350 + debug "btrfs volume $UUID mounted"
351 + else
352 + warn "cannot mount btrfs volume $UUID, exiting"
353 + rmdir "$tmpmnt" || true
354 + exit 1
355 + fi
356 + # besides regular subvols, get ro and snapshot so thet can be excluded
357 + subvols=$(btrfs subvolume list "$tmpmnt" | cut -d ' ' -f 9)
358 + rosubvols=$(btrfs subvolume list -r "$tmpmnt" | cut -d ' ' -f 9)
359 + sssubvols=$(btrfs subvolume list -s "$tmpmnt" | cut -d ' ' -f 14)
360 + if ! umount "$tmpmnt"; then
361 + warn "failed to umount btrfs volume on $tmpmnt"
362 + rmdir "$tmpmnt" || true
363 + exit 1
364 + fi
366 + found=
367 + mounted=
369 + mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | cut -d ' ' -f 5)"
370 + if [ -n "$mpoint" -a "x$mpoint" = "x/" ]; then
371 + debug "This is the root for the running system" #running system must be done elsewhere
372 + else
373 + #partition was not root of running system, so lets look for bootable subvols
374 + if [ -n "$mpoint" ] ; then
375 + mounted=1 #partition was already mounted,so lets not unmount it when done
376 + else
377 + # again, do not mount btrfs ro
378 + mount -t btrfs -U "$UUID" "$tmpmnt"
379 + mpoint="$tmpmnt"
380 + fi
382 + test="/usr/lib/os-probes/mounted/90linux-distro"
383 + if [ -f "$test" ] && [ -x "$test" ]; then
384 + debug "running subtest $test"
385 + if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID"; then
386 + debug "os found by subtest $test on $partition"
387 + found=1
388 + fi
389 + fi
390 + if [ -z "$mounted" ]; then
391 + if ! umount "$tmpmnt"; then
392 + warn "failed to umount $tmpmnt"
393 + fi
394 + fi
395 + fi
397 + if [ -z "$subvols" ]; then
398 + debug "no subvols found on btrfs volume $UUID"
399 + else
400 + found=
401 + for subvol in $subvols; do
402 + debug "begin btrfs processing for $UUID subvol=$subvol"
403 + if echo "$rosubvols" | grep -q -x "$subvol"; then
404 + continue
405 + fi
406 + if echo "$sssubvols" | grep -q -x "$subvol"; then
407 + continue
408 + fi
409 + mounted=
410 + mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)"
411 + if [ -n "$mpoint" ]; then
412 + if [ "x$mpoint" = "x/" ]; then
413 + continue # this is the root for the running system
414 + fi
415 + mounted=1
416 + else
417 + # again, do not mount btrfs ro
418 + mount -t btrfs -o subvol="$subvol" -U "$UUID" "$tmpmnt"
419 + mpoint="$tmpmnt"
420 + fi
421 + test="/usr/lib/os-probes/mounted/90linux-distro"
422 + if [ -f "$test" ] && [ -x "$test" ]; then
423 + debug "running subtest $test"
424 + if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID" "subvol=$subvol"; then
425 + debug "os found by subtest $test on subvol $subvol"
426 + found=1
427 + fi
428 + fi
429 + if [ -z "$mounted" ]; then
430 + if ! umount "$tmpmnt"; then
431 + warn "failed to umount $tmpmnt"
432 + fi
433 + fi
434 + done
435 + fi
436 + rmdir "$tmpmnt" || true
437 + if [ "$found" ]; then
438 + exit 0
439 + else
440 + exit 1
441 + fi
444 if type grub-mount >/dev/null 2>&1 && \
445 type grub-probe >/dev/null 2>&1 && \
446 grub-mount "$partition" "$tmpmnt" 2>/dev/null; then
447 diff --git a/os-probes/mounted/common/90linux-distro b/os-probes/mounted/common/90linux-distro
448 index badfbb1..9bc5154 100755
449 --- a/os-probes/mounted/common/90linux-distro
450 +++ b/os-probes/mounted/common/90linux-distro
451 @@ -7,6 +7,8 @@ set -e
452 partition="$1"
453 dir="$2"
454 type="$3"
455 +uuid="$4"
456 +subvol="$5"
458 # This test is inaccurate, but given separate / and /boot partitions and the
459 # fact that only some architectures have ld-linux.so, I can't see anything
460 @@ -143,7 +145,11 @@ if (ls "$dir"/lib*/ld*.so* && [ -d "$dir/boot" ] || ls "$dir"/usr/lib*/ld*.so*)
463 label="$(count_next_label "$short")"
464 - result "$partition:$long:$label:linux"
465 + if [ "x$type" = "xbtrfs" -a "x$uuid" != "x" -a "x$subvol" != "x" ]; then
466 + result "$partition:$long:$label:linux:$type:$uuid:$subvol"
467 + else
468 + result "$partition:$long:$label:linux"
469 + fi
470 exit 0
471 else
472 exit 1