Antynea / grub-btrfs

Include btrfs snapshots at boot options. (Grub menu)
GNU General Public License v3.0
775 stars 77 forks source link

2 grub-btrfs Questions #355

Closed dos4gw-exe closed 1 week ago

dos4gw-exe commented 3 weeks ago

Hello Antynea, I got 2 Question for you:

  1. Is there an option to change the timeout of the grub menu?
  2. Is it possible to remove your program if necessary?

Kind regards

Schievel1 commented 2 weeks ago

Yes, there is an option, but it has nothing to do with grub-btrfs. It's an option of grub itself. Have a look at GRUB_TIMEOUT and friends in /etc/default/grub.

You can uninstall using the Makefile with "sudo make uninstall". If your distribution packaged grub-btrfs the uninstallation depends on your distribution. But most package managers offer uninstallation of packages. (Using something like "sudo apt-get remove...")

dos4gw-exe commented 2 weeks ago

Thank you for your response. I tried already to change the GRUB_TIMEOUT with running the grub-update command and I also tried to change it via the grub-optimizer. Both didn't work. I overlooked some other files witch sounded like "grub" or "btrfs" without success. My distribution is Linux Mint 22.

Schievel1 commented 2 weeks ago

Hm can you show me the contents of the file /etc/default/grub?

dos4gw-exe commented 2 weeks ago

See below...

If you change this file, run 'update-grub' afterwards to update

/boot/grub/grub.cfg.

For full documentation of the options in this file, see:

info -f grub -n 'Simple configuration'

GRUB_DEFAULT="0" GRUB_TIMEOUT_STYLE="hidden" GRUB_TIMEOUT="3" GRUB_DISTRIBUTOR="( . /etc/os-release; echo ${NAME:-Ubuntu} ) 2>/dev/null || echo Ubuntu" GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" GRUB_CMDLINE_LINUX=""

If your computer has multiple operating systems installed, then you

probably want to run os-prober. However, if your computer is a host

for guest OSes installed via LVM or raw disk devices, running

os-prober can cause damage to those guest OSes as it mounts

filesystems to look for things.

GRUB_DISABLE_OS_PROBER="false"

Uncomment to enable BadRAM filtering, modify to suit your needs

This works with Linux (no patch required) and with any kernel that obtains

the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)

GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"

Uncomment to disable graphical terminal

GRUB_TERMINAL="console"

The resolution used on graphical terminal

note that you can use only modes which your graphic card supports via VBE

you can see them in real GRUB with the command `vbeinfo'

GRUB_GFXMODE="640x480"

Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux

GRUB_DISABLE_LINUX_UUID="true"

Uncomment to disable generation of recovery mode menu entries

GRUB_DISABLE_RECOVERY="true"

Uncomment to get a beep at grub start

GRUB_INIT_TUNE="480 440 1"

dos4gw-exe commented 2 weeks ago

Sorry here is the file... grub.txt

Schievel1 commented 2 weeks ago

So, right now you got a 3 second timeout. In order to actually see whats going on, you can change GRUB_TIMEOUT_STYLE="hidden" to GRUB_TIMEOUT_STYLE="countdown" or GRUB_TIMEOUT_STYLE="menu". This will show you the timeout (and the menu as well if set to menu) To change the length of the timeout set GRUB_TIMEOUT=10 for 10s for example. You have to run sudo update-grub for your system to take those values from the defaults and compile an actual menu settings file from them. The menu file gets put into /boot/grub/grub.cfg automatically. Hope this helps.

dos4gw-exe commented 2 weeks ago

The timeout in the menu should be 3 second but it is 30 seconds. No matter what number I type in it remains at 30 seconds. I have changed from GRUB_TIMEOUT_STYLE="hidden" to the GRUB_TIMEOUT_STYLE="countdown" as you said and the menu was the same. I looked into the /boot/grub/grub.cfg and found following at line 101:

terminal_output gfxterm if [ "${recordfail}" = 1 ] ; then set timeout=30 else if [ x$feature_timeout_style = xy ] ; then set timeout_style=countdown set timeout=3

Maybe it uses the timeout written above. I renamed the file to upload it here:

grub_cfg.txt

Schievel1 commented 2 weeks ago

recordfail is usually set when the system failed to boot the last time. But when grub is installed in a btrfs partition, it does not work because grub can't write to it. My guess is that something set recordfail and now it cannot reset. What is your partition layout? Can you run fdisk -l and show the output here?

btw. you can format code in the comments here with the backtick. In line like this use single backticks ` before and after. For multi lines use an line with three backticks before and after:

if (this) {
    that();
}
dos4gw-exe commented 1 week ago

Here is the output from fdisk -l:

Festplatte /dev/nvme0n1: 476,94 GiB, 512110190592 Bytes, 1000215216 Sektoren
Festplattenmodell: KINGSTON SKC3000S512G                   
Einheiten: Sektoren von 1 * 512 = 512 Bytes
Sektorgröße (logisch/physikalisch): 512 Bytes / 512 Bytes
E/A-Größe (minimal/optimal): 512 Bytes / 512 Bytes
Festplattenbezeichnungstyp: gpt
Festplattenbezeichner: A530ADA5-5848-401F-BB34-2A357C87C937

Gerät           Anfang       Ende  Sektoren  Größe Typ
/dev/nvme0n1p1    2048    1026047   1024000   500M EFI-System
/dev/nvme0n1p2 1026048    9414655   8388608     4G Linux Swap
/dev/nvme0n1p3 9414656 1000214527 990799872 472,5G Linux-Dateisystem

Festplatte /dev/sda: 223,57 GiB, 240057409536 Bytes, 468862128 Sektoren
Festplattenmodell: SATA3 240GB SSD 
Einheiten: Sektoren von 1 * 512 = 512 Bytes
Sektorgröße (logisch/physikalisch): 512 Bytes / 512 Bytes
E/A-Größe (minimal/optimal): 512 Bytes / 512 Bytes
Festplattenbezeichnungstyp: gpt
Festplattenbezeichner: A9142496-27F5-4A4F-BDC4-7ABE8AB7C3CE

Gerät         Anfang      Ende  Sektoren Größe Typ
/dev/sda1       2048    206847    204800  100M EFI-System
/dev/sda2     206848    239615     32768   16M Microsoft reserviert
/dev/sda3     239616 179265535 179025920 85,4G Microsoft Basisdaten
/dev/sda4  179265536 180887551   1622016  792M Windows-Wiederherstellungsumgebung
/dev/sda5  180887552 333998079 153110528   73G Linux-Dateisystem
/dev/sda6  467611648 468858879   1247232  609M Windows-Wiederherstellungsumgebung
/dev/sda7  333998080 467611647 133613568 63,7G Linux-Dateisystem

Partitionstabelleneinträge sind nicht in Festplatten-Reihenfolge.

Festplatte /dev/sdc: 14,56 GiB, 15634300928 Bytes, 30535744 Sektoren
Festplattenmodell:                 
Einheiten: Sektoren von 1 * 512 = 512 Bytes
Sektorgröße (logisch/physikalisch): 512 Bytes / 512 Bytes
E/A-Größe (minimal/optimal): 512 Bytes / 512 Bytes
Festplattenbezeichnungstyp: dos
Festplattenbezeichner: 0x95faa017

Gerät      Boot Anfang     Ende Sektoren Größe Kn Typ
/dev/sdc1         2048 30535679 30533632 14,6G  7 HPFS/NTFS/exFAT
Schievel1 commented 1 week ago

hm, stunning. I guess grub is installed in /dev/nvme0n1p1 but that seems to be a FAT partition so recordfail should work. For a quick workaround, can you set GRUB_RECORDFAIL_TIMEOUT=5 in /etc/default/grub and run sudo update-grub? And maybe post the content of /etc/grub.d/00_header, maybe we can change something in there to make this work.

dos4gw-exe commented 1 week ago

The workaround seems to work... Here is the content of 00_header:

set -e

# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
#
# 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/>.

prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
grub_lang=`echo $LANG | cut -d . -f 1`
grubdir="`echo "/boot/grub" | sed 's,//*,/,g'`"
quick_boot="1"

export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"

. "$pkgdatadir/grub-mkconfig_lib"

# Do this as early as possible, since other commands might depend on it.
# (e.g. the `loadfont' command might need lvm or raid modules)
for i in ${GRUB_PRELOAD_MODULES} ; do
  echo "insmod $i"
done

if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=auto ; fi

if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi

