]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-10-14 Yoshinori K. Okuji <okuji@enbug.org>
authorokuji <okuji@localhost>
Sat, 14 Oct 2006 15:24:53 +0000 (15:24 +0000)
committerokuji <okuji@localhost>
Sat, 14 Oct 2006 15:24:53 +0000 (15:24 +0000)
        * DISTLIST: Added commands/echo.c, disk/lvm.c, disk/raid.c,
        include/grub/bitmap.h, include/grub/lvm.h, include/grub/raid.h,
        include/grub/i386/pc/vbeutil.h, include/grub/util/lvm.h,
        include/grub/util/raid.h, util/lvm.c, util/raid.c, video/bitmap.c,
        video/readers/tga.c and video/i386/pc/vbeutil.c.

2006-10-14  Jeroen Dekkers  <jeroen@dekkers.cx>

        Added support for RAID and LVM.

        * disk/lvm.c: New file.
        * disk/raid.c: Likewise.
        * include/grub/lvm.h: Likewise.
        * include/grub/raid.h: Likewise.
        * include/grub/util/lvm.h: Likewise.
        * include/grub/util/raid.h: Likewise.
        * util/lvm.c: Likewise.
        * util/raid.c: Likewise.

        * include/grub/disk.h (grub_disk_dev_id): Add
        GRUB_DISK_DEVICE_RAID_ID and GRUB_DISK_DEVICE_LVM_ID.
        (grub_disk_get_size): New prototype.
        * kern/disk.c (grub_disk_open): Check whether grub_partition_probe()
        returns a partition.
        (grub_disk_get_size): New function.

        * kern/i386/pc/init.c (make_install_device): Copy the prefix
        verbatim if grub_install_dos_part is -2.

        * util/i386/pc/getroot.c (grub_guess_root_device): Support RAID
        and LVM devices.

        * util/i386/pc/grub-setup.c (setup): New argument
        MUST_EMBED. Force embedding of GRUB when the argument is
        true. Close FILE before returning.
        (main): Add support for RAID and LVM.

        * conf/common.rmk: Add RAID and LVM modules.
        * conf/i386-pc.rmk (grub_setup_SOURCES): Add util/raid.c and
        util/lvm.c.
        (grub_emu_SOURCES): Add disk/raid.c and disk/lvm.c.

        * kern/misc.c (grub_strstr): New function.
        * include/grub/misc.h (grub_strstr): New prototype.

23 files changed:
ChangeLog
DISTLIST
conf/common.mk
conf/common.rmk
conf/i386-pc.mk
conf/i386-pc.rmk
configure
disk/lvm.c [new file with mode: 0644]
disk/raid.c [new file with mode: 0644]
include/grub/disk.h
include/grub/lvm.h [new file with mode: 0644]
include/grub/misc.h
include/grub/raid.h [new file with mode: 0644]
include/grub/util/lvm.h [new file with mode: 0644]
include/grub/util/raid.h [new file with mode: 0644]
kern/disk.c
kern/i386/pc/init.c
kern/misc.c
util/genmoddep.c [new file with mode: 0644]
util/i386/pc/getroot.c
util/i386/pc/grub-setup.c
util/lvm.c [new file with mode: 0644]
util/raid.c [new file with mode: 0644]

index 0fce113b629b8da0fdcaac6e28d5e357da57af25..6acba42ff169fe9a72d51e0ea948a9eedc4a2eb8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2006-10-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+       * DISTLIST: Added commands/echo.c, disk/lvm.c, disk/raid.c,
+       include/grub/bitmap.h, include/grub/lvm.h, include/grub/raid.h,
+       include/grub/i386/pc/vbeutil.h, include/grub/util/lvm.h,
+       include/grub/util/raid.h, util/lvm.c, util/raid.c, video/bitmap.c,
+       video/readers/tga.c and video/i386/pc/vbeutil.c.
+
+2006-10-14  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+       Added support for RAID and LVM.
+       
+       * disk/lvm.c: New file.
+       * disk/raid.c: Likewise.
+       * include/grub/lvm.h: Likewise.
+       * include/grub/raid.h: Likewise.        
+       * include/grub/util/lvm.h: Likewise.
+       * include/grub/util/raid.h: Likewise.
+       * util/lvm.c: Likewise.
+       * util/raid.c: Likewise.
+
+       * include/grub/disk.h (grub_disk_dev_id): Add
+       GRUB_DISK_DEVICE_RAID_ID and GRUB_DISK_DEVICE_LVM_ID.
+       (grub_disk_get_size): New prototype.
+       * kern/disk.c (grub_disk_open): Check whether grub_partition_probe()
+       returns a partition.
+       (grub_disk_get_size): New function.
+       
+       * kern/i386/pc/init.c (make_install_device): Copy the prefix
+       verbatim if grub_install_dos_part is -2.
+
+       * util/i386/pc/getroot.c (grub_guess_root_device): Support RAID
+       and LVM devices.
+
+       * util/i386/pc/grub-setup.c (setup): New argument
+       MUST_EMBED. Force embedding of GRUB when the argument is
+       true. Close FILE before returning.
+       (main): Add support for RAID and LVM.
+       
+       * conf/common.rmk: Add RAID and LVM modules.
+       * conf/i386-pc.rmk (grub_setup_SOURCES): Add util/raid.c and
+       util/lvm.c.
+       (grub_emu_SOURCES): Add disk/raid.c and disk/lvm.c.
+
+       * kern/misc.c (grub_strstr): New function.
+       * include/grub/misc.h (grub_strstr): New prototype.
+
 2006-10-10  Tristan Gingold  <tristan.gingold@bull.net>
 
        * include/grub/efi/api.h (GRUB_EFI_ERROR_CODE): Long constant.
index 6e8132e872528dd12c21945c565ec29f9e42d18c..689e76c8040d817a92d744fa23efac57bf176991 100644 (file)
--- a/DISTLIST
+++ b/DISTLIST
@@ -36,6 +36,7 @@ commands/blocklist.c
 commands/cat.c
 commands/cmp.c
 commands/configfile.c
+commands/echo.c
 commands/help.c
 commands/ls.c
 commands/search.c
@@ -61,6 +62,8 @@ conf/powerpc-ieee1275.rmk
 conf/sparc64-ieee1275.mk
 conf/sparc64-ieee1275.rmk
 disk/loopback.c
+disk/lvm.c
+disk/raid.c
 disk/efi/efidisk.c
 disk/i386/pc/biosdisk.c
 disk/ieee1275/ofdisk.c
@@ -80,6 +83,7 @@ fs/hfsplus.c
 hello/hello.c
 include/grub/acorn_filecore.h
 include/grub/arg.h
+include/grub/bitmap.h
 include/grub/boot.h
 include/grub/cache.h
 include/grub/device.h
@@ -96,6 +100,7 @@ include/grub/gzio.h
 include/grub/hfs.h
 include/grub/kernel.h
 include/grub/loader.h
+include/grub/lvm.h
 include/grub/misc.h
 include/grub/mm.h
 include/grub/net.h
@@ -103,6 +108,7 @@ include/grub/normal.h
 include/grub/parser.h
 include/grub/partition.h
 include/grub/pc_partition.h
+include/grub/raid.h
 include/grub/rescue.h
 include/grub/script.h
 include/grub/setjmp.h
@@ -140,6 +146,7 @@ include/grub/i386/pc/time.h
 include/grub/i386/pc/vbe.h
 include/grub/i386/pc/vbeblit.h
 include/grub/i386/pc/vbefill.h
+include/grub/i386/pc/vbeutil.h
 include/grub/i386/pc/vga.h
 include/grub/i386/pc/util/biosdisk.h
 include/grub/ieee1275/ieee1275.h
@@ -162,7 +169,9 @@ include/grub/sparc64/ieee1275/ieee1275.h
 include/grub/sparc64/ieee1275/kernel.h
 include/grub/sparc64/ieee1275/time.h
 include/grub/util/getroot.h
+include/grub/util/lvm.h
 include/grub/util/misc.h
+include/grub/util/raid.h
 include/grub/util/resolve.h
 io/gzio.c
 kern/device.c
@@ -244,7 +253,9 @@ term/i386/pc/vga.c
 term/ieee1275/ofconsole.c
 util/console.c
 util/grub-emu.c
+util/lvm.c
 util/misc.c
+util/raid.c
 util/resolve.c
 util/unifont2pff.rb
 util/i386/efi/grub-mkimage.c
@@ -259,7 +270,10 @@ util/i386/pc/misc.c
 util/powerpc/ieee1275/grub-install.in
 util/powerpc/ieee1275/grub-mkimage.c
 util/powerpc/ieee1275/misc.c
+video/bitmap.c
 video/video.c
 video/i386/pc/vbe.c
 video/i386/pc/vbeblit.c
 video/i386/pc/vbefill.c
+video/readers/tga.c
+video/i386/pc/vbeutil.c
index df057ef2db3d04034496698cc1ec07ad0ee3a0b2..accb3cf25b30fb84019fb277e413788d31641d43 100644 (file)
@@ -963,6 +963,113 @@ fs-gpt_mod-partmap_gpt.lst: partmap/gpt.c genfslist.sh
 gpt_mod_CFLAGS = $(COMMON_CFLAGS)
 gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# Special disk structures
