Grub: dynamisch von letzter HDD im System booten?

Du kommst mit der Installation nicht voran oder willst noch was nachfragen? Schau auch in den "Tipps und Tricks"-Bereich.
Antworten
marting
Beiträge: 61
Registriert: 30.09.2008 17:31:05

Grub: dynamisch von letzter HDD im System booten?

Beitrag von marting » 08.10.2017 12:26:02

Hallo,

ich habe einen HP Microserver Gen8 im AHCI Modus laufen, d.h. das integrierte RAID wird nicht verwendet. Das Problem ist, dass in diesem Modus nicht festgelegt werden kann, von welcher Platte gebootet wird. Es wird immer die erste Platte verwendet. Nun ist meine Bootplatte aber an SATA5 angeschlossen. SATA1-4 sind die Wechseleinschübe und werden für Nutzdaten verwendet.

Der bekannte Workaround für dieses Gerät ist, dass Grub auf den internen USB Port installiert wird und Grub dann das eigentliche OS auf SATA5 bootet. Die korrekte Nummer hd1-5 hängt nun aber davon ab, wieviele Wechselplatten gesteckt sind. Wenn alle Einschübe drin, muss hd5 gewählt werden, ohne Einschub hd1 usw.
Nun hätte ich gerne, dass grub dies automatisch macht.
Gibt es hierfür eine Möglichkeit? Zwei Ideen:
- es gibt eine Möglichkeit, grub zu sagen, die letzte Platte zu nehmen (bevorzugt)
- es werden fünf Einträge im Bootmenü angelegt und diese werden der Reihe nach durchprobiert bis das System erfolgreich bootet

Hat jemand eine Idee, wie das bewerkstelligt werden könnte?

Viele Grüße
Martin

marting
Beiträge: 61
Registriert: 30.09.2008 17:31:05

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von marting » 08.10.2017 14:03:46

Für die zweite Variante ist wohl fallback das Mittel der Wahl. Muss ich mal testen, aber Variante 1 fände ich sauberer (falls das überhaupt möglich ist).

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von smutbert » 08.10.2017 14:24:06

Hm, ich glaube ich versteh das Problem nicht bzw. sehe kein Problem:

Wenn es sich um grub-pc handelt und du gezielt vom USB-Stick booten kannst, dann kannst du auch einfach nur die ersten beiden Teile von grub auf einen ansonsten beliebig per MBR partitionierten Stick schreiben. Vom Stick wird dann nur der MBR und gegenenfalls ein freier Bereich dahinter genutzt und der enthält, ohne dass man etwas dafür unternehmen müsste, soetwas wie eine "eingebettete Konfiguration", in der steht wo grub den Rest finden kann und zwar unabhängig von der Nummerierung der Platten.
In der eingebetteten Konfiguration sieht das z. B. so aus:

Code: Alles auswählen

search.fs_uuid 11adf701-62df-45bd-949b-493582d3e6e4 root 
set prefix=($root)/boot/grub
grub sucht das Dateisystem auf dem /boot liegt also anhand der UUID des Dateisystems und wie du leicht überprüfen kannst, gilt das erst recht für die Booteinträge in der automatisch erstellten »/boot/grub/grub.cfg« die dann geladen wird.

Das eröffnet meiner Meinung nach auch gleich eine zweite Möglichkeit damit umzugehen:
Du partitionierst die Platten einfach ebenfalls alle mit MBR oder wenn du willst auch mit gpt und legst dafür dann jeweils eine kleine BIOS Boot Partition an (1 MB) genügt und schreibst die ersten grub-Teile ebenfalls auf jede der Platten.

In beiden Fällen macht man das mit »grub-install«

Code: Alles auswählen

# grub-install /dev/sdX
im Falle der Festplatten wiederholt man das eben für jede eingesetzte Platte.
___

