Bug 25981 - menu.lst Datei generieren
menu.lst Datei generieren
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: Grub
UCS 3.0
Other Linux
: P5 enhancement (vote)
: UCS 3.0-1
Assigned To: Moritz Muehlenhoff
Philipp Hahn
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-01-31 11:10 CET by Stefan Gohmann
Modified: 2012-03-04 14:34 CET (History)
0 users

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments
/boot/vmlinuz* → menu.lst (3.73 KB, text/plain)
2012-02-21 19:56 CET, Philipp Hahn
Details
grub.cfg → menu.lst (4.52 KB, text/plain)
2012-02-21 19:56 CET, Philipp Hahn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Gohmann univentionstaff 2012-01-31 11:10:13 CET
Einige Virtualisierungssysteme, beispielsweise Amazon EC2, nutzen eine ältere pygrub Version und verwenden deshalb die alte menu.lst. Wir sollten diese automatisch generieren.
Comment 1 Moritz Muehlenhoff univentionstaff 2012-02-10 14:47:18 CET
univention-grub-generate-menu-lst generiert jetzt aus allen installierten Kerneln eine menu.lst. Das wird dann aus update-grub aufgerufen.

Taucht in einer bestehenden /boot/grub/menu.lst nicht der String "auto-generated through univention-grub-generate-menu-lst" auf, bricht das Tool ab, um Chainloading-Setups nach Updates von 2.4 nicht zu gefährden. 

Tests mit einem entsprechenden pygrub-Setup stehen noch aus. Ggf. müssen einige Werte für die menu.lst auch noch über UCR gesetzt werden, die von grub2 automatisch ermittelt werden.
Comment 2 Moritz Muehlenhoff univentionstaff 2012-02-15 12:46:57 CET
Das in Kommentar 1 beschriebene Verhalten kann mit der UCR-Variable grub/generate-menu-lst deaktiviert werden (standardmässig ist es an). 

Ich habe in Xen ein Basis-System installiert und auf 3.0-1 aktualisiert. Dann habe ich das Image auf ein UCS 2.4-0-Xen-System kopiert und in UVMM eine VM angelegt und ihr das 3.0-1-Image zugewiesen. Pygrub konnte es damit direkt starten.

Für die QA wäre es aber vielleicht sinnvoll, UCS 3.0-1 nochmal in EC2 zu installieren.

Changelog wurde ergänzt.
Comment 3 Philipp Hahn univentionstaff 2012-02-20 16:32:43 CET
I: Beim Testen gab es Probleme mit Sparse-Files, was aber nicht unbedingt was mit diesem Bug hier zu tun hatte → Bug #26192

OK: Bei Installieren von neuen Kerneln und De-Installieren von alten Kerneln wird dir die Liste entsprechend automatisch neu generiert.

OK: Die /boot/grub/menu.lst kann von einem alten PyGrub (UCS-2.4-3) verwendet werden. Ohne dieses Patch wird ein Fehler dieser gemeldet.

OK: Erkennung von "magischen Zeichenkette" funktioniert; die Datei wird dann nicht überschrieben.

FAIL: Die Sortierung stimmt noch nicht: ucs7 wird in der umgekehrten Reihenfolge vor ucs52 einsortiert und dann verwendet. Hier muß numerisch anstatt per Zeichenkette sortiert werden.

