Login
Log in using an SSO provider:
Fedora Account System
Red Hat Associate
Red Hat Customer
Login using a Red Hat Bugzilla account
Forgot Password
Create an Account
Red Hat Bugzilla – Attachment 652201 Details for
Bug 875356
OS prober is slow
Home
New
Search
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh90 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
[?]
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch against os-prober-1.56
os-prober-1.56-ORIGIN.patch (text/plain), 67.26 KB, created by
John Reiser
on 2012-11-26 19:04:33 UTC
(
hide
)
Description:
patch against os-prober-1.56
Filename:
MIME Type:
Creator:
John Reiser
Created:
2012-11-26 19:04:33 UTC
Size:
67.26 KB
patch
obsolete
>diff --git a/common.sh b/common.sh >index 82d019e..3c9b0cf 100644 >--- a/common.sh >+++ b/common.sh >@@ -5,10 +5,9 @@ newns () { > cleanup_tmpdir=false > cleanup_ro_partitions= > cleanup () { >- local partition >- for partition in $cleanup_ro_partitions; do >- blockdev --setrw "$partition" >- done >+ if [ "$cleanup_ro_partitions" ]; then >+ blockdev --setrw $cleanup_ro_partitions >+ fi > if $cleanup_tmpdir; then > rm -rf "$OS_PROBER_TMP" > fi >@@ -57,16 +56,75 @@ progname= > cache_progname() { > case $progname in > '') >- progname="$(basename "$0")" >+ progname="${0##*/}" > ;; > esac > } > >-log() { >- cache_progname >- logger -t "$progname" "$@" >+path_lookup() { >+ local _t >+ unset $1 # default to failure >+ if _t=$(type "$1" 2>/dev/null); then >+ set -- $_t # "app is /path/to/app" >+ eval $1=\"$3\" >+ fi >+} >+ >+strmid_extract() { # str left right; let str= a $2 b $3 c >+ local _b3c _b >+ eval '_b3c="${1#*'\\"$2"'}"' >+ eval '_b="${_b3c%'\\"$3"'*}"' >+ if [ "$_b3c" != "$1" -a "$_b" != "$_b3c" ]; then >+ # both prefix and suffix were removed >+ value="$_b" >+ else >+ value="" # one was missing >+ fi >+} >+ >+strmid_delete() { # str left right; let str= a $2 b $3 c >+ local _a _c >+ eval '_a="${1%%'\\"$2"'*}"' >+ eval '_c="${1##*'\\"$3"'}"' >+ if [ ${#1} -ge $(( ${#_a} + 2 + ${#_c} )) ]; then >+ # there was a middle >+ value="$_a$_c" >+ else >+ value="$1" # one was missing >+ fi >+} >+ >+strchar_delete() { # str char >+ _IFS="$IFS" >+ IFS="$2"; set -- $1 >+ IFS=""; value="$*" >+ IFS="$_IFS" >+} >+ >+strcat_sep_split() { # sep split str >+ local _sep _split >+ _sep="$1"; _split="$2"; shift 2 >+ _IFS="$IFS" >+ IFS="$_split"; set -- $1 # adjacent splitters give only one cut >+ IFS="$_sep"; value="$*" >+ IFS="$_IFS" >+} >+ >+# Single-quote "'" cannot be single quoted, because backslash does not escape. >+_PUNCT="'"'!"#$%&()*+,-./:;<=>?@[\]^`{|}~' # non-whitespace non-identifier >+ >+str_tame() { # make $1 into an identifier >+ strcat_sep_split '_' "$_PUNCT" "$1" # result is $value > } > >+# fd_logger: bind value now, possibly after assigning default. >+eval ' >+ log() { >+ cache_progname >+ echo "$progname: $@" 1>&'${fd_logger:=9}' >+ } >+' >+ > error() { > log "error: $@" > } >@@ -79,10 +137,14 @@ debug() { > log "debug: $@" > } > >-result () { >- log "result:" "$@" >- echo "$@" >-} >+ >+# fd_result: bind value now, possibly after assigning default. >+eval ' >+ result() { >+ log "result:" "$@" >+ echo "$@" 1>&'${fd_result:=1}' >+ } >+' > > # shim to make it easier to use os-prober outside d-i > if ! type mapdevfs >/dev/null 2>&1; then >@@ -106,21 +168,20 @@ item_in_dir () { > # We can't always tell the filesystem type up front, but if we have the > # information then we should use it. Note that we can't use block-attr here > # as it's only available in udebs. >-fs_type () { >- if (export PATH="/lib/udev:$PATH"; type vol_id) >/dev/null 2>&1; then >- PATH="/lib/udev:$PATH" vol_id --type "$1" 2>/dev/null >- elif type blkid >/dev/null 2>&1; then >- blkid -o value -s TYPE "$1" 2>/dev/null >- else >- return 0 >- fi >+define__fs_type() { # needed so that "set --" does not change $1 of main program! >+ PATH="/lib/udev:$PATH" path_lookup vol_id; if [ "$vol_id" ]; then >+ eval 'fs_type() { '$vol_id' --type "$1" 2>/dev/null; }' >+ else path_lookup blkid; if [ "$blkid" ]; then >+ eval 'fs_type() { '$blkid' -o value -s TYPE "$1" 2>/dev/null; }' >+ else >+ fs_type() { return 0; } >+ fi; fi > } >+define__fs_type > > parse_proc_mounts () { > while read -r line; do >- set -f >- set -- $line >- set +f >+ set -f; set -- $line; set +f > printf '%s %s %s\n' "$(mapdevfs "$1")" "$2" "$3" > done > } >@@ -132,56 +193,56 @@ parsefstab () { > : > ;; > *) >- set -f >- set -- $line >- set +f >+ set -f; set -- $line; set +f > printf '%s %s %s\n' "$1" "$2" "$3" > ;; > esac > done > } > >+# Change encoded <tab><newline><space><backslash> back to actual characters. > unescape_mount () { > printf %s "$1" | \ > sed 's/\\011/ /g; s/\\012/\n/g; s/\\040/ /g; s/\\134/\\/g' > } > >-ro_partition () { >- if type blockdev >/dev/null 2>&1 && \ >- [ "$(blockdev --getro "$1")" = 0 ] && \ >- blockdev --setro "$1"; then >- cleanup_ro_partitions="${cleanup_ro_partitions:+$cleanup_ro_partitions }$1" >+define__ro_partition() { >+ path_lookup blockdev; if [ "$blockdev" ]; then eval ' >+ ro_partition() { >+ if [ "$('$blockdev' --getro "$1")" = 0 ] \ >+ && '$blockdev' --setro "$1"; then >+ cleanup_ro_partitions="$cleanup_ro_partitions $1" > trap cleanup EXIT HUP INT QUIT TERM >- fi >-} >- >-find_label () { >- local output >- if type blkid >/dev/null 2>&1; then >- # Hopefully everyone has blkid by now >- output="$(blkid -o device -t LABEL="$1")" || return 1 >- echo "$output" | head -n1 >- elif [ -h "/dev/disk/by-label/$1" ]; then >- # Last-ditch fallback >- readlink -f "/dev/disk/by-label/$1" >- else >- return 1 >- fi >+ fi >+ }' >+ else >+ ro_partition() { :; } # ignore, for benefit of "set -e" >+ fi > } >+define__ro_partition > >-find_uuid () { >- local output >- if type blkid >/dev/null 2>&1; then >- # Hopefully everyone has blkid by now >- output="$(blkid -o device -t UUID="$1")" || return 1 >- echo "$output" | head -n1 >- elif [ -h "/dev/disk/by-uuid/$1" ]; then >- # Last-ditch fallback >- readlink -f "/dev/disk/by-uuid/$1" >- else >- return 1 >- fi >+define__find__kind() { >+ local name="$1" >+ local NAME="$2" >+ path_lookup blkid; if [ "$blkid" ]; then eval ' >+ find_'$name'() { >+ local output >+ output="$('$blkid' -o device -t '$NAME'="$1")" || return 1 >+ echo "$output" | head -n1 >+ }' >+ else eval ' >+ find_'$name'() { >+ if [ -h "/dev/disk/by-'$name'/$1" ]; then >+ readlink -f "/dev/disk/by-'$name'/$1" >+ else >+ return 1 >+ fi >+ }' >+ fi > } >+define__find__kind label LABEL # find_label() >+define__find__kind uuid UUID # find_uuid() >+set +x > > # Sets $mountboot as output variable. (We do this rather than requiring a > # subshell so that we can run ro_partition without the cleanup trap firing >@@ -196,9 +257,7 @@ linux_mount_boot () { > # Try to mount any /boot partition. > bootmnt=$(parsefstab < "$tmpmnt/etc/fstab" | grep " /boot ") || true > if [ -n "$bootmnt" ]; then >- set -f >- set -- $bootmnt >- set +f >+ set -f; set -- $bootmnt; set +f > boottomnt="" > > # Try to map labels and UUIDs ourselves if possible, >@@ -283,3 +342,15 @@ linux_mount_boot () { > > mountboot="$bootpart $mounted" > } >+ >+linux_unmount_boot() { >+ mpoint="$1" um_root="$2" um_boot="$3" >+ if [ 1 == "$um_boot" ]; then >+ umount "$mpoint/boot" >+ rmdir "$mpoint/boot" 2>/dev/null || true >+ fi >+ if [ 1 == "$um_root" ]; then >+ umount "$mpoint" >+ rmdir "$mpoint" >+ fi >+} >diff --git a/linux-boot-prober b/linux-boot-prober >index ee8f2b9..4298c1b 100755 >--- a/linux-boot-prober >+++ b/linux-boot-prober >@@ -1,14 +1,50 @@ > #!/bin/sh >-. /usr/share/os-prober/common.sh >- > set -e > >+# $1: optional alternate root for scripts in this package >+# (for testing without install, etc.) >+# Use the default directories if $1 is not supplied. >+export execpfx="${1:-/usr/share/os-prober}" >+export libexecpfx="${1:-/usr/libexec}/linux-boot-probes" >+ >+# dash shell does not have "{varname}>&1" feature that bash shell has >+# for auto-assignment of new filedescriptors. >+# It is cumbersome to write the 'eval' to use our own variables. >+# Therefore use fixed numbers. >+export fd_result=3 # file descriptor for external results >+export fd_logger=9 # file descriptor for input to logger >+ >+. $execpfx/common.sh # note: binds fd_result and fd_logger >+ > newns "$@" > require_tmpdir > >+pipe_mounted="" >+for test in $libexecpfx/mounted/* \ >+ $libexecpfx/mounted/x86/* \ >+ $libexecpfx/mounted/common/* # last two lines: test without install >+do >+ if [ -r "$test" -a -x "$test" -a ! -d "$test" ]; then >+ pipe_mounted="$pipe_mounted|$test" >+ fi >+done >+pipe_mounted="${pipe_mounted#|}" >+# echo pipe_mounted= "$pipe_mounted" 1>&2 >+ >+pipe_not_yet="" >+for test in $libexecpfx/*; do >+ if [ -r "$test" -a -x "$test" -a ! -d "$test" ]; then >+ pipe_not_yet="$pipe_not_yet|$test" >+ fi >+done >+pipe_not_yet="${pipe_not_yet#|}" >+# echo pipe_not_yet= "$pipe_not_yet" 1>&2 >+ > grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true > >-partition="$1" >+ >+# READ partition FROM STDIN (THIS IS A CHANGE FROM PREVIOUS USAGE.) >+( ( ( while read partition; do > > if [ -z "$partition" ]; then > echo "usage: linux-boot-prober partition" >&2 >@@ -21,41 +57,31 @@ if ! mapped="$(mapdevfs "$partition")"; then > fi > > if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map"; then >- for test in /usr/libexec/linux-boot-probes/*; do >- debug "running $test" >- if [ -x $test ] && [ -f $test ]; then >- if $test "$partition"; then >- debug "linux detected by $test" >- break >- fi >- fi >- done >+ echo "$partition" # pipe_not_yet > else > mpoint=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2) > mpoint="$(unescape_mount "$mpoint")" >- if [ "$mpoint" != "/target/boot" ] && [ "$mpoint" != "/target" ] && [ "$mpoint" != "/" ]; then >+ if [ "$mpoint" != "/target/boot" \ >+ -a "$mpoint" != "/target" \ >+ -a "$mpoint" != "/" ]; then > type=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 3) > if ! grep -q " $mpoint/boot " "$OS_PROBER_TMP/mounted-map"; then >- linux_mount_boot "$partition" "$mpoint" >+ linux_mount_boot "$partition" "$mpoint" # mountboot="$bootpart $mounted" > bootpart="${mountboot%% *}" > bootmounted="${mountboot#* }" > else > bootpart="$partition" > bootmounted=0 > fi >- for test in /usr/libexec/linux-boot-probes/mounted/*; do >- if [ -f $test ] && [ -x $test ]; then >- debug "running $test on mounted $partition" >- if $test "$partition" "$bootpart" "$mpoint" "$type"; then >- debug "$test succeeded" >- break >- fi >- fi >- done >- if [ "$bootmounted" = 1 ]; then >- if ! umount "$mpoint/boot"; then >- warn "failed to umount $mpoint/boot" >- fi >- fi >+ echo "$partition $bootpart $mpoint $type 0 $bootmounted" 1>&8 # pipe_mounted > fi > fi >+ >+done \ >+ | eval "${pipe_not_yet}" >+) 8>&1 | eval "${pipe_mounted}" \ >+ | while read line; do echo "\?unknown $line"; done 1>&2 >+) 9>&1 | logger 1>&- # fd_logger >+) 3>&1 # fd_result >+ >+# EOF linux-boot-prober >diff --git a/linux-boot-probes/common/50mounted-tests b/linux-boot-probes/common/50mounted-tests >index b649663..481255f 100755 >--- a/linux-boot-probes/common/50mounted-tests >+++ b/linux-boot-probes/common/50mounted-tests >@@ -3,35 +3,45 @@ > . /usr/share/os-prober/common.sh > set -e > >-partition="$1" >+tmpmntdir=/var/lib/os-prober/mount >+mkdir "$tmpmntdir" >/dev/null 2>&1 || true >+(cd $tmpmntdir >+ umount -f lbp* >/dev/null 2>&1 || true >+ rmdir lbp* >/dev/null 2>&1 || true >+) > >+while read partition; do >+ >+tmpmnt=$tmpmntdir/lbp$(( mount_count+=1 )) >+mkdir $tmpmnt >+ >+xtra_types="" > types="$(fs_type "$partition")" || types=NOT-DETECTED >-if [ "$types" = NOT-DETECTED ]; then >+case "$types" in >+ NOT-DETECTED) > debug "$1 type not recognised; skipping" >- exit 0 >-elif [ "$types" = swap ]; then >+ continue ;; >+ swap) > debug "$1 is a swap partition; skipping" >- exit 0 >-elif [ "$types" = crypto_LUKS ]; then >+ continue ;; >+ crypto_LUKS) > debug "$1 is a LUKS partition; skipping" >- exit 0 >-elif [ "$types" = ntfs ]; then >+ continue ;; >+ ntfs) > if type ntfs-3g >/dev/null 2>&1; then >- types='ntfs-3g ntfs' >- fi >-elif [ -z "$types" ]; then >+ xtra_types='ntfs-3g ntfs' >+ fi ;; >+ ?*) # non-null >+ xtra_types="$types" ;; # guess this one first >+ '') # null > if type cryptsetup >/dev/null 2>&1 && \ > cryptsetup luksDump "$partition" >/dev/null 2>&1; then > debug "$1 is a LUKS partition; skipping" >- exit 0 >+ continue > fi > types="$(grep -v nodev /proc/filesystems)" >-fi >- >-tmpmnt=/var/lib/os-prober/mount >-if [ ! -d "$tmpmnt" ]; then >- mkdir "$tmpmnt" >-fi >+ ;; >+esac > > mounted= > if type grub-mount >/dev/null 2>&1 && \ >@@ -51,32 +61,13 @@ else > fi > > if [ "$mounted" ]; then >- linux_mount_boot "$partition" "$tmpmnt" >+ linux_mount_boot "$partition" "$tmpmnt" # mountboot="$bootpart $mounted" > bootpart="${mountboot%% *}" > mounted="${mountboot#* }" > >- for test in /usr/libexec/linux-boot-probes/mounted/*; do >- if [ -f "$test" ] && [ -x "$test" ]; then >- debug "running $test $partition $bootpart $tmpmnt $type" >- if $test "$partition" "$bootpart" "$tmpmnt" "$type"; then >- debug "$test succeeded" >- umount "$tmpmnt/boot" 2>/dev/null || true >- if ! umount "$tmpmnt"; then >- warn "failed to umount $tmpmnt" >- fi >- rmdir "$tmpmnt" || true >- exit 0 >- fi >- fi >- done >- >- umount "$tmpmnt/boot" 2>/dev/null || true >- if ! umount "$tmpmnt"; then >- warn "failed to umount $tmpmnt" >- fi >+ echo "$partition $bootpart $tmpmnt $type 1 $mounted" # 1: must unmount >+else >+ rmdir "$tmpmnt" || : > fi > >-rmdir "$tmpmnt" || true >- >-# No tests found anything. >-exit 1 >+done >diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2 >index 885614e..49acfd5 100755 >--- a/linux-boot-probes/mounted/common/40grub2 >+++ b/linux-boot-probes/mounted/common/40grub2 >@@ -1,19 +1,12 @@ > #!/bin/sh >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > set -e > >-partition="$1" >-bootpart="$2" >-mpoint="$3" >-type="$4" >- >-found_item=0 >- > entry_result () { > if [ "$ignore_item" = 0 ] && \ > [ -n "$kernel" ] && \ > [ -e "$mpoint/$kernel" ]; then >- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" >+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" # success > found_item=1 > fi > kernel="" >@@ -23,6 +16,11 @@ entry_result () { > ignore_item=0 > } > >+parse_done () { >+ debug "${0##*/}: $parse_part: $lineno lines from $parse_file" >+ debug "${0##*/}: $parse_part: $on_dev \"(on /dev/...)\" were ignored" >+} >+ > parse_grub_menu () { > mpoint="$1" > rootpart="$2" >@@ -33,78 +31,158 @@ parse_grub_menu () { > initrd="" > title="" > ignore_item=0 >+ lineno=0 >+ on_dev=0 >+ local OLDIFS="$IFS" >+ local _t > > while read line; do >- debug "parsing: $line" >- set -f >- set -- $line >- set +f >+ (( ++lineno )) >+ # debug "parsing: $line" >+ set -f; set -- $line; set +f # apply IFS; do not expand filenames > case "$1" in >- menuentry) >- entry_result >- shift 1 >- # The double-quoted string is the title. >- # Make sure to look at the text of the line >- # before 'set' mangled it. >- title="$(echo "$line" | sed -n 's/[^"]*"\(.*\)".*/\1/p' | sed 's/://g')" >- if [ -z "$title" ]; then >- # ... or single-quoted? Be careful >- # to handle constructions like >- # 'foo'\''bar' (which expands to >- # foo'bar, as in shell), and to >- # handle multiple single-quoted >- # strings on the same line. >- title="$(echo "$line" | sed -n "s/[^']*'\(\([^']\|'\\\\''\)*\)'.*/\1/p" | sed "s/'\\\\''/'/; s/://g")" >- fi >- if [ -z "$title" ]; then >- ignore_item=1 >- elif echo "$title" | grep -q '(on /dev/[^)]*)$'; then >- log "Skipping entry '$title':" >- log "appears to be an automatic reference taken from another menu.lst" >- ignore_item=1 >- fi >+ menuentry) >+ # In each case we remove : because we use a colon >+ # to separate fields in the output. >+ entry_result >+ shift 1 >+ >+# Shell should provide a "tokenize" operator much like 'set'. The output >+# for a literal string would be a prefix of '"', followed by the value. >+# The difficulty is handling escapes (backslashes). >+# >+# We cannot use 'eval' to tokenize, then take the second token: >+# set -f; eval 'IFS="" set -- '"${line}"; set +f # IFS: split no more! >+# echo $2 # the token after the key word >+# because 'eval' detects syntax errors. (Knowing where the quoting ends >+# is equivalent to lexing the string in the first place.) >+# >+# However, we can try the easy case first, before resorting to 'sed'. >+ >+ case "$1" in >+ \"*) IFS='\'; set -f; set -- $line; set +f # detect backslash >+ IFS="$OLDIFS" >+ if (( 1 == $# )); then # no backslash >+ IFS='"'; set -f; set -- $line; set +f # split at double quote >+ IFS="$OLDIFS" >+ strchar_delete "$2" ':'; title="$value" >+ else # the hard case >+ title="$(echo "$line" | >+ $sed -n 's/[^"]*"\(\(\\[$`"\\]\|[^"]\)*\)".*/\1/p' | >+# The $sed above extracts the (longest) left-most double-quoted string, if any. >+# The outer \( \) delimit what will be remembered for \1 . >+# The inner \( \| \)* is a repeated alternation of two choices. >+# The first choice is backslash followed by dollar, backtick, double quote, >+# or backslash; those are the characters for which backslash retains its >+# meaning as an escape character within double quotes. >+# The second choice is any character other than a double quote. >+# A bare double quote would be the terminator. >+ $sed 's/\\\([$`"\\]\)/\1/g; s/://g' )" >+# The $sed above evaluates the double quoting by processing the backslash >+# escapes which are legal within double quotes. >+ fi > ;; >- linux) >- # Hack alert: sed off any (hdn,n) but >- # assume the kernel is on the same >- # partition. >- kernel="$(echo "$2" | sed 's/(.*)//')" >- shift 2 >- parameters="$@" >- # Systems with a separate /boot will not have >- # the path to the kernel in grub.cfg. >- if [ "$partition" != "$bootpart" ]; then >- kernel="/boot$kernel" >- fi >+ \'*) IFS='\'; set -f; set -- $line; set +f # detect backslash >+ IFS="$OLDIFS" >+ if (( 1 == $# )); then # no backslash >+ IFS="'"; set -f; set -- $line; set +f # split at single quote >+ IFS="$OLDIFS" >+ strchar_delete "$2" ':'; title="$value" >+ else # the hard case >+ title="$(echo "$line" | >+ $sed -n "s/[^']*'\(\([^']\|'\(\\\\'\)*'\)*\)'.*/\1/p" | >+# The $sed above extracts the (longest) left-most single-quoted string, if any. >+# The outer \( \) delimit what will be remembered for \1 . >+# The middle \( \| \)* is a repeated alternation of two choices. >+# The first choice is any character other than single quote. >+# The second choice is two single quotes which surround any number of \' , >+# which reads as that number of embedded single quotes. 'a'\'\''b' => "a''b" >+ $sed "s/\\\\'/'/g; s/'\\('*\\)'/\\1/g; s/://g" )" >+# The $sed above evaluates the single quoting. >+# Any \' becomes that single quote. >+# Then a run of at least two single quotes becomes the interior of that run. >+ fi > ;; >- initrd) >- initrd="$(echo "$2" | sed 's/(.*)//')" >- # Initrd same. >- if [ "$partition" != "$bootpart" ]; then >- initrd="/boot$initrd" >- fi >- ;; >- "}") >- entry_result >+ *) strchr_delete "$1" ':'; title="$value" > ;; >+ esac >+ >+ _t="${title%(on /dev/[!)]*)}" # speculative >+ if [ -z "$title" ]; then >+ ignore_item=1 >+ elif [ ${#_t} -ne ${#title} ]; then # was "(on /dev/...)" >+ if (( ++on_dev <= 2 )); then >+log "Skipping entry '$title':" >+log "appears to be an automatic reference taken from another menu.lst" >+ if (( on_dev == 2)); then >+log "Further \"(on /dev/...)\" entries will be counted but not logged." >+ fi >+ fi >+ ignore_item=1 >+ fi >+ ;; >+ linux) >+ # Hack alert: sed off any (hdn,n) but >+ # assume the kernel is on the same >+ # partition. >+ #kernel="$(echo "$2" | $sed 's/(.*)//')" >+ strmid_delete "$2" "(" ")"; kernel="$value" >+ shift 2 >+ parameters="$@" >+ # Systems with a separate /boot will not have >+ # the path to the kernel in grub.cfg. >+ if [ "$partition" != "$bootpart" ]; then >+ kernel="/boot$kernel" >+ fi >+ ;; >+ initrd) >+ #initrd="$(echo "$2" | $sed 's/(.*)//')" >+ strmid_delete "$2" "(" ")"; initrd="$value" >+ # Initrd same. >+ if [ "$partition" != "$bootpart" ]; then >+ initrd="/boot$initrd" >+ fi >+ ;; >+ "}") >+ entry_result >+ ;; > esac > done > > entry_result > } > >-if [ -e "$mpoint/boot/grub/grub.cfg" ] && \ >- ([ ! -e "$mpoint/boot/grub/menu.lst" ] || \ >- [ "$mpoint/boot/grub/grub.cfg" -nt "$mpoint/boot/grub/menu.lst" ]); then >- debug "parsing grub.cfg" >- parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub/grub.cfg" >-elif [ -e "$mpoint/boot/grub2/grub.cfg" ]; then >- debug "parsing grub.cfg" >- parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub2/grub.cfg" >+path_lookup sed # find 'sed' in $PATH; set $sed >+export sed # for sub-shells >+ >+trap parse_done EXIT HUP INT QUIT TERM >+ >+while read partition bootpart mpoint type um_root um_boot; do >+# echo $0: $read $partition $bootpart $mpoint $type $um_root $um_boot 1>&2 >+ >+found_item=0 >+lineno=0 >+ >+parse_part="$partition" >+parse_file="$mpoint/boot/grub/menu.lst" >+if [ -e "$mpoint/boot/grub/grub.cfg" ] \ >+&& [ ! -e "$mpoint/boot/grub/menu.lst" \ >+ -o "$mpoint/boot/grub/grub.cfg" \ >+ -nt "$mpoint/boot/grub/menu.lst" ]; then >+ parse_file="$mpoint/boot/grub/grub.cfg" >+elif [ -e "$mpoint/boot/grub2/grub.cfg" ]; then >+ parse_file="$mpoint/boot/grub2/grub.cfg" >+fi >+if [ "$parse_file" ]; then >+ debug "${0##*/}: $parse_part: parsing $parse_file" >+ parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$parse_file" >+ parse_done > fi > > if [ "$found_item" = 0 ]; then >- exit 1 >+ echo "$partition $bootpart $mpoint $type $um_root $um_boot" # failure > else >- exit 0 >+ linux_unmount_boot "$mpoint" "$um_root" "$um_boot" > fi >+ >+done >diff --git a/linux-boot-probes/mounted/common/90fallback b/linux-boot-probes/mounted/common/90fallback >index 9ff78e1..dbc9700 100755 >--- a/linux-boot-probes/mounted/common/90fallback >+++ b/linux-boot-probes/mounted/common/90fallback >@@ -1,13 +1,11 @@ > #!/bin/sh > # Fallback in case nothing else works. Look for vmlinu[xz] file in root and > # /boot, see if there is a matching initrd, and wing it. >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > set -e > >-partition="$1" >-bootpart="$2" >-mpoint="$3" >-type="$4" >+while read partition bootpart mpoint type um_root um_boot; do >+# echo $0: $read $partition $bootpart $mpoint $type $um_root $um_boot 1>&2 > > mappedpartition=$(mapdevfs "$partition" 2>/dev/null) || mappedpartition="$partition" > >@@ -21,7 +19,7 @@ for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \ > fi > for kernfile in $(eval ls "$mpoint$kernpat" 2>/dev/null); do > kernbasefile=$(echo "$kernfile" | sed "s!^$mpoint!!") >- if [ -f "$kernfile" ] && [ ! -L "$kernfile" ]; then >+ if [ -f "$kernfile" -a ! -L "$kernfile" ]; then > initrdname=$(echo "$kernfile" | sed "s/vmlinu[zx]/initrd\*/") > # Yellow Dog Linux appends .img to it. > initrdname1="${initrdname}.img" >@@ -36,18 +34,28 @@ for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \ > initrdname4=$(echo "$kernfile" | sed "s/kernel/initramfs\*/") > foundinitrd=0 > for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null); do >- if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then >+ if [ "$initrd" != "$kernfile" -a -f "$initrd" -a ! -L "$initrd" ]; then > initrd=$(echo "$initrd" | sed "s!^$mpoint!!") >- result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition" >+result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition" # success > exitcode=0 > foundinitrd=1 > fi > done > if [ "$foundinitrd" = 0 ]; then >- result "$partition:$kernbootpart::$kernbasefile::root=$mappedpartition" >+result "$partition:$kernbootpart::$kernbasefile::root=$mappedpartition" # success > exitcode=0 > fi > fi > done > done >-exit "$exitcode" >+ >+if [ 0 != "$exitcode" ]; then >+ echo "$partition $bootpart $mpoint $type" # failure >+fi >+if [ 0 != "$exitcode" ]; then >+ echo "$partition $bootpart $mpoint $type $um_root $um_boot" # failure >+else >+ linux_unmount_boot "$mpoint" "$um_root" "$um_boot" >+fi >+ >+done >diff --git a/linux-boot-probes/mounted/x86/40grub b/linux-boot-probes/mounted/x86/40grub >index 08f6605..8d501c7 100755 >--- a/linux-boot-probes/mounted/x86/40grub >+++ b/linux-boot-probes/mounted/x86/40grub >@@ -1,19 +1,11 @@ > #!/bin/sh >-. /usr/share/os-prober/common.sh >-set -e >- >-partition="$1" >-bootpart="$2" >-mpoint="$3" >-type="$4" > >-found_item=0 >+. $execpfx/common.sh >+set -e > > entry_result () { >- if [ "$ignore_item" = 0 ] && \ >- [ -n "$kernel" ] && \ >- [ -e "$mpoint/$kernel" ]; then >- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" >+ if [ "$ignore_item" = 0 -a -n "$kernel" -a -e "$mpoint/$kernel" ]; then >+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" # success > found_item=1 > fi > kernel="" >@@ -23,6 +15,10 @@ entry_result () { > ignore_item=0 > } > >+parse_done () { >+ debug "${0##*/}: $parse_part: $lineno lines from $grubconf" >+} >+ > parse_grub_menu () { > mpoint="$1" > rootpart="$2" >@@ -35,16 +31,18 @@ parse_grub_menu () { > ignore_item=0 > > while read line; do >+ (( ++lineno )) > #debug "parsing: $line" >- set -f >- set -- $line >- set +f >+ set -f; set -- $line; set +f > case "$1" in > title) > entry_result > shift 1 >- title="$(echo "$@" | sed 's/://g')" >- if echo "$title" | grep -q '(on /dev/[^)]*)$'; then >+ #title="$(echo "$@" | sed 's/://g')" >+ strchar_delete "$*" ':'; title="$value" >+ #if echo "$title" | grep -q '(on /dev/[^)]*)$'; then >+ _t="${title%(on /dev/[!)]*)}" >+ if [ ${#_t} -ne ${#title} ]; then # was "(on /dev/...)" > log "Skipping entry '$title':" > log "appears to be an automatic reference taken from another menu.lst" > ignore_item=1 >@@ -54,7 +52,8 @@ parse_grub_menu () { > # Hack alert: sed off any (hdn,n) but > # assume the kernel is on the same > # partition. >- kernel="$(echo "$2" | sed 's/(.*)//')" >+ #kernel="$(echo "$2" | sed 's/(.*)//')" >+ strmid_delete "$2" '(' ')'; kernel="$value" > shift 2 > parameters="$@" > # Systems with a separate /boot will not have >@@ -66,7 +65,8 @@ parse_grub_menu () { > initrd) > # Hack alert take 2: sed off any (hdn,n) > # See #566102 >- initrd="$(echo "$2" | sed 's/(.*)//')" >+ #initrd="$(echo "$2" | sed 's/(.*)//')" >+ strmid_delete "$2" '(' ')'; initrd="$value" > # Initrd same. > if [ "$partition" != "$bootpart" ]; then > initrd="/boot$initrd" >@@ -86,6 +86,14 @@ parse_grub_menu () { > entry_result > } > >+trap parse_done EXIT HUP INT QUIT TERM >+ >+while read partition bootpart mpoint type um_root um_boot; do >+# echo $0: $read $partition $bootpart $mpoint $type $um_root $um_boot 1>&2 >+ >+found_item=0 >+lineno=0 >+ > grubconf= > if [ -e "$mpoint/boot/grub/menu.lst" ]; then > grubconf="menu.lst" >@@ -93,15 +101,19 @@ elif [ -e "$mpoint/boot/grub/grub.conf" ]; then > grubconf="grub.conf" > fi > >-if [ "$grubconf" ] && \ >- ([ ! -e "$mpoint/boot/grub/grub.cfg" ] || \ >- [ "$mpoint/boot/grub/$grubconf" -nt "$mpoint/boot/grub/grub.cfg" ]); then >- debug "parsing $grubconf" >+# Parse now using grub1 format unless grub.cfg exists and is newer. >+if [ "$grubconf" -a ! -e "$mpoint/boot/grub/grub.cfg" \ >+ -o "$mpoint/boot/grub/$grubconf" -nt "$mpoint/boot/grub/grub.cfg" ]; then >+ # debug "parsing $grubconf" >+ debug "${0##*/}: $parse_part: parsing $mpoint/boot/grub/$grubconf" > parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub/$grubconf" >+ parse_done > fi > > if [ "$found_item" = 0 ]; then >- exit 1 >+ echo "$partition $bootpart $mpoint $type $um_root $um_boot" # failure > else >- exit 0 >+ linux_unmount_boot "$mpoint" "$um_root" "$um_boot" > fi >+ >+done >diff --git a/linux-boot-probes/mounted/x86/50lilo b/linux-boot-probes/mounted/x86/50lilo >index a011b56..6c30bde 100755 >--- a/linux-boot-probes/mounted/x86/50lilo >+++ b/linux-boot-probes/mounted/x86/50lilo >@@ -1,27 +1,7 @@ > #!/bin/sh >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > set -e > >-partition="$1" >-bootpart="$2" >-mpoint="$3" >-type="$4" >- >-found_item=0 >- >-title="" >-rootdev="" >-kernel="" >-parameters="" >-initrd="" >-read_only="" >-added_parameters=0 >-default_rootdev="" >-default_kernel="" >-default_parameters="" >-default_initrd="" >-default_read_only="" >- > dequote () { > item="${1%\"}" > echo "${item#\"}" >@@ -48,7 +28,7 @@ recordstanza () { > parameters="root=$rootdev $parameters" > fi > parameters="${parameters% }" >- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" >+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters" # success > found_item=1 > else > debug "cannot find $kernel or $initrd, not recording" >@@ -76,10 +56,8 @@ parse_lilo_conf () { > bootpart="$3" > IFS=" =" > while read line; do >- debug "parsing: $line" >- set -f >- set -- $line >- set +f >+ # debug "parsing: $line" >+ set -f; set -- $line; set +f > case "$1" in > root) > rootdev=$(dequote "$2") >@@ -114,13 +92,33 @@ parse_lilo_conf () { > recordstanza > } > >+while read partition bootpart mpoint type um_root um_boot; do >+# echo $0: $read $partition $bootpart $mpoint $type $um_root $um_boot 1>&2 >+ >+found_item=0 >+ >+title="" >+rootdev="" >+kernel="" >+parameters="" >+initrd="" >+read_only="" >+added_parameters=0 >+default_rootdev="" >+default_kernel="" >+default_parameters="" >+default_initrd="" >+default_read_only="" >+ > if [ -e "$mpoint/etc/lilo.conf" ]; then > debug "parsing lilo.conf" > parse_lilo_conf "$mpoint" "$partition" "$bootpart" < "$mpoint/etc/lilo.conf" > fi > > if [ "$found_item" = 0 ]; then >- exit 1 >+ echo "$partition $bootpart $mpoint $type $um_root $um_boot" # failure > else >- exit 0 >+ linux_unmount_boot "$mpoint" "$um_root" "$um_boot" > fi >+ >+done >diff --git a/os-prober b/os-prober >index 54798ae..f821d5f 100755 >--- a/os-prober >+++ b/os-prober >@@ -1,7 +1,22 @@ > #!/bin/sh > set -e > >-. /usr/share/os-prober/common.sh >+# $1: optional alternate root for scripts in this package >+# (for testing without install, etc.) >+# Use the default directories if $1 is not supplied. >+export execpfx="${1:-/usr/share/os-prober}" >+export libexecpfx="${1:-/usr/libexec}/os-probes" >+ >+# dash shell does not have "{varname}>&1" feature that bash shell has >+# for auto-assignment of new filedescriptors. >+# It is cumbersome to write the 'eval' to use our own variables. >+# Therefore use fixed numbers. >+export fd_result=3 # file descriptor for external results >+export fd_logger=9 # file descriptor for input to logger >+ >+# export PS4=' ${FUNCNAME[0]}@$LINENO < ${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]} :' >+ >+. $execpfx/common.sh # note: binds fd_result and fd_logger > > newns "$@" > require_tmpdir >@@ -14,15 +29,19 @@ log_output () { > fi > } > >-on_sataraid () { >- type dmraid >/dev/null 2>&1 || return 1 >- local parent="${1%/*}" >- local device="/dev/${parent##*/}" >- if dmraid -r -c | grep -q "$device"; then >- return 0 >- fi >- return 1 >-} >+ on_sataraid() { return 1; } # default always returns false >+if type dmraid >/dev/null 2>&1; then >+ dmraid_r_c="$(dmraid -r -c)" || : # a constant! >+ on_sataraid () { # re-define >+ local parent="${1%/*}" >+ local device="/dev/${parent##*/}" >+ local t="${dmraid_r_c#*$device}" # Is $device in $dmraid_r_c ? >+ if [ ${#t} -ne ${#dmraid_r_c} ]; then # yes >+ return 0 # true >+ fi >+ return 1 # false >+ } >+fi > > partitions () { > # Exclude partitions that have whole_disk sysfs attribute set. >@@ -30,9 +49,13 @@ partitions () { > # Exclude partitions on physical disks that are part of a > # Serial ATA RAID disk. > for part in /sys/block/*/*[0-9]; do >- if [ -f "$part/start" ] && \ >- [ ! -f "$part/whole_disk" ] && ! on_sataraid $part; then >- name="$(echo "${part##*/}" | sed 's,[!.],/,g')" >+ if [ -f "$part/start" -a ! -f "$part/whole_disk" ] \ >+ && ! on_sataraid $part; then >+ name="${part##*/}" >+ # An empty name designates a root. >+ if [ 0 -eq ${#name} ]; then >+ name='/' >+ fi > if [ -e "/dev/$name" ]; then > echo "/dev/$name" > fi >@@ -50,11 +73,11 @@ partitions () { > fi > elif [ "$(uname -s)" = Linux ]; then > echo "Cannot find list of partitions! (Try mounting /sys.)" >&2 >- exit 1 >+ return 1 > else > # We don't know how to probe OSes on non-Linux kernels. For > # now, just don't get in the way. >- exit 0 >+ return 0 > fi > > # Add MD RAID devices >@@ -64,41 +87,42 @@ partitions () { > > # Also detect OSes on LVM volumes (assumes LVM is active) > if type lvs >/dev/null 2>&1; then >- echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name | >- sed "s|-|--|g;s|^[[:space:]]*\(.*\):\(.*\)$|/dev/mapper/\1-\2|")" >+ LVM_SUPPRESS_FD_WARNINGS=1 log_output \ >+ lvs --noheadings --separator : -o vg_name,lv_name 2>/dev/null | >+ sed "s|-|--|g;s|^[[:space:]]*\(.*\):\(.*\)$|/dev/mapper/\1-\2|" >+ # Double the original dashes to distinguish them from the >+ # single dash that will be added later. Ignore leading >+ # whitespace, then find two fields separated by a colon >+ # and replace using /dev/mapper with the fields separated >+ # by a dash. > fi > } > >-parse_proc_swaps () { >- while read line; do >- set -f >- set -- $line >- set +f >- echo "$(mapdevfs $1) swap" >- done >-} >- >-parse_proc_mdstat () { >+parse_proc_mdstat () { # filters stdin >+ udevinfo () { return 1; } # default is false and empty > if type udevadm >/dev/null 2>&1; then >- udevinfo () { >- udevadm info "$@" >- } >+ udevinfo () { udevadm info "$@" 2>/dev/null; } # re-define > fi >+ local _udi _t > while read line; do > for word in $line; do >- dev="${word%%[*}" >+ dev="${word%%[*}" # ] > # TODO: factor this out to something in di-utils if > # it's needed elsewhere >- if [ -d /sys/block ] && type udevinfo >/dev/null 2>&1; then >- if ! udevinfo -q path -n "/dev/$dev" 2>/dev/null | \ >- grep -q '/.*/.*/'; then >+ if [ -d /sys/block ]; then >+ _udi="$(udevinfo -q path -n "/dev/$dev")" >+ _t="${_udi%/*/*/*}" # trim any 3 '/' and suffix >+ if [ ${#_t} -eq ${#_udi} ]; then # no match >+ continue >+ fi >+ else >+ _t="${dev%/part*}" # trim "/part" and suffix >+ if [ ${#_t} -eq ${#dev} ]; then # no match > continue > fi >- elif ! echo "$dev" | grep -q "/part"; then >- continue > fi > raidpart="/dev/$dev" >- echo "$(mapdevfs "$raidpart")" >+ echo ":$(mapdevfs "$raidpart")" # ':' marks beginning > done > done > } >@@ -106,66 +130,110 @@ parse_proc_mdstat () { > # Needed for idempotency > rm -f /var/lib/os-prober/labels > >-for prog in /usr/libexec/os-probes/init/*; do >- if [ -x "$prog" ] && [ -f "$prog" ]; then >+for prog in $libexecpfx/init/*; do >+ if [ -r "$prog" -a -x "$prog" -a ! -d "$prog" ]; then > "$prog" || true > fi > done > > # We need to properly canonicalize partitions with mount points and partitions > # used in RAID >-grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true >-: >"$OS_PROBER_TMP/swaps-map" >-if [ -f /proc/swaps ]; then >- grep "^/dev/" /proc/swaps | parse_proc_swaps >"$OS_PROBER_TMP/swaps-map" || true >-fi >-: >"$OS_PROBER_TMP/raided-map" >-if [ -f /proc/mdstat ] ; then >- grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true >-fi > >-for partition in $(partitions); do >+# Parse /proc/mounts. >+# bash would use two associative arrays, indexed by $part, to store results. >+# dash has no arrays, so use variables with stylized names. >+while read part mpoint fs_type _rest; do >+ _t="${part#/dev/}"; if [ ${#_t} -ne ${#part} -a "$mpoint" -a "$fs_type" ]; then >+ str_tame "$(mapdevfs "$part")" >+ eval 'MPOINT_'$value'="$mpoint" FS_TYPE_'$value'="$fs_type"' >+ fi >+done </proc/mounts >+ >+# Parse /proc/swaps. >+# bash would use an associative array, indexed by $part, to store results. >+# dash has no arrays, so use variables with stylized names. >+while read part _rest; do >+ _t="${part#/dev/}"; if [ ${#_t} -ne ${#part} ]; then >+ # line from file begins with "/dev/" >+ str_tame "$(mapdevfs "$part")" >+ eval SWAP_$value=1 >+ fi >+done </proc/swaps >+ >+# Store results in a string, with $part marked by a prefix ':'. >+raided="" >+[[ -f /proc/mdstat ]] && raided=$(grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat ) >+ >+pipe_mounted="" >+for test in $libexecpfx/mounted/* \ >+ $libexecpfx/mounted/x86/* \ >+ $libexecpfx/mounted/common/* # last two lines: test without install >+do >+ if [ -r "$test" -a -x "$test" -a ! -d "$test" ]; then >+ pipe_mounted="$pipe_mounted|$test" >+ fi >+done >+pipe_mounted="${pipe_mounted#|}" >+# echo pipe_mounted= "$pipe_mounted" 1>&2 >+ >+pipe_not_yet="" >+for test in $libexecpfx/*; do >+ if [ -r "$test" -a -x "$test" -a ! -d "$test" ]; then >+ pipe_not_yet="$pipe_not_yet|$test" >+ fi >+done >+pipe_not_yet="${pipe_not_yet#|}" >+# echo pipe_not_yet= "$pipe_not_yet" 1>&2 >+ >+# Arrange the processing as a chain of filters, to enable parallelism. >+# When a filter recognizes a partition, then the filter uses the 'result' >+# function to write the details to the fd_result pipe. Each filter >+# passes any unrecognized partition on to the next filter by using stdout. >+# Logging is performed by writing to fd_logger, which goes to a single >+# logger process that reads its stdin. Stderr remains available for >+# debugging and emergencies. >+# Plumbing by John Reiser (jreiser bitwagon com), November 2012. >+ >+partitions | ( ( ( >+ while read partition ; do >+ # Distribute to proper entrypoint in pipeline of filters. >+ > if ! mapped="$(mapdevfs "$partition")"; then > log "Device '$partition' does not exist; skipping" > continue > fi >- >- # Skip partitions used in software RAID arrays >- if grep -q "^$mapped" "$OS_PROBER_TMP/raided-map" ; then >+ str_tame "$mapped"; tamed="$value" >+ raid="${raided%:$mapped}"; if [ ${#raid} -ne ${#raided} ]; then > debug "$partition: part of software raid array" > continue > fi >- >- # Skip partitions used as active swap >- if grep -q "^$mapped " "$OS_PROBER_TMP/swaps-map" ; then >+ eval 'swap="$SWAP_'$tamed'"'; if [ -n "$swap" ]; then > debug "$partition: is active swap" > continue > fi >- >- if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then >- for test in /usr/libexec/os-probes/*; do >- if [ -f "$test" ] && [ -x "$test" ]; then >- debug "running $test on $partition" >- if "$test" "$partition"; then >- debug "os detected by $test" >- break >- fi >- fi >- done >- else >- mpoint=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2) >+ eval 'mpoint="$MPOINT_'$tamed'"'; if [ -z "$mpoint" ]; then >+ echo "$partition" # not yet mounted >+ else # already mounted > mpoint="$(unescape_mount "$mpoint")" >- if [ "$mpoint" != "/target/boot" ] && [ "$mpoint" != "/target" ] && [ "$mpoint" != "/" ]; then >- type=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 3) >- for test in /usr/libexec/os-probes/mounted/*; do >- if [ -f "$test" ] && [ -x "$test" ]; then >- debug "running $test on mounted $partition" >- if "$test" "$partition" "$mpoint" "$type"; then >- debug "os detected by $test" >- break >- fi >- fi >- done >+ if [ "$mpoint" != "/target/boot" \ >+ -a "$mpoint" != "/target" \ >+ -a "$mpoint" != "/" ]; then >+ eval 'type="$FS_TYPE_'$tamed'"' >+ echo "$partition $mpoint $type 0" 1>&8 # 0: do not unmount > fi > fi >-done >+ done \ >+ | eval "${pipe_not_yet}" >+) 8>&1 | eval "${pipe_mounted}" | while read line; do >+ echo '?'unknown "$line" >+ set -f; set -- $line; set +f >+ part="$1"; dir="$2"; type="$3"; discard="$4" >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi >+ done 1>&2 >+) 9>&1 | logger 1>&- # fd_logger >+) 3>&1 # fd_result >+ >+# EOF os-prober >diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests >index 4e0f6d6..33824d5 100755 >--- a/os-probes/common/50mounted-tests >+++ b/os-probes/common/50mounted-tests >@@ -1,49 +1,63 @@ > #!/bin/sh > # Sub-tests that require a mounted partition. > set -e >-partition="$1" > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >+delay_types="" # file system types that should be checked last >+kfs_types="" # kernel file system types >+for mod_type in $(grep -v nodev /proc/filesystems); do >+ # hfsplus filesystems are mountable as hfs. Try hfs last so >+ # that we can tell the difference. >+ if [ "$mod_type" = hfs ]; then >+ delay_types="$delay_types $mod_type" >+ elif [ "$mod_type" = fuseblk ]; then >+ if type ntfs-3g >/dev/null 2>&1; then >+ kfs_types="$kfs_types ntfs-3g" >+ fi >+ else >+ kfs_types="$kfs_types $mod_type" >+ fi >+done >+ >+tmpmntdir=/var/lib/os-prober/mount >+mkdir "$tmpmntdir" >/dev/null 2>&1 || true >+(cd $tmpmntdir >+ umount -f osp* >/dev/null 2>&1 || true >+ rmdir osp* >/dev/null 2>&1 || true >+) >+ >+ >+while read partition; do >+ >+tmpmnt=$tmpmntdir/osp$(( mount_count+=1 )) >+mkdir $tmpmnt >+ >+xtra_types="" > types="$(fs_type "$partition")" || types=NOT-DETECTED >-if [ "$types" = NOT-DETECTED ]; then >+case "$types" in >+NOT-DETECTED) > debug "$1 type not recognised; skipping" >- exit 0 >-elif [ "$types" = swap ]; then >+ continue ;; >+swap) > debug "$1 is a swap partition; skipping" >- exit 0 >-elif [ "$types" = crypto_LUKS ]; then >+ continue ;; >+crypto_LUKS) > debug "$1 is a LUKS partition; skipping" >- exit 0 >-elif [ "$types" = ntfs ]; then >+ continue ;; >+ntfs) > if type ntfs-3g >/dev/null 2>&1; then >- types='ntfs-3g ntfs' >- fi >-elif [ -z "$types" ]; then >+ xtra_types='ntfs-3g ntfs' >+ fi ;; >+?*) # non-null >+ xtra_types="$types" ;; # guess this one first >+'') # null > if type cryptsetup >/dev/null 2>&1 && \ > cryptsetup luksDump "$partition" >/dev/null 2>&1; then > debug "$1 is a LUKS partition; skipping" >- exit 0 >- fi >- for type in $(grep -v nodev /proc/filesystems); do >- # hfsplus filesystems are mountable as hfs. Try hfs last so >- # that we can tell the difference. >- if [ "$type" = hfs ]; then >- delaytypes="${delaytypes:+$delaytypes }$type" >- elif [ "$type" = fuseblk ]; then >- if type ntfs-3g >/dev/null 2>&1; then >- types="${types:+$types }ntfs-3g" >- fi >- else >- types="${types:+$types }$type" >- fi >- done >-fi >- >-tmpmnt=/var/lib/os-prober/mount >-if [ ! -d "$tmpmnt" ]; then >- mkdir "$tmpmnt" >-fi >+ continue >+ fi ;; >+esac > > mounted= > if type grub-mount >/dev/null 2>&1 && \ >@@ -59,9 +73,9 @@ if type grub-mount >/dev/null 2>&1 && \ > fi > else > ro_partition "$partition" >- for type in $types $delaytypes; do >+ for type in $xtra_types $kfs_types $delay_types; do > if mount -o ro -t "$type" "$partition" "$tmpmnt" 2>/dev/null; then >- debug "mounted as $type filesystem" >+ # debug "mounted as $type filesystem" > mounted=1 > break > fi >@@ -69,25 +83,9 @@ else > fi > > if [ "$mounted" ]; then >- for test in /usr/libexec/os-probes/mounted/*; do >- debug "running subtest $test" >- if [ -f "$test" ] && [ -x "$test" ]; then >- if "$test" "$partition" "$tmpmnt" "$type"; then >- debug "os found by subtest $test" >- if ! umount "$tmpmnt"; then >- warn "failed to umount $tmpmnt" >- fi >- rmdir "$tmpmnt" || true >- exit 0 >- fi >- fi >- done >- if ! umount "$tmpmnt"; then >- warn "failed to umount $tmpmnt" >- fi >+ echo "$partition $tmpmnt $type 1" # 1: must unmount >+else >+ rmdir "$tmpmnt" || : > fi > >-rmdir "$tmpmnt" || true >- >-# No tests found anything. >-exit 1 >+done >diff --git a/os-probes/mounted/common/40lsb b/os-probes/mounted/common/40lsb >index ce8d4e1..2b7e576 100755 >--- a/os-probes/mounted/common/40lsb >+++ b/os-probes/mounted/common/40lsb >@@ -2,30 +2,25 @@ > # Test for LSB systems. > set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-dir="$2" >-type="$3" >- >-lsb_field () { >- file="$1" >- field="$2" >- grep ^"$field" "$file" | cut -d = -f 2 | sed 's/^"//' | sed 's/"$//' | sed 's/:/ /g' >-} >+while read partition dir type discard; do > > file="$dir/etc/lsb-release" > if [ ! -e "$file" ]; then >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi > >-release=$(lsb_field "$file" DISTRIB_RELEASE) >+while read line; do eval "$line"; done < $file >+ >+release="$DISTRIB_RELEASE" > if [ -z "$release" ]; then >- release=$(lsb_field "$file" DISTRIB_CODENAME) >+ release="$DISTRIB_CODENAME" > fi >-description=$(lsb_field "$file" DISTRIB_DESCRIPTION) >+ >+description="$DISTRIB_DESCRIPTION" > if [ -z "$description" ]; then >- description=$(lsb_field "$file" DISTRIB_CODENAME) >+ description="$DISTRIB_CODENAME" > fi > > if [ -n "$description" ]; then >@@ -35,14 +30,19 @@ if [ -n "$description" ]; then > long="$description" > fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi > >-short=$(lsb_field "$file" DISTRIB_ID | sed 's/ //g') >+strchar_delete "$DISTRIB_ID" ' '; short="$value" > if [ -z "$short" ]; then > short="UnknownLSB" > fi > >-label="$(count_next_label "$short")" >-result "$partition:$long:$label:linux" >-exit 0 >+result "$partition:$long:$short$((label += 1)):linux" # success >+ >+if [ 1 == "$discard" ]; then >+ umount $dir >+ rmdir $dir >+fi >+ >+done >diff --git a/os-probes/mounted/common/90linux-distro b/os-probes/mounted/common/90linux-distro >index fb56b61..87ec273 100755 >--- a/os-probes/mounted/common/90linux-distro >+++ b/os-probes/mounted/common/90linux-distro >@@ -2,134 +2,196 @@ > # Test for linux distributions. > set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh >+path_lookup cat; export cat # search once only > >-partition="$1" >-dir="$2" >-type="$3" >+origdir=$PWD >+ >+function fail() { >+ echo "$partition $dir $type $discard" 1>&7 # failure >+ >+ cd $origdir >+} >+ >+function succeed() { >+ echo "$partition:$long:$short" 1>&6 # success >+ >+ cd $origdir >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi >+} >+ >+function filter() { >+ while read partition dir type discard; do > > # This test is inaccurate, but given separate / and /boot partitions and the > # fact that only some architectures have ld-linux.so, I can't see anything > # better. Make sure this test has a high number so that more accurate tests > # can come first. > # TODO: look for ld-linux.so on arches that have it >-if ls "$dir"/lib*/ld*.so* >/dev/null 2>/dev/null && [ -d "$dir/boot" ] \ >- || ls "$dir"/usr/libexec*/ld*.so* >/dev/null 2>/dev/null; then >- if [ -e "$dir/etc/debian_version" ]; then >+ >+# Check for any actual file that matches the pattern. >+# If pathname expansion finds no matches then it returns the pattern itself, >+# and the '[ -r "$1" ]' fails. >+# If pathname expansion does find a match then the '[ -r "$1" ]' succeeds. >+# The syntax with braces avoids using a subprocess. >+# All that saves 0.02 seconds over using the exit code of /bin/ls. >+# It matters when you have several dozen partitions to check. >+ if { set -- "$dir"/lib*/ld*.so*; [ -r "$1" ]; } \ >+ || { set -- "$dir"/usr/libexec*/ld*.so*; [ -r "$1" ]; } ; then >+ cd "$dir"/etc 2>/dev/null || { fail; continue; } >+ short="" >+ set -- *[_-]version >+ >+ for file do case "$file" in >+ debian_version) > short="Debian" >- long="$(printf "Debian GNU/Linux (%s)\n" "$(cat "$dir/etc/debian_version")")" >+ long="$(printf "Debian GNU/Linux (%s)\n" "$($cat "$dir/etc/debian_version")")" ;; >+ kanotix-version) >+ short="Kanotix" >+ long="$($cat "$dir/etc/kanotix-version")" ;; >+ slackware-version) >+ short="Slackware" >+ long="$(printf "Slackware Linux (%s)\n" "$($cat "$dir/etc/slackware-version")")" ;; >+ esac; done >+ if [ -n "$short" ]; then succeed; continue; fi >+ > # RPM derived distributions may also have a redhat-release or >- # mandrake-release, so check their files first. >- elif [ -e "$dir/etc/altlinux-release" ]; then >+ # mandrake-release. Set base first, then override using derived. >+ set -- *-release >+ >+ for file do case "$file" in # base distro >+ redhat-release) >+ short="RedHat" >+ long="$($cat "$dir/etc/redhat-release")" ;; >+ esac; done >+ >+ for file do case "$file" in # possible intermediate distro >+ fedora-release) >+ short="Fedora" >+ long="$($cat "$dir/etc/fedora-release")" ;; >+ esac; done >+ >+ for file do case "$file" in # possible intermediate distro >+ mandrake-release) >+ short="Mandrake" >+ long="$($cat "$dir/etc/mandrake-release")" ;; >+ esac; done >+ >+ for file do case "$file" in # possible derived distro >+ SuSE-release) >+ short="SuSE" >+ long="$(head -n 1 "$dir/etc/SuSE-release")" ;; >+ altlinux-release) > short="ALTLinux" >- long="$(cat "$dir/etc/altlinux-release")" >- elif [ -e "$dir/etc/magic-release" ]; then >+ long="$($cat "$dir/etc/altlinux-release")" ;; >+ magic-release) > short="Magic" >- long="$(cat "$dir/etc/magic-release")" >- elif [ -e "$dir/etc/blackPanther-release" ]; then >+ long="$($cat "$dir/etc/magic-release")" ;; >+ blackPanther-release) > short="blackPanther" >- long="$(cat "$dir/etc/blackPanther-release")" >- elif [ -e "$dir/etc/ark-release" ]; then >+ long="$($cat "$dir/etc/blackPanther-release")" ;; >+ ark-release) > short="Ark" >- long="$(cat "$dir/etc/ark-release")" >- elif [ -e "$dir/etc/arch-release" ]; then >+ long="$($cat "$dir/etc/ark-release")" ;; >+ arch-release) > short="Arch" >- long="$(cat "$dir/etc/arch-release")" >- elif [ -e "$dir/etc/asplinux-release" ]; then >+ long="$($cat "$dir/etc/arch-release")" ;; >+ asplinux-release) > short="ASPLinux" >- long="$(cat "$dir/etc/asplinux-release")" >- elif [ -e "$dir/etc/lvr-release" ]; then >+ long="$($cat "$dir/etc/asplinux-release")" ;; >+ lvr-release) > short="LvR" >- long="$(cat "$dir/etc/lvr-release")" >- elif [ -e "$dir/etc/caos-release" ]; then >+ long="$($cat "$dir/etc/lvr-release")" ;; >+ caos-release) > short="cAos" >- long="$(cat "$dir/etc/caos-release")" >- elif [ -e "$dir/etc/aurox-release" ]; then >+ long="$($cat "$dir/etc/caos-release")" ;; >+ aurox-release) > short="Aurox" >- long="$(cat "$dir/etc/aurox-release")" >- elif [ -e "$dir/etc/engarde-release" ]; then >+ long="$($cat "$dir/etc/aurox-release")" ;; >+ engarde-release) > short="EnGarde" >- long="$(cat "$dir/etc/engarde-release")" >- elif [ -e "$dir/etc/vine-release" ]; then >+ long="$($cat "$dir/etc/engarde-release")" ;; >+ vine-release) > short="Vine" >- long="$(cat "$dir/etc/vine-release")" >- elif [ -e "$dir/etc/whitebox-release" ]; then >+ long="$($cat "$dir/etc/vine-release")" ;; >+ whitebox-release) > short="WhiteBox" >- long="$(cat "$dir/etc/whitebox-release")" >- elif [ -e "$dir/etc/pld-release" ]; then >+ long="$($cat "$dir/etc/whitebox-release")" ;; >+ pld-release) > short="PLD" >- long="$(cat "$dir/etc/pld-release")" >- elif [ -e "$dir/etc/startcom-release" ]; then >+ long="$($cat "$dir/etc/pld-release")" ;; >+ startcom-release) > short="StartCom" >- long="$(cat "$dir/etc/startcom-release")" >- elif [ -e "$dir/etc/trustix-release" ]; then >+ long="$($cat "$dir/etc/startcom-release")" ;; >+ trustix-release) > short="Trustix" >- long="$(cat "$dir/etc/trustix-release")" >- elif [ -e "$dir/etc/openna-release" ]; then >+ long="$($cat "$dir/etc/trustix-release")" ;; >+ openna-release) > short="OpenNA" >- long="$(cat "$dir/etc/openna-release")" >- elif [ -e "$dir/etc/conectiva-release" ]; then >+ long="$($cat "$dir/etc/openna-release")" ;; >+ conectiva-release) > short="Conectiva" >- long="$(cat "$dir/etc/conectiva-release")" >- elif [ -e "$dir/etc/mandrake-release" ]; then >- short="Mandrake" >- long="$(cat "$dir/etc/mandrake-release")" >- elif [ -e "$dir/etc/fedora-release" ]; then >- short="Fedora" >- long="$(cat "$dir/etc/fedora-release")" >- elif [ -e "$dir/etc/redhat-release" ]; then >- short="RedHat" >- long="$(cat "$dir/etc/redhat-release")" >- elif [ -e "$dir/etc/SuSE-release" ]; then >- short="SuSE" >- long="$(head -n 1 "$dir/etc/SuSE-release")" >- elif [ -e "$dir/etc/gentoo-release" ]; then >+ long="$($cat "$dir/etc/conectiva-release")" ;; >+ gentoo-release) > short="Gentoo" >- long="$(cat "$dir/etc/gentoo-release")" >- elif [ -e "$dir/etc/cobalt-release" ]; then >+ long="$($cat "$dir/etc/gentoo-release")" ;; >+ cobalt-release) > short="Cobalt" >- long="$(cat "$dir/etc/cobalt-release")" >- elif [ -e "$dir/etc/yellowdog-release" ]; then >+ long="$($cat "$dir/etc/cobalt-release")" ;; >+ yellowdog-release) > short="YellowDog" >- long="$(cat "$dir/etc/yellowdog-release")" >- elif [ -e "$dir/etc/turbolinux-release" ]; then >+ long="$($cat "$dir/etc/yellowdog-release")" ;; >+ turbolinux-release) > short="Turbolinux" >- long="$(cat "$dir/etc/turbolinux-release")" >- elif [ -e "$dir/etc/pardus-release" ]; then >+ long="$($cat "$dir/etc/turbolinux-release")" ;; >+ pardus-release) > short="Pardus" >- long="$(cat "$dir/etc/pardus-release")" >- elif [ -e "$dir/etc/kanotix-version" ]; then >- short="Kanotix" >- long="$(cat "$dir/etc/kanotix-version")" >- elif [ -e "$dir/etc/slackware-version" ]; then >- short="Slackware" >- long="$(printf "Slackware Linux (%s)\n" "$(cat "$dir/etc/slackware-version")")" >- elif [ -e "$dir/sbin/pkgtool" ]; then >+ long="$($cat "$dir/etc/pardus-release")" ;; >+ frugalware-release) >+ short="Frugalware Linux" >+ long="$($cat "$dir/etc/frugalware-release")" ;; >+ kdemar-release) >+ short="K-DEMar" >+ long="$(printf "K-DEMar GNU/Linux (%s)\n" "$($cat "$dir/etc/kdemar-release")")" ;; >+ lfs-release) >+ short="LFS" >+ long="$(printf "Linux From Scratch (%s)\n" "$($cat "$dir/etc/lfs-release")")" ;; >+ meego-release) >+ short="MeeGo" >+ long="$(head -1 "$dir/etc/meego-release")" ;; >+ esac; done >+ if [ -n "$short" ]; then succeed; continue; fi >+ >+ # The oddballs. >+ if [ -e "$dir/sbin/pkgtool" ]; then > short="Slackware" > long="Slackware Linux" > elif grep -qs OpenLinux "$dir/etc/issue"; then > short="Caldera" > long="Caldera OpenLinux" >- elif [ -e "$dir/etc/frugalware-release" ]; then >- short="Frugalware Linux" >- long="$(cat "$dir/etc/frugalware-release")" >- elif [ -e "$dir/etc/kdemar-release" ]; then >- short="K-DEMar" >- long="$(printf "K-DEMar GNU/Linux (%s)\n" "$(cat "$dir/etc/kdemar-release")")" >- elif [ -e "$dir/etc/lfs-release" ]; then >- short="LFS" >- long="$(printf "Linux From Scratch (%s)\n" "$(cat "$dir/etc/lfs-release")")" >- elif [ -e "$dir/etc/meego-release" ]; then >- short="MeeGo" >- long="$(head -1 "$dir/etc/meego-release")" > else > short="Linux" > long="unknown Linux distribution" > fi >- >- label="$(count_next_label "$short")" >- result "$partition:$long:$label:linux" >- exit 0 >-else >- exit 1 >-fi >+ >+ succeed >+ else >+ fail >+ fi >+ done # read next partition >+} >+ >+# Use two parallel streams to filter alternating partitions. >+# Count the over-all results to avoid a race when incrementing the label. >+( ( ( while read line; do echo "$line" 1>&5 # side2 >+ if read line; then echo "$line" # side1 >+ fi >+ done | filter 1>&- # side1 >+) 5>&1 | filter 1>&- # side2 >+) 6>&1 | while read line; do result "$line$((label += 1)):linux"; done >+) 7>&1 >+ >+# EOF >diff --git a/os-probes/mounted/powerpc/20macosx b/os-probes/mounted/powerpc/20macosx >index 16d9da6..e97f30d 100755 >--- a/os-probes/mounted/powerpc/20macosx >+++ b/os-probes/mounted/powerpc/20macosx >@@ -6,10 +6,6 @@ partition="$1" > mpoint="$2" > type="$3" > >-debug() { >- logger -t macosx-prober "debug: $@" >-} >- > # Weed out stuff that doesn't apply to us > case "$type" in > hfsplus) debug "$1 is an HFS+ partition" ;; >diff --git a/os-probes/mounted/powerpc/20macosx.macosxdummyfix b/os-probes/mounted/powerpc/20macosx.macosxdummyfix >index dd4207f..5ad29da 100755 >--- a/os-probes/mounted/powerpc/20macosx.macosxdummyfix >+++ b/os-probes/mounted/powerpc/20macosx.macosxdummyfix >@@ -6,10 +6,6 @@ partition="$1" > mpoint="$2" > type="$3" > >-debug() { >- logger -t macosx-prober "debug: $@" >-} >- > # Weed out stuff that doesn't apply to us > case "$type" in > hfsplus) debug "$1 is an HFS+ partition" ;; >diff --git a/os-probes/mounted/x86/10freedos b/os-probes/mounted/x86/10freedos >index 94388f3..a15a957 100755 >--- a/os-probes/mounted/x86/10freedos >+++ b/os-probes/mounted/x86/10freedos >@@ -1,23 +1,26 @@ > #!/bin/sh > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-mpoint="$2" >-type="$3" >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in > vfat) debug "$1 is a FAT32 partition" ;; > msdos) debug "$1 is a FAT16 partition" ;; > fat) debug "$1 is a FAT partition (mounted by GRUB)" ;; >- *) debug "$1 is not a FAT partition: exiting"; exit 1 ;; >+ *) # debug "$1 is not a FAT partition" >+ echo "$partition $dir $type $discard"; continue ;; # failure > esac > > if item_in_dir -q kernel.sys "$2" && item_in_dir -q command.com "$2"; then >- label="$(count_next_label FreeDOS)" >- result "$1:FreeDOS:$label:chain" >- exit 0 >+ result "$1:FreeDOS:FreeDos$((label += 1)):chain" # success >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done >diff --git a/os-probes/mounted/x86/10qnx b/os-probes/mounted/x86/10qnx >index 8d40398..6f1dc70 100755 >--- a/os-probes/mounted/x86/10qnx >+++ b/os-probes/mounted/x86/10qnx >@@ -1,21 +1,25 @@ > #!/bin/sh > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-mpoint="$2" >-type="$3" >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in > qnx4) debug "$partition is a QNX4 partition" ;; >- *) debug "$partition is not a QNX4 partition: exiting"; exit 1 ;; >+ *) # debug "$partition is not a QNX4 partition" >+ echo "$partition $dir $type $discard"; continue ;; # failure > esac > > if [ -e "$mpoint/.boot" ]; then >- label="$(count_next_label QNX)" >- result "$partition:QNX:$label:chain" >- exit 0 >+ result "$partition:QNX:QNX$((label += 1)):chain" # success >+ >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done >diff --git a/os-probes/mounted/x86/20microsoft b/os-probes/mounted/x86/20microsoft >index 644d63c..f68d453 100755 >--- a/os-probes/mounted/x86/20microsoft >+++ b/os-probes/mounted/x86/20microsoft >@@ -1,43 +1,44 @@ > #!/bin/sh > # Detects all Microsoft OSes on a collection of partitions. > >-. /usr/share/os-prober/common.sh >+set -e > >-partition="$1" >-mpoint="$2" >-type="$3" >+. $execpfx/common.sh >+ >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in >- ntfs|ntfs-3g) debug "$1 is a NTFS partition" ;; >- vfat) debug "$1 is a FAT32 partition" ;; >- msdos) debug "$1 is a FAT16 partition" ;; >- fat) debug "$1 is a FAT partition (mounted by GRUB)" ;; >- fuse|fuseblk) debug "$1 is a FUSE partition" ;; # might be ntfs-3g >- *) debug "$1 is not a MS partition: exiting"; exit 1 ;; >+ ntfs|ntfs-3g) debug "$partition is a NTFS partition" ;; >+ vfat) debug "$partition is a FAT32 partition" ;; >+ msdos) debug "$partition is a FAT16 partition" ;; >+ fat) debug "$partition is a FAT partition (mounted by GRUB)" ;; >+ fuse|fuseblk) debug "$partition is a FUSE partition" ;; # might be ntfs-3g >+ *) # debug "$partition is not a MS partition" >+ echo "$partition $dir $type $discard"; continue ;; # failure > esac > > found= > # Vista (previously Longhorn) >-if item_in_dir -q bootmgr "$2"; then >+if item_in_dir -q bootmgr "$dir"; then > # there might be different boot directories in different case as: > # boot Boot BOOT >- for boot in $(item_in_dir boot "$2"); do >- bcd=$(item_in_dir bcd "$2/$boot") >+ for boot in $(item_in_dir boot "$dir"); do >+ bcd=$(item_in_dir bcd "$dir/$boot") > if [ -n "$bcd" ]; then >- if grep -qs "W.i.n.d.o.w.s. .8" "$2/$boot/$bcd"; then >+ if grep -qs "W.i.n.d.o.w.s. .8" "$dir/$boot/$bcd"; then > long="Windows 8 (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .7" "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .7" "$dir/$boot/$bcd"; then > long="Windows 7 (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .V.i.s.t.a" "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .V.i.s.t.a" "$dir/$boot/$bcd"; then > long="Windows Vista (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .S.e.r.v.e.r. .2.0.0.8. .R.2." "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .S.e.r.v.e.r. .2.0.0.8. .R.2." "$dir/$boot/$bcd"; then > long="Windows Server 2008 R2 (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .S.e.r.v.e.r. .2.0.0.8." "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .S.e.r.v.e.r. .2.0.0.8." "$dir/$boot/$bcd"; then > long="Windows Server 2008 (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .R.e.c.o.v.e.r.y. .E.n.v.i.r.o.n.m.e.n.t" "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .R.e.c.o.v.e.r.y. .E.n.v.i.r.o.n.m.e.n.t" "$dir/$boot/$bcd"; then > long="Windows Recovery Environment (loader)" >- elif grep -qs "W.i.n.d.o.w.s. .S.e.t.u.p" "$2/$boot/$bcd"; then >+ elif grep -qs "W.i.n.d.o.w.s. .S.e.t.u.p" "$dir/$boot/$bcd"; then > long="Windows Recovery Environment (loader)" > else > long="Windows Vista (loader)" >@@ -52,25 +53,25 @@ if item_in_dir -q bootmgr "$2"; then > fi > > # 2000/XP/NT4.0 >-if [ -z "$found" ] && item_in_dir -q ntldr "$2" && item_in_dir -q ntdetect.com "$2"; then >+if [ -z "$found" ] && item_in_dir -q ntldr "$dir" && item_in_dir -q ntdetect.com "$dir"; then > long="Windows NT/2000/XP" > short=Windows >- ini=$(item_in_dir boot.ini "$2") >+ ini=$(item_in_dir boot.ini "$dir") > if [ -n "$ini" ]; then >- multicount="$(grep -e "^multi" "$2/$ini" | wc -l)" >- scsicount="$(grep -e "^scsi" "$2/$ini" | wc -l)" >+ multicount="$(grep -e "^multi" "$dir/$ini" | wc -l)" >+ scsicount="$(grep -e "^scsi" "$dir/$ini" | wc -l)" > msoscount="$(expr "${multicount}" + "${scsicount}")" > if [ "$msoscount" -eq 1 ]; then > # We need to remove a Carriage Return at the end of > # the line... >- defaultmspart="$(grep -e "^default=" "$2/$ini" | cut -d '=' -f2 | tr -d '\r')" >+ defaultmspart="$(grep -e "^default=" "$dir/$ini" | cut -d '=' -f2 | tr -d '\r')" > # Escape any backslashes in defaultmspart > grepexp="^$(echo "$defaultmspart" | sed -e 's/\\/\\\\/')=" > # Colons not allowed; replace by spaces > # Accented characters (non UTF-8) cause debconf to > # hang, so we fall back to the default if the name > # contains any weird characters. >- long="$(grep -e "$grepexp" "$2/$ini" | cut -d '"' -f2 | \ >+ long="$(grep -e "$grepexp" "$dir/$ini" | cut -d '"' -f2 | \ > tr ':' ' ' | LC_ALL=C grep -v '[^a-zA-Z0-9 &()/_-]')" > if [ -z "$long" ]; then > long="Windows NT/2000/XP" >@@ -84,7 +85,7 @@ if [ -z "$found" ] && item_in_dir -q ntldr "$2" && item_in_dir -q ntdetect.com " > fi > > # MS-DOS >-if [ -z "$found" ] && item_in_dir -q dos "$2"; then >+if [ -z "$found" ] && item_in_dir -q dos "$dir"; then > long="MS-DOS 5.x/6.x/Win3.1" > short=MS-DOS > >@@ -92,8 +93,8 @@ if [ -z "$found" ] && item_in_dir -q dos "$2"; then > fi > > # 95/98/Me >-if [ -z "$found" ] && item_in_dir -q windows "$2" && >- item_in_dir -q win.com "$2"/"$(item_in_dir windows "$2")"; then >+if [ -z "$found" ] && item_in_dir -q windows "$dir" && >+ item_in_dir -q win.com "$dir"/"$(item_in_dir windows "$dir")"; then > long="Windows 95/98/Me" > short=Windows9xMe > >@@ -101,9 +102,13 @@ if [ -z "$found" ] && item_in_dir -q windows "$2" && > fi > > if [ -z "$found" ]; then >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi > >-label="$(count_next_label "$short")" >-result "${partition}:${long}:${label}:chain" >-exit 0 >+result "${partition}:${long}:${short}$((label += 1)):chain" # success >+ >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi >+done >diff --git a/os-probes/mounted/x86/30utility b/os-probes/mounted/x86/30utility >index af48d30..995e523 100755 >--- a/os-probes/mounted/x86/30utility >+++ b/os-probes/mounted/x86/30utility >@@ -1,18 +1,19 @@ > #!/bin/sh > # Detects utility (hw vendor recovery) partitions. > >-. /usr/share/os-prober/common.sh >+set -e > >-partition="$1" >-mpoint="$2" >-type="$3" >+. $execpfx/common.sh >+ >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in > vfat) debug "$1 is a FAT32 partition" ;; > msdos) debug "$1 is a FAT16 partition" ;; > fat) debug "$1 is a FAT partition (mounted by GRUB)" ;; >- *) debug "$1 is not a FAT partition: exiting"; exit 1 ;; >+ *) # debug "$1 is not a FAT partition" >+ echo "$partition $dir $type $discard"; continue ;; # failure > esac > > # Dell Utility partitions have partition type 0xde, but no idea how to >@@ -25,9 +26,14 @@ elif item_in_dir -q f11.sys "$2"; then > long="Acronis Secure Zone" > short=AcroneZone > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi > >-label="$(count_next_label "$short")" >-result "${partition}:${long}:${label}:chain" >-exit 0 >+result "${partition}:${long}:${short}$((label += 1)):chain" # success >+ >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi >+ >+done >diff --git a/os-probes/mounted/x86/70hurd b/os-probes/mounted/x86/70hurd >index ffc0a44..3e23ee0 100755 >--- a/os-probes/mounted/x86/70hurd >+++ b/os-probes/mounted/x86/70hurd >@@ -1,16 +1,19 @@ > #!/bin/sh > set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-dir="$2" >-type="$3" >+while read partition dir type discard; do > > if [ -e "$dir/servers/exec" ] && [ -x "$dir/hurd/init" ]; then >- label="$(count_next_label Hurd)" >- result "$partition:GNU/Hurd:$label:hurd" >- exit 0 >+ result "$partition:GNU/Hurd:Hurd$((label += 1)):hurd" # success >+ >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done >diff --git a/os-probes/mounted/x86/80minix b/os-probes/mounted/x86/80minix >index e01f669..edb09ed 100755 >--- a/os-probes/mounted/x86/80minix >+++ b/os-probes/mounted/x86/80minix >@@ -1,16 +1,14 @@ > #!/bin/sh > set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-dir="$2" >-type="$3" >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in > minix|minix2|ext2) ;; >- *) exit 1 ;; >+ *) echo "$partition $dir $type $discard"; continue ;; # failure > esac > > if [ -f "$dir/minix" ] || [ -e "$dir/boot/image_big" ]; then >@@ -20,9 +18,13 @@ if [ -f "$dir/minix" ] || [ -e "$dir/boot/image_big" ]; then > boot="chain" > fi > >- label="$(count_next_label Minix)" >- result "$partition:Minix:$label:$boot" >- exit 0 >+ result "$partition:Minix:Minix$((label += 1)):$boot" # success >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done >diff --git a/os-probes/mounted/x86/83haiku b/os-probes/mounted/x86/83haiku >index 6de7a1d..ccd1555 100755 >--- a/os-probes/mounted/x86/83haiku >+++ b/os-probes/mounted/x86/83haiku >@@ -1,23 +1,22 @@ > #!/bin/sh > # Detects Haiku on BeFS partitions. >+set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-mpoint="$2" >-type="$3" >+while read partition dir type discard; do > > # Weed out stuff that doesn't apply to us > case "$type" in > befs|befs_be) debug "$partition is a BeFS partition" ;; >- *) debug "$partition is not a BeFS partition: exiting"; exit 1 ;; >+ *) # debug "$partition is not a BeFS partition" >+ echo "$partition $dir $type $discard"; continue ;; # failure > esac > > if head -c 512 "$partition" | grep -qs "system.haiku_loader"; then > debug "Stage 1 bootloader found" > else >- debug "Stage 1 bootloader not found: exiting" >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi > > if system="$(item_in_dir "system" "$mpoint")" && >@@ -26,10 +25,14 @@ if system="$(item_in_dir "system" "$mpoint")" && > item_in_dir -q "kernel_x86_64" "$mpoint/$system") > then > debug "Stage 2 bootloader and kernel found" >- label="$(count_next_label Haiku)" >- result "$partition:Haiku:$label:chain" >- exit 0 >+ result "$partition:Haiku:Haiku$((label += 1)):chain" # success >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- debug "Stage 2 bootloader and kernel not found: exiting" >- exit 1 >+ debug "Stage 2 bootloader and kernel not found" >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done >diff --git a/os-probes/mounted/x86/90solaris b/os-probes/mounted/x86/90solaris >index 0e9148c..00359ec 100755 >--- a/os-probes/mounted/x86/90solaris >+++ b/os-probes/mounted/x86/90solaris >@@ -4,16 +4,19 @@ > > set -e > >-. /usr/share/os-prober/common.sh >+. $execpfx/common.sh > >-partition="$1" >-dir="$2" >-type="$3" >+while read partition dir type discard; do > > if [ -f "$dir/etc/system" ] && [ -f "$dir/etc/vfstab" ]; then >- label="$(count_next_label Solaris)" >- result "$partition:Solaris/IA32:$label:chain" >- exit 0 >+ result "$partition:Solaris/IA32:Solaris$((label += 1)):chain" # success >+ >+ if [ 1 == "$discard" ]; then >+ umount "$dir" >+ rmdir "$dir" >+ fi > else >- exit 1 >+ echo "$partition $dir $type $discard"; continue # failure > fi >+ >+done
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 875356
: 652201 |
688069
|
689262
|
689263
|
689264
|
689265
|
692170
|
692171
|
692172