Eine weitere Variante wäre es auf jeder Platte eine kleine Partition vorzusehen, vielleicht 100 MB und dort jeweils einen eigenen, vom System unabhängigen grub zu installieren, bei dem auch die Booteinträge nicht mehr aktualisiert werden müssen. Letzteres erreicht man mit automatisch erstellen symbolischen Links auf den jeweils aktuellen und vorigen Kernel - das grundsätzliche Vorgehen habe ich in dem Wiki-Artikel beschrieben (der allerdings noch verbesserungsfähig ist):
https://wiki.debianforum.de/Ein_Notfall ... stallieren
(wenn ich das mache orientiere ich mich dann nicht an der UUID sondern den Labeln des Dateisystems, aber das ist nur eine Frage der Vorliebe)
___

und schließlich, wenn du grub-efi verwendest, dann gibt's sowieso kein Problem, weil entweder der Booteintrag im nvram auf die richtige Datei auf der richtigen Festplatte verweist oder weil das System ohne Booteintrag einfach auf allen Platten nach einer »EFI/BOOT/BOOTX64.EFI« auf einem vom UEFI lesbaren Dateisystem, vorzugsweise vfat auf einer EFI System Partition, sucht (das dann wieder ein grub-Image mit eingebetteter Konfiguration beinhalten kann/soll, dem die Nummerierung der Platten egal ist).

EDIT:
Das durchprobieren sollte auch gehen - tatsächlich gibt es bereits in der automatisch erstellten Konfiguration eine Art Fallback, der auf die Nummerierung zurückgreift, wenn die gewünschte UUID nicht gefunden wird, aber das würde ich wirklich nur versuchen, wenn es gar nicht anders geht, was imho nicht der Fall ist.

marting
Beiträge: 61
Registriert: 30.09.2008 17:31:05

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von marting » 09.10.2017 07:16:01

Vielen Dank für Deine sehr ausführliche Antwort. Ich habe mal wieder nur die Häfte der notwendigen Angaben gemacht, dafür bitte ich um Entschuldigung :-)

Also, aktuell bootet mein grub-pc/grub2 per Chainloader einen Windows Server. Den Inhalt der vier Einschub-Platten kann ich nicht beeinflussen, also keine zusätzliche Bootpartition anlegen o.ä., die Partitionstabelle wird beim Initialisieren des Datenträgers überschrieben.

Die Variante über search.fs_uuid hört sich erstmal sehr gut an. Hat den kleinen Nachteil, dass ich bei zwei quasi identischen Servern dennoch unterschiedliche Boot-Sticks bräuchte. Kann ich die fs_uuid auch aus der Grub Console heraus finden?

Meine grub.cfg sieht aktuell so aus:

Code: Alles auswählen

set default='0'
set timeout='5'

menuentry 'Windows Server 2016 Essentials' {
        set root=(hd5,msdos2)
        chainloader +1
}
Um nun korrekt zu booten, wenn nur zwei Zusatzplatten gesteckt sind, muss ich im Bootmenü ändern auf:

Code: Alles auswählen

set default='0'
set timeout='5'

menuentry 'Windows Server 2016 Essentials' {
        set root=(hd3,msdos2)
        chainloader +1
}
Die Fallback Variante ist eher unsauber, aber würde mir prinzipiell besser gefallen, als unterschiedliche Bootsticks für unterschiedliche Server. Würde nur sowas gehen?

Code: Alles auswählen

set default='0'
set fallback='1'
set timeout='5'

menuentry 'Windows Server 2016 Essentials 4 HDD Trays' {
        set root=(hd5,msdos2)
        chainloader +1
}
menuentry 'Windows Server 2016 Essentials 2 HDD Trays' {
        set root=(hd3,msdos2)
        chainloader +1
}
Oder auch sowas?

Code: Alles auswählen

set default='0'
set timeout='5'