I: Installation in EC2 wird hier nicht getestet.
Comment 4 Moritz Muehlenhoff univentionstaff 2012-02-21 09:40:21 CET
(In reply to comment #3)

> FAIL: Die Sortierung stimmt noch nicht: ucs7 wird in der umgekehrten
> Reihenfolge vor ucs52 einsortiert und dann verwendet. Hier muß numerisch
> anstatt per Zeichenkette sortiert werden.

Die Sortierung erfolgt nun primär anhand der Kernel-Version und sekundär anhand der Integer-Repräsentation des UCS-Build-Strings hinter dem "ucs". Für diese mit touch erzeugten vmlinuz-Dateien

root@master:~# ls /boot/vmlinuz-2.6.3*
/boot/vmlinuz-2.6.31-ucs52-amd64  /boot/vmlinuz-2.6.32-ucs52-amd64  /boot/vmlinuz-2.6.32-ucs59-amd64  /boot/vmlinuz-2.6.32-ucs9-amd64

ergibt sich damit folgende Sortierung:

root@master:~# grep title /boot/grub/menu.lst
title           UCS, kernel 2.6.32-ucs59-amd64
title           UCS, kernel 2.6.32-ucs52-amd64
title           UCS, kernel 2.6.32-ucs9-amd64
title           UCS, kernel 2.6.31-ucs52-amd64

Changelog bleibt gleich.
Comment 5 Philipp Hahn univentionstaff 2012-02-21 19:55:09 CET
Besser, aber das Skript scheitert jetzt an Kernel-Namen, die ein flavour (xen, bigmem) enthalten, weil dadurch beim split() ein 4-Tupel entsteht, von denen aber dann nur die ersten 3 Teile genutzt werden, um daraus den Pfadnamen unvollständig zu rekonstruieren.
Ein weiteres Problem sind die Übergänge zwischen 1- und 2-stelligen Versionskomponenten: 2.6.9 < 2.6.10 < 3.0.0

# ls -1v /boot/vmlinuz-2.6.*
/boot/vmlinuz-2.6.4-4-junk
/boot/vmlinuz-2.6.32-5-amd64
/boot/vmlinuz-2.6.32-5-xen-amd64
/boot/vmlinuz-2.6.32-ucs4-junk
/boot/vmlinuz-2.6.32-ucs6-junk
/boot/vmlinuz-2.6.32-ucs52-amd64
/boot/vmlinuz-2.6.32-ucs52-xen-amd64
/boot/vmlinuz-2.6.32-ucs59-amd64
/boot/vmlinuz-2.6.32-ucs59-xen-amd64
/boot/vmlinuz-2.6.100-4-junk

Ich würde hier die Verwendung von LooseVersion aus distutils empfehlen, was eine Versionsnummer zerlegt und die Bestandteile entsprechend numerisch oder lexikografisch vergleicht:

 from distutils.version import LooseVersion
 kernels = glob("/boot/vmlinuz-*")
 for kernel in sorted(kernels, key=LooseVersion, reverse=True):
   kver = kernel[14:] # /boot/vmlinuz-
   initrd = "initrd.img-%s" % kver
   print "title           UCS, kernel %s" % kver
   print "root            (hd0,0)"
   print "kernel          /vmlinuz-%s root=/dev/mapper/vg_ucs-rootfs ro splash=nosplash" % kver
   if os.path.exists('/boot/%s' % initrd):
    print "initrd          /%s" % initrd
   print ""

Ein weiteres Problem (?) ist, das PyGrub die grub1-Konfiguration bevorzugt und damit die grub2-Konfiguration überspringt. Insbesondere den hier hart kodierten Wert für root sehe ich als problematisch an, weil dieser Name während der Partitionierung frei gewählt werden kann.
Ggf. sollte hier der Inhalt von /proc/cmdline angehängt werden, was allerdings bei der Installation schief geht (Boot von DVD vs. Boot von HD). Von daher wären hier die gleichen Argumente wie in /boot/grub/grub.cfg am besten.

Mit scheint es fast besser zu sein /boot/grub/grub.cfg zu parsen und daraus /boot/grub/menu.lst zu generieren.
Comment 6 Philipp Hahn univentionstaff 2012-02-21 19:56:07 CET
Created attachment 4206 [details]
/boot/vmlinuz* → menu.lst

Verwendet LooseVersion
Comment 7 Philipp Hahn univentionstaff 2012-02-21 19:56:33 CET
Created attachment 4207 [details]
grub.cfg → menu.lst

Parsed grub.cfg
Comment 8 Philipp Hahn univentionstaff 2012-02-22 11:20:31 CET
(In reply to comment #5)
> Ein weiteres Problem (?) ist, das PyGrub die grub1-Konfiguration bevorzugt und
> damit die grub2-Konfiguration überspringt. Insbesondere den hier hart kodierten
> Wert für root sehe ich als problematisch an, weil dieser Name während der
> Partitionierung frei gewählt werden kann.

/usr/bin/pygrub: class Grub → def read_config() → #400
  cfg_list = map(lambda x: (x,grub.GrubConf.GrubConfigFile),
                 ["/boot/grub/menu.lst", "/boot/grub/grub.conf",
                  "/grub/menu.lst", "/grub/grub.conf"]) + \
             map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
                  ["/boot/grub/grub.cfg", "/grub/grub.cfg"]) + \
             map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile),
                 ["/boot/isolinux/isolinux.cfg",
                  "/boot/extlinux.conf"])

Hier reicht es vermutlich, die Zeilen für Grub2 und Grub1 zu vertauschen.

Allerdings stolpert solch eine Version momentan über die Zeile
	set root = (/dev/xvdb,msdos1)
was noch auf einen neuen Bug von update-grub in Verbindung Xen-PV-Domains hindeutet.