cat << EOF
if [ -s \$prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
EOF
cat <<EOF
if [ "\${initrdfail}" = 2 ]; then
   set initrdfail=
elif [ "\${initrdfail}" = 1 ]; then
   set next_entry="\${prev_entry}"
   set prev_entry=
   save_env prev_entry
   if [ "\${next_entry}" ]; then
      set initrdfail=2
   fi
fi
EOF
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
    cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
   set default="${GRUB_DEFAULT_BUTTON}"
elif [ "\${next_entry}" ] ; then
   set default="\${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${GRUB_DEFAULT}"
fi
EOF
else
    cat <<EOF
if [ "\${next_entry}" ] ; then
   set default="\${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${GRUB_DEFAULT}"
fi
EOF
fi
cat <<EOF

if [ x"\${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "\${prev_saved_entry}" ]; then
  set saved_entry="\${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "\${boot_once}" ]; then
    saved_entry="\${chosen}"
    save_env saved_entry
  fi
}
EOF

cat <<"EOF"
function initrdfail {
    if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
      if [ -z "${initrdfail}" ]; then
        set initrdfail=1
        if [ -n "${boot_once}" ]; then
          set prev_entry="${default}"
          save_env prev_entry
        fi
      fi
      save_env initrdfail
    fi; fi
}
EOF

if [ "$quick_boot" = 1 ]; then
    cat <<EOF
function recordfail {
  set recordfail=1
EOF

  check_writable () {
    abstractions="$(grub-probe --target=abstraction "${grubdir}")"
    for abstraction in $abstractions; do
      case "$abstraction" in
        diskfilter | lvm)
          cat <<EOF
  # GRUB lacks write support for $abstraction, so recordfail support is disabled.
EOF
          return 1
          ;;
      esac
    done

    FS="$(grub-probe --target=fs "${grubdir}")"
    case "$FS" in
      btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
    cat <<EOF
  # GRUB lacks write support for $FS, so recordfail support is disabled.
EOF
    return 1
    ;;
    esac

    cat <<EOF
  if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
EOF
  }

  if ! check_writable; then
    recordfail_broken=1
  fi

  cat <<EOF
}
EOF
fi

cat <<EOF
function load_video {
EOF
if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
    cat <<EOF
  insmod ${GRUB_VIDEO_BACKEND}
EOF
else
# If all_video.mod isn't available load all modules available
# with versions prior to introduction of all_video.mod
cat <<EOF
  if [ x\$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
EOF
fi
cat <<EOF
}

EOF

serial=0;
gfxterm=0;
for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
    if [ xserial = "x$x" ]; then
    serial=1;
    fi
    if [ xgfxterm = "x$x" ]; then
    gfxterm=1;
    fi
done

if [ "x$serial" = x1 ]; then
    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
    grub_warn "$(gettext "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used.")"
    GRUB_SERIAL_COMMAND=serial
    fi
    echo "${GRUB_SERIAL_COMMAND}"
fi

if [ "x$gfxterm" = x1 ]; then
    if [ -n "$GRUB_FONT" ] ; then
       # Make the font accessible
       prepare_grub_to_access_device `${grub_probe} --target=device "${GRUB_FONT}"`
    cat << EOF
if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT}"` ; then
EOF
    else
    for dir in "${pkgdatadir}" "`echo '/boot/grub' | sed "s,//*,/,g"`" /usr/share/grub ; do
        for basename in unicode unifont ascii; do
        path="${dir}/${basename}.pf2"
        if is_path_readable_by_grub "${path}" > /dev/null ; then
            font_path="${path}"
        else
            continue
        fi
        break 2
        done
    done
    if [ -n "${font_path}" ] ; then
    cat << EOF
if [ x\$feature_default_font_path = xy ] ; then
   font=unicode
else
EOF
                # Make the font accessible
        prepare_grub_to_access_device `${grub_probe} --target=device "${font_path}"`
    cat << EOF
    font="`make_system_path_relative_to_its_root "${font_path}"`"
fi

if loadfont \$font ; then
EOF
        else
    cat << EOF
if loadfont unicode ; then
EOF
        fi
    fi

    cat << EOF
  set gfxmode=${GRUB_GFXMODE}
  load_video
  insmod gfxterm
EOF

# Gettext variables and module
if [ "x${grub_lang}" != "xC" ] && [ "x${LANG}" != "xPOSIX" ] && [ "x${LANG}" != "x" ]; then
  cat << EOF
  set locale_dir=\$prefix/locale
  set lang=${grub_lang}
  insmod gettext