menuentry 'Windows Server 2016 Essentials 4 HDD Trays' {
	set fallback='1'
        set root=(hd5,msdos2)
        chainloader +1
}
menuentry 'Windows Server 2016 Essentials 3 HDD Trays' {
	set fallback='2'
        set root=(hd4,msdos2)
        chainloader +1
}
menuentry 'Windows Server 2016 Essentials 2 HDD Trays' {
	set fallback='3'
        set root=(hd3,msdos2)
        chainloader +1
}
menuentry 'Windows Server 2016 Essentials 1 HDD Tray' {
	set fallback='4'
        set root=(hd2,msdos2)
        chainloader +1
}
menuentry 'Windows Server 2016 Essentials no HDD Trays' {
        set root=(hd1,msdos2)
        chainloader +1
}
Was meinst Du mit "einfach nur die ersten beiden Teile von grub auf einen ansonsten beliebig per MBR partitionierten Stick schreiben"? Was sind "die ersten beiden Teile"? Aktuell hat der Stick folgenden Inhalt:

Code: Alles auswählen

Z:\>tree /F
Folder PATH listing for volume BOOTSTICK
Volume serial number is 00000041 945F:361E
Z:.
└───boot
    └───grub
        │   grubenv
        │   grub.cfg
        │
        ├───i386-pc
        │       gcry_md4.mod
        │       normal.mod
        │       cmosdump.mod
        │       sendkey.mod
        │       search_fs_file.mod
        │       ohci.mod
        │       gcry_seed.mod
        │       geli.mod
        │       squash4.mod
        │       gcry_whirlpool.mod
        │       legacycfg.mod
        │       xnu_uuid.mod
        │       gcry_rsa.mod
        │       usbserial_usbdebug.mod
        │       gfxterm.mod
        │       gcry_serpent.mod
        │       hfsplus.mod
        │       acpi.mod
        │       gcry_idea.mod
        │       memdisk.mod
        │       cbtime.mod
        │       password_pbkdf2.mod
        │       linux16.mod
        │       hwmatch.mod
        │       pata.mod
        │       cs5536.mod
        │       lsapm.mod
        │       terminfo.mod
        │       keylayouts.mod
        │       linux.mod
        │       memrw.mod
        │       reboot.mod
        │       file.mod
        │       ufs1.mod
        │       tftp.mod
        │       relocator.mod
        │       signature_test.mod
        │       gcry_sha256.mod
        │       drivemap.mod
        │       archelp.mod
        │       gcry_rmd160.mod
        │       mmap.mod
        │       cmp.mod
        │       videotest_checksum.mod
        │       setpci.mod
        │       progress.mod
        │       configfile.mod
        │       spkmodem.mod
        │       chain.mod
        │       odc.mod
        │       hello.mod
        │       multiboot.mod
        │       minicmd.mod
        │       play.mod
        │       testload.mod
        │       ldm.mod
        │       part_msdos.mod
        │       gfxterm_menu.mod
        │       gfxterm_background.mod
        │       ufs2.mod
        │       macho.mod
        │       video_colors.mod
        │       pci.mod
        │       xfs.mod
        │       ata.mod
        │       part_gpt.mod
        │       morse.mod
        │       test_blockarg.mod
        │       loadenv.mod
        │       password.mod
        │       pcidump.mod
        │       extcmd.mod
        │       crc64.mod
        │       raid5rec.mod
        │       udf.mod
        │       search_label.mod
        │       lsmmap.mod
        │       bfs.mod
        │       backtrace.mod
        │       gcry_des.mod
        │       probe.mod
        │       hfspluscomp.mod
        │       hashsum.mod
        │       legacy_password_test.mod
        │       uhci.mod
        │       cpuid.mod
        │       gcry_md5.mod
        │       part_sun.mod
        │       cpio_be.mod
        │       xzio.mod
        │       minix3.mod
        │       offsetio.mod
        │       halt.mod
        │       lspci.mod
        │       gcry_rijndael.mod
        │       syslinuxcfg.mod
        │       gcry_camellia.mod
        │       tar.mod
        │       romfs.mod
        │       setjmp.mod
        │       tr.mod
        │       vga.mod
        │       terminal.mod
        │       help.mod
        │       gzio.mod
        │       echo.mod
        │       ntfscomp.mod
        │       zfscrypt.mod
        │       ufs1_be.mod
        │       time.mod
        │       functional_test.mod
        │       plan9.mod
        │       mdraid09.mod
        │       part_amiga.mod
        │       raid6rec.mod
        │       bitmap_scale.mod
        │       minix_be.mod
        │       afs.mod
        │       cryptodisk.mod
        │       usbserial_pl2303.mod
        │       pxechain.mod
        │       bitmap.mod
        │       xnu_uuid_test.mod
        │       mpi.mod
        │       gettext.mod
        │       gcry_crc.mod
        │       nativedisk.mod
        │       cmdline_cat_test.mod
        │       macbless.mod
        │       minix2.mod
        │       regexp.mod
        │       true.mod
        │       reiserfs.mod
        │       mdraid09_be.mod
        │       datehook.mod
        │       gdb.mod
        │       blocklist.mod
        │       gptsync.mod
        │       fat.mod
        │       minix2_be.mod
        │       iso9660.mod
        │       verify.mod
        │       keystatus.mod
        │       sleep.mod
        │       serial.mod
        │       hfs.mod
        │       lsacpi.mod
        │       pbkdf2.mod
        │       dm_nv.mod
        │       loopback.mod
        │       iorw.mod
        │       crypto.mod
        │       cpio.mod
        │       http.mod
        │       biosdisk.mod
        │       msdospart.mod
        │       nilfs2.mod
        │       cbtable.mod
        │       elf.mod
        │       hdparm.mod
        │       gcry_cast5.mod
        │       gcry_dsa.mod
        │       pbkdf2_test.mod
        │       part_sunpc.mod
        │       efiemu.mod
        │       usbms.mod
        │       font.mod
        │       disk.mod
        │       part_plan.mod
        │       gfxmenu.mod
        │       part_acorn.mod
        │       cmostest.mod
        │       gcry_sha512.mod
        │       parttool.mod
        │       gcry_rfc2268.mod
        │       diskfilter.mod
        │       gcry_arcfour.mod
        │       eval.mod
        │       procfs.mod
        │       hexdump.mod
        │       usbtest.mod
        │       video_cirrus.mod
        │       jpeg.mod
        │       boot.mod
        │       testspeed.mod
        │       ls.mod
        │       lvm.mod
        │       mdraid1x.mod
        │       part_dvh.mod
        │       bufio.mod
        │       sfs.mod
        │       tga.mod
        │       multiboot2.mod
        │       mda_text.mod
        │       minix.mod
        │       setjmp_test.mod
        │       pxe.mod
        │       video_fb.mod
        │       ntfs.mod
        │       read.mod
        │       newc.mod
        │       priority_queue.mod
        │       cbmemc.mod
        │       part_apple.mod
        │       all_video.mod
        │       vbe.mod
        │       fshelp.mod
        │       gcry_blowfish.mod
        │       cbfs.mod
        │       usbserial_common.mod
        │       videoinfo.mod
        │       lzopio.mod
        │       search.mod
        │       div_test.mod
        │       luks.mod
        │       bsd.mod
        │       xnu.mod
        │       aout.mod
        │       zfsinfo.mod
        │       ahci.mod
        │       gcry_twofish.mod
        │       at_keyboard.mod
        │       usb.mod
        │       freedos.mod
        │       test.mod
        │       vga_text.mod
        │       cbls.mod
        │       ntldr.mod
        │       scsi.mod
        │       gcry_sha1.mod
        │       usbserial_ftdi.mod
        │       video_bochs.mod
        │       ext2.mod
        │       datetime.mod
        │       usb_keyboard.mod
        │       affs.mod
        │       gcry_tiger.mod
        │       cat.mod
        │       search_fs_uuid.mod
        │       915resolution.mod
        │       png.mod
        │       truecrypt.mod
        │       sleep_test.mod
        │       btrfs.mod
        │       exfat.mod
        │       date.mod
        │       zfs.mod
        │       jfs.mod
        │       ehci.mod
        │       minix3_be.mod
        │       part_bsd.mod
        │       trig.mod
        │       adler32.mod
        │       videotest.mod
        │       video.mod
        │       part_dfly.mod
        │       net.mod
        │       exfctest.mod
        │       efiemu32.o
        │       efiemu64.o
        │       moddep.lst
        │       command.lst
        │       fs.lst
        │       partmap.lst
        │       parttool.lst
        │       video.lst
        │       crypto.lst
        │       terminal.lst
        │       modinfo.sh
        │       core.img
        │       boot.img
        │
        ├───locale
        │       de@hebrew.mo
        │       en@quot.mo
        │       it.mo
        │       pt_BR.mo
        │       vi.mo
        │       de_CH.mo
        │       tr.mo
        │       hu.mo
        │       es.mo
        │       sv.mo
        │       ja.mo
        │       id.mo
        │       lt.mo
        │       pa.mo
        │       zh_TW.mo
        │       fi.mo
        │       eo.mo
        │       fr.mo
        │       en@greek.mo
        │       uk.mo
        │       gl.mo
        │       ast.mo
        │       da.mo
        │       en@hebrew.mo
        │       de.mo
        │       zh_CN.mo
        │       en@piglatin.mo
        │       pl.mo
        │       sl.mo
        │       en@arabic.mo
        │       nl.mo
        │       ru.mo
        │       en@cyrillic.mo
        │       ca.mo
        │
        └───fonts
                unicode.pf2
