30_os-prober.in 11 KB
Newer Older
1 2
#! /bin/sh
set -e
3

4 5
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
6 7 8 9 10 11 12 13 14 15 16 17 18 19
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

20 21 22
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
23

24 25 26
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"

27
. "$pkgdatadir/grub-mkconfig_lib"
28

29 30 31 32
if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then
  exit 0
fi

33
if [ -z "`which os-prober 2> /dev/null`" ] || [ -z "`which linux-boot-prober 2> /dev/null`" ] ; then
34 35 36 37
  # missing os-prober and/or linux-boot-prober
  exit 0
fi

38
OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`"
39 40 41 42 43
if [ -z "${OSPROBED}" ] ; then
  # empty os-prober output, nothing doing
  exit 0
fi

44
osx_entry() {
45 46 47 48
    if [ x$2 = x32 ]; then
        # TRANSLATORS: it refers to kernel architecture (32-bit)
	bitstr="$(gettext "(32-bit)")"
    else
49
        # TRANSLATORS: it refers to kernel architecture (64-bit)
50 51 52 53
	bitstr="$(gettext "(64-bit)")"
    fi
    # TRANSLATORS: it refers on the OS residing on device %s
    onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
54
        cat << EOF
55
menuentry '$(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")'  {
56
EOF
57 58
	save_default_entry | grub_add_tab
	prepare_grub_to_access_device ${DEVICE} | grub_add_tab
59
	cat << EOF
60
        load_video
61
        set do_resume=0
62 63
        if [ /var/vm/sleepimage -nt10 / ]; then
           if xnu_resume /var/vm/sleepimage; then
64
             set do_resume=1
65 66
           fi
        fi
67
        if [ \$do_resume = 0 ]; then
68 69 70 71
           xnu_uuid ${OSXUUID} uuid
           if [ -f /Extra/DSDT.aml ]; then
              acpi -e /Extra/DSDT.aml
           fi
72 73
           if [ /kernelcache -nt /System/Library/Extensions ]; then
              $1 /kernelcache boot-uuid=\${uuid} rd=*uuid
74 75 76
           elif [ -f /System/Library/Kernels/kernel ]; then
              $1 /System/Library/Kernels/kernel boot-uuid=\${uuid} rd=*uuid
              xnu_kextdir /System/Library/Extensions
77 78
           else
              $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid
79 80 81 82 83
              if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then
                xnu_mkext /System/Library/Extensions.mkext
              else
                xnu_kextdir /System/Library/Extensions
              fi
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
           fi
           if [ -f /Extra/Extensions.mkext ]; then
              xnu_mkext /Extra/Extensions.mkext
           fi
           if [ -d /Extra/Extensions ]; then
              xnu_kextdir /Extra/Extensions
           fi
           if [ -f /Extra/devprop.bin ]; then
              xnu_devprop_load /Extra/devprop.bin
           fi
           if [ -f /Extra/splash.jpg ]; then
              insmod jpeg
              xnu_splash /Extra/splash.jpg
           fi
           if [ -f /Extra/splash.png ]; then
              insmod png
              xnu_splash /Extra/splash.png
           fi
           if [ -f /Extra/splash.tga ]; then
              insmod tga
              xnu_splash /Extra/splash.tga
           fi
        fi
}
EOF
}

111 112
used_osprober_linux_ids=

113 114 115 116 117
for OS in ${OSPROBED} ; do
  DEVICE="`echo ${OS} | cut -d ':' -f 1`"
  LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
  LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`"
  BOOT="`echo ${OS} | cut -d ':' -f 4`"
118 119
  if UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then
    EXPUUID="$UUID"
120

121
    if [ x"${DEVICE#*@}" != x ] ; then
122
      EXPUUID="${EXPUUID}@${DEVICE#*@}"
123
    fi
124

125 126 127 128
    if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" ] && [ "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then
      echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2
      continue
    fi
129 130
  fi

131 132 133 134 135
  BTRFS="`echo ${OS} | cut -d ':' -f 5`"
  if [ "x$BTRFS" = "xbtrfs" ]; then
	BTRFSuuid="`echo ${OS} | cut -d ':' -f 6`"
	BTRFSsubvol="`echo ${OS} | cut -d ':' -f 7`"
  fi
136 137 138 139 140

  if [ -z "${LONGNAME}" ] ; then
    LONGNAME="${LABEL}"
  fi

141 142 143
  # os-prober returns text string followed by optional counter
  CLASS="--class $(echo "${LABEL}" | LC_ALL=C sed 's,[[:digit:]]*$,,' | cut -d' ' -f1 | tr 'A-Z' 'a-z' | LC_ALL=C sed 's,[^[:alnum:]_],_,g')"

144
  gettext_printf "Found %s on %s\n" "${LONGNAME}" "${DEVICE}" >&2
145 146 147 148

  case ${BOOT} in
    chain)

149
	  onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
150
      cat << EOF
151
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
152
EOF
153 154
      save_default_entry | grub_add_tab
      prepare_grub_to_access_device ${DEVICE} | grub_add_tab
155

156 157 158 159 160 161
      if [ x"`${grub_probe} --device ${DEVICE} --target=partmap`" = xmsdos ]; then
	  cat << EOF
	parttool \${root} hidden-
EOF
      fi

162
      case ${LONGNAME} in
163
	Windows\ Vista*|Windows\ 7*|Windows\ Server\ 2008*)
164 165 166
	;;
	*)
	  cat << EOF
167
	drivemap -s (hd0) \${root}
168
EOF
169 170 171
	;;
      esac

172
      cat <<EOF