+
+pkgdata_MODULES += raid.mod lvm.mod
+
+# For raid.mod
+raid_mod_SOURCES = disk/raid.c
+CLEANFILES += raid.mod mod-raid.o mod-raid.c pre-raid.o raid_mod-disk_raid.o und-raid.lst
+ifneq ($(raid_mod_EXPORTS),no)
+CLEANFILES += def-raid.lst
+DEFSYMFILES += def-raid.lst
+endif
+MOSTLYCLEANFILES += raid_mod-disk_raid.d
+UNDSYMFILES += und-raid.lst
+
+raid.mod: pre-raid.o mod-raid.o
+       -rm -f $@
+       $(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-raid.o: $(raid_mod_DEPENDENCIES) raid_mod-disk_raid.o
+       -rm -f $@
+       $(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid_mod-disk_raid.o
+
+mod-raid.o: mod-raid.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -c -o $@ $<
+
+mod-raid.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'raid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(raid_mod_EXPORTS),no)
+def-raid.lst: pre-raid.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid/' > $@
+endif
+
+und-raid.lst: pre-raid.o
+       echo 'raid' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+raid_mod-disk_raid.o: disk/raid.c
+       $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -MD -c -o $@ $<
+-include raid_mod-disk_raid.d
+
+CLEANFILES += cmd-raid_mod-disk_raid.lst fs-raid_mod-disk_raid.lst
+COMMANDFILES += cmd-raid_mod-disk_raid.lst
+FSFILES += fs-raid_mod-disk_raid.lst
+
+cmd-raid_mod-disk_raid.lst: disk/raid.c gencmdlist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $<       | sh $(srcdir)/gencmdlist.sh raid > $@ || (rm -f $@; exit 1)
+
+fs-raid_mod-disk_raid.lst: disk/raid.c genfslist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $<       | sh $(srcdir)/genfslist.sh raid > $@ || (rm -f $@; exit 1)
+
+
+raid_mod_CFLAGS = $(COMMON_CFLAGS)
+raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid.mod
+lvm_mod_SOURCES = disk/lvm.c
+CLEANFILES += lvm.mod mod-lvm.o mod-lvm.c pre-lvm.o lvm_mod-disk_lvm.o und-lvm.lst
+ifneq ($(lvm_mod_EXPORTS),no)
+CLEANFILES += def-lvm.lst
+DEFSYMFILES += def-lvm.lst
+endif
+MOSTLYCLEANFILES += lvm_mod-disk_lvm.d
+UNDSYMFILES += und-lvm.lst
+
+lvm.mod: pre-lvm.o mod-lvm.o
+       -rm -f $@
+       $(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-lvm.o: $(lvm_mod_DEPENDENCIES) lvm_mod-disk_lvm.o
+       -rm -f $@
+       $(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lvm_mod-disk_lvm.o
+
+mod-lvm.o: mod-lvm.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -c -o $@ $<
+
+mod-lvm.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'lvm' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(lvm_mod_EXPORTS),no)
+def-lvm.lst: pre-lvm.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lvm/' > $@
+endif
+
+und-lvm.lst: pre-lvm.o
+       echo 'lvm' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+lvm_mod-disk_lvm.o: disk/lvm.c
+       $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -MD -c -o $@ $<
+-include lvm_mod-disk_lvm.d
+
+CLEANFILES += cmd-lvm_mod-disk_lvm.lst fs-lvm_mod-disk_lvm.lst
+COMMANDFILES += cmd-lvm_mod-disk_lvm.lst
+FSFILES += fs-lvm_mod-disk_lvm.lst
+
+cmd-lvm_mod-disk_lvm.lst: disk/lvm.c gencmdlist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $<        | sh $(srcdir)/gencmdlist.sh lvm > $@ || (rm -f $@; exit 1)
+
+fs-lvm_mod-disk_lvm.lst: disk/lvm.c genfslist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $<        | sh $(srcdir)/genfslist.sh lvm > $@ || (rm -f $@; exit 1)
+
+
+lvm_mod_CFLAGS = $(COMMON_CFLAGS)
+lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # Commands.
 pkgdata_MODULES += hello.mod boot.mod terminal.mod ls.mod      \
index 54aa554d7b30edc412941f697e1af248344ff382..77a7e367f3cb40728861efad1a570b0c22c62664 100644 (file)
@@ -117,6 +117,19 @@ gpt_mod_SOURCES = partmap/gpt.c
 gpt_mod_CFLAGS = $(COMMON_CFLAGS)
 gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# Special disk structures
+
+pkgdata_MODULES += raid.mod lvm.mod
+
+# For raid.mod
+raid_mod_SOURCES = disk/raid.c
+raid_mod_CFLAGS = $(COMMON_CFLAGS)
+raid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For raid.mod
+lvm_mod_SOURCES = disk/lvm.c
+lvm_mod_CFLAGS = $(COMMON_CFLAGS)
+lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # Commands.
 pkgdata_MODULES += hello.mod boot.mod terminal.mod ls.mod      \
index 8a8c18f401fce551771640512f0e5c4ff3a4cb24..b3edf8a3bed6f763dd36602334a0e3e9252a7d60 100644 (file)
@@ -214,12 +214,12 @@ grub_setup_SOURCES = util/i386/pc/grub-setup.c util/i386/pc/biosdisk.c    \
        kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c    \
        fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c            \
        fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c  \
-       kern/fs.c kern/env.c fs/fshelp.c
-CLEANFILES += grub-setup grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o
-MOSTLYCLEANFILES += grub_setup-util_i386_pc_grub_setup.d grub_setup-util_i386_pc_biosdisk.d grub_setup-util_misc.d grub_setup-util_i386_pc_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-fs_fat.d grub_setup-fs_ext2.d grub_setup-fs_xfs.d grub_setup-fs_affs.d grub_setup-fs_sfs.d grub_setup-kern_parser.d grub_setup-kern_partition.d grub_setup-partmap_pc.d grub_setup-fs_ufs.d grub_setup-fs_minix.d grub_setup-fs_hfs.d grub_setup-fs_jfs.d grub_setup-fs_hfsplus.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d grub_setup-fs_fshelp.d
+       kern/fs.c kern/env.c fs/fshelp.c util/raid.c util/lvm.c
+CLEANFILES += grub-setup grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-util_raid.o grub_setup-util_lvm.o
+MOSTLYCLEANFILES += grub_setup-util_i386_pc_grub_setup.d grub_setup-util_i386_pc_biosdisk.d grub_setup-util_misc.d grub_setup-util_i386_pc_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-fs_fat.d grub_setup-fs_ext2.d grub_setup-fs_xfs.d grub_setup-fs_affs.d grub_setup-fs_sfs.d grub_setup-kern_parser.d grub_setup-kern_partition.d grub_setup-partmap_pc.d grub_setup-fs_ufs.d grub_setup-fs_minix.d grub_setup-fs_hfs.d grub_setup-fs_jfs.d grub_setup-fs_hfsplus.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d grub_setup-fs_fshelp.d grub_setup-util_raid.d grub_setup-util_lvm.d
 
-grub-setup: $(grub_setup_DEPENDENCIES) grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o
-       $(CC) -o $@ grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o $(LDFLAGS) $(grub_setup_LDFLAGS)
+grub-setup: $(grub_setup_DEPENDENCIES) grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-util_raid.o grub_setup-util_lvm.o
+       $(CC) -o $@ grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_xfs.o grub_setup-fs_affs.o grub_setup-fs_sfs.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-partmap_pc.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-fs_hfsplus.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-util_raid.o grub_setup-util_lvm.o $(LDFLAGS) $(grub_setup_LDFLAGS)
 
 grub_setup-util_i386_pc_grub_setup.o: util/i386/pc/grub-setup.c
        $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
@@ -321,6 +321,14 @@ grub_setup-fs_fshelp.o: fs/fshelp.c
        $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
 -include grub_setup-fs_fshelp.d
 
+grub_setup-util_raid.o: util/raid.c
+       $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_raid.d
+
+grub_setup-util_lvm.o: util/lvm.c
+       $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $<
+-include grub_setup-util_lvm.d
+
 
 # For grub-mkdevicemap.
 grub_mkdevicemap_SOURCES = util/i386/pc/grub-mkdevicemap.c util/misc.c
@@ -457,7 +465,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c    \
        commands/terminal.c commands/ls.c commands/test.c               \
        commands/search.c commands/blocklist.c                          \
        commands/i386/pc/halt.c commands/i386/pc/reboot.c               \
-       disk/loopback.c                                                 \
+       disk/loopback.c disk/raid.c disk/lvm.c                          \
        fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c  \
        fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c     \
        io/gzio.c                                                       \
@@ -473,11 +481,11 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c  \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
        util/i386/pc/misc.c grub_emu_init.c
-CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o
-MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_i386_pc_halt.d grub_emu-commands_i386_pc_reboot.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_ext2.d grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_hfsplus.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d grub_emu-util_i386_pc_getroot.d grub_emu-util_i386_pc_misc.d grub_emu-grub_emu_init.d
+CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-disk_raid.o grub_emu-disk_lvm.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o
+MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_i386_pc_halt.d grub_emu-commands_i386_pc_reboot.d grub_emu-disk_loopback.d grub_emu-disk_raid.d grub_emu-disk_lvm.d grub_emu-fs_affs.d grub_emu-fs_ext2.d grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_hfsplus.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d grub_emu-util_i386_pc_getroot.d grub_emu-util_i386_pc_misc.d grub_emu-grub_emu_init.d
 
-grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o
-       $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS)
+grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-disk_raid.o grub_emu-disk_lvm.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o
+       $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-disk_raid.o grub_emu-disk_lvm.o grub_emu-fs_affs.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_hfsplus.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS)
 
 grub_emu-commands_boot.o: commands/boot.c
        $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
@@ -535,6 +543,14 @@ grub_emu-disk_loopback.o: disk/loopback.c
        $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
 -include grub_emu-disk_loopback.d
 
+grub_emu-disk_raid.o: disk/raid.c
+       $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_raid.d
+
+grub_emu-disk_lvm.o: disk/lvm.c
+       $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
+-include grub_emu-disk_lvm.d
+
 grub_emu-fs_affs.o: fs/affs.c
        $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
 -include grub_emu-fs_affs.d
index c8f222dc487a685ea44c7c0986c3f905df6328c3..678ded38dc2106ed9a3abe273c6cc83c4fd8a435 100644 (file)
@@ -64,7 +64,7 @@ grub_setup_SOURCES = util/i386/pc/grub-setup.c util/i386/pc/biosdisk.c        \
        kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c    \
        fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c            \
        fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c  \
-       kern/fs.c kern/env.c fs/fshelp.c
+       kern/fs.c kern/env.c fs/fshelp.c util/raid.c util/lvm.c
 
 # For grub-mkdevicemap.
 grub_mkdevicemap_SOURCES = util/i386/pc/grub-mkdevicemap.c util/misc.c
@@ -85,7 +85,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c      \
        commands/terminal.c commands/ls.c commands/test.c               \
        commands/search.c commands/blocklist.c                          \
        commands/i386/pc/halt.c commands/i386/pc/reboot.c               \
-       disk/loopback.c                                                 \
+       disk/loopback.c disk/raid.c disk/lvm.c                          \
        fs/affs.c fs/ext2.c fs/fat.c fs/fshelp.c fs/hfs.c fs/iso9660.c  \
        fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c fs/hfsplus.c     \
        io/gzio.c                                                       \
index 60f568931b023facac673727e8fbbfe4209a0a6d..ab4ade0bc43267ca855d3ec0b3cb8949693a3dcc 100644 (file)
--- a/configure
+++ b/configure
@@ -959,7 +959,7 @@ esac
     else
       echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi
-    cd "$ac_popdir"
+    cd $ac_popdir
   done
 fi
 
@@ -2342,7 +2342,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2400,7 +2401,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2516,7 +2518,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2570,7 +2573,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2615,7 +2619,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2659,7 +2664,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2760,7 +2766,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2789,7 +2796,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2859,7 +2867,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2911,7 +2920,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -2982,7 +2992,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3034,7 +3045,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3105,7 +3117,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3147,7 +3160,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3204,7 +3218,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3580,7 +3595,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3750,7 +3766,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3815,7 +3832,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3877,7 +3895,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3917,7 +3936,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -3973,7 +3993,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4013,7 +4034,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4077,7 +4099,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4108,8 +4131,10 @@ See \`config.log' for more details." >&2;}
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
-echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -4221,7 +4246,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4283,7 +4309,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4323,7 +4350,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4379,7 +4407,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4419,7 +4448,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4483,7 +4513,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4514,8 +4545,10 @@ See \`config.log' for more details." >&2;}
 esac
 else
   if test "$cross_compiling" = yes; then
-  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
-echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
    { (exit 1); exit 1; }; }
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -4644,7 +4677,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4710,7 +4744,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4776,7 +4811,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4880,7 +4916,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -4949,7 +4986,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5105,7 +5143,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5171,7 +5210,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5241,7 +5281,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -5428,7 +5469,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6093,7 +6135,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6156,7 +6199,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6357,7 +6401,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6413,7 +6458,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6489,7 +6535,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6545,7 +6592,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6601,7 +6649,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6682,7 +6731,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -6738,7 +6788,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); } &&
-        { ac_try='test -z "$ac_c_werror_flag"                   || test ! -s conftest.err'
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
   (eval $ac_try) 2>&5
   ac_status=$?
@@ -7856,6 +7907,11 @@ esac
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -7894,12 +7950,6 @@ echo "$as_me: error: cannot find input file: $f" >&2;}
         fi;;
       esac
     done` || { (exit 1); exit 1; }
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
diff --git a/disk/lvm.c b/disk/lvm.c
new file mode 100644 (file)
index 0000000..e218f20
--- /dev/null
@@ -0,0 +1,497 @@
+/* lvm.c - module to read Logical Volumes.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/lvm.h>
+
+static struct grub_lvm_vg *vgs;
+static int lv_count;
+
+\f
+/* Go the string STR and return the number after STR.  *P will point
+   at the number. */
+static int
+grub_lvm_getvalue (char **p, char *str)
+{
+  *p = grub_strstr (*p, str) + grub_strlen (str);
+  return grub_strtoul (*p, NULL, 10);
+}
+
+static int
+grub_lvm_iterate (int (*hook) (const char *name))
+{
+  struct grub_lvm_vg *vg;
+  for (vg = vgs; vg; vg = vg->next)
+    {
+      struct grub_lvm_lv *lv;
+      for (lv = vgs->lvs; lv; lv = lv->next)
+       if (hook (lv->name))
+         return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_lvm_open (const char *name, grub_disk_t disk)
+{
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *lv = NULL;
+  for (vg = vgs; vg; vg = vg->next)
+    {
+      for (lv = vgs->lvs; lv; lv = lv->next)
+       if (! grub_strcmp (lv->name, name))
+         break;
+
+      if (lv)
+       break;
+    }
+
+  if (! lv)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown device");
+
+  disk->has_partitions = 0;
+  disk->id = lv->number;
+  disk->data = lv;
+  disk->total_sectors = lv->size;
+  
+  return 0;
+}
+
+static void
+grub_lvm_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+static grub_err_t
+grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_size_t size, char *buf)
+{
+  grub_err_t err = 0;
+  struct grub_lvm_lv *lv = disk->data;
+  struct grub_lvm_vg *vg = lv->vg;
+  struct grub_lvm_segment *seg = lv->segments;
+  struct grub_lvm_pv *pv;
+  grub_uint64_t offset;
+  grub_uint64_t extent;
+  unsigned int i;
+
+  extent = grub_divmod64 (sector, vg->extent_size, NULL);
+
+  /* Find the right segment.  */
+  for (i = 0; i < lv->segment_count; i++)
+    {
+      if ((seg->start_extent <= extent)
+         && ((seg->start_extent + seg->extent_count) > extent))
+       {
+         break;
+       }
+
+      seg++;
+    }
+
+  if (seg->stripe_count == 1)
+    {
+      /* This segment is linear, so that's easy.  We just need to find
+        out the offset in the physical volume and read SIZE bytes
+        from that.  */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+
+      pv = stripe->pv;
+      seg_offset = ((grub_uint64_t) stripe->start
+                   * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+                        * (grub_uint64_t) vg->extent_size) + seg_offset;
+    }
+  else
+    {
+      /* This is a striped segment. We have to find the right PV
+        similar to RAID0. */
+      struct grub_lvm_stripe *stripe = seg->stripes;
+      grub_uint32_t a, b;
+      grub_uint64_t seg_offset; /* Offset of the segment in PV device.  */
+      unsigned int stripenr;
+
+      offset = sector - ((grub_uint64_t) seg->start_extent
+                        * (grub_uint64_t) vg->extent_size);
+
+      a = grub_divmod64 (offset, seg->stripe_size, NULL);
+      grub_divmod64 (a, seg->stripe_count, &stripenr);
+
+      a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL);
+      grub_divmod64 (offset, seg->stripe_size, &b);
+      offset = a * seg->stripe_size + b;
+
+      stripe += stripenr;
+      pv = stripe->pv;
+      
+      seg_offset = ((grub_uint64_t) stripe->start
+                   * (grub_uint64_t) vg->extent_size) + pv->start;
+
+      offset += seg_offset;
+    }
+
+  /* Check whether we actually know the physical volume we want to
+     read from.  */
+  if (pv->disk)
+    err = grub_disk_read (pv->disk, offset, 0,
+                         size << GRUB_DISK_SECTOR_BITS, buf);
+  else
+    err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+                     "Physical volume %s not found", pv->name);
+  
+  return err;
+}
+
+static grub_err_t
+grub_lvm_write (grub_disk_t disk __attribute ((unused)),
+                grub_disk_addr_t sector __attribute ((unused)),
+                grub_size_t size __attribute ((unused)),
+                const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static int
+grub_lvm_scan_device (const char *name)
+{
+  grub_err_t err;
+  grub_disk_t disk;
+  grub_uint64_t da_offset, da_size, mda_offset, mda_size;
+  char buf[GRUB_LVM_LABEL_SIZE];
+  char vg_id[GRUB_LVM_ID_STRLEN+1];
+  char pv_id[GRUB_LVM_ID_STRLEN+1];
+  char *metadatabuf, *p, *q, *vgname;
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_disk_locn *dlocn;
+  struct grub_lvm_mda_header *mdah;
+  struct grub_lvm_raw_locn *rlocn;
+  unsigned int i, j, vgname_len;
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_pv *pv;
+  
+  disk = grub_disk_open (name);
+  if (!disk)
+    return 0;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
+      if (err)
+       goto fail;
+      
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+                          sizeof (lh->id)))
+         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+                             sizeof (lh->type))))
+       break;
+    }
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    goto fail;
+  
+  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+
+  for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
+    {
+      pv_id[j++] = pvh->pv_uuid[i];
+      if ((i != 1) && (i != 29) && (i % 4 == 1))
+       pv_id[j++] = '-';
+    }
+  pv_id[j] = '\0';
+
+  dlocn = pvh->disk_areas_xl;
+  da_offset = grub_le_to_cpu64 (dlocn->offset);
+  da_size = grub_le_to_cpu64 (dlocn->size);
+
+  dlocn++;
+  /* Is it possible to have multiple data/metadata areas? I haven't
+     seen devices that have it. */
+  if (dlocn->offset)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "We don't support multiple data areas");
+                 
+      goto fail;
+    }
+
+  dlocn++;
+  mda_offset = grub_le_to_cpu64 (dlocn->offset);
+  mda_size = grub_le_to_cpu64 (dlocn->size);
+  dlocn++;
+  
+  if (dlocn->offset)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "We don't support multiple metadata areas");
+                 
+      goto fail;
+    }
+
+  metadatabuf = grub_malloc (mda_size);
+  if (! metadatabuf)
+    goto fail;
+
+  err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf);
+  if (err)
+    goto fail2;
+
+  mdah = (struct grub_lvm_mda_header *) metadatabuf;
+  if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC,
+                    sizeof (mdah->magic)))
+      || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION))
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "Unknown metadata header");
+      goto fail2;
+    }
+
+  rlocn = mdah->raw_locns;
+  p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
+
+  while (*q != ' ')
+    q++;
+
+  vgname_len = q - p;
+  vgname = grub_malloc (vgname_len + 1);
+  if (!vgname)
+    goto fail2;
+
+  grub_memcpy (vgname, p, vgname_len);
+  vgname[vgname_len] = '\0';
+
+  p = grub_strstr (q, "id = \"") + sizeof ("id = \"") - 1;
+  grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
+  vg_id[GRUB_LVM_ID_STRLEN] = '\0';
+
+  for (vg = vgs; vg; vg = vg->next)
+    {
+      if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN))
+       break;
+    }
+
+  if (! vg)
+    {
+      /* First time we see this volume group. We've to create the
+        whole volume group structure. */
+      vg = grub_malloc (sizeof (*vg));
+      if (! vg)
+       {
+         grub_free (vgname);
+         goto fail;
+       }
+      vg->name = vgname;
+      grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1);
+
+      vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
+
+      vg->lvs = NULL;
+      vg->pvs = NULL;
+      vg->next = vgs;
+      vgs = vg;
+
+      p = grub_strstr (p, "physical_volumes {")
+       + sizeof ("physical_volumes {") - 1;
+
+      /* Add all the pvs to the volume group. */
+      while (1)
+       {
+         int s;
+         while (grub_isspace (*p))
+           p++;
+         
+         if (*p == '}')
+           break;
+
+         pv = grub_malloc (sizeof (*pv));
+         q = p;
+         while (*q != ' ')
+           q++;
+         
+         s = q - p;
+         pv->name = grub_malloc (s + 1);
+         grub_memcpy (pv->name, p, s);
+         pv->name[s] = '\0';
+
+         p = grub_strstr (p, "id = \"") + sizeof("id = \"") - 1;
+
+         grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
+         pv->id[GRUB_LVM_ID_STRLEN] = '\0';
+
+         pv->start = grub_lvm_getvalue (&p, "pe_start = ");
+         pv->disk = NULL;
+         pv->next = vg->pvs;
+         vg->pvs = pv;
+
+         p = grub_strchr (p, '}') + 1;
+       }
+
+      p = grub_strstr (p, "logical_volumes");
+      p += 18;
+      
+      /* And add all the lvs to the volume group. */
+      while (1)
+       {
+         int s;
+         struct grub_lvm_lv *lv;
+         struct grub_lvm_segment *seg;
+         
+         while (grub_isspace (*p))
+           p++;
+         
+         if (*p == '}')
+           break;
+
+         lv = grub_malloc (sizeof (lv));
+
+         q = p;
+         while (*q != ' ')
+           q++;
+
+         s = q - p;
+         lv->name = grub_malloc (vgname_len + 1 + s + 1);
+         grub_memcpy (lv->name, vgname, vgname_len);
+         lv->name[vgname_len] = '-';
+         grub_memcpy (lv->name + vgname_len + 1, p, s);
+         lv->name[vgname_len + 1 + s] = '\0';
+
+         lv->size = 0;
+         
+         lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
+         lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
+         seg = lv->segments;
+
+         for (i = 0; i < lv->segment_count; i++)
+           {
+             struct grub_lvm_stripe *stripe;
+               
+             p = grub_strstr (p, "segment");
+
+             seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
+             seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
+             seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
+
+             lv->size += seg->extent_count * vg->extent_size;
+             
+             if (seg->stripe_count != 1)
+               seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
+
+             seg->stripes = grub_malloc (sizeof (*stripe)
+                                         * seg->stripe_count);
+             stripe = seg->stripes;
+             
+             p = grub_strstr (p, "stripes = [")
+               + sizeof("stripes = [") - 1;
+             
+             for (j = 0; j < seg->stripe_count; j++)
+               {
+                 char pvname[10];
+                 
+                 q = p = grub_strchr (p, '"') + 1;
+                 while (*q != '"')
+                   q++;
+
+                 s = q - p;
+                 grub_memcpy (pvname, p, s);
+                 pvname[s] = '\0';
+                 
+                 for (pv = vg->pvs; pv; pv = pv->next)
+                   {
+                     if (! grub_strcmp (pvname, pv->name))
+                       {
+                         stripe->pv = pv;
+                         break;
+                       }
+                   }
+
+                 p = grub_strchr (p, ',') + 1;
+                 stripe->start = grub_strtoul (p, NULL, 10);
+                 
+                 stripe++;
+               }
+
+             seg++;
+           }
+
+         lv->number = lv_count++;
+         lv->vg = vg;
+         lv->next = vg->lvs;
+         vg->lvs = lv;
+
+         p = grub_strchr (p, '}') + 3;
+       }
+    }
+  else
+    {
+      grub_free (vgname);
+    }
+
+  /* Match the device we are currently reading from with the right
+     PV. */
+  for (pv = vg->pvs; pv; pv = pv->next)
+    {
+      if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
+       {
+         pv->disk = grub_disk_open (name);
+         break;
+       }
+    }
+
+ fail2:
+  grub_free (metadatabuf);
+ fail:
+  grub_disk_close (disk);
+  return 0;
+}
+
+static struct grub_disk_dev grub_lvm_dev =
+  {
+    .name = "lvm",
+    .id = GRUB_DISK_DEVICE_LVM_ID,
+    .iterate = grub_lvm_iterate,
+    .open = grub_lvm_open,
+    .close = grub_lvm_close,
+    .read = grub_lvm_read,
+    .write = grub_lvm_write,
+    .next = 0
+  };
+
+\f
+GRUB_MOD_INIT(lvm)
+{
+  grub_device_iterate (&grub_lvm_scan_device);
+  grub_disk_dev_register (&grub_lvm_dev);
+}
+
+GRUB_MOD_FINI(lvm)
+{
+  grub_disk_dev_unregister (&grub_lvm_dev);
+  /* FIXME: free the lvm list. */
+}
diff --git a/disk/raid.c b/disk/raid.c
new file mode 100644 (file)
index 0000000..52d2f0c
--- /dev/null
@@ -0,0 +1,543 @@
+/* raid.c - module to read RAID arrays.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/raid.h>
+
+/* Linked list of RAID arrays. */
+static struct grub_raid_array *array_list;
+
+\f
+static char
+grub_is_array_readable (struct grub_raid_array *array)
+{
+  switch (array->level)
+    {
+    case 0:
+      if (array->nr_devs == array->total_devs)
+       return 1;
+      break;
+
+    case 1:
+      if (array->nr_devs >= 1)
+       return 1;
+      break;
+
+    case 5:
+      if (array->nr_devs >= array->total_devs - 1)
+       return 1;
+      break;
+    }
+
+  return 0;
+}
+
+static int
+grub_raid_iterate (int (*hook) (const char *name))
+{
+  struct grub_raid_array *array;
+  
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (grub_is_array_readable (array))
+       if (hook (array->name))
+         return 1;
+    }
+
+  return 0;
+}
+
+static grub_err_t
+grub_raid_open (const char *name, grub_disk_t disk)
+{
+  struct grub_raid_array *array;
+  
+  for (array = array_list; array != NULL; array = array->next)
+    {
+      if (!grub_strcmp (array->name, name))
+       if (grub_is_array_readable (array))
+         break;
+    }
+
+  if (!array)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown device");
+
+  /* FIXME: superblock version 1 supports partitions.  */
+  disk->has_partitions = 0;
+  disk->id = array->number;
+  disk->data = array;
+
+  switch (array->level)
+    {
+    case 0:
+      /* FIXME: RAID0 disks can have different sizes! */
+      disk->total_sectors = array->total_devs * array->disk_size;
+      break;
+
+    case 1:
+      disk->total_sectors = array->disk_size;
+      break;
+
+    case 5:
+      disk->total_sectors = (array->total_devs - 1) * array->disk_size;
+      break;
+    }
+  
+  return 0;
+}
+
+static void
+grub_raid_close (grub_disk_t disk __attribute ((unused)))
+{
+  return;
+}
+
+static grub_err_t
+grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
+               grub_size_t size, char *buf)
+{
+  struct grub_raid_array *array = disk->data;
+  grub_err_t err = 0;
+
+  switch (array->level)
+    {
+    case 0:
+      {
+       grub_uint64_t a;
+       grub_uint32_t b;
+       unsigned int disknr;
+       grub_disk_addr_t read_sector;
+       grub_size_t read_size;
+
+       /* Find the first sector to read. */
+       a = grub_divmod64 (sector, array->chunk_size, NULL);
+       grub_divmod64 (a, array->total_devs, &disknr);
+
+       a = grub_divmod64 (sector, array->chunk_size * array->total_devs, NULL);
+       grub_divmod64 (sector, array->chunk_size, &b);
+       read_sector = a * array->chunk_size + b;
+
+       grub_divmod64 (read_sector, array->chunk_size, &b);
+       read_size = array->chunk_size - b;
+       
+       if (read_size > size)
+         read_size = size;
+       
+       while (1)
+         {
+           grub_uint32_t i;
+
+           err = grub_disk_read (array->device[disknr].disk, read_sector, 0,
+                                 read_size << GRUB_DISK_SECTOR_BITS, buf);
+           if (err)
+             break;
+
+           buf += read_size;
+           size -= read_size;
+           if (! size)
+             break;
+
+           if (size > array->chunk_size)
+             read_size = array->chunk_size;
+           else
+             read_size = size;
+
+           /* Check whether the sector was aligned on a chunk size
+              bounday. If this isn't the case, it's the first read
+              and the next read should be set back to start of the
+              boundary.  */
+           grub_divmod64 (read_sector, array->chunk_size, &i);
+           read_sector -= i;
+
+           disknr++;
+           /* See whether the disk was the last disk, and start
+              reading from the first disk in that case. */
+           if (disknr == array->total_devs)
+             {
+               disknr = 0;
+               read_sector += array->chunk_size;
+             }
+         }
+      }
+      break;
+
+    case 1:
+      /* This is easy, we can read from any disk we want. We will loop
+        over all disks until we've found one that is available. In
+        case of errs, we will try the to read the next disk. */
+      {
+       unsigned int i = 0;
+       
+       for (i = 0; i < array->total_devs; i++)
+         {
+           if (array->device[i].disk)
+             {
+               err = grub_disk_read (array->device[i].disk, sector, 0,
+                                     size << GRUB_DISK_SECTOR_BITS, buf);
+
+               if (!err)
+                 break;
+             }
+         }
+      }
+      break;
+
+    case 5:
+      {
+       grub_uint64_t a;
+       grub_uint32_t b;
+       int disknr;
+       grub_disk_addr_t read_sector;
+       grub_size_t read_size;
+
+       /* Find the first sector to read. */
+       a = grub_divmod64 (sector, array->chunk_size, NULL);
+       grub_divmod64 (a, (array->total_devs - 1), &b);
+       disknr = b;
+
+       a = grub_divmod64 (sector, array->chunk_size * (array->total_devs - 1),
+                          NULL);
+       grub_divmod64 (sector, array->chunk_size, &b);
+       read_sector = a * array->chunk_size + b;
+
+       grub_divmod64 (read_sector, array->chunk_size * array->total_devs, &b);
+       disknr -= (b / array->chunk_size);
+       if (disknr < 0)
+         disknr += array->total_devs;
+         
+       grub_divmod64 (read_sector, array->chunk_size, &b);
+       read_size = array->chunk_size - b;
+
+       if (read_size > size)
+         read_size = size;
+       
+       while (1)
+         {
+           grub_uint32_t i;
+
+           if (array->device[disknr].disk)
+             err = grub_disk_read (array->device[disknr].disk, read_sector, 0,
+                                   read_size << GRUB_DISK_SECTOR_BITS, buf);
+
+           /* If an error occurs when we already have an degraded
+              array we can't recover from that. */
+           if (err && ((array->total_devs - 1) == array->nr_devs))
+             break;
+           
+           if (err || ! array->device[disknr].disk)
+             {
+               /* Either an error occured or the disk is not
+                  available.  We have to compute this block from the
+                  blocks on the other hard disks. */
+               grub_size_t buf_size = read_size << GRUB_DISK_SECTOR_BITS;
+               char buf2[buf_size];
+               unsigned int j;
+
+               grub_memset (buf, 0, buf_size);
+               
+               for (j = 0; j < array->total_devs; j++)
+                 {
+                   unsigned int k;
+
+                   if (j != (unsigned int) disknr)
+                     {
+                       err = grub_disk_read (array->device[j].disk, read_sector,
+                                             0, buf_size, buf2);
+                       if (err)
+                         return err;
+                       
+                       for (k = 0; k < buf_size; k++)
+                         buf[k] = buf[k] ^ buf2[k];
+                     }
+                 }
+             }
+
+           buf += (read_size << GRUB_DISK_SECTOR_BITS);
+           size -= read_size;
+           if (! size)
+             break;
+
+           if (size > array->chunk_size)
+             read_size = array->chunk_size;
+           else
+             read_size = size;
+
+           /* Check whether the sector was aligned on a chunk size
+              bounday. If this isn't the case, it's the first read
+              and the next read should be set back to start of the
+              boundary.  */
+           grub_divmod64 (read_sector, array->chunk_size, &i);
+           read_sector -= i;
+
+           disknr++;
+           grub_divmod64 (read_sector,
+                          array->chunk_size * array->total_devs, &i);
+           if ((unsigned int) disknr == (array->total_devs - (i / array->chunk_size) - 1))
+             disknr++;
+           /* See whether the disk was the last disk, and start
+              reading from the first disk in that case. */
+           if ((unsigned int) disknr == array->total_devs)
+             {
+               disknr = 0;
+               read_sector += array->chunk_size;
+               grub_divmod64 (read_sector,
+                              array->chunk_size * array->total_devs, &i);
+
+               if ((i / array->chunk_size) == (array->total_devs - 1))
+                 disknr++;
+             }
+         }
+      }
+      break;
+    }
+  
+  return err;
+}
+
+static grub_err_t
+grub_raid_write (grub_disk_t disk __attribute ((unused)),
+                grub_disk_addr_t sector __attribute ((unused)),
+                grub_size_t size __attribute ((unused)),
+                const char *buf __attribute ((unused)))
+{
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static int
+grub_raid_scan_device (const char *name)
+{
+  grub_err_t err;
+  grub_disk_t disk;
+  grub_disk_addr_t sector;
+  grub_uint64_t size;
+  struct grub_raid_super_09 sb;
+  struct grub_raid_array *p, *array = NULL;
+
+  disk = grub_disk_open (name);
+  if (!disk)
+    return 0;
+
+  /* The sector where the RAID superblock is stored, if available. */
+  size = grub_disk_get_size (disk);
+  sector = GRUB_RAID_NEW_SIZE_SECTORS(size);
+
+  err = grub_disk_read (disk, sector, 0, GRUB_RAID_SB_BYTES, (char *) &sb);
+  grub_disk_close (disk);
+  if (err)
+    return 0;
+
+  /* Look whether there is a RAID superblock. */
+  if (sb.md_magic != GRUB_RAID_SB_MAGIC)
+    return 0;
+  
+  /* FIXME: Also support version 1.0. */
+  if (sb.major_version != 0 || sb.minor_version != 90)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "Unsupported RAID version: %d.%d",
+                 sb.major_version, sb.minor_version);
+      return 0;
+    }
+
+  /* FIXME: Check the checksum. */
+
+  /* FIXME: Support all RAID levels.  */
+  if (sb.level != 0 && sb.level != 1 && sb.level != 5)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "Unsupported RAID level: %d",
+                 sb.level);
+      return 0;
+    }
+
+  /* FIXME: Support all layouts.  */
+  if (sb.level == 5 && sb.layout != 2)
+    {
+      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                 "Unsupported RAID5 layout: %d",
+                 sb.layout);
+      return 0;
+    }
+  
+  /* See whether the device is part of an array we have already seen a
+     device from. */
+  for (p = array_list; p != NULL; p = p->next)
+    {
+      if (p->uuid[0] == sb.set_uuid0 && p->uuid[1] == sb.set_uuid1
+         && p->uuid[2] == sb.set_uuid2 && p->uuid[3] == sb.set_uuid3)
+       {
+         array = p;
+         break;
+       }
+    }
+
+  /* Do some checks before adding the device to the array.  */
+  if (array)
+    {
+      /* FIXME: Check whether the update time of the superblocks are
+        the same. */
+      
+      if (array->total_devs == array->nr_devs)
+       {
+         /* We found more members of the array than the array
+            actually has according to its superblock.  This shouldn't
+            happen normally, but what is the sanest things to do in such
+            a case? */
+            
+         grub_error (GRUB_ERR_BAD_NUMBER,
+                     "array->nr_devs > array->total_devs (%d)?!?",
+                     array->total_devs);
+
+         return 0;
+       }
+  
+      if (array->device[sb.this_disk.number].name != 0)
+       {
+         /* We found multiple devices with the same number. Again,
+            this shouldn't happen.*/
+
+         grub_error (GRUB_ERR_BAD_NUMBER,
+                     "Found two disks with the number %d?!?",
+                     sb.this_disk.number);
+
+         return 0;
+       }
+    }
+
+  /* Add an array to the list if we didn't find any.  */
+  if (!array)
+    {
+      array = grub_malloc (sizeof (*array));
+      if (!array)
+       return 0;
+      grub_memset (array, 0, sizeof (*array));      
+      array->number = sb.md_minor;
+      array->version = sb.major_version;
+      array->level = sb.level;
+      array->layout = sb.layout;
+      array->total_devs = sb.nr_disks;
+      array->nr_devs = 0;
+      array->uuid[0] = sb.set_uuid0;
+      array->uuid[1] = sb.set_uuid1;
+      array->uuid[2] = sb.set_uuid2;
+      array->uuid[3] = sb.set_uuid3;
+      /* The superblock specifies the size in 1024-byte sectors. */
+      array->disk_size = sb.size * 2;
+      array->chunk_size = sb.chunk_size / 512;
+      
+      /* Check whether we don't have multiple arrays with the same number. */
+      for (p = array_list; p != NULL; p = p->next)
+       {
+         if (p->number == array->number)
+           break;
+       }
+
+      if (p)
+       {
+         /* The number is already in use, so we need to find an new number. */
+         int i = 0;
+
+         while (1)
+           {
+             for (p = array_list; p != NULL; p = p->next)
+               {
+                 if (p->number == i)
+                   break;
+               }
+
+             if (!p)
+               {
+                 /* We found an unused number.  */
+                 array->number = i;
+                 break;
+               }
+
+             i++;
+           }
+       }
+
+      array->name = grub_malloc (13);
+      if (! array->name)
+       {
+         grub_free (array);
+
+         return 0;
+       }
+
+      grub_sprintf (array->name, "md%d", array->number);
+
+      /* Add our new array to the list.  */
+      array->next = array_list;
+      array_list = array;
+    }
+
+  /* Add the device to the array. */
+  array->device[sb.this_disk.number].name = grub_strdup (name);
+  array->device[sb.this_disk.number].disk = grub_disk_open (name);
+  
+  if (! array->device[sb.this_disk.number].name
+      || ! array->device[sb.this_disk.number].disk)
+    {
+      grub_free (array->device[sb.this_disk.number].name);
+
+      /* Remove array from the list if we have just added it. */
+      if (array->nr_devs == 0)
+       {
+         array_list = array->next;
+         grub_free (array->name);
+         grub_free (array);
+       }
+         
+      return 0;
+    }
+
+  array->nr_devs++;
+  
+  return 0;
+}
+
+static struct grub_disk_dev grub_raid_dev =
+  {
+    .name = "raid",
+    .id = GRUB_DISK_DEVICE_RAID_ID,
+    .iterate = grub_raid_iterate,
+    .open = grub_raid_open,
+    .close = grub_raid_close,
+    .read = grub_raid_read,
+    .write = grub_raid_write,
+    .next = 0
+  };
+
+\f
+GRUB_MOD_INIT(raid)
+{
+  grub_device_iterate (&grub_raid_scan_device);
+  grub_disk_dev_register (&grub_raid_dev);
+}
+
+GRUB_MOD_FINI(raid)
+{
+  grub_disk_dev_unregister (&grub_raid_dev);
+  /* FIXME: free the array list. */
+}
index 05974e02bf676c949c6e3f56a6d5ffa8d11403c7..011efe63d2cc8ac9e0bcc0897cacdc591bd8c4f6 100644 (file)
@@ -32,7 +32,9 @@ enum grub_disk_dev_id
     GRUB_DISK_DEVICE_BIOSDISK_ID,
     GRUB_DISK_DEVICE_OFDISK_ID,
     GRUB_DISK_DEVICE_LOOPBACK_ID,