Die für mich perfekte Lösung sähe etwa so aus:

Code: Alles auswählen

set default='0'
set timeout='5'

menuentry 'Windows Server 2016 Essentials' {
        set root=(hd-1,msdos2)
        chainloader +1
}
Wobei das natürlich zu Schwierigkeiten führen würde, wenn eine USB-Platte o.ä. zum Booten am Server hängt. Vermutlich ist sogar der Bootstick schon die letzte "Platte", müsste also die vorletzte (-2) Platte gebootet werden.

Je länger ich darüber nachdenke, umso mehr komme ich zur Überzeugung, dass Fallbacks von vorne startend am geeignetsten sind.

Viele Grüße
Martin

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von smutbert » 09.10.2017 10:17:46

Mit den ersten Teilen, meine ich den ersten und den eineinhalbten Stage, von denen der erste in dem MBR und der zweite in einen freien Bereich dahinter bzw. in eine eventuell vorhandene BIOS Boot Partition geschrieben wird. Das sind also keine Dateien auf einem Dateisystem (solange es nicht um uefi geht).

Mit dem Starten von Windows und dem chainloaden ganz allgemein habe ich kaum Erfahrung, aber du kannst ja vielleicht die Namen der Dateisysteme so anpassen, dass sie überall gleich sind und dann mit Einträgen in der Art (bin mir nicht 100%ig sicher, dass das mit dem chainloader so funktioniert):