EOF
fi

cat <<EOF
fi
EOF
fi

case x${GRUB_TERMINAL_INPUT} in
  x)
    # Just use the native terminal
  ;;
  x*)
    cat << EOF
terminal_input ${GRUB_TERMINAL_INPUT}
EOF
  ;;
esac

case x${GRUB_TERMINAL_OUTPUT} in
  x)
    # Just use the native terminal
  ;;
  x*)
    cat << EOF
terminal_output ${GRUB_TERMINAL_OUTPUT}
EOF
  ;;
esac

if [ "x$gfxterm" = x1 ]; then
    if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \
    && is_path_readable_by_grub "$GRUB_THEME"; then
    gettext_printf "Found theme: %s\n" "$GRUB_THEME" >&2

    prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"`
    cat << EOF
insmod gfxmenu
EOF
    themedir="`dirname "$GRUB_THEME"`"
    for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do
        if [ -f "$x" ]; then
        cat << EOF
loadfont (\$root)`make_system_path_relative_to_its_root $x`
EOF
        fi
    done
    if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then
        cat << EOF
insmod jpeg
EOF
    fi
    if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then
        cat << EOF
insmod png
EOF
    fi
    if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then
        cat << EOF
insmod tga
EOF
    fi

    cat << EOF
set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME`
export theme
EOF
    elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \
        && is_path_readable_by_grub "$GRUB_BACKGROUND"; then
    gettext_printf "Found background: %s\n" "$GRUB_BACKGROUND" >&2
    case "$GRUB_BACKGROUND" in 
        *.png)         reader=png ;;
        *.tga)         reader=tga ;;
        *.jpg|*.jpeg)  reader=jpeg ;;
        *)             gettext "Unsupported image format" >&2; echo >&2; exit 1 ;;
    esac
    prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"`
    cat << EOF
insmod $reader
background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
EOF
    fi
fi

make_timeout ()
{
    cat << EOF
if [ "\${recordfail}" = 1 ] ; then
  set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
else
EOF
    if [ "x${3}" != "x" ] ; then
    timeout="${2}"
    style="${3}"
    elif [ "x${1}" != "x" ] && \
     ([ "$quick_boot" = 1 ] || [ "x${1}" != "x0" ]) ; then
    # Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
    timeout="${1}"
    if [ "x${2}" != "x0" ] ; then
        grub_warn "$(gettext "Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.")"
    fi
    if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
        style="hidden"
        verbose=
    else
        style="countdown"
        verbose=" --verbose"
    fi
    else
    # No hidden timeout, so treat as GRUB_TIMEOUT_STYLE=menu
    timeout="${2}"
    style="menu"
    fi
    cat << EOF
  if [ x\$feature_timeout_style = xy ] ; then
    set timeout_style=${style}
    set timeout=${timeout}
EOF
    if [ "x${style}" = "xmenu" ] ; then
    cat << EOF
  # Fallback normal timeout code in case the timeout_style feature is
  # unavailable.
  else
    set timeout=${timeout}
EOF
    else
    cat << EOF
  # Fallback hidden-timeout code in case the timeout_style feature is
  # unavailable.
  elif sleep${verbose} --interruptible ${timeout} ; then
    set timeout=0
EOF
    fi
    cat << EOF
  fi
fi
EOF
if [ "$recordfail_broken" = 1 ]; then
  cat << EOF
if [ \$grub_platform = efi ]; then
  set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
  if [ x\$feature_timeout_style = xy ] ; then
    set timeout_style=menu
  fi
fi
EOF
fi
}

if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
    cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_STYLE_BUTTON}"
echo else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
echo fi
else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
fi

if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ] && [ "x$GRUB_BUTTON_CMOS_CLEAN" = "xyes" ]; then
    cat <<EOF
cmosclean $GRUB_BUTTON_CMOS_ADDRESS
EOF
fi

# Play an initial tune
if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then
  echo "play ${GRUB_INIT_TUNE}"
fi

if [ "x${GRUB_BADRAM}" != "x" ] ; then
  echo "badram ${GRUB_BADRAM}"
fi
Schievel1 commented 1 week ago

I don't know where your grub is installed, but it seems to think it's installed in a btrfs partition. Anyway, if you're happy with the workaround, we don't need to investigate further. This isn't really the right place for it anyway.

dos4gw-exe commented 1 week ago

Thank you for your effort!