-    GRUB_DISK_DEVICE_EFIDISK_ID
+    GRUB_DISK_DEVICE_EFIDISK_ID,
+    GRUB_DISK_DEVICE_RAID_ID,
+    GRUB_DISK_DEVICE_LVM_ID
   };
 
 struct grub_disk;
@@ -132,5 +134,6 @@ grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk,
                                         grub_size_t size,
                                         const char *buf);
 
+grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk);
 
 #endif /* ! GRUB_DISK_HEADER */
diff --git a/include/grub/lvm.h b/include/grub/lvm.h
new file mode 100644 (file)
index 0000000..6fb7451
--- /dev/null
@@ -0,0 +1,129 @@
+/* lvm.h - On disk structures for LVM. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_LVM_H
+#define GRUB_LVM_H     1
+
+#include <grub/types.h>
+
+/* Length of ID string, excluding terminating zero. */
+#define GRUB_LVM_ID_STRLEN 38
+
+struct grub_lvm_vg {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  int extent_size;
+  struct grub_lvm_pv *pvs;
+  struct grub_lvm_lv *lvs;
+  struct grub_lvm_vg *next;
+};
+
+struct grub_lvm_pv {
+  char id[GRUB_LVM_ID_STRLEN+1];
+  char *name;
+  grub_disk_t disk;
+  int start; /* Sector number where the data area starts. */
+  struct grub_lvm_pv *next;
+};
+
+struct grub_lvm_lv {
+  char *name;
+  unsigned int number;
+  unsigned int segment_count;
+  grub_uint64_t size;
+  struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */
+  struct grub_lvm_vg *vg;
+  struct grub_lvm_lv *next;
+};
+
+struct grub_lvm_segment {
+  unsigned int start_extent;
+  unsigned int extent_count;
+  unsigned int stripe_count;
+  unsigned int stripe_size;
+  struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */
+};
+
+struct grub_lvm_stripe {
+  int start;
+  struct grub_lvm_pv *pv;
+};
+
+#define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE
+#define GRUB_LVM_LABEL_SCAN_SECTORS 4L
+
+#define GRUB_LVM_LABEL_ID "LABELONE"
+#define GRUB_LVM_LVM2_LABEL "LVM2 001"
+
+#define GRUB_LVM_ID_LEN 32
+
+/* On disk - 32 bytes */
+struct grub_lvm_label_header {
+  grub_int8_t id[8];           /* LABELONE */
+  grub_uint64_t sector_xl;     /* Sector number of this label */
+  grub_uint32_t crc_xl;                /* From next field to end of sector */
+  grub_uint32_t offset_xl;     /* Offset from start of struct to contents */
+  grub_int8_t type[8];         /* LVM2 001 */
+} __attribute__ ((packed));
+
+/* On disk */
+struct grub_lvm_disk_locn {
+  grub_uint64_t offset;                /* Offset in bytes to start sector */
+  grub_uint64_t size;          /* Bytes */
+} __attribute__ ((packed));
+
+/* Fields with the suffix _xl should be xlate'd wherever they appear */
+/* On disk */
+struct grub_lvm_pv_header {
+  grub_int8_t pv_uuid[GRUB_LVM_ID_LEN];
+
+  /* This size can be overridden if PV belongs to a VG */
+  grub_uint64_t device_size_xl;        /* Bytes */
+
+  /* NULL-terminated list of data areas followed by */
+  /* NULL-terminated list of metadata area headers */
+  struct grub_lvm_disk_locn disk_areas_xl[0];  /* Two lists */
+} __attribute__ ((packed));
+
+#define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
+#define GRUB_LVM_FMTT_VERSION 1
+
+/* On disk */
+struct grub_lvm_raw_locn {
+  grub_uint64_t offset;                /* Offset in bytes to start sector */
+  grub_uint64_t size;          /* Bytes */
+  grub_uint32_t checksum;
+  grub_uint32_t filler;
+} __attribute__ ((packed));
+
+/* On disk */
+/* Structure size limited to one sector */
+struct grub_lvm_mda_header {
+  grub_uint32_t checksum_xl;   /* Checksum of rest of mda_header */
+  grub_int8_t magic[16];       /* To aid scans for metadata */
+  grub_uint32_t version;
+  grub_uint64_t start;         /* Absolute start byte of mda_header */
+  grub_uint64_t size;          /* Size of metadata area */
+  
+  struct grub_lvm_raw_locn raw_locns[0];       /* NULL-terminated list */
+} __attribute__ ((packed));
+
+
+#endif /* ! GRUB_LVM_H */
index 35f7507a25be9f0e9241eb68a43cf98247e288a7..b0aff910d41d8442652d95c079aeaa76a1d4aebd 100644 (file)
@@ -1,7 +1,7 @@
 /* misc.h - prototypes for misc functions */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005  Free Software Foundation, Inc.