173 174
	chainloader +1
}
175 176 177 178 179 180 181 182
EOF
    ;;
    efi)

	EFIPATH=${DEVICE#*@}
	DEVICE=${DEVICE%@*}
	onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
      cat << EOF
183
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-efi-$(grub_get_device_id "${DEVICE}")' {
184 185 186 187 188 189 190
EOF
      save_default_entry | sed -e "s/^/\t/"
      prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"

      cat <<EOF
	chainloader ${EFIPATH}
}
191 192 193
EOF
    ;;
    linux)
194 195 196 197 198
      if [ "x$BTRFS" = "xbtrfs" ]; then
         LINUXPROBED="`linux-boot-prober btrfs ${BTRFSuuid} ${BTRFSsubvol}  2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
      else
         LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
      fi
199
      prepare_boot_cache=
200
      boot_device_id=
201
      is_top_level=true
202 203
      title_correction_code=
      OS="${LONGNAME}"
204

205 206 207 208 209 210 211 212 213 214 215 216
      for LINUX in ${LINUXPROBED} ; do
        LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
        LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
        LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`"
        LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
        LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
        LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`"

        if [ -z "${LLABEL}" ] ; then
          LLABEL="${LONGNAME}"
        fi

217 218 219 220 221
	if [ "${LROOT}" != "${LBOOT}" ]; then
	  LKERNEL="${LKERNEL#/boot}"
	  LINITRD="${LINITRD#/boot}"
	fi

222
	onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
223
	recovery_params="$(echo "${LPARAMS}" | grep single)" || true
224 225 226 227 228 229 230 231
	counter=1
	while echo "$used_osprober_linux_ids" | grep 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id' > /dev/null; do
	    counter=$((counter+1));
	done
	if [ -z "$boot_device_id" ]; then
	    boot_device_id="$(grub_get_device_id "${DEVICE}")"
	fi
	used_osprober_linux_ids="$used_osprober_linux_ids 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id'"
232

233
	if [ -z "${prepare_boot_cache}" ]; then
234
	  prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)"
235
	fi
236

237
	if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
238
            cat << EOF
239
menuentry '$(echo "$OS $onstr" | grub_quote)' $CLASS --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' {
240
EOF
241
	    save_default_entry | grub_add_tab
242 243
	    printf '%s\n' "${prepare_boot_cache}"
	    cat <<  EOF
244 245
	linux ${LKERNEL} ${LPARAMS}
EOF
246
            if [ -n "${LINITRD}" ] ; then
247 248 249
          cat << EOF
	initrd ${LINITRD}
EOF
250
            fi
251 252 253
        cat << EOF
}
EOF
254
	    echo "submenu '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"
255
	    is_top_level=false
256 257 258 259 260
	fi
	title="${LLABEL} $onstr"
        cat << EOF
	menuentry '$(echo "$title" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-$LKERNEL-${recovery_params}-$boot_device_id' {
EOF
261 262
	save_default_entry | sed -e "s/^/$grub_tab$grub_tab/"
	printf '%s\n' "${prepare_boot_cache}" | grub_add_tab
263 264 265 266 267 268 269 270 271 272 273 274
	cat <<  EOF
		linux ${LKERNEL} ${LPARAMS}
EOF
        if [ -n "${LINITRD}" ] ; then
            cat << EOF
		initrd ${LINITRD}
EOF
        fi
        cat << EOF
	}
EOF
	if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
275
	    replacement_title="$(echo "Advanced options for ${OS} $onstr" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
276 277 278 279
	    quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
	    title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
	    grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
	fi
280
      done
281
      if [ x"$is_top_level" != xtrue ]; then
282 283 284
	  echo '}'
      fi
      echo "$title_correction_code"
285
    ;;
286
    macosx)
287 288 289 290 291
      if [ "${UUID}" ]; then
	OSXUUID="${UUID}"
	osx_entry xnu_kernel 32
	osx_entry xnu_kernel64 64
      fi
292
    ;;
293
    hurd)
294
      onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
295
      cat << EOF
296
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
297
EOF
298 299
      save_default_entry | grub_add_tab
      prepare_grub_to_access_device ${DEVICE} | grub_add_tab
300
      grub_device="`${grub_probe} --device ${DEVICE} --target=drive`"
301
      mach_device="`echo "${grub_device}" | sed -e 's/(\(hd.*\),msdos\(.*\))/\1s\2/'`"
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
      grub_fs="`${grub_probe} --device ${DEVICE} --target=fs`"
      case "${grub_fs}" in
	*fs)	hurd_fs="${grub_fs}" ;;
	*)	hurd_fs="${grub_fs}fs" ;;
      esac
      cat << EOF
	multiboot /boot/gnumach.gz root=device:${mach_device}
	module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
			--multiboot-command-line='\${kernel-command-line}' \\
			--host-priv-port='\${host-port}' \\
			--device-master-port='\${device-port}' \\
			--exec-server-task='\${exec-task}' -T typed '\${root}' \\
			'\$(task-create)' '\$(task-resume)'
	module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
}
317 318 319 320 321 322 323 324 325 326 327
EOF
    ;;
    minix)
	  cat << EOF
menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" {
EOF
         save_default_entry | sed -e "s/^/\t/"
         prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
	 cat << EOF
	multiboot /boot/image_latest
}
328
EOF
329
    ;;
330
    *)
331
      # TRANSLATORS: %s is replaced by OS name.
332
      gettext_printf "%s is not yet supported by grub-mkconfig.\n" "  ${LONGNAME}" >&2
333
    ;;
334 335
  esac
done