Confirmed this issue. To reproduce: Install a fresh Wheezy AMD64 guest under Xen 4.1 (hypervirtualized, boot from the debian-7.1.0-amd64-CD-1.iso). Use "entire disk" automatic layout for partitioning, this creates /dev/xvda1 for / and /dev/xvda5 for swap. It will create /boot/grub/grub.cfg with many references to (/dev/xvda,msdos1) which works fine when the machine is booted hypervirtualized. PyGrub can not handle the /dev/ syntax for devices, even though Grub can. My details: Package: xen-utils-4.1 Version: 4.1.4-3+deb7u1 Architecture: amd64 Confirmed workaround: inside the guest, create /boot/grub/device.map (NOT devices.map) containing: (hd0) /dev/xvda run update-grub shutdown the guest and reboot it using PyGrub. It will now work. Backtrace from manual run of the buggy GrubConf.py: # python /usr/lib/xen-4.1/lib/python/grub/GrubConf.py grub2 grub.cfg WARNING:root:Unknown directive load_video WARNING:root:Unknown directive terminal_output WARNING:root:Unknown image directive load_video Traceback (most recent call last): File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 462, in <module> g = Grub2ConfigFile(sys.argv[2]) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 354, in __init__ _GrubConfigFile.__init__(self, fn) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 174, in __init__ self.parse() File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 413, in parse self.add_image(Grub2Image(title, img)) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 320, in __init__ _GrubImage.__init__(self, title, lines) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 89, in __init__ self.reset(lines) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 105, in reset self._parse(lines) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 100, in _parse map(self.set_from_line, lines) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 330, in set_from_line setattr(self, self.commands[com], arg.strip()) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 108, in set_root self._root = GrubDiskPart(val) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 55, in __init__ (self.disk, self.part) = str.split(",", 2) File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 70, in set_disk self._disk = int(val[2:]) ValueError: invalid literal for int() with base 10: 'ev/xvda' Contents of grub.cfg triggering the error: # # DO NOT EDIT THIS FILE # # It is automatically generated by grub-mkconfig using templates # from /etc/grub.d and settings from /etc/default/grub # ### BEGIN /etc/grub.d/00_header ### if [ -s $prefix/grubenv ]; then load_env fi set default="0" 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 } function load_video { insmod vbe insmod vga insmod video_bochs insmod video_cirrus } insmod part_msdos insmod ext2 set root='(/dev/xvda,msdos1)' search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 if loadfont /usr/share/grub/unicode.pf2 ; then set gfxmode=640x480 load_video insmod gfxterm insmod part_msdos insmod ext2 set root='(/dev/xvda,msdos1)' search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 set locale_dir=($root)/boot/grub/locale set lang=en_US insmod gettext fi terminal_output gfxterm set timeout=5 ### END /etc/grub.d/00_header ### ### BEGIN /etc/grub.d/05_debian_theme ### set menu_color_normal=cyan/blue set menu_color_highlight=white/blue ### END /etc/grub.d/05_debian_theme ### ### BEGIN /etc/grub.d/10_linux ### menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64' --class debian --class gnu-linux --class gnu --class os { load_video insmod gzio insmod part_msdos insmod ext2 set root='(/dev/xvda,msdos1)' search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 echo 'Loading Linux 3.2.0-4-amd64 ...' linux /boot/vmlinuz-3.2.0-4-amd64 root=UUID=f395d5a0-4612-4872-806c-33cd37c152f0 ro echo 'Loading initial ramdisk ...' initrd /boot/initrd.img-3.2.0-4-amd64 } menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os { load_video insmod gzio insmod part_msdos insmod ext2 set root='(/dev/xvda,msdos1)' search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 echo 'Loading Linux 3.2.0-4-amd64 ...' linux /boot/vmlinuz-3.2.0-4-amd64 root=UUID=f395d5a0-4612-4872-806c-33cd37c152f0 ro single echo 'Loading initial ramdisk ...' initrd /boot/initrd.img-3.2.0-4-amd64 } ### END /etc/grub.d/10_linux ### ### BEGIN /etc/grub.d/20_linux_xen ### ### END /etc/grub.d/20_linux_xen ### ### BEGIN /etc/grub.d/30_os-prober ### ### END /etc/grub.d/30_os-prober ### ### BEGIN /etc/grub.d/40_custom ### # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. ### END /etc/grub.d/40_custom ### ### BEGIN /etc/grub.d/41_custom ### if [ -f $prefix/custom.cfg ]; then source $prefix/custom.cfg; fi ### END /etc/grub.d/41_custom ###
Ian Campbell
2013-Oct-01 09:48 UTC
[Pkg-xen-devel] Bug#603391: Bug#603391: Workaround PyGrub issue
On Sat, 2013-09-28 at 20:59 -0700, Tril wrote:> Backtrace from manual run of the buggy GrubConf.py: > # python /usr/lib/xen-4.1/lib/python/grub/GrubConf.py grub2 grub.cfg > WARNING:root:Unknown directive load_video > WARNING:root:Unknown directive terminal_output > WARNING:root:Unknown image directive load_video > Traceback (most recent call last): > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 462, in <module> > g = Grub2ConfigFile(sys.argv[2]) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 354, in __init__ > _GrubConfigFile.__init__(self, fn) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 174, in __init__ > self.parse() > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 413, in parse > self.add_image(Grub2Image(title, img)) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 320, in __init__ > _GrubImage.__init__(self, title, lines) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 89, in __init__ > self.reset(lines) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 105, in reset > self._parse(lines) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 100, in _parse > map(self.set_from_line, lines) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 330, in set_from_line > setattr(self, self.commands[com], arg.strip()) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 108, in set_root > self._root = GrubDiskPart(val) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 55, in __init__ > (self.disk, self.part) = str.split(",", 2) > File "/usr/lib/xen-4.1/lib/python/grub/GrubConf.py", line 70, in set_disk > self._disk = int(val[2:]) > ValueError: invalid literal for int() with base 10: 'ev/xvda'I think the following patch will fix this. If you could manually apply the GrubConf.py change to /usr/lib/xen-4.1/lib/python/grub/GrubConf.py and give it a go then I'll forward upstream. Ian. 8<---------------------------- commit 3236f37acc8c0d160c2f1ba1ccc89658257fc746 Author: Ian Campbell <ian.campbell at citrix.com> Date: Tue Oct 1 10:46:07 2013 +0100 pygrub: Support (/dev/xvda) style disk specifications You get these if you install Debian Wheezy as HVM and then try to convert to PV. This is Debian bug #603391. Signed-off-by: Ian Campbell <ian.campbell at citrix.com> diff --git a/tools/pygrub/examples/debian-wheezy-hvm.grub2 b/tools/pygrub/examples/debian-wheezy-hvm.grub2 new file mode 100644 index 0000000..b5ee9e2 --- /dev/null +++ b/tools/pygrub/examples/debian-wheezy-hvm.grub2 @@ -0,0 +1,104 @@ + +# +# DO NOT EDIT THIS FILE +# +# It is automatically generated by grub-mkconfig using templates +# from /etc/grub.d and settings from /etc/default/grub +# + +### BEGIN /etc/grub.d/00_header ### +if [ -s $prefix/grubenv ]; then + load_env +fi +set default="0" +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 +} + +function load_video { + insmod vbe + insmod vga + insmod video_bochs + insmod video_cirrus +} + +insmod part_msdos +insmod ext2 +set root='(/dev/xvda,msdos1)' +search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 +if loadfont /usr/share/grub/unicode.pf2 ; then + set gfxmode=640x480 + load_video + insmod gfxterm + insmod part_msdos + insmod ext2 + set root='(/dev/xvda,msdos1)' + search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 + set locale_dir=($root)/boot/grub/locale + set lang=en_US + insmod gettext +fi +terminal_output gfxterm +set timeout=5 +### END /etc/grub.d/00_header ### + +### BEGIN /etc/grub.d/05_debian_theme ### +set menu_color_normal=cyan/blue +set menu_color_highlight=white/blue +### END /etc/grub.d/05_debian_theme ### + +### BEGIN /etc/grub.d/10_linux ### +menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64' --class debian --class gnu-linux --class gnu --class os { + load_video + insmod gzio + insmod part_msdos + insmod ext2 + set root='(/dev/xvda,msdos1)' + search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 + echo 'Loading Linux 3.2.0-4-amd64 ...' + linux /boot/vmlinuz-3.2.0-4-amd64 root=UUID=f395d5a0-4612-4872-806c-33cd37c152f0 ro + echo 'Loading initial ramdisk ...' + initrd /boot/initrd.img-3.2.0-4-amd64 +} +menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os { + load_video + insmod gzio + insmod part_msdos + insmod ext2 + set root='(/dev/xvda,msdos1)' + search --no-floppy --fs-uuid --set=root f395d5a0-4612-4872-806c-33cd37c152f0 + echo 'Loading Linux 3.2.0-4-amd64 ...' + linux /boot/vmlinuz-3.2.0-4-amd64 root=UUID=f395d5a0-4612-4872-806c-33cd37c152f0 ro single + echo 'Loading initial ramdisk ...' + initrd /boot/initrd.img-3.2.0-4-amd64 +} +### END /etc/grub.d/10_linux ### + +### BEGIN /etc/grub.d/20_linux_xen ### +### END /etc/grub.d/20_linux_xen ### + +### BEGIN /etc/grub.d/30_os-prober ### +### END /etc/grub.d/30_os-prober ### + +### BEGIN /etc/grub.d/40_custom ### +# This file provides an easy way to add custom menu entries. Simply type the +# menu entries you want to add after this comment. Be careful not to change +# the 'exec tail' line above. +### END /etc/grub.d/40_custom ### + +### BEGIN /etc/grub.d/41_custom ### +if [ -f $prefix/custom.cfg ]; then + source $prefix/custom.cfg; +fi +### END /etc/grub.d/41_custom ### diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 6324c62..cb853c9 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -67,7 +67,11 @@ class GrubDiskPart(object): return self._disk def set_disk(self, val): val = val.replace("(", "").replace(")", "") - self._disk = int(val[2:]) + if val.startswith("/dev/xvd"): + disk = val[len("/dev/xvd")] + self._disk = ord(disk)-ord('a') + else: + self._disk = int(val[2:]) disk = property(get_disk, set_disk) def get_part(self):
Tril
2013-Oct-01 16:10 UTC
[Pkg-xen-devel] Bug#603391: Bug#603391: Workaround PyGrub issue
Sorry didn't work. Aso it will only handle this special case, not the general case of /dev/something. # python GrubConf.py grub2 /home/tehadmin/snail-grub.cfg WARNING:root:Unknown directive load_video WARNING:root:Unknown directive terminal_output WARNING:root:Unknown image directive load_video Traceback (most recent call last): File "GrubConf.py", line 467, in <module> g = Grub2ConfigFile(sys.argv[2]) File "GrubConf.py", line 359, in __init__ _GrubConfigFile.__init__(self, fn) File "GrubConf.py", line 179, in __init__ self.parse() File "GrubConf.py", line 418, in parse self.add_image(Grub2Image(title, img)) File "GrubConf.py", line 325, in __init__ _GrubImage.__init__(self, title, lines) File "GrubConf.py", line 94, in __init__ self.reset(lines) File "GrubConf.py", line 110, in reset self._parse(lines) File "GrubConf.py", line 105, in _parse map(self.set_from_line, lines) File "GrubConf.py", line 335, in set_from_line setattr(self, self.commands[com], arg.strip()) File "GrubConf.py", line 113, in set_root self._root = GrubDiskPart(val) File "GrubConf.py", line 55, in __init__ (self.disk, self.part) = str.split(",", 2) File "GrubConf.py", line 73, in set_disk self.disk = ord(disk)-ord('a') File "GrubConf.py", line 69, in set_disk val = val.replace("(", "").replace(")", "") AttributeError: 'int' object has no attribute 'replace'> diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py > index 6324c62..cb853c9 100644 > --- a/tools/pygrub/src/GrubConf.py > +++ b/tools/pygrub/src/GrubConf.py > @@ -67,7 +67,11 @@ class GrubDiskPart(object): > return self._disk > def set_disk(self, val): > val = val.replace("(", "").replace(")", "") > - self._disk = int(val[2:]) > + if val.startswith("/dev/xvd"): > + disk = val[len("/dev/xvd")] > + self._disk = ord(disk)-ord('a') > + else: > + self._disk = int(val[2:]) > disk = property(get_disk, set_disk) > > def get_part(self): > >