+ *  Copyright (C) 2002,2003,2005,2006  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
@@ -48,6 +48,7 @@ int EXPORT_FUNC(grub_strncasecmp) (const char *s1, const char *s2, int c);
 char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
 char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
 int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
+char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle);
 int EXPORT_FUNC(grub_iswordseparator) (int c);
 int EXPORT_FUNC(grub_isspace) (int c);
 int EXPORT_FUNC(grub_isprint) (int c);
diff --git a/include/grub/raid.h b/include/grub/raid.h
new file mode 100644 (file)
index 0000000..f7bd467
--- /dev/null
@@ -0,0 +1,191 @@
+/* raid.h - On disk structures for RAID. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_RAID_H
+#define GRUB_RAID_H    1
+
+#include <grub/types.h>
+
+struct grub_raid_array
+{
+  int number;              /* The device number, taken from md_minor so we
+                             are consistent with the device name in
+                             Linux. */
+  int version;             /* 0 = 0.90, 1 = 1.0 */
+  int level;               /* RAID levels, only 0, 1 or 5 at the moment. */
+  int layout;              /* Only for RAID 5.  */
+  unsigned int total_devs; /* Total number of devices in the array. */
+  unsigned int nr_devs;    /* The number of devices we've found so far. */
+  grub_size_t chunk_size; /* The size of a chunk, in 512 byte sectors. */
+  grub_uint32_t uuid[4];   /* The UUID of the device. */
+  char *name;              /* That will be "md<number>". */
+  grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte
+                             sectors. */
+  struct
+  {
+    char *name;            /* Name of the device */
+    grub_disk_t disk;      /* The device itself. */
+  } device[32];            /* Array of total_devs devices. */          
+  struct grub_raid_array *next;
+};
+
+/* Linux RAID on disk structures and constants,
+   copied from include/linux/raid/md_p.h.  */
+
+#define GRUB_RAID_RESERVED_BYTES               (64 * 1024)
+#define GRUB_RAID_RESERVED_SECTORS             (GRUB_RAID_RESERVED_BYTES / 512)
+
+#define GRUB_RAID_NEW_SIZE_SECTORS(x)          ((x & ~(GRUB_RAID_RESERVED_SECTORS - 1)) \
+                                                - GRUB_RAID_RESERVED_SECTORS)
+
+#define GRUB_RAID_SB_BYTES                     4096
+#define GRUB_RAID_SB_WORDS                     (GRUB_RAID_SB_BYTES / 4)
+#define GRUB_RAID_SB_SECTORS                   (GRUB_RAID_SB_BYTES / 512)
+
+/*
+ * The following are counted in 32-bit words
+ */
+#define        GRUB_RAID_SB_GENERIC_OFFSET             0
+
+#define GRUB_RAID_SB_PERSONALITY_OFFSET        64
+#define GRUB_RAID_SB_DISKS_OFFSET              128
+#define GRUB_RAID_SB_DESCRIPTOR_OFFSET         992
+
+#define GRUB_RAID_SB_GENERIC_CONSTANT_WORDS    32
+#define GRUB_RAID_SB_GENERIC_STATE_WORDS       32
+#define GRUB_RAID_SB_GENERIC_WORDS             (GRUB_RAID_SB_GENERIC_CONSTANT_WORDS \
+                                                + GRUB_RAID_SB_GENERIC_STATE_WORDS)
+#define GRUB_RAID_SB_PERSONALITY_WORDS         64
+#define GRUB_RAID_SB_DESCRIPTOR_WORDS          32
+#define GRUB_RAID_SB_DISKS                     27
+#define GRUB_RAID_SB_DISKS_WORDS               (GRUB_RAID_SB_DISKS*GRUB_RAID_SB_DESCRIPTOR_WORDS)
+#define GRUB_RAID_SB_RESERVED_WORDS            (1024 - GRUB_RAID_SB_GENERIC_WORDS \
+                                                - GRUB_RAID_SB_PERSONALITY_WORDS \
+                                                - GRUB_RAID_SB_DISKS_WORDS \
+                                                - GRUB_RAID_SB_DESCRIPTOR_WORDS)
+#define GRUB_RAID_SB_EQUAL_WORDS               (GRUB_RAID_SB_GENERIC_WORDS \
+                                                + GRUB_RAID_SB_PERSONALITY_WORDS \
+                                                + GRUB_RAID_SB_DISKS_WORDS)
+
+/*
+ * Device "operational" state bits
+ */
+#define GRUB_RAID_DISK_FAULTY          0 /* disk is faulty / operational */
+#define GRUB_RAID_DISK_ACTIVE          1 /* disk is running or spare disk */
+#define GRUB_RAID_DISK_SYNC            2 /* disk is in sync with the raid set */
+#define GRUB_RAID_DISK_REMOVED         3 /* disk is in sync with the raid set */
+
+#define        GRUB_RAID_DISK_WRITEMOSTLY      9 /* disk is "write-mostly" is RAID1 config.
+                                          * read requests will only be sent here in
+                                          * dire need
+                                          */
+
+
+#define GRUB_RAID_SB_MAGIC             0xa92b4efc
+
+/*
+ * Superblock state bits
+ */
+#define GRUB_RAID_SB_CLEAN             0
+#define GRUB_RAID_SB_ERRORS            1
+
+#define        GRUB_RAID_SB_BITMAP_PRESENT     8 /* bitmap may be present nearby */
+
+struct grub_raid_disk_09 {
+  grub_uint32_t number;                /* 0 Device number in the entire set          */
+  grub_uint32_t major;         /* 1 Device major number                      */
+  grub_uint32_t minor;         /* 2 Device minor number                      */
+  grub_uint32_t raid_disk;     /* 3 The role of the device in the raid set   */
+  grub_uint32_t state;         /* 4 Operational state                        */
+  grub_uint32_t reserved[GRUB_RAID_SB_DESCRIPTOR_WORDS - 5];
+};
+
+struct grub_raid_super_09 {
+  /*
+   * Constant generic information
+   */
+  grub_uint32_t md_magic;      /*  0 MD identifier                           */
+  grub_uint32_t major_version; /*  1 major version to which the set conforms */
+  grub_uint32_t minor_version; /*  2 minor version ...                       */
+  grub_uint32_t patch_version; /*  3 patchlevel version ...                  */
+  grub_uint32_t gvalid_words;  /*  4 Number of used words in this section    */
+  grub_uint32_t set_uuid0;     /*  5 Raid set identifier                     */
+  grub_uint32_t ctime;         /*  6 Creation time                           */
+  grub_uint32_t level;         /*  7 Raid personality                        */
+  grub_uint32_t size;          /*  8 Apparent size of each individual disk   */
+  grub_uint32_t nr_disks;      /*  9 total disks in the raid set             */
+  grub_uint32_t raid_disks;    /* 10 disks in a fully functional raid set    */
+  grub_uint32_t md_minor;      /* 11 preferred MD minor device number        */
+  grub_uint32_t not_persistent;        /* 12 does it have a persistent superblock    */
+  grub_uint32_t set_uuid1;     /* 13 Raid set identifier #2                  */
+  grub_uint32_t set_uuid2;     /* 14 Raid set identifier #3                  */
+  grub_uint32_t set_uuid3;     /* 15 Raid set identifier #4                  */
+  grub_uint32_t gstate_creserved[GRUB_RAID_SB_GENERIC_CONSTANT_WORDS - 16];
+
+  /*
+   * Generic state information
+   */
+  grub_uint32_t utime;         /*  0 Superblock update time                  */
+  grub_uint32_t state;         /*  1 State bits (clean, ...)                 */
+  grub_uint32_t active_disks;  /*  2 Number of currently active disks        */
+  grub_uint32_t working_disks; /*  3 Number of working disks                 */
+  grub_uint32_t failed_disks;  /*  4 Number of failed disks                  */
+  grub_uint32_t spare_disks;   /*  5 Number of spare disks                   */
+  grub_uint32_t sb_csum;       /*  6 checksum of the whole superblock        */
+#ifdef GRUB_HOST_WORDS_BIGENDIAN
+  grub_uint32_t events_hi;     /*  7 high-order of superblock update count   */
+  grub_uint32_t events_lo;     /*  8 low-order of superblock update count    */
+  grub_uint32_t cp_events_hi;  /*  9 high-order of checkpoint update count   */
+  grub_uint32_t cp_events_lo;  /* 10 low-order of checkpoint update count    */
+#else
+  grub_uint32_t events_lo;     /*  7 low-order of superblock update count    */
+  grub_uint32_t events_hi;     /*  8 high-order of superblock update count   */
+  grub_uint32_t cp_events_lo;  /*  9 low-order of checkpoint update count    */
+  grub_uint32_t cp_events_hi;  /* 10 high-order of checkpoint update count   */
+#endif
+  grub_uint32_t recovery_cp;   /* 11 recovery checkpoint sector count        */
+  grub_uint32_t gstate_sreserved[GRUB_RAID_SB_GENERIC_STATE_WORDS - 12];
+
+  /*
+   * Personality information
+   */
+  grub_uint32_t layout;                /*  0 the array's physical layout             */
+  grub_uint32_t chunk_size;    /*  1 chunk size in bytes                     */
+  grub_uint32_t root_pv;       /*  2 LV root PV */
+  grub_uint32_t root_block;    /*  3 LV root block */
+  grub_uint32_t pstate_reserved[GRUB_RAID_SB_PERSONALITY_WORDS - 4];
+
+  /*
+   * Disks information
+   */
+  struct grub_raid_disk_09 disks[GRUB_RAID_SB_DISKS];
+
+  /*
+   * Reserved
+   */
+  grub_uint32_t reserved[GRUB_RAID_SB_RESERVED_WORDS];
+
+  /*
+   * Active descriptor
+   */
+  struct grub_raid_disk_09 this_disk;
+};
+
+#endif /* ! GRUB_RAID_H */
diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h
new file mode 100644 (file)
index 0000000..3d5c460
--- /dev/null
@@ -0,0 +1,28 @@
+/* lvm.h - LVM support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_LVM_UTIL_HEADER
+#define GRUB_LVM_UTIL_HEADER   1
+
+#ifdef __linux__
+int grub_util_lvm_isvolume (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h
new file mode 100644 (file)
index 0000000..8b691ff
--- /dev/null
@@ -0,0 +1,28 @@
+/* raid.h - RAID support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRUB_RAID_UTIL_HEADER
+#define GRUB_RAID_UTIL_HEADER  1
+
+#ifdef __linux__
+char** grub_util_raid_getmembers (char *name);
+#endif
+
+#endif /* ! GRUB_RAID_UTIL_HEADER */
index 5ae8d78b3bcc5a8d0c32b9b10fcc2f899ce14f3d..114d3ae495de076ff2b4a5368690c8b0151f79e2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2004  Free Software Foundation, Inc.
+ *  Copyright (C) 2002,2003,2004,2006  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
@@ -265,7 +265,14 @@ grub_disk_open (const char *name)
   disk->dev = dev;
 
   if (p)