Code: Alles auswählen

menuentry 'von der Partition mit dem Dateisystem namens Windows chainloaden' {
	search --no-floppy --label --set=root Windows
	chainloader +1
}
Das mit dem Fallback müsste anders aussehen. Ich kenne es nur so wie es die automatisch generierte grub.cfg macht, die root zuerst auf ein Gerät nach der Nummer setzt und dann den Wert überschreibt, falls es ein Gerät mit der richtigen UUID gibt. Den zweiten Teil kann man dann beliebig wiederholen und auch durch Suchen nach dem Dateisystemlabel ersetzen oder ergänzen

Code: Alles auswählen

set root='hd1,msdos2'
search --no-floppy --fs-uuid --set=root eine_Dateisystem_UUID
search --no-floppy --fs-uuid --set=root eine_andere_Dateisystem_UUID
search --no-floppy --label --set=root Name_eines_Windowsdateisystems
chainloader +1
aber es hat keinen Sinn zu versuchen, die Zuweisung nach Nummern zu wiederholen, weil man damit die Variable zweifelsfalls einfach auf ein nicht existentes Gerät setzt und auch hier gilt, dass ich mir nicht sicher bin, dass sich der search-Aufruf mit chainloader kombinieren lässt.
Die erste "set root=..."-Zeile wäre also der Fallback, die folgenden Zeilen überschreiben root, wenn ein passendes passendes Dateisystem gefunden wird.