Traceback (most recent call last):
  File "/usr/bin/pygrub", line 777, in <module>
    chosencfg = run_grub(file, entry, fs, incfg["args"])
  File "/usr/bin/pygrub", line 568, in run_grub
    g = Grub(file, fs)
  File "/usr/bin/pygrub", line 220, in __init__
    self.read_config(file, fs)
  File "/usr/bin/pygrub", line 429, in read_config
    self.cf.parse(buf)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 402, in parse
    self.add_image(Grub2Image(title, img))
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 318, in __init__
    _GrubImage.__init__(self, title, lines)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 87, in __init__
    self.reset(lines)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 103, in reset
    self._parse(lines)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 98, in _parse
    map(self.set_from_line, lines)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 328, in set_from_line
    setattr(self, self.commands[com], arg.strip())
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 106, in set_root
    self._root = GrubDiskPart(val)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 55, in __init__
    (self.disk, self.part) = str.split(",", 2)
  File "/usr/lib/python2.6/dist-packages/grub/GrubConf.py", line 70, in set_disk
    self._disk = int(val[2:])
ValueError: invalid literal for int() with base 10: 'ev/xvdb'
Comment 9 Moritz Muehlenhoff univentionstaff 2012-02-22 14:16:47 CET
Die Sortierung habe ich auf LooseVerson umgestellt und es wird jetzt der komplette Kernel-Name auch bei Subflavours übergeben.

Ich teste mal, ob das root= überhaupt von pygrub ausgewertet wird.
Comment 10 Moritz Muehlenhoff univentionstaff 2012-02-22 15:19:22 CET
(In reply to comment #9)
> Die Sortierung habe ich auf LooseVerson umgestellt und es wird jetzt der
> komplette Kernel-Name auch bei Subflavours übergeben.
> 
> Ich teste mal, ob das root= überhaupt von pygrub ausgewertet wird.

root= wird benötigt, sonst kann die Instanz von pygrub nicht gestartet werden.
Comment 11 Moritz Muehlenhoff univentionstaff 2012-02-27 09:03:30 CET
(In reply to comment #10)
> (In reply to comment #9)
> > Die Sortierung habe ich auf LooseVerson umgestellt und es wird jetzt der
> > komplette Kernel-Name auch bei Subflavours übergeben.
> > 
> > Ich teste mal, ob das root= überhaupt von pygrub ausgewertet wird.
> 
> root= wird benötigt, sonst kann die Instanz von pygrub nicht gestartet werden.

Die menu.lst wird jetzt anhand aus der grub.cfg generiert. Ich habe in Xen ein Basis-System installiert und auf 3.0-1 aktualisiert. Dann habe ich das Image auf ein UCS 2.4-0-Xen-System kopiert und in UVMM eine VM angelegt und ihr das 3.0-1-Image zugewiesen. Pygrub konnte es damit direkt starten.

Bzgl. des Verhaltens, dass PyGrub die Grub1-Konfiguration gegenüber der Grub2-Konfiguration vorzieht: Da das anhand der Tests aus Kommentar 8 weitere Probleme mit sich mitbring und keine Probleme mit dem aktuellen Setup bekannt sind, habe ich das so belassen.

Wir sollten die Erkennung eines alten PyGrub im Installer für 3.1 durchführen und 
grub/generate-menu-lst nur noch setzen, wenn ein alter PyGrub erkannt wurde. Ich habe dazu Bug 26251 angelegt.
Comment 12 Philipp Hahn univentionstaff 2012-02-27 16:26:26 CET
OK: PyGrub akzeptiert nun die generierte menu.lst-Datei und kann das UCS-System booten.

OK: Es werden jetzt nur noch root-Devices der Form "(hd0,_)" generiert, auch wenn /boot=/dev/xvdb ist. (svn31134)

OK: "univention-grub-generate-menu-lst" wird in "updater-grub" nach "grub-mkconfig" aufgerufen. (svn10179)

I: Bei meiner Test-VM hat /boot/grub/device,map gefehlt, weshalb dann in der grub.cfg '/dev/xvdb' statt 'hd0' stand. PyGrub stürzt dann mit einem ValueError() aus comment #8 ab. Das ist dann aber ein neues Problem und gehört nicht mehr hier hin.

OK: VERIFIED
univention-grub_5.0.9-8.83.201202271446
grub2_1.98+20100804-14.31.201202271524
Comment 13 Sönke Schwardt-Krummrich univentionstaff 2012-03-04 14:34:22 CET
UCS 3.0-1 wurde veröffentlicht. Sollte der hier beschriebene Bug mit einer
neueren Version von UCS erneut auftreten, so sollte dieser Bug dupliziert
werden: "Clone This Bug"