-    disk->partition = grub_partition_probe (disk, p + 1);
+    {
+      disk->partition = grub_partition_probe (disk, p + 1);
+      if (! disk->partition)
+       {
+         grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
+         goto fail;
+       }
+    }
 
   /* The cache will be invalidated about 2 seconds after a device was
      closed.  */
@@ -522,3 +529,12 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
 
   return grub_errno;
 }
+
+grub_uint64_t 
+grub_disk_get_size (grub_disk_t disk)
+{
+  if (disk->partition)
+    return grub_partition_get_len (disk->partition);
+  else
+    return disk->total_sectors;
+}
index 2baf6a1078cad6f6f8c49a10c2b0204c72047e49..99fbc3932ddc7a499885befefe2d17afc35f6788 100644 (file)
@@ -59,19 +59,22 @@ make_install_device (void)
   /* XXX: This should be enough.  */
   char dev[100];
 
-  grub_sprintf (dev, "(%cd%u",
-               (grub_boot_drive & 0x80) ? 'h' : 'f',
-               grub_boot_drive & 0x7f);
-  
-  if (grub_install_dos_part >= 0)
-    grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
-
-  if (grub_install_bsd_part >= 0)
-    grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
-
-  grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
-  grub_strcpy (grub_prefix, dev);
-  
+  if (grub_install_dos_part != -2)
+    {
+      grub_sprintf (dev, "(%cd%u",
+                   (grub_boot_drive & 0x80) ? 'h' : 'f',
+                   grub_boot_drive & 0x7f);
+      
+      if (grub_install_dos_part >= 0)
+       grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
+      
+      if (grub_install_bsd_part >= 0)
+       grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
+      
+      grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
+      grub_strcpy (grub_prefix, dev);
+    }
+      
   return grub_prefix;
 }
 
index e8dfa3a5ffdbf719a0097af071b341fd5f049bb4..1e4ffdf7fe2cab28fefc5a503de28366c437de5d 100644 (file)
@@ -1,7 +1,7 @@
 /* misc.c - definitions of misc functions */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006  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
@@ -256,6 +256,52 @@ grub_strrchr (const char *s, int c)
   return p;
 }
 
+/* Copied from gnulib.
+   Written by Bruno Haible <bruno@clisp.org>, 2005. */
+char *
+grub_strstr (const char *haystack, const char *needle)
+{
+  /* Be careful not to look at the entire extent of haystack or needle
+     until needed.  This is useful because of these two cases:
+       - haystack may be very long, and a match of needle found early,
+       - needle may be very long, and not even a short initial segment of
+       needle may be found in haystack.  */
+  if (*needle != '\0')
+    {
+      /* Speed up the following searches of needle by caching its first
+        character.  */
+      char b = *needle++;
+      
+      for (;; haystack++)
+       {
+         if (*haystack == '\0')
+           /* No match.  */
+           return NULL;
+         if (*haystack == b)
+           /* The first character matches.  */
+           {
+             const char *rhaystack = haystack + 1;
+             const char *rneedle = needle;
+
+             for (;; rhaystack++, rneedle++)
+               {
+                 if (*rneedle == '\0')
+                   /* Found a match.  */
+                   return (char *) haystack;
+                 if (*rhaystack == '\0')
+                   /* No match.  */
+                   return NULL;
+                 if (*rhaystack != *rneedle)
+                   /* Nothing in this round.  */
+                   break;
+               }
+           }
+       }
+    }
+  else
+    return (char *) haystack;
+}
+
 int
 grub_strword (const char *haystack, const char *needle)
 {
diff --git a/util/genmoddep.c b/util/genmoddep.c
new file mode 100644 (file)
index 0000000..9edd063
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002  Free Software Foundation, Inc.
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define BUF_SIZE       1024
+#define SYMTAB_SIZE    509
+
+struct symbol
+{
+  const char *name;
+  const char *mod;
+  struct symbol *next;
+};
+
+struct module
+{
+  const char *name;
+  struct module *next;
+};
+
+static char buf[BUF_SIZE];
+static struct symbol *symtab[SYMTAB_SIZE];
+
+static void
+err (const char *fmt, ...)
+{
+  va_list ap;
+
+  fprintf (stderr, "genmoddep: error: ");
+  
+  va_start (ap, fmt);
+  vfprintf (stderr, fmt, ap);
+  va_end (ap);
+
+  fputc ('\n', stderr);
+  exit (1);
+}
+
+static void *
+xmalloc (size_t size)
+{
+  void *p;
+
+  p = malloc (size);
+  if (! p)
+    err ("out of memory");
+
+  return p;
+}
+
+static char *
+xstrdup (const char *str)
+{
+  char *s;
+  size_t len;
+
+  len = strlen (str);
+  s = (char *) xmalloc (len + 1);
+  memcpy (s, str, len + 1);
+
+  return s;
+}
+
+static void
+chomp (char *str)
+{
+  int end;
+  
+  end = strlen (str) - 1;
+  if (end < 0)
+    err ("empty string");
+
+  if (str[end] == '\n')
+    str[end] = '\0';
+}
+
+static unsigned
+symbol_hash (const char *s)
+{
+  unsigned key = 0;
+
+  while (*s)
+    key = key * 65599 + *s++;
+
+  return (key + (key >> 5)) % SYMTAB_SIZE;
+}
+
+static struct symbol *
+get_symbol (const char *name)
+{
+  unsigned k;
+  struct symbol *sym;
+  
+  k = symbol_hash (name);
+  for (sym = symtab[k]; sym; sym = sym->next)
+    if (strcmp (sym->name, name) == 0)
+      return sym;
+
+  return 0;
+}
+
+static void
+add_symbol (const char *name, const char *mod)
+{
+  unsigned k;
+  struct symbol *sym;
+
+  if (get_symbol (name))
+    err ("duplicated symbol: %s", name);
+  
+  sym = (struct symbol *) xmalloc (sizeof (*sym));
+  sym->name = xstrdup (name);
+  sym->mod = xstrdup (mod);
+
+  k = symbol_hash (name);
+  sym->next = symtab[k];
+  symtab[k] = sym;
+}
+
+static void
+free_symbols (void)
+{
+  int i;
+
+  for (i = 0; i < SYMTAB_SIZE; i++)
+    {
+      struct symbol *p, *q;
+
+      p = symtab[i];
+      while (p)
+       {
+         q = p->next;
+         free ((void *) p->name);
+         free ((void *) p->mod);
+         free (p);
+         p = q;
+       }
+    }
+}
+
+static void
+read_defined_symbols (FILE *fp)
+{
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *p;
+
+      if (! *buf)
+       err ("empty symbol name: %s", buf);
+      
+      p = strchr (buf, ' ');
+      if (! p)
+       err ("invalid line format: %s", buf);
+
+      p++;
+      
+      if (! *p)
+       err ("empty module name: %s", buf);
+
+      *(p - 1) = '\0';
+      chomp (p);
+      
+      add_symbol (buf, p);
+    }
+}
+
+static void
+add_module (struct module **head, const char *name)
+{
+  struct module *mod;
+
+  for (mod = *head; mod; mod = mod->next)
+    if (strcmp (mod->name, name) == 0)
+      return;
+
+  mod = (struct module *) xmalloc (sizeof (*mod));
+  mod->name = xstrdup (name);
+
+  mod->next = *head;
+  *head = mod;
+}
+
+static void
+free_modules (struct module *head)
+{
+  struct module *next;
+
+  while (head)
+    {
+      next = head->next;
+      free ((void *) head->name);
+      free (head);
+      head = next;
+    }
+}
+
+static void
+find_dependencies (FILE *fp)
+{
+  char *mod_name;
+  struct module *mod_list = 0;
+  struct module *mod;
+  
+  if (! fgets (buf, sizeof (buf), fp) || buf[0] == '\n' || buf[0] == '\0')
+    err ("no module name");
+
+  chomp (buf);
+  mod_name = xstrdup (buf);
+
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      struct symbol *sym;
+      
+      chomp (buf);
+      sym = get_symbol (buf);
+      if (! sym)
+       err ("%s in %s is not defined", buf, mod_name);
+
+      add_module (&mod_list, sym->mod);
+    }
+
+  printf ("%s:", mod_name);
+  
+  for (mod = mod_list; mod; mod = mod->next)
+    if (strcmp (mod->name, "kernel") != 0)
+      printf (" %s", mod->name);
+  
+  putchar ('\n');
+
+  free_modules (mod_list);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int i;
+  
+  /* First, get defined symbols.  */
+  read_defined_symbols (stdin);
+
+  /* Second, find the dependecies.  */
+  for (i = 1; i < argc; i++)
+    {
+      FILE *fp;
+
+      fp = fopen (argv[i], "r");
+      if (! fp)
+       err ("cannot open %s", argv[i]);
+
+      find_dependencies (fp);
+
+      fclose (fp);
+    }
+
+  /* Last, free memory.  */
+  free_symbols ();
+  
+  return 0;
+}
index e72c156e96eef01f13832800b4a448d195ba1ffc..1e544db873c64cc66773966138ad475e340a1835 100644 (file)
@@ -1,7 +1,7 @@
 /* getroot.c - Get root device */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2003,2006  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