Man kann aber bestimmt noch viel gefinkeltere Dinge mit grub anstellen. Die super grub boot disk hat z. B. eine sehr aufwändige grub-Konfiguration, die sich auf viele Dateien verteilt und die automatisch Systeme erkennt, passende Bootmenüeinträge erzeugt, u. s. w.
Ich durchblicke die Konfiguration dort noch nicht einmal ansatzweise, aber vielleicht genügt es ja nur bei einem kleinen Teil der Konfiguration zu erkennen wofür er da ist und den Code zu klauen:
https://github.com/supergrub/supergrub/ ... /menus/sgd

marting
Beiträge: 61
Registriert: 30.09.2008 17:31:05

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von marting » 09.10.2017 10:57:26

Deine Lösung mit search-by-label dürfte das Mittel der Wahl sein, wenn das in Verbindung mit chainloader funktioniert. Sobald ich die Kiste neu starten kann, werde ich das ausprobieren. Vielen Dank, darauf bin ich absolut nicht gekommen.

Ich glaube, Du meinst mit Fallback etwas anderes als ich (auch wenn Deins ebenfalls möglich sein mag). Die Direktive fallback wird laut Manual unterstützt und gibt wie default den numerischen Listeneintrag an: https://www.gnu.org/software/grub/manua ... l#fallback
Zumindest beim Legacy steht in der Doku auch, dass mehrere Fallbacks möglich sind: https://www.gnu.org/software/grub/manua ... l#fallback
Ich denke, dass sich das nicht geändert hat.

Evtl. wäre die Syntax dann aber soetwas in der Art:

Code: Alles auswählen

default=0
fallback=1,2,3   (in Legacy: fallback 1 2)
menuentry { ..... }
menuentry { ..... }
menuentry { ..... }
menuentry { ..... }
Nachdem mir Deine erste Lösung aber am besten überhaupt gefällt, werde ich erstmal das testen.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von smutbert » 09.10.2017 11:01:52

Oh, die Möglichkeit ist mir bis jetzt komplett entgangen - ja das muss auch gehen.
Allerdings ist es mir bei fehlerhaften Booteinträgen und ähnlichem schon oft passiert, dass ich nicht zurück in das grub-Menü oder auch die grub-Kommandozeile gekommen bin und nach einem so misslungenen Bootversuch kann diese Art von Fallback natürlich nicht weiterhelfen.

marting
Beiträge: 61
Registriert: 30.09.2008 17:31:05

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von marting » 09.10.2017 11:08:13

Ich bin mir auch nicht sicher, ob diese Syntax wirklich korrekt ist: fallback=1,2,3
Dafür habe ich kein Beispiel gefunden und ich weiß nicht, wie man Listen an Grub2 übergibt. Für Legacy ist hier ein Beispiel: https://www.gnu.org/software/grub/manua ... ck-systems

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Grub: dynamisch von letzter HDD im System booten?

Beitrag von smutbert » 09.10.2017 21:26:59

hier [1] steht es so als könnte man so nur einen Fallback definieren, indem man einfach fallback=nummer schreibt und so ähnlich klingt es auch im Ubuntuwiki, auch wenn das nur das übliche automatische Erstellen der grub.cfg behandelt.
Sonst habe ich auch kein Beispiel gefunden und ich bin mir auch nicht sicher in welchen Situationen dieser Fallback funktioniert - immerhin ist im Ubuntuwiki eher die Rede davon, dass man das System nach einem erfolglosen Bootversuch resettet und beim nächsten Versuch automatisch der Fallback-Eintrag startet. Wenn das wirklich so läuft setzt das imho auch voraus, dass grub den fehlgeschlagenen Versuch irgendwie dokumentiert.

edit:
Es könnte doch das sein was du suchst oder sich zumindest ganz ähnlich realisieren lassen [3], aber ich durchblicke es noch nicht ganz.

[1] https://access.redhat.com/documentation ... gfile.html
[2] https://wiki.ubuntuusers.de/GRUB_2/Skripte/
[3] https://lists.gnu.org/archive/html/help ... 00018.html

Antworten