@@ -223,5 +223,27 @@ grub_guess_root_device (const char *dir)
   if (! os_dev)
     return 0;
 
+#ifdef __linux__
+  /* Check for LVM.  */
+  if (!strncmp (os_dev, "/dev/mapper/", 12))
+    {
+      char *grub_dev = xmalloc (strlen (os_dev) - 12);
+
+      strcpy (grub_dev, os_dev+12);
+
+      return grub_dev;
+    }
+
+  if (!strncmp (os_dev, "/dev/md", 7) || !strncmp (os_dev, "/dev/.static/dev/md", 19))
+    {
+      char *p, *grub_dev = xmalloc (8);
+
+      p = strchr (os_dev, 'm');
+      strncpy (grub_dev, p, 8);
+
+      return grub_dev;
+    }
+#endif
+    
   return grub_util_biosdisk_get_grub_dev (os_dev);
 }
index e128fb0f22dc789fc9794fd11db50fda664ed66d..bf92e4e95c1eb314c0b40686fd8cd553e1f52881 100644 (file)
@@ -32,6 +32,8 @@
 #include <grub/machine/boot.h>
 #include <grub/machine/kernel.h>
 #include <grub/term.h>
+#include <grub/util/raid.h>
+#include <grub/util/lvm.h>
 
 #include <stdio.h>
 #include <unistd.h>
@@ -91,7 +93,7 @@ grub_refresh (void)
 static void
 setup (const char *prefix, const char *dir,
        const char *boot_file, const char *core_file,
-       const char *root, const char *dest)
+       const char *root, const char *dest, int must_embed)
 {
   char *boot_path, *core_path;
   char *boot_img, *core_img;
@@ -218,9 +220,12 @@ setup (const char *prefix, const char *dir,
                    + GRUB_KERNEL_MACHINE_PREFIX);
 
   /* Open the root device and the destination device.  */
-  root_dev = grub_device_open (root);
-  if (! root_dev)
-    grub_util_error ("%s", grub_errmsg);
+  if (!must_embed)
+    {
+      root_dev = grub_device_open (root);
+      if (! root_dev)
+       grub_util_error ("%s", grub_errmsg);
+    }
 
   dest_dev = grub_device_open (dest);
   if (! dest_dev)
@@ -280,7 +285,9 @@ setup (const char *prefix, const char *dir,
          block->segment = 0;
 
          /* Embed information about the installed location.  */
-         if (root_dev->disk->partition)
+         if (must_embed)
+           *install_dos_part = *install_bsd_part = grub_cpu_to_le32 (-2);
+         else if (root_dev->disk->partition)
            {
              struct grub_pc_partition *pcdata =
                root_dev->disk->partition->data;
@@ -316,6 +323,9 @@ setup (const char *prefix, const char *dir,
          goto finish;
        }
     }
+  else if (must_embed)
+    grub_util_error ("Can't embed the core image, but this is required when\n"
+                    "the root device is on a RAID array or LVM volume.");
   
   /* The core image must be put on a filesystem unfortunately.  */
   grub_util_info ("will leave the core image on the filesystem");
@@ -422,6 +432,8 @@ setup (const char *prefix, const char *dir,
       != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
     grub_util_error ("Failed to read the rest sectors of the core image");
 
+  grub_file_close (file);
+  
   free (core_path);
   free (tmp_img);
   
@@ -481,7 +493,8 @@ setup (const char *prefix, const char *dir,
   free (core_img);
   free (boot_img);
   grub_device_close (dest_dev);
-  grub_device_close (root_dev);
+  if (!must_embed)
+    grub_device_close (root_dev);
 }
 
 static struct option options[] =
@@ -548,6 +561,7 @@ main (int argc, char *argv[])
   char *root_dev = 0;
   char *prefix;
   char *dest_dev;
+  int must_embed = 0;
   
   progname = "grub-setup";
 
@@ -678,12 +692,50 @@ main (int argc, char *argv[])
        }
     }
 
+#ifdef __linux__
+  if (grub_util_lvm_isvolume (root_dev))
+    {
+      char *newprefix;
+      must_embed = 1;
+
+      newprefix = xmalloc (1 + strlen (root_dev) + 1 + strlen (prefix) + 1);
+      sprintf (newprefix, "(%s)%s", root_dev, prefix);
+      free (prefix);
+      prefix = newprefix;
+    }
+    
+  if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
+      && dest_dev[2] >= '0' && dest_dev[2] <= '9')
+    {
+      char **devicelist;
+      char *raid_prefix;
+      int i;
+
+      raid_prefix = xmalloc (1 + strlen (dest_dev) + 1 + strlen (prefix) + 1);
+
+      sprintf (raid_prefix, "(%s)%s", dest_dev, prefix);
+      
+      devicelist = grub_util_raid_getmembers (dest_dev);
+
+      for (i = 0; devicelist[i]; i++)
+       {
+         setup (raid_prefix,
+                dir ? : DEFAULT_DIRECTORY,
+                boot_file ? : DEFAULT_BOOT_FILE,
+                core_file ? : DEFAULT_CORE_FILE,
+                root_dev, grub_util_biosdisk_get_grub_dev (devicelist[i]), 1);
+       }
+
+      free (raid_prefix);
+    }
+  else
+#endif
   /* Do the real work.  */
-  setup (prefix,
-        dir ? : DEFAULT_DIRECTORY,
-        boot_file ? : DEFAULT_BOOT_FILE,
-        core_file ? : DEFAULT_CORE_FILE,
-        root_dev, dest_dev);
+    setup (prefix,
+          dir ? : DEFAULT_DIRECTORY,
+          boot_file ? : DEFAULT_BOOT_FILE,
+          core_file ? : DEFAULT_CORE_FILE,
+          root_dev, dest_dev, must_embed);
 
   /* Free resources.  */
   grub_ext2_fini ();
diff --git a/util/lvm.c b/util/lvm.c
new file mode 100644 (file)
index 0000000..0591a55
--- /dev/null
@@ -0,0 +1,50 @@
+/* lvm.c - LVM support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* We only support LVM on Linux.  */
+#ifdef __linux__
+
+#include <grub/util/misc.h>
+
+#include <string.h>
+#include <sys/stat.h>
+
+int
+grub_util_lvm_isvolume (char *name)
+{
+  char *devname;
+  struct stat st;
+  int err;
+  
+  devname = xmalloc (strlen (name) + 13);
+
+  strcpy (devname, "/dev/mapper/");
+  strcpy (devname+12, name);
+
+  err = stat (devname, &st);
+  free (devname);
+
+  if (err)
+    return 0;
+  else
+    return 1;
+}
+
+#endif /* ! __linux__ */
diff --git a/util/raid.c b/util/raid.c
new file mode 100644 (file)
index 0000000..88e54d7
--- /dev/null
@@ -0,0 +1,112 @@
+/* raid.c - RAID support for GRUB utils.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2006  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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* We only support RAID on Linux.  */
+#ifdef __linux__
+#include <grub/util/misc.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+
+char *
+grub_util_getdiskname (int major, int minor)
+{
+  char *name = xmalloc (15);
+
+  if (major == LOOP_MAJOR)
+    sprintf (name, "/dev/loop%d", minor);
+  else if (major == IDE0_MAJOR)
+    sprintf (name, "/dev/hd%c", 'a' + minor / 64);
+  else if (major == IDE1_MAJOR)
+    sprintf (name, "/dev/hd%c", 'c' + minor / 64);
+  else if (major == IDE2_MAJOR)
+    sprintf (name, "/dev/hd%c", 'e' + minor / 64);
+  else if (major == IDE3_MAJOR)
+    sprintf (name, "/dev/hd%c", 'g' + minor / 64);
+  else if (major == SCSI_DISK0_MAJOR)
+    sprintf (name, "/dev/sd%c", 'a' + minor / 16);
+  else
+    grub_util_error ("Unknown device number: %d, %d", major, minor);
+    
+  return name;
+}
+
+char **
+grub_util_raid_getmembers (char *name)
+{
+  int fd, ret, i, j;
+  char *devname;
+  char **devicelist;
+  mdu_version_t version;
+  mdu_array_info_t info;
+  mdu_disk_info_t disk;
+
+  devname = xmalloc (strlen (name) + 6);
+  strcpy (devname, "/dev/");
+  strcpy (devname+5, name);
+
+  fd = open (devname, O_RDONLY);
+
+  if (fd == -1)
+    grub_util_error ("Can't open %s: %s", devname, strerror (errno));
+
+  free (devname);
+
+  ret = ioctl (fd, RAID_VERSION, &version);
+  if (ret != 0)
+    grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno));
+
+  if (version.major != 0 || version.minor != 90)
+    grub_util_error ("Unsupported RAID version: %d.%d",
+                    version.major, version.minor);
+  
+  ret = ioctl (fd, GET_ARRAY_INFO, &info);
+  if (ret != 0)
+    grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno));
+
+  devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *));
+
+  for (i = 0, j = 0; i <info.nr_disks; i++)
+    {
+      disk.number = i;
+      ret = ioctl (fd, GET_DISK_INFO, &disk);
+      if (ret != 0)
+       grub_util_error ("ioctl GET_DISK_INFO error: %s", strerror (errno));
+
+      if (disk.state & (1 << MD_DISK_ACTIVE))
+       {
+         devicelist[j] = grub_util_getdiskname (disk.major, disk.minor);
+         j++;
+       }
+    }
+
+  devicelist[j] = NULL;
+  
+  return devicelist;
+}
+
+#endif /* ! __linux__ */