diff options
52 files changed, 7771 insertions, 526 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..643cdcc5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/genkernel.8 + @@ -1,8 +1,150 @@ # ChangeLog for genkernel -# Copyright 1999-2009 Gentoo Foundation; 2008-2009 Various authors (see AUTHORS) +# Copyright: +# - 2003-2008 Gentoo Foundation +# - 2008-2011 Various authors (see AUTHORS) # Distributed under the GPL v2 # $Id$ + 20 Jan 2011; Sebastian Pipping <sping@gentoo.org> genkernel: + Bump version to 3.4.11.1 + + 20 Jan 2011; Sebastian Pipping <sping@gentoo.org> gen_configkernel.sh: + Move application of kernel config after "make mrproper" as that deletes + .config (whereas "make clean" does not) (bug #351906) + + Special thanks: + - Xake + + 20 Jan 2011; Sebastian Pipping <sping@gentoo.org> + patches/busybox/1.18.1/1.18.1-mdstart.diff: + busybox 1.18.1: Return of mdstart as an applet (regression) (bug #351909) + + 16 Jan 2011; Sebastian Pipping <sping@gentoo.org> genkernel: + Bump version to 3.4.11 + + 16 Jan 2011; Sebastian Pipping <sping@gentoo.org> defaults/initrd.scripts: + Do not sleep after vgscan (bug #351047) + + 16 Jan 2011; Sebastian Pipping <sping@gentoo.org> ChangeLog: + Changes: + - Fix compilation of LVM 2.02.74 (and 2.02.28) (bug #255196, bug #267383) + - Add minimal btrfs support (bug #303529) + - Add support for UUID to crypt_root (bug #315467) + - Run "make firmware_install" if CONFIG_FIRMWARE_IN_KERNEL != y (bug #244651) + - Port busybox patches from 1.7.4 to 1.18.1 (bug #331971) + - Handle missing kernel .config better (bug #271528) + - Improve slowusb handling (bug #323317) + - Add GnuPG 1.x support (bug #217959) + - Check return codes of cpio (bug #246370) + - Update e2fsprogs/blkid to 1.41.14 (bug #291822) + - Create /bin/vg* symlinks when called as /linuxrc, too (bug #307855) + - Pick first device when several devices are matching real_root (bug #303531) + - Fix warning "cannot remove `/var/cache/genkernel/src'" (bug #347213) + - Allow configuring the list of busybox applets (bug #326593) + - Fix arithmetic bug in defaults/initrd.scripts (bug #339789) + + Special thanks: + - Amadeusz Zolnowski (LVM update) + - Christian Giessner (UUID crypt_root) + - dacook (GnuPG 1.x support) + - Denis Kaganovich (Busybox patch porting) + - devsk (Multi-device patch) + - Fabio Erculiani (Slowusb fixes) + - Kai Dietrich (Symlink analysis) + - Kolbjørn Barmen (Arithmetic fix) + + 13 Dec 2010; Sebastian Pipping <sping@gentoo.org> genkernel: + Bump version to 3.4.10.908 + + 13 Dec 2010; <sping@gentoo.org> doc/genkernel.8.txt, gen_cmdline.sh: + docs: Document --genzimage + + 13 Dec 2010; <sping@gentoo.org> gen_cmdline.sh: + Fix a reference to --nomenuconfig into --no-menuconfig + + 13 Dec 2010; <sping@gentoo.org> doc/genkernel.8.txt: + docs: Update man page from output of --help + + 13 Dec 2010; <sping@gentoo.org> doc/genkernel.8.txt: + docs: Document keymap= and dokeymap (bug #346017) + + 6 Dec 2010; <sping@gentoo.org> genkernel.conf: + .conf: Document LUKS variable (bug #346015) + + 6 Dec 2010; <sping@gentoo.org> doc/genkernel.8.txt: + docs: Mention both "initramfs" and "ramdisk" as available actions + (bug #251702) + + 6 Dec 2010; <sping@gentoo.org> genkernel.8: + man page: Propagate rename of --no-initrdmodules to --no-ramdisk-modules + + 29 Nov 2010; <sping@gentoo.org> ChangeLog: + Add patch allowing compilation of busybox 1.7.4 with make 3.82 (bug #341943) + + 20 Feb 2010; Andrew Gaffney <agaffney@gentoo.org> defaults/initrd.scripts: + Apply patches from Gentoo bug #268468 + + 19 Jan 2010; Andrew Gaffney <agaffney@gentoo.org> genkernel: + Only call set_bootloader is CMD_NOINSTALL is not set for Gentoo bug + #301454 + + 27 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> arch/alpha/modules_load, + arch/arm/modules_load, arch/ia64/kernel-config, arch/ia64/modules_load, + arch/mips/modules_load, arch/parisc/modules_load, + arch/parisc64/modules_load, arch/ppc/kernel-config, arch/ppc/modules_load, + arch/ppc64/modules_load, arch/sparc/modules_load, + arch/sparc64/kernel-config, arch/sparc64/modules_load, + arch/um/modules_load, arch/x86/kernel-config, arch/x86/modules_load, + arch/x86_64/kernel-config, arch/x86_64/modules_load, + defaults/kernel-config: + Add USB HID modules to modules_load and default kernel-config (for Gentoo + bug #270983) + + 27 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> + arch/alpha/kernel-config, arch/alpha/modules_load, arch/arm/modules_load, + arch/ia64/kernel-config, arch/ia64/modules_load, arch/mips/modules_load, + arch/parisc/modules_load, arch/parisc64/modules_load, + arch/ppc/kernel-config, arch/ppc/modules_load, arch/ppc64/modules_load, + arch/sparc/modules_load, arch/sparc64/kernel-config, + arch/sparc64/modules_load, arch/um/modules_load, arch/x86/kernel-config, + arch/x86/modules_load, arch/x86_64/kernel-config, + arch/x86_64/modules_load, defaults/kernel-config, defaults/modules_load: + Enable ext4 by default everywhere (for Gentoo bug #268818) + + 27 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> defaults/initrd.scripts, + defaults/linuxrc: + Add support for isoboot= option (for Gentoo bug #294268) + + 26 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> + defaults/initrd.defaults, defaults/initrd.scripts: + Properly apply NFS mount options for Gentoo bug #262915 + + 26 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> + arch/alpha/kernel-config, arch/ia64/kernel-config, arch/ppc/kernel-config, + arch/x86_64/kernel-config: + Enable CONFIG_SCSI_MULTI_LUN option for Gentoo bug #261122 + + 26 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> defaults/initrd.scripts: + Apply patch to make sure loop cache directory exists for Gentoo bug + #297814 + + 17 Dec 2009; Robin H. Johnson <robbat2@gentoo.org> HACKING: + Document how to roll a release for the next time. + + 17 Dec 2009; Robin H. Johnson <robbat2@gentoo.org> genkernel: + Tag 3.4.10.907 release. + + 06 Dec 2009; Andrew Gaffney <agaffney@gentoo.org> gen_initramfs.sh: + use a symlink instead of a hardlink for busybox utils (for Gentoo bug + #246370) + + 23 Nov 2009; Andrew Gaffney <agaffney@gentoo.org> defaults/linuxrc: + Fix typo for Gentoo bug #294138 + + 16 Nov 2009; Andrew Gaffney <agaffney@gentoo.org> gen_initramfs.sh: + Make sure to change back to existant directory before removing the current + directory for Gentoo bug #291794 + 15 Oct 2009; <craig@haquarter.de> Changelog: added iSCSI support @@ -178,6 +320,7 @@ 23 Dec 2008; Andrew Gaffney <agaffney@gentoo.org> gen_cmdline.sh: Allow old 'initramfs' option instead of 'ramdisk' for compatability + (bug #251702) 17 Dec 2008; Andrew Gaffney <agaffney@gentoo.org> defaults/linuxrc: Remove the use of 'env -i' when calling switch_root due to Gentoo bug @@ -11,3 +11,12 @@ Phases: - source global scripts - +Rolling a release: +- Bump the version in the main genkernel file. +- echangelog commit the bump +- git tag -a -m "Tag release v${PV}" v${PV} +- git push ${REMOTE} master --tags +- make dist +- upload genkernel-${PV}.tar.bz2 to the hosting: + scp genkernel-${PV}.tar.bz2 ${USER}@dev.gentoo.org:/space/distfiles-local/ +- check open bugs with keyword "InSVN" for closability diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..74c5bb97 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +PACKAGE_VERSION = `/bin/fgrep GK_V= genkernel | sed "s/.*GK_V='\([^']\+\)'/\1/"` +distdir = genkernel-$(PACKAGE_VERSION) + +# Add off-Git/generated files here that need to be shipped with releases +EXTRA_DIST = genkernel.8 + +genkernel.8: doc/genkernel.8.txt doc/asciidoc.conf Makefile + a2x --conf-file=doc/asciidoc.conf --attribute="genkernelversion=$(PACKAGE_VERSION)" \ + --format=manpage -D . "$<" + +clean: + rm -f genkernel.8 + +check-git-repository: + git diff --quiet || { echo 'STOP, you have uncommitted changes in the working directory' ; false ; } + git diff --cached --quiet || { echo 'STOP, you have uncommitted changes in the index' ; false ; } + +dist: check-git-repository genkernel.8 + rm -Rf "$(distdir)" "$(distdir)".tar "$(distdir)".tar.bz2 + mkdir "$(distdir)" + git ls-files -z | xargs -0 cp --no-dereference --parents --target-directory="$(distdir)" \ + $(EXTRA_DIST) + tar cf "$(distdir)".tar "$(distdir)" + bzip2 -9v "$(distdir)".tar + rm -Rf "$(distdir)" + +.PHONY: clean check-git-repository dist diff --git a/arch/alpha/kernel-config b/arch/alpha/kernel-config index b4eb04c7..812fe8fd 100644 --- a/arch/alpha/kernel-config +++ b/arch/alpha/kernel-config @@ -400,7 +400,7 @@ CONFIG_CHR_DEV_SG=y # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set @@ -976,10 +976,10 @@ CONFIG_EXT3_FS=m CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4DEV_FS=m -CONFIG_EXT4DEV_FS_XATTR=y -CONFIG_EXT4DEV_FS_POSIX_ACL=y -CONFIG_EXT4DEV_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=m CONFIG_JBD2=m CONFIG_FS_MBCACHE=y diff --git a/arch/alpha/modules_load b/arch/alpha/modules_load index 85bf3d0a..63ef20fa 100644 --- a/arch/alpha/modules_load +++ b/arch/alpha/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/arm/modules_load b/arch/arm/modules_load index 9a446184..b2cf1d15 100644 --- a/arch/arm/modules_load +++ b/arch/arm/modules_load @@ -19,7 +19,7 @@ MODULES_NET="e1000 tg3" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/ia64/kernel-config b/arch/ia64/kernel-config index 202eb72c..8fbc90cb 100644 --- a/arch/ia64/kernel-config +++ b/arch/ia64/kernel-config @@ -476,7 +476,7 @@ CONFIG_CHR_DEV_SG=y # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SCAN_ASYNC is not set @@ -867,6 +867,41 @@ CONFIG_USB_HID=y CONFIG_USB_HIDDEV=y # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # USB support # CONFIG_USB_ARCH_HAS_HCD=y @@ -1032,7 +1067,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y CONFIG_JBD_DEBUG=y CONFIG_FS_MBCACHE=y diff --git a/arch/ia64/modules_load b/arch/ia64/modules_load index 33dbd12e..2612197e 100644 --- a/arch/ia64/modules_load +++ b/arch/ia64/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/mips/modules_load b/arch/mips/modules_load index 85bf3d0a..63ef20fa 100644 --- a/arch/mips/modules_load +++ b/arch/mips/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/parisc/modules_load b/arch/parisc/modules_load index 85bf3d0a..63ef20fa 100644 --- a/arch/parisc/modules_load +++ b/arch/parisc/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/parisc64/modules_load b/arch/parisc64/modules_load index 33dbd12e..2612197e 100644 --- a/arch/parisc64/modules_load +++ b/arch/parisc64/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/ppc/kernel-config b/arch/ppc/kernel-config index 9cf960dd..c62386d0 100644 --- a/arch/ppc/kernel-config +++ b/arch/ppc/kernel-config @@ -651,7 +651,7 @@ CONFIG_CHR_DEV_SCH=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set @@ -1837,6 +1837,41 @@ CONFIG_USB=y # CONFIG_USB_DEBUG is not set # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y @@ -2058,7 +2093,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y diff --git a/arch/ppc/modules_load b/arch/ppc/modules_load index 85bf3d0a..63ef20fa 100644 --- a/arch/ppc/modules_load +++ b/arch/ppc/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/ppc64/modules_load b/arch/ppc64/modules_load index 33dbd12e..2612197e 100644 --- a/arch/ppc64/modules_load +++ b/arch/ppc64/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/sparc/modules_load b/arch/sparc/modules_load index 85bf3d0a..63ef20fa 100644 --- a/arch/sparc/modules_load +++ b/arch/sparc/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/sparc64/kernel-config b/arch/sparc64/kernel-config index 68d20c15..c4b23593 100644 --- a/arch/sparc64/kernel-config +++ b/arch/sparc64/kernel-config @@ -1478,6 +1478,41 @@ CONFIG_USB_HID=m CONFIG_USB_HIDDEV=y # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # USB HID Boot Protocol drivers # CONFIG_USB_KBD=m @@ -1740,10 +1775,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4DEV_FS=m -CONFIG_EXT4DEV_FS_XATTR=y -CONFIG_EXT4DEV_FS_POSIX_ACL=y -CONFIG_EXT4DEV_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_JBD2=m diff --git a/arch/sparc64/modules_load b/arch/sparc64/modules_load index 33dbd12e..2612197e 100644 --- a/arch/sparc64/modules_load +++ b/arch/sparc64/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/um/modules_load b/arch/um/modules_load index 67b280dc..55dcc238 100644 --- a/arch/um/modules_load +++ b/arch/um/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/x86/kernel-config b/arch/x86/kernel-config index 12ca2c6a..1dbc07e9 100644 --- a/arch/x86/kernel-config +++ b/arch/x86/kernel-config @@ -2888,6 +2888,41 @@ CONFIG_ZEROPLUS_FF=y CONFIG_USB_HIDDEV=y # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # USB HID Boot Protocol drivers # # CONFIG_USB_KBD is not set @@ -3233,10 +3268,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4DEV_FS=m -CONFIG_EXT4DEV_FS_XATTR=y -CONFIG_EXT4DEV_FS_POSIX_ACL=y -CONFIG_EXT4DEV_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_JBD2=m diff --git a/arch/x86/modules_load b/arch/x86/modules_load index b1be781c..2d159fb2 100644 --- a/arch/x86/modules_load +++ b/arch/x86/modules_load @@ -23,7 +23,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/arch/x86_64/kernel-config b/arch/x86_64/kernel-config index 7656dc9a..1260e39c 100644 --- a/arch/x86_64/kernel-config +++ b/arch/x86_64/kernel-config @@ -976,7 +976,7 @@ CONFIG_CHR_DEV_SCH=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set CONFIG_SCSI_SCAN_ASYNC=y @@ -2388,6 +2388,41 @@ CONFIG_USB_HIDINPUT_POWERBOOK=y CONFIG_USB_HIDDEV=y # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # USB HID Boot Protocol drivers # # CONFIG_USB_KBD is not set @@ -2698,10 +2733,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4DEV_FS=y -CONFIG_EXT4DEV_FS_XATTR=y -CONFIG_EXT4DEV_FS_POSIX_ACL=y -CONFIG_EXT4DEV_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y CONFIG_JBD2=y CONFIG_FS_MBCACHE=y diff --git a/arch/x86_64/modules_load b/arch/x86_64/modules_load index 73bf530f..fe268910 100644 --- a/arch/x86_64/modules_load +++ b/arch/x86_64/modules_load @@ -22,7 +22,7 @@ MODULES_ISCSI="scsi_transport_iscsi libiscsi iscsi_tcp" # Hardware (Pluggable) MODULES_FIREWIRE="ieee1394 ohci1394 sbp2" MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide-cs firmware_class" -MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" +MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd hid-a4tech hid-apple hid-belkin hid-cherry hid-chicony hid-cypress hid-dummy hid-ezkey hid-gyration hid-logitech hid-microsoft hid-monterey hid-petalynx hid-pl hid-samsung hid-sony hid-sunplus" # Filesystems MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/defaults/initrd.defaults b/defaults/initrd.defaults index db5cb25b..14a403ff 100755 --- a/defaults/initrd.defaults +++ b/defaults/initrd.defaults @@ -75,6 +75,8 @@ CONSOLE='/dev/console' LOOPS='/livecd.loop /zisofs /livecd.squashfs /image.squashfs /livecd.gcloop' +DEFAULT_NFSOPTIONS="ro,nolock,rsize=1024,wsize=1024" + # Only sections that are in by default or those that # are not module groups need to be defined here... HWOPTS='keymap cache modules pata sata scsi usb firewire waitscan slowusb evms lvm dmraid mdadm fs net' diff --git a/defaults/initrd.scripts b/defaults/initrd.scripts index 7b638388..b7493aa3 100755 --- a/defaults/initrd.scripts +++ b/defaults/initrd.scripts @@ -72,8 +72,17 @@ findmediamount() { if [ "$#" -gt "0" ] then - [ ! -d "${mntdir}" ] && mkdir -p ${mntdir} 2>/dev/null >/dev/null + if [ -n "${ISOBOOT}" ] + then + mntcddir="${mntdir%${media}}iso" + if [ ! -f ${mntcddir} ] + then + mkdir ${mntcddir} + fi + else + mntcddir=${mntdir} + fi for x in $* do @@ -104,9 +113,18 @@ findmediamount() { # else # mount -r -t auto ${x} ${mntdir} &>/dev/null # fi - mount -r -t ${CDROOT_TYPE} ${x} ${mntdir} >/dev/null 2>&1 + mount -r -t ${CDROOT_TYPE} ${x} ${mntcddir} >/dev/null 2>&1 if [ "$?" = '0' ] then + if [ -n "${ISOBOOT}" ]; then + if [ -f ${mntcddir}/${ISOBOOT} ]; then + mount -o loop ${mntcddir}/${ISOBOOT} ${mntdir} + if [ "$?" = "0" ]; then + good_msg "iso mounted on ${mntdir}" + fi + fi + fi + # Check for the media if [ -f "${mntdir}/${recon}" ] then @@ -115,7 +133,7 @@ findmediamount() { good_msg "Media found on ${x}" ${CRYPT_SILENT} break else - umount ${mntdir} + umount ${mntcddir} fi fi fi @@ -175,6 +193,8 @@ cache_cd_contents() { # z=$(($z + $i)) ; done # echo $z good_msg "Copying loop file for caching..." + # Verify that the needed directory exists + mkdir -p "$(dirname ${NEW_ROOT}/mnt/${LOOP})" cp -a ${NEW_ROOT}/mnt/cdrom/${LOOP} ${NEW_ROOT}/mnt/${LOOP} if [ $? -ne 0 ] then @@ -192,7 +212,7 @@ cache_cd_contents() { mount_sysfs() { mount -t sysfs /sys /sys >/dev/null 2>&1 ret=$? - [ "$ret" -eq '0' ] || bad_msg "Failed to mount /sys!" + [ ${ret} -eq 0 ] || bad_msg "Failed to mount /sys!" } aufs_setup_dir() { @@ -241,10 +261,19 @@ findnfsmount() { if [ "${NFSROOT}" != '' ] then + NFSOPTIONS=${NFSROOT#*,} + NFSROOT=${NFSROOT%%,*} + if [ "${NFSOPTIONS}" = "${NFSROOT}" ] + then + NFSOPTIONS=$DEFAULT_NFSOPTIONS + else + NFSOPTIONS="${DEFAULT_NFSOPTIONS},${NFSOPTIONS}" + fi + if [ "${CDROOT}" != '0' ] then - good_msg "Attempting to mount NFS CD image on ${NFSROOT}" - mount -t nfs -o ro,nolock,rsize=1024,wsize=1024 ${NFSROOT} ${NEW_ROOT}/mnt/cdrom + good_msg "Attempting to mount NFS CD image on ${NFSROOT} with options ${NFSOPTIONS}" + mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${NEW_ROOT}/mnt/cdrom if [ "$?" = '0' ] then REAL_ROOT="/dev/nfs" @@ -252,8 +281,8 @@ findnfsmount() { bad_msg "NFS Mounting failed. Is the path corrent ?" fi else - good_msg "Attempting to mount NFS root on ${NFSROOT}" - mount -t nfs -o ro,nolock,rsize=1024,wsize=1024 ${NFSROOT} ${NEW_ROOT} + good_msg "Attempting to mount NFS root on ${NFSROOT} with options ${NFSOPTIONS}" + mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${NEW_ROOT} if [ "$?" = '0' ] then REAL_ROOT="/dev/nfs" @@ -329,11 +358,16 @@ warn_msg() { } crypt_filter() { - if [ ${CRYPT_SILENT} -eq 1 ] + if [ "${CRYPT_SILENT}" = '1' ] then eval $1 >/dev/null 2>/dev/null else + splash 'verbose' > /dev/null & eval $1 + if [ $? -eq 0 ] + then + splash set_msg 'Disk unlocked.' + fi fi } @@ -383,12 +417,23 @@ setup_hotplug() { fi } -check_slowusb() { - [ "${DO_slowusb}" ] || \ - for x in /sys/bus/usb/drivers/usb-storage/* +setup_slowusb() { + # slowusb already set? + if [ "${DO_slowusb}" = "1" ] + then + return + fi + + local usb_storage_dir="/sys/bus/usb/drivers/usb-storage" + if [ ! -d "${usb_storage_dir}" ] + then + # no automated slowusb required. no usb-storage devices attached. + return + fi + for x in "${usb_storage_dir}"/* do - [ -d "${x}" ] && [ "${x}" != "/sys/bus/usb/drivers/usb-storage/module" ] \ - && FORCE_slowusb="1" + [ -d "${x}" ] && [ "${x}" != "${usb_storage_dir}/module" ] \ + && { DO_slowusb="1" ; break ; } done } @@ -396,11 +441,8 @@ start_dev_mgr() { if [ "${KV_2_6_OR_GREATER}" ] then cd /sys - check_slowusb good_msg 'Activating mdev' runmdev - [ "${DO_slowusb}" ] || \ - [ "${FORCE_slowusb}" ] && sdelay cd / fi } @@ -479,7 +521,7 @@ setup_keymap() { [ "${DEVBIND}" = '1' ] && umount /dev - if [ -e /etc/sysconfig/keyboard -a "${CDROOT}" -eq '1' ] + if [ -e /etc/sysconfig/keyboard -a "${CDROOT}" = '1' ] then mkdir -p ${NEW_ROOT}/etc/sysconfig/ cp /etc/sysconfig/keyboard ${NEW_ROOT}/etc/sysconfig/keyboard @@ -491,6 +533,7 @@ chooseKeymap() { good_msg "Loading keymaps" if [ -z "${keymap}" ] then + splash 'verbose' > /dev/null & cat /lib/keymaps/keymapList read -t 10 -p '<< Load keymap (Enter for default): ' keymap case ${keymap} in @@ -544,17 +587,19 @@ chooseKeymap() { loadkmap < /lib/keymaps/${keymap}.map # xkeymap=${keymap} # echo ${keymap} | egrep -e "[0-9]+" >/dev/null 2>&1 -# if [ "$?" -eq '0' ] +# if [ $? -eq 0 ] # then # xkeymap=`tail -n 7 /lib/keymaps/keymapList | grep ${keymap} | sed -r "s/.*\s+${keymap}\s+([a-z-]+).*/\1/g" | egrep -v 1` # fi mkdir -p /etc/sysconfig # echo "XKEYBOARD=${xkeymap}" > /etc/sysconfig/keyboard echo "XKEYBOARD=${keymap}" > /etc/sysconfig/keyboard + splash set_msg "Set keymap to ${keymap}" elif [ -z "${keymap}" ] then echo good_msg "Keeping default keymap" + splash set_msg "Keeping default keymap" else bad_msg "Sorry, but keymap ''${keymap}'' is invalid!" unset keymap @@ -573,7 +618,7 @@ startVolumes() { ln -sf /dev/device-mapper /dev/mapper/control fi - if [ "${USE_MDADM}" -eq '1' ] + if [ "${USE_MDADM}" = '1' ] then if [ ! -e '/etc/mdadm.conf' ] then @@ -607,7 +652,6 @@ startVolumes() { good_msg "Scanning for Volume Groups" /bin/vgscan --ignorelockingfailure --mknodes 2>/dev/null - sleep 2 good_msg "Activating Volume Groups" /bin/vgchange -ay --ignorelockingfailure 2>/dev/null @@ -678,6 +722,9 @@ startiscsi() { fi iscsistart -i "${ISCSI_INITIATORNAME}" -t "${ISCSI_TARGET}" -a "${ISCSI_ADDRESS}" ${ADDITIONAL} + + # let iscsid settle - otherwise mounting the iSCSI-disk will fail (very rarely, though) + sleep 1 fi } @@ -705,6 +752,7 @@ openLUKS() { [ ! -e /sbin/cryptsetup ] && bad_msg "The ramdisk does not support LUKS" && exit 1 while [ 1 ] do + local gpg_cmd="" # if crypt_silent=1 and some error occurs, enter shell quietly if [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ] then @@ -722,9 +770,36 @@ openLUKS() { whereis "LUKS_KEYDEV" "${LUKS_NAME} key device" KEYDEV_ERROR=0 else + case "${LUKS_DEVICE}" in + UUID\=*|LABEL\=*) + local REAL_LUKS="" + local retval=1 + + if [ "${retval}" -ne 0 ]; then + REAL_LUKS=`findfs "${LUKS_DEVICE}" 2>/dev/null` + retval=$? + fi + + if [ "$retval" -ne 0 ]; then + REAL_LUKS=`busybox findfs "${LUKS_DEVICE}" 2>/dev/null` + retval=$? + fi + + if [ "${retval}" -ne 0 ]; then + REAL_LUKS=`blkid -l -t "${LUKS_DEVICE}" | cut -d ":" -f 1 2>/dev/null` + retval=$? + fi + + if [ "${retval}" -eq 0 ] && [ -n "${REAL_LUKS}" ]; then + good_msg "Detected device ${REAL_LUKS}" + LUKS_DEVICE="${REAL_LUKS}" + fi + ;; + esac + setup_md_device ${LUKS_DEVICE} cryptsetup isLuks ${LUKS_DEVICE} - if [ ! "$?" -eq '0' ] + if [ $? -ne 0 ] then bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT} DEV_ERROR=1 @@ -789,10 +864,17 @@ openLUKS() { fi # At this point a candidate key exists (either mounted before or not) good_msg "${LUKS_KEY} on device ${LUKS_KEYDEV} found" ${CRYPT_SILENT} - cryptsetup_options="-d ${mntkey}${LUKS_KEY}" + if [ $(echo ${LUKS_KEY} | grep -o '.gpg$') = ".gpg" ] && [ -e /sbin/gpg ] ; then + [ -e /dev/tty ] && mv /dev/tty /dev/tty.org + mknod /dev/tty c 5 1 + cryptsetup_options="-d -" + gpg_cmd="/sbin/gpg --logger-file /dev/null --quiet --decrypt ${mntkey}${LUKS_KEY} |" + else + cryptsetup_options="-d ${mntkey}${LUKS_KEY}" + fi fi # At this point, keyfile or not, we're ready! - crypt_filter "cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" + crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}" if [ $? -eq 0 ] then good_msg "LUKS device ${LUKS_DEVICE} opened" ${CRYPT_SILENT} @@ -843,15 +925,15 @@ startLUKS() { } sdelay() { - # Sleep a specific number of seconds if SDELAY is set otherwise only sleep - # 1 second - if [ -n "${SDELAY}" ] + # Sleep a specific number of seconds if SDELAY is set + if [ "${SDELAY}" ] then + good_msg 'Waiting ${SDELAY} seconds...' sleep ${SDELAY} elif grep cdroot /proc/cmdline > /dev/null 2>&1; then sleep 3 else - sleep 1 + good_msg 'Hint: Use parameter scandelay[=seconds] if you need waiting here' fi } @@ -884,6 +966,11 @@ cdupdate() { fi } +setup_btrfsctl() { + # start BTRFS volume detection, if available + [ -x /sbin/btrfsctl ] && /sbin/btrfsctl -a +} + setup_md_device() { local device @@ -897,7 +984,7 @@ setup_md_device() { if [ ! -e /dev/md${MD_NUMBER} ] then mknod /dev/md${MD_NUMBER} b 9 ${MD_NUMBER} >/dev/null 2>&1 - [ "$?" -ne 0 ] && bad_msg "Creation of /dev/md${MD_NUMBER} failed..." + [ $? -ne 0 ] && bad_msg "Creation of /dev/md${MD_NUMBER} failed..." fi mdstart ${MDPART} /dev/md${MD_NUMBER} fi @@ -1058,7 +1145,7 @@ setup_unionfs() { # # mount tmpfs only in the case when changes= boot parameter was # # empty or we were not able to mount the storage device # ret=$? -# if [ "${ret}" -ne 0 ] +# if [ ${ret} -ne 0 ] # then # bad_msg "mount of $CHANGESDEV failed falling back to ramdisk based unionfs" # mount -t tmpfs tmpfs $MEMORY @@ -1083,7 +1170,7 @@ setup_unionfs() { good_msg "Creating union mount" unionfs -o allow_other,cow,noinitgroups,suid,dev,default_permissions,use_ino ${rw_dir}=RW:${ro_dir}=RO ${UNION} 2>/dev/null ret=$? - if [ "${ret}" -ne 0 ] + if [ ${ret} -ne 0 ] then bad_msg "Can't setup union mount!" USE_UNIONFS_NORMAL=0 diff --git a/defaults/kernel-config b/defaults/kernel-config index 5f8c2ad5..62de5e77 100644 --- a/defaults/kernel-config +++ b/defaults/kernel-config @@ -2888,6 +2888,41 @@ CONFIG_ZEROPLUS_FF=y CONFIG_USB_HIDDEV=y # +# Special HID drivers +# +CONFIG_HID_COMPAT=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# # USB HID Boot Protocol drivers # # CONFIG_USB_KBD is not set @@ -3233,10 +3268,10 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4DEV_FS=m -CONFIG_EXT4DEV_FS_XATTR=y -CONFIG_EXT4DEV_FS_POSIX_ACL=y -CONFIG_EXT4DEV_FS_SECURITY=y +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_JBD2=m diff --git a/defaults/linuxrc b/defaults/linuxrc index 4a2ab72b..73796334 100755 --- a/defaults/linuxrc +++ b/defaults/linuxrc @@ -29,12 +29,12 @@ mount -o remount,rw / >/dev/null 2>&1 if [ "$0" = '/init' ] then [ -e /linuxrc ] && rm /linuxrc - - if [ -e /bin/lvm ] - then - ln -s /bin/lvm /bin/vgscan - ln -s /bin/lvm /bin/vgchange - fi +fi + +if [ -e /bin/lvm ] +then + [ -e /bin/vgscan ] || ln -s /bin/lvm /bin/vgscan + [ -e /bin/vgchange ] || ln -s /bin/lvm /bin/vgchange fi quiet_kmsg @@ -80,6 +80,9 @@ do looptype\=*) LOOPTYPE=`parse_opt "${x}"` ;; + isoboot\=*) + ISOBOOT=`parse_opt "${x}"` + ;; # Start Volume manager options dolvm) USE_LVM_NORMAL=1 @@ -114,7 +117,7 @@ do SDELAY=`parse_opt "${x}"` ;; scandelay) - SDELAY=10 + SDELAY=3 ;; # Module no-loads doload\=*) @@ -239,7 +242,7 @@ do # USE_UNIONFS_NORMAL=1 # CMD_UNIONFS=`parse_opt "${x}"` # echo ${CMD_UNIONFS}|grep , >/dev/null 2>&1 -# if [ "$?" -eq '0' ] +# if [ $? -eq 0 ] # then # UID=`echo ${CMD_UNIONFS#*,}` # UNIONFS=`echo ${CMD_UNIONFS%,*}` @@ -251,7 +254,7 @@ do esac done -if [ -z "${REAL_ROOT}" -a \( "${CDROOT}" -eq 0 \) -a \( "${FAKE_ROOT}" != "/dev/ram0" \) ] +if [ -z "${REAL_ROOT}" -a \( "${CDROOT}" = '0' \) -a \( "${FAKE_ROOT}" != "/dev/ram0" \) ] then REAL_ROOT="${FAKE_ROOT}" fi @@ -287,17 +290,23 @@ else good_msg 'Skipping module load; no modules in the ramdisk!' fi -# Delay if needed for USB hardware +# Apply scan delay if specified sdelay +# Setup slow USB bits +setup_slowusb + # Start device manager start_dev_mgr +# if doslowusb is passed, pause other 10 seconds here, after mdev load +[ "${DO_slowusb}" ] && sleep 10 + # Start iSCSI startiscsi -# let iscsid settle - otherwise mounting the iSCSI-disk will fail (very rarely, though) -sleep 1 +# Setup btrfs, see bug 303529 +setup_btrfsctl # start BTRFS volume detection [ -x /sbin/btrfsctl ] && /sbin/btrfsctl -a @@ -322,22 +331,22 @@ then RESUME_DEV="" retval=1 - if [ "${retval}" -ne '0' ]; then + if [ ${retval} -ne 0 ]; then RESUME_DEV=`findfs "${REAL_RESUME}" 2>/dev/null` retval=$? fi - if [ "$retval" -ne '0' ]; then + if [ ${retval} -ne 0 ]; then RESUME_DEV=`busybox findfs "${REAL_RESUME}" 2>/dev/null` retval=$? fi - if [ "${retval}" -ne '0' ]; then - RESUME_DEV=`blkid -t "${REAL_RESUME}" | cut -d ":" -f 1 2>/dev/null` + if [ ${retval} -ne 0 ]; then + RESUME_DEV=`blkid -l -t "${REAL_RESUME}" | cut -d ":" -f 1 2>/dev/null` retval=$? fi - if [ "${retval}" -eq '0' ] && [ -n "${RESUME_DEV}" ]; then + if [ ${retval} -eq 0 ] && [ -n "${RESUME_DEV}" ]; then good_msg "Detected real_resume=${RESUME_DEV}" REAL_RESUME="${RESUME_DEV}" fi @@ -429,22 +438,22 @@ do ROOT_DEV="" retval=1 - if [ "${retval}" -ne '0' ]; then + if [ ${retval} -ne 0 ]; then ROOT_DEV=`findfs "${REAL_ROOT}" 2>/dev/null` retval=$? fi - if [ "$retval" -ne '0' ]; then + if [ ${retval} -ne 0 ]; then ROOT_DEV=`busybox findfs "${REAL_ROOT}" 2>/dev/null` retval=$? fi - if [ "${retval}" -ne '0' ]; then - ROOT_DEV=`blkid -t "${REAL_ROOT}" | cut -d ":" -f 1 2>/dev/null` + if [ ${retval} -ne 0 ]; then + ROOT_DEV=`blkid -l -t "${REAL_ROOT}" | cut -d ":" -f 1 2>/dev/null` retval=$? fi - if [ "${retval}" -eq '0' ] && [ -n "${ROOT_DEV}" ]; then + if [ ${retval} -eq 0 ] && [ -n "${ROOT_DEV}" ]; then good_msg "Detected real_root=${ROOT_DEV}" REAL_ROOT="${ROOT_DEV}" else @@ -660,8 +669,8 @@ then directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}" # Skip this directory if we already linked a parent directory - if [ "${curent_parrent}" != '' ]; then - var=`echo "${directory}" | grep "^${curent_parrent}"` + if [ "${current_parent}" != '' ]; then + var=`echo "${directory}" | grep "^${current_parent}"` if [ "${var}" != '' ]; then continue fi @@ -700,11 +709,6 @@ then # Let Init scripts know that we booted from CD export CDBOOT CDBOOT=1 - check_slowusb - if [ "${DO_slowusb}" ] || [ "${FORCE_slowusb}" ] - then - sleep 10 - fi else if [ "${USE_UNIONFS_NORMAL}" = '1' ] then diff --git a/defaults/modprobe b/defaults/modprobe index 87901220..ba2d890f 100755 --- a/defaults/modprobe +++ b/defaults/modprobe @@ -112,7 +112,7 @@ modprobe2() { done ${INSMOD} ${real_path} > /dev/null 2>&1 ret=$? - if [ "$ret" -eq '0' ] + if [ ${ret} -eq 0 ] then echoAppend=' loaded.' [ "${2}" = '-n' ] && echoFlags='-n' && echoAppend=', ' diff --git a/defaults/modules_load b/defaults/modules_load index 15ad3e5f..47643a1b 100644 --- a/defaults/modules_load +++ b/defaults/modules_load @@ -25,5 +25,5 @@ MODULES_PCMCIA="pcmcia pcmcia_core yenta_socket pd6729 i82092 i82365 tcic ds ide MODULES_USB="ehci-hcd uhci usb-ohci hid usb-storage uhci-hcd ohci-hcd usbhid sl811-hcd" # Filesystems -MODULES_FS="ext2 ext3 reiserfs jfs nfs xfs fuse" +MODULES_FS="ext2 ext3 ext4 reiserfs jfs nfs xfs fuse" diff --git a/doc/asciidoc.conf b/doc/asciidoc.conf new file mode 100644 index 00000000..5835345f --- /dev/null +++ b/doc/asciidoc.conf @@ -0,0 +1,3 @@ +# +# asciidoc.conf for genkernel's man page +# diff --git a/doc/genkernel.8.txt b/doc/genkernel.8.txt new file mode 100644 index 00000000..b36137a9 --- /dev/null +++ b/doc/genkernel.8.txt @@ -0,0 +1,478 @@ +GENKERNEL(8) +============ +:man source: genkernel {genkernelversion} +:man manual: genkernel {genkernelversion} + + +NAME +---- +genkernel - the Gentoo Linux automatic kernel compiler. + + +SYNOPSIS +-------- +*genkernel* [options...] action + + +INTRODUCTION +------------ +Genkernel is designed to allow users who are not previously used to +compiling a kernel to use a similar setup to that one that is used on +the Gentoo LiveCDs which auto-detects your hardware. + +Some users may also be interested in using genkernel for hardware which +requires initialization and a working kernel before it can be booted +because genkernel also automatically compiles your kernel modules, +allowing hardware which needs to be loaded with module parameters to be +used. + + +USAGE +----- +All that is needed to run genkernel is just `genkernel` with an +action and any flags you might need: + +------------------------------------------ +# genkernel --menuconfig --no-clean --no-install all +------------------------------------------ + +This would produce a kernel, asking you what how to configure it to +your desire, leaving alone any existing compiled object files, but not +installing anything. + + +ACTIONS +------- +An action tells genkernel what you want it to do - the following +actions are supported: + +*all*:: + Build all steps - the kernel, modules, and the ramdisk. +*bzImage*:: + Build only the kernel. +*initramfs*:: + Build only the ramdisk/initramfs. +*kernel*:: + Build only the kernel and the modules. +*ramdisk*:: + Build only the ramdisk/initramfs. + + +OPTIONS +------- +Genkernel supports the following options which alter its behaviour. +Certain options have *--no-* variants which do the opposite thing. +You can specify your options in any order. + + +CONFIGURATION OPTIONS +~~~~~~~~~~~~~~~~~~~~~ +*--config*=<file>:: + Genkernel configuration file to use + + +DEBUGGING OPTIONS +~~~~~~~~~~~~~~~~~ +*--loglevel*=<0-5>:: + This controls the out verbosity level of genkernel output - if + this is set to 0, minimal debugging is done; if this is set to 5 + as much output as possible is given. + +*--logfile*=<outfile>:: + This outputs debugging data to the file <outfile>. By default + this is '/var/log/genkernel.log'. + +*--*[*no-*]*color*:: + Turns on, or off, output in color using escape sequences. + + +KERNEL CONFIGURATION +~~~~~~~~~~~~~~~~~~~~ +*--*[*no-*]*menuconfig*:: + Runs, or does not run "make menuconfig" after running "make oldconfig". + +*--*[*no-*]*save-config*:: + Saves, or does not save the kernel configuration to '/etc/kernels' + if the kernel is successfully compiled. + +*--gconfig*:: + Run "make gconfig" after "make oldconfig". + +*--xconfig*:: + Run "make xconfig" after "make oldconfig". + + +KERNEL COMPILATION +~~~~~~~~~~~~~~~~~~ +*--*[*no-*]*clean*:: + Runs, or does not run, "make clean" before compilation - this + erases any compiled object files in the kernel source tree but + does not have an impact on the kernel configuration. Specifying + *--no-clean* implies *--no-mrproper*. + +*--*[*no-*]*mrproper*:: + Runs, or does not run, "make mrproper" before compilation - this + erases both any compiled object files in the kernel source tree + as well as the kernel configuration. + +*--*[*no-*]*install*:: + Installs, or does not install the kernel to '/boot' after building. + The default is *--install*. If MOUNTBOOT is set in + '/etc/genkernel.conf' then '/boot' will be automatically mounted if + it is not already mounted before the ramdisk and kernel images + are copied over. + +*--*[*no-*]*symlink*:: + Manages, or does not manage, symlinks in '/boot' like the manual + kernel "make install" process does. A kernel (or, depending on + options, kernelz) symlink will link to the most recently built + kernel image and a kernel.old (or kernelz.old) symlink will link + to the second most recently built image, if one exists. Similar + symlinks (both * and *.old) are managed for initramfs and System.map. + The corresponding work products (i.e., the actual kernel + and initamfs images, and System.map) are also managed accordingly. + NOTE: Specifying *--symlink* does nothing unless + *--install* is also specified. + +*--oldconfig*:: + Implies *--no-clean*, and thus *--no-mrproper*, running a "make oldconfig". + +*--gensplash*:: + Install framebuffer splash support into initramfs. + +*--*[*no-*]*splash*:: + Installs, or not, framebuffer splash support into initramfs. + +*--no-ramdisk-modules*:: + Don't copy any modules to the ramdisk. + +*--all-ramdisk-modules*:: + Copy all kernel modules to the initrd. + +*--callback*=<...>:: + Run the specified arguments in the current environment after the + kernel and modules have been compiled. + +*--static*:: + This builds a monolithic kernel without any modules on any + initial ramdisks. + + +KERNEL LOCATIONS +~~~~~~~~~~~~~~~~ +*--kerneldir*=<dir>:: + This specifies the location of the kernel sources; the default + is '/usr/src/linux'. + +*--kernel-config*=<file>:: + This specifies a kernel configuration file to use for compilation; + by default genkernel uses the config from the previous + build of the same kernel version or a default kernel config if + there isn't a previous config. + +*--module-prefix*=<dir>:: + Prefix to kernel module destination, modules will be installed in + '<prefix>/lib/modules'. + + +LOW-LEVEL COMPILATION OPTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*--kernel-cc*=<compiler>:: + Compiler to use for the kernel compilation (e.g. distcc). + +*--kernel-as*=<assembler>:: + Assembler to use for the kernel compilation. + +*--kernel-ld*=<linker>:: + Linker to use for the kernel compilation. + +*--kernel-cross-compile*=<cross var>:: + CROSS_COMPILE kernel variable. + +*--kernel-make*=<makeprg>:: + GNU Make to use for the kernel compilation. + +*--utils-cc*=<compiler>:: + Compiler to use for utilities. + +*--utils-as*=<assembler>:: + Assembler to use for utilities. + +*--utils-ld*=<linker>:: + Linker to use for utilities. + +*--utils-make*=<makeprog>:: + GNU Make to use for utilities. + +*--utils-cross-compile*=<cross var>:: + CROSS_COMPILE utils variable. + +*--utils-arch*=<arch>:: + Force to arch for utils only instead of autodetect. + +*--*[*no-*]*mountboot*:: + Mount, or not, BOOTDIR automatically if mountable. + +*--bootdir*=<dir>:: + Set the location of the boot-directory, default is '/boot'. + +*--makeopts*=<makeopts>:: + GNU Make options such as -j2, etc. + + +INITIALIZATION +~~~~~~~~~~~~~~ +*--gensplash*=<theme>:: + Enable framebuffer splash using <theme>. + +*--gensplash-res*=<resolutions>:: + Select gensplash resolutions to include. + +*--*[*no-*]*splash*=<theme>:: + If the extra argument is specified, splash is forced using + <theme> rather than the default theme specified in your splash + configuration. If *--no-splash* is specified, then splash is disabled. + +*--splash-res*=<resolutions>:: + Optionally select splash resolutions to include. + +*--do-keymap-auto*:: + Force keymap selection at boot. + +*--no-keymap*:: + Disables keymap selection at boot. + +*--evms*:: +*--evms2*:: + Add in EVMS support from static binaries if they exist on the system: + you should run "emerge evms" first (in the host system). + +*--lvm*:: +*--lvm2*:: + Add in LVM support from static binaries if they exist on the + system, or compile static LVM binaries if static ones do not + exist. + +*--mdadm*:: + Copy '/etc/mdadm.conf' to initramfs. + +*--dmraid*:: + Add DMRAID support. + +*--multipath*:: + Include Multipath support + +*--iscsi*:: + Include iSCSI support + +*--slowusb*:: + Enables extra pauses for slow USB CD boots. + +*--bootloader*=*grub*:: + Add new kernel to GRUB configuration. + +*--linuxrc*=<file>:: + Use <file> for the linuxrc instead of the genkernel linuxrc. + +*--busybox-config*=<file>:: + Specifies a user created busybox config. + +*--genzimage*:: + Make and install kernelz image from 'arch/powerpc/boot/zImage.initrd'. + +*--disklabel*:: + Include disk label and uuid support in your initrd. + +*--luks*:: + Add in Luks support from static binaries if they exist on the + system. + +*--gpg*:: + Add support for GnuPG 1.x, the portable standalone branch of GnuPG. + A key can be made from + `gpg --encrypt --symmetric /path/to/LUKS-key > /path/to/LUKS-key.gpg` . + After that, re-point the *root_key* argument to the new .gpg file. + +*--no-busybox*:: + Do not include busybox in the initrd or initramfs. + +*--unionfs*:: + Include support for unionfs + +*--netboot*:: + Create a self-contained env in the initramfs + +*--real-root*=<foo>:: + Specify a default for *real_root*= kernel option. + + +INTERNALS +~~~~~~~~~ +*--arch-override*=<arch>:: + Force the architecture settings described by the <arch> profile + instead of autodetecting the running architecture. + +*--cachedir*=<dir>:: + Override the default cache location. + +*--tempdir*=<dir>:: + Sets genkernel's temporary working directory to <dir>. + +*--postclear*:: + Clear all tmp files and caches after genkernel has run. + + +OUTPUT SETTINGS +~~~~~~~~~~~~~~~ +*--kernname*=<...>:: + Tag the kernel and initrd with a name, if not defined this + option defaults to genkernel + +*--minkernpackage*=<tbz2>:: + File to output a .tar.bz2'd kernel and initrd: no modules outside + of the initrd will be included... + +*--modulespackage*=<tbz2>:: + File to output a .tar.bz2'd modules after the callbacks have run + +*--kerncache*=<tbz2>:: + File to output a .tar.bz2'd kernel, contents of '/lib/modules/' + and the kernel config. NOTE: This is created before the callbacks + are run. + +*--no-kernel-sources*=<tbz2>:: + This option is only valid if kerncache is defined If there is a + valid kerncache no checks will be made against a kernel source + tree. + +*--initramfs-overlay*=<dir>:: + Directory structure to include in the initramfs, only available + on 2.6 kernels + +*--firmware*:: + Enable copying of firmware into initramfs. + +*--firmware-dir*=<dir>:: + Specify directory to copy firmware from (defaults to '/lib/firmware'). + +*--firmware-files*=<files>:: + Specifies specific firmware files to copy. This overrides *--firmware-dir*. + For multiple files, separate the filenames with a comma. + +*--integrated-initramfs*:: + Build the generated initramfs into the kernel instead of keeping it as a separate file. + + +RAMDISK OPTIONS +--------------- +The following options can be passed as kernel parameters from the bootloader, +which the ramdisk scripts would recognize. + +*real_root*=<...>:: + Specifies the device node of the root filesystem to mount. + +*crypt_root*=<...>:: + This specifies the device encrypted by Luks, which contains the + root filesystem to mount. + +*crypt_swap*=<...>:: + This specifies the swap device encrypted by Luks. + +*root_key*=<...>:: + In case your root is encrypted with a key, you can use a device + like a usb pen to store the key. This value should be the key + path relative to the mount point. + +*root_keydev*=<...>:: + If necessary provide the name of the device that carries the + root_key. If unset while using root_key, it will automatically + look for the device in every boot. + +*swap_key*=<...>:: + Same as root_key for swap. + +*swap_keydev*=<...>:: + Same as root_keydev for swap. + +*crypt_silent*:: + Set this to silent all the output related to the cryptographic + software, and in case your encrypted device isn't open with the + key, it opens a shell in the initrd quietly. + +*dodmraid*=<...>:: + Passes arguments to dmraid on bootup. + +*real_init*=<...>:: + Passes arguments to init on bootup. + +*scandelay*=<...>:: + Pauses for 10 seconds before running devfsd if no argument is + specified; otherwise pauses for the number of specified seconds. + +*ip*=<...>:: + Normally used to tell the kernel that it should start a network + interface. If present, the initrd will try to mount a livecd + over NFS. + +*nfsroot*=<...>:: + If present, the initrd will try to mount a livecd from that + location. Otherwise the location will be deduced from the DCHP + request (option root-path) + +*doevms*:: + Activate EVMS volumes on bootup + +*dolvm*:: + Activate LVM volumes on bootup + +*doscsi*:: + Activate SCSI devices on bootup, necessary when SCSI support is + compiled as modules and you're using SCSI or SATA devices. + +*keymap*='MAP':: + Set keymap to 'MAP', e.g. *keymap*=de. + For valid values of 'MAP' please see + '/usr/share/genkernel/defaults/keymaps.tar.gz'. + +*dokeymap*:: + Use keymap. Usage of *keymap*= implies this option, already. + + +NETBOOTING +---------- +The initrd scripts have limited support for network booting. This is +activated if the *ip*=<...> kernel parameter was given. Please refer to +the genkernel guide at 'http://www.gentoo.org/doc/en/genkernel.xml' for +more information. + +The initrd scripts will extract any *.tar.gz files found in the '/add' +directory of the livecd into the root filesystem during boot. This way +it is easy to extend a netbooted LiveCD i.e. add custom tools, or other +kernel modules. + + +REPORTING BUGS +-------------- +If you believe you have found a bug in the genkernel scripts, then +please file a bug on the Gentoo Linux Bugzilla: 'http://bugs.gentoo.org', +assigning your bug to genkernel@gentoo.org. We cannot assist you with +kernel compilation failures unless they are caused by a genkernel bug. + +Kernel issues for Gentoo-supported kernels, including compilation failures +should go to 'http://bugs.gentoo.org' and should be assigned to kernel@gentoo.org. +Please check if an existing bug documents the same +issue before opening a new bug. Issues for kernel sources not supported +by Gentoo should go to their relevant authors. + + +AUTHORS +------- +- Tim Yamin <plasmaroo@gentoo.org> +- Eric Edgar <rocket@gentoo.org> +- NFS Support by Thomas Seiler <thseiler@gmail.com> +- GnuPG 1.x integration by dacook <schism@subverted.org> + + +SEE ALSO +-------- +/etc/genkernel.conf - genkernel configuration file diff --git a/gen_bootloader.sh b/gen_bootloader.sh index 9b1deefa..3e6f98b9 100755 --- a/gen_bootloader.sh +++ b/gen_bootloader.sh @@ -63,7 +63,7 @@ set_bootloader_grub() { # Add grub configuration to grub.conf echo "# Genkernel generated entry, see GRUB documentation for details" >> ${GRUB_CONF} echo "title=Gentoo Linux ($KV)" >> ${GRUB_CONF} - if [ "${BUILD_INITRD}" -eq '0' ] + if [ "${BUILD_INITRD}" = '0' ] then echo -e "\tkernel /kernel-${KNAME}-${ARCH}-${KV} root=${GRUB_ROOTFS}" >> ${GRUB_CONF} else diff --git a/gen_cmdline.sh b/gen_cmdline.sh index bb0d8fd7..1bf5de3c 100755 --- a/gen_cmdline.sh +++ b/gen_cmdline.sh @@ -3,12 +3,14 @@ longusage() { echo "Gentoo Linux Genkernel ${GK_V}" + echo echo "Usage: " echo " genkernel [options] action" echo echo "Available Actions: " echo " all Build all steps" echo " bzImage Build only the kernel" + echo " initramfs Build only the ramdisk/initramfs" echo " kernel Build only the kernel and modules" echo " ramdisk Build only the ramdisk/initramfs" echo @@ -90,10 +92,12 @@ longusage() { echo " --bootloader=grub Add new kernel to GRUB configuration" echo " --linuxrc=<file> Specifies a user created linuxrc" echo " --busybox-config=<file> Specifies a user created busybox config" + echo " --genzimage Make and install kernelz image (PowerPC)" echo " --disklabel Include disk label and uuid support in your" echo " ramdisk" echo " --luks Include LUKS support" echo " --> 'emerge cryptsetup-luks' with USE=-dynamic" + echo " --gpg Include GPG-armored LUKS key support" echo " --no-busybox Do not include busybox in the initramfs." echo " --unionfs Include support for unionfs" echo " --netboot Create a self-contained env in the initramfs" @@ -138,6 +142,7 @@ longusage() { usage() { echo "Gentoo Linux Genkernel ${GK_V}" + echo echo "Usage: " echo " genkernel [options] all" echo @@ -307,7 +312,7 @@ parse_cmdline() { if [[ TERM_LINES -lt 19 || TERM_COLUMNS -lt 80 ]] then echo "Error: You need a terminal with at least 80 columns" - echo " and 19 lines for --menuconfig; try --nomenuconfig..." + echo " and 19 lines for --menuconfig; try --no-menuconfig..." exit 1 fi CMD_MENUCONFIG=1 @@ -520,6 +525,10 @@ parse_cmdline() { CMD_LUKS=1 print_info 2 "CMD_LUKS: ${CMD_LUKS}" ;; + --gpg) + CMD_GPG=1 + print_info 2 "CMD_GPG: ${CMD_GPG}" + ;; --firmware) CMD_FIRMWARE=1 print_info 2 "CMD_FIRMWARE: ${CMD_FIRMWARE}" diff --git a/gen_compile.sh b/gen_compile.sh index 7bab9e1c..7438f34d 100755 --- a/gen_compile.sh +++ b/gen_compile.sh @@ -203,6 +203,7 @@ apply_patches() { print_info 1 "${util}: >> Applying patches..." for i in ${GK_SHARE}/patches/${util}/${version}/*{diff,patch} do + [ -f "${i}" ] || continue patch_success=0 for j in `seq 0 5` do @@ -213,8 +214,10 @@ apply_patches() { break fi done - if [ ${patch_success} != 1 ] + if [ ${patch_success} -eq 1 ] then + print_info 1 " - `basename ${i}`" + else gen_die "could not apply patch ${i} for ${util}-${version}" fi done @@ -264,7 +267,7 @@ compile_generic() { eval ${MAKE} ${MAKEOPTS} ${ARGS} ${target} $* >> ${LOGFILE} 2>&1 RET=$? fi - [ "${RET}" -ne '0' ] && + [ ${RET} -ne 0 ] && gen_die "Failed to compile the \"${target}\" target..." unset MAKE @@ -300,6 +303,15 @@ compile_kernel() { compile_generic "${KERNEL_MAKE_DIRECTIVE_2}" kernel fi + local firmware_in_kernel_line=`fgrep CONFIG_FIRMWARE_IN_KERNEL "${KERNEL_DIR}"/.config` + if [ -n "${firmware_in_kernel_line}" -a "${firmware_in_kernel_line}" != CONFIG_FIRMWARE_IN_KERNEL=y ] + then + print_info 1 " >> Installing firmware ('make firmware_install') due to CONFIG_FIRMWARE_IN_KERNEL != y..." + compile_generic "firmware_install" kernel + else + print_info 1 " >> Not installing firmware as it's included in the kernel already (CONFIG_FIRMWARE_IN_KERNEL=y)..." + fi + local tmp_kernel_binary=$(find_kernel_binary ${KERNEL_BINARY}) local tmp_kernel_binary2=$(find_kernel_binary ${KERNEL_BINARY_2}) if [ -z "${tmp_kernel_binary}" ] @@ -405,7 +417,6 @@ compile_busybox() { } compile_lvm() { - compile_device_mapper if [ ! -f "${LVM_BINCACHE}" ] then [ -f "${LVM_SRCTAR}" ] || @@ -421,11 +432,13 @@ compile_lvm() { gen_die "Could not extract device-mapper binary cache!"; cd "${LVM_DIR}" + apply_patches lvm ${LVM_VER} print_info 1 'lvm: >> Configuring...' - LDFLAGS="-L${TEMP}/device-mapper/lib" \ - CFLAGS="-I${TEMP}/device-mapper/include" \ - CPPFLAGS="-I${TEMP}/device-mapper/include" \ - ./configure --enable-static_link --prefix=${TEMP}/lvm >> ${LOGFILE} 2>&1 || + CFLAGS="-fPIC" \ + ./configure --enable-static_link --prefix=${TEMP}/lvm \ + --with-lvm1=internal --with-clvmd=none --with-cluster=none \ + --disable-readline --disable-selinux --with-mirrors=internal \ + --with-snapshots=internal --with-pool=internal >> ${LOGFILE} 2>&1 || \ gen_die 'Configure of lvm failed!' print_info 1 'lvm: >> Compiling...' compile_generic '' utils @@ -502,6 +515,7 @@ compile_device_mapper() { [ ! -d "${DEVICE_MAPPER_DIR}" ] && gen_die "device-mapper directory ${DEVICE_MAPPER_DIR} invalid" cd "${DEVICE_MAPPER_DIR}" + CFLAGS="-fPIC" \ ./configure --prefix=${TEMP}/device-mapper --enable-static_link \ --disable-selinux >> ${LOGFILE} 2>&1 || gen_die 'Configuring device-mapper failed!' @@ -525,8 +539,10 @@ compile_device_mapper() { } compile_e2fsprogs() { - if [ ! -f "${BLKID_BINCACHE}" ] + if [ -f "${BLKID_BINCACHE}" ] then + print_info 1 "blkid: >> Using cache" + else [ ! -f "${E2FSPROGS_SRCTAR}" ] && gen_die "Could not find e2fsprogs source tarball: ${E2FSPROGS_SRCTAR}. Please place it there, or place another version, changing /etc/genkernel.conf as necessary!" cd "${TEMP}" @@ -536,7 +552,7 @@ compile_e2fsprogs() { gen_die "e2fsprogs directory ${E2FSPROGS_DIR} invalid" cd "${E2FSPROGS_DIR}" print_info 1 'e2fsprogs: >> Configuring...' - ./configure --with-ldopts=-static >> ${LOGFILE} 2>&1 || + LDFLAGS=-static ./configure >> ${LOGFILE} 2>&1 || gen_die 'Configuring e2fsprogs failed!' print_info 1 'e2fsprogs: >> Compiling...' MAKE=${UTILS_MAKE} compile_generic "" "" @@ -663,3 +679,46 @@ compile_iscsi() { fi } +compile_gpg() { + if [ -f "${GPG_BINCACHE}" ] + then + print_info 1 "gnupg: >> Using cache" + else + [ ! -f "${GPG_SRCTAR}" ] && + gen_die "Could not find gnupg source tarball: ${GPG_SRCTAR}. Please place it there, or place another version, changing /etc/genkernel.conf as necessary!" + cd "${TEMP}" + rm -rf "${GPG_DIR}" + tar -jxf "${GPG_SRCTAR}" + [ ! -d "${GPG_DIR}" ] && + gen_die "gnupg directory ${GPG_DIR} invalid" + cd "${GPG_DIR}" + print_info 1 'gnupg: >> Configuring...' + # --enable-minimal works, but it doesn't reduce the command length much. + # Given its history and the precision this needs, explicit is cleaner. + LDFLAGS='-static' CFLAGS='-Os' ./configure --prefix=/ \ + --enable-static-rnd=linux --disable-dev-random --disable-asm \ + --disable-selinux-support --disable-gnupg-iconv --disable-card-support \ + --disable-agent-support --disable-bzip2 --disable-exec \ + --disable-photo-viewers --disable-keyserver-helpers --disable-ldap \ + --disable-hkp --disable-finger --disable-generic --disable-mailto \ + --disable-keyserver-path --disable-dns-srv --disable-dns-pka \ + --disable-dns-cert --disable-nls --disable-threads --disable-regex \ + --disable-optimization --with-included-zlib --without-capabilities \ + --without-tar --without-ldap --without-libcurl --without-mailprog \ + --without-libpth-prefix --without-libiconv-prefix --without-libintl-prefix\ + --without-zlib --without-bzip2 --without-libusb --without-readline \ + >> ${LOGFILE} 2>&1 || gen_die 'Configuring gnupg failed!' + print_info 1 'gnupg: >> Compiling...' + compile_generic "" "utils" + print_info 1 'gnupg: >> Copying to cache...' + [ -f "${TEMP}/${GPG_DIR}/g10/gpg" ] || + gen_die 'gnupg executable does not exist!' + strip "${TEMP}/${GPG_DIR}/g10/gpg" || + gen_die 'Could not strip gpg binary!' + bzip2 -z -c "${TEMP}/${GPG_DIR}/g10/gpg" > "${GPG_BINCACHE}" || + gen_die 'Could not copy the gpg binary to the package directory, does the directory exist?' + + cd "${TEMP}" + rm -rf "${GPG_DIR}" > /dev/null + fi +} diff --git a/gen_configkernel.sh b/gen_configkernel.sh index 8c00f8d5..2f14b4d8 100755 --- a/gen_configkernel.sh +++ b/gen_configkernel.sh @@ -29,43 +29,57 @@ config_kernel() { determine_config_file cd "${KERNEL_DIR}" || gen_die 'Could not switch to the kernel directory!' - isTrue "${CLEAN}" && cp "${KERNEL_DIR}/.config" "${KERNEL_DIR}/.config.bak" > /dev/null 2>&1 + # Backup current kernel .config + if isTrue "${MRPROPER}" || [ ! -f "${KERNEL_DIR}/.config" ] + then + print_info 1 "kernel: Using config from ${KERNEL_CONFIG}" + if [ -f "${KERNEL_DIR}/.config" ] + then + NOW=`date +--%Y-%m-%d--%H-%M-%S` + cp "${KERNEL_DIR}/.config" "${KERNEL_DIR}/.config${NOW}.bak" \ + || gen_die "Could not backup kernel config (${KERNEL_DIR}/.config)" + print_info 1 " Previous config backed up to .config${NOW}.bak" + fi + fi + if isTrue ${MRPROPER} then print_info 1 'kernel: >> Running mrproper...' compile_generic mrproper kernel + else + print_info 1 "kernel: --mrproper is disabled; not running 'make mrproper'." fi - # If we're not cleaning, then we don't want to try to overwrite the configs + # If we're not cleaning a la mrproper, then we don't want to try to overwrite the configs # or we might remove configurations someone is trying to test. - - if isTrue "${CLEAN}" + if isTrue "${MRPROPER}" || [ ! -f "${KERNEL_DIR}/.config" ] then - print_info 1 "config: Using config from ${KERNEL_CONFIG}" - print_info 1 ' Previous config backed up to .config.bak' cp "${KERNEL_CONFIG}" "${KERNEL_DIR}/.config" || gen_die 'Could not copy configuration file!' fi + if isTrue "${OLDCONFIG}" then print_info 1 ' >> Running oldconfig...' yes '' 2>/dev/null | compile_generic oldconfig kernel 2>/dev/null + else + print_info 1 "kernel: --oldconfig is disabled; not running 'make oldconfig'." fi if isTrue "${CLEAN}" then print_info 1 'kernel: >> Cleaning...' compile_generic clean kernel else - print_info 1 "config: --no-clean is enabled; leaving the .config alone." + print_info 1 "kernel: --clean is disabled; not running 'make clean'." fi if isTrue ${MENUCONFIG} then - print_info 1 'config: >> Invoking menuconfig...' + print_info 1 'kernel: >> Invoking menuconfig...' compile_generic menuconfig runtask [ "$?" ] || gen_die 'Error: menuconfig failed!' elif isTrue ${CMD_GCONFIG} then - print_info 1 'config: >> Invoking gconfig...' + print_info 1 'kernel: >> Invoking gconfig...' compile_generic gconfig kernel [ "$?" ] || gen_die 'Error: gconfig failed!' @@ -74,7 +88,7 @@ config_kernel() { if isTrue ${CMD_XCONFIG} then - print_info 1 'config: >> Invoking xconfig...' + print_info 1 'kernel: >> Invoking xconfig...' compile_generic xconfig kernel [ "$?" ] || gen_die 'Error: xconfig failed!' fi diff --git a/gen_determineargs.sh b/gen_determineargs.sh index abf3f083..3e39e867 100755 --- a/gen_determineargs.sh +++ b/gen_determineargs.sh @@ -20,6 +20,11 @@ get_KV() { # Configure the kernel # If BUILD_KERNEL=0 then assume --no-clean, menuconfig is cleared + if [ ! -f "${KERNEL_DIR}"/Makefile ] + then + gen_die "Kernel Makefile (${KERNEL_DIR}/Makefile) missing. Maybe re-install the kernel sources." + fi + VER=`grep ^VERSION\ \= ${KERNEL_DIR}/Makefile | awk '{ print $3 };'` PAT=`grep ^PATCHLEVEL\ \= ${KERNEL_DIR}/Makefile | awk '{ print $3 };'` SUB=`grep ^SUBLEVEL\ \= ${KERNEL_DIR}/Makefile | awk '{ print $3 };'` @@ -29,6 +34,7 @@ get_KV() { then # Handle O= build directories KERNEL_SOURCE_DIR=`grep ^MAKEARGS\ \:\= ${KERNEL_DIR}/Makefile | awk '{ print $4 };'` + [ -z "${KERNEL_SOURCE_DIR}" ] && gen_die "Deriving \${KERNEL_SOURCE_DIR} failed" SUB=`grep ^SUBLEVEL\ \= ${KERNEL_SOURCE_DIR}/Makefile | awk '{ print $3 };'` EXV=`grep ^EXTRAVERSION\ \= ${KERNEL_SOURCE_DIR}/Makefile | sed -e "s/EXTRAVERSION =//" -e "s/ //g" -e 's/\$([a-z]*)//gi'` fi @@ -110,6 +116,7 @@ determine_real_args() { set_config_with_override 2 REAL_ROOT CMD_REAL_ROOT set_config_with_override 1 DISKLABEL CMD_DISKLABEL set_config_with_override 1 LUKS CMD_LUKS + set_config_with_override 1 GPG CMD_GPG set_config_with_override 1 MDADM CMD_MDADM set_config_with_override 1 MULTIPATH CMD_MULTIPATH set_config_with_override 1 FIRMWARE CMD_FIRMWARE @@ -133,6 +140,7 @@ determine_real_args() { BLKID_BINCACHE=`cache_replace "${BLKID_BINCACHE}"` FUSE_BINCACHE=`cache_replace "${FUSE_BINCACHE}"` UNIONFS_FUSE_BINCACHE=`cache_replace "${UNIONFS_FUSE_BINCACHE}"` + GPG_BINCACHE=`cache_replace "${GPG_BINCACHE}"` DEFAULT_KERNEL_CONFIG=`arch_replace "${DEFAULT_KERNEL_CONFIG}"` BUSYBOX_CONFIG=`arch_replace "${BUSYBOX_CONFIG}"` @@ -144,6 +152,7 @@ determine_real_args() { BLKID_BINCACHE=`arch_replace "${BLKID_BINCACHE}"` FUSE_BINCACHE=`arch_replace "${FUSE_BINCACHE}"` UNIONFS_FUSE_BINCACHE=`arch_replace "${UNIONFS_FUSE_BINCACHE}"` + GPG_BINCACHE=`arch_replace "${GPG_BINCACHE}"` if [ -n "${CMD_BOOTLOADER}" ] then diff --git a/gen_funcs.sh b/gen_funcs.sh index e4a1c4ac..6af595ef 100755 --- a/gen_funcs.sh +++ b/gen_funcs.sh @@ -94,7 +94,7 @@ print_info() { # PRINT TO SCREEN ONLY IF PASSED LOGLEVEL IS HIGHER THAN # OR EQUAL TO SET DEBUG LEVEL - if [ "$1" -lt "${LOGLEVEL}" -o "$1" -eq "${LOGLEVEL}" ] + if [ "$1" -lt "${LOGLEVEL}" -o "$1" = "${LOGLEVEL}" ] then SCRPRINT='1' fi @@ -106,7 +106,7 @@ print_info() { fi # STRUCTURE DATA TO BE OUTPUT TO SCREEN, AND OUTPUT IT - if [ "${SCRPRINT}" -eq '1' ] + if [ "${SCRPRINT}" = '1' ] then if [ "${PREFIXLINE}" = '1' ] then @@ -124,7 +124,7 @@ print_info() { fi # STRUCTURE DATA TO BE OUTPUT TO FILE, AND OUTPUT IT - if [ "${SCRPRINT}" -eq '1' -o "${FORCEFILE}" -eq '1' ] + if [ "${SCRPRINT}" = '1' -o "${FORCEFILE}" = '1' ] then STRR=${2//${WARN}/} STRR=${STRR//${BAD}/} @@ -140,13 +140,13 @@ print_info() { if [ "${NEWLINE}" = '0' ] then - if [ "${TODEBUGCACHE}" -eq '1' ]; then + if [ "${TODEBUGCACHE}" = '1' ]; then DEBUGCACHE="${DEBUGCACHE}${STR}" else echo -ne "${STR}" >> ${LOGFILE} fi else - if [ "${TODEBUGCACHE}" -eq '1' ]; then + if [ "${TODEBUGCACHE}" = '1' ]; then DEBUGCACHE="${DEBUGCACHE}${STR}"$'\n' else echo "${STR}" >> ${LOGFILE} @@ -250,13 +250,11 @@ setup_cache_dir() if [ "${CLEAR_CACHE_DIR}" == 'yes' ] then print_info 1 "Clearing cache dir contents from ${CACHE_DIR}" - CACHE_DIR_CONTENTS=`ls ${CACHE_DIR}|grep -v CVS|grep -v cpio|grep -v README` - - for i in ${CACHE_DIR_CONTENTS} + while read i do print_info 1 " >> removing ${i}" - rm ${CACHE_DIR}/${i} - done + rm "${i}" + done < <(find "${CACHE_DIR}" -maxdepth 1 -type f -name '*.tar.*' -o -name '*.bz2') fi } @@ -265,13 +263,13 @@ clear_tmpdir() { if ! isTrue ${CMD_NOINSTALL} then - TMPDIR_CONTENTS=`ls ${TMPDIR}` - print_info 1 "Removing tmp dir contents" - for i in ${TMPDIR_CONTENTS} - do - print_info 1 " >> removing ${i}" - rm ${TMPDIR}/${i} - done + TMPDIR_CONTENTS=`ls ${TMPDIR}` + print_info 1 "Removing tmp dir contents" + for i in ${TMPDIR_CONTENTS} + do + print_info 1 " >> removing ${i}" + rm ${TMPDIR}/${i} + done fi } @@ -303,7 +301,7 @@ copy_image_with_preserve() { # Old product might be a different version. If so, we need to read # the symlink to see what it's name is, if there are symlinks. - if [ "${SYMLINK}" -eq '1' ] + if [ "${SYMLINK}" = '1' ] then print_info 4 "automatically managing symlinks and old images." 1 0 if [ -e "${BOOTDIR}/${symlinkName}" ] @@ -349,7 +347,7 @@ copy_image_with_preserve() { # When symlinks are not being managed by genkernel, old symlinks might # still be useful. Leave 'em alone unless managed. - if [ "${SYMLINK}" -eq '1' ] + if [ "${SYMLINK}" = '1' ] then print_info 5 " Deleting old symlinks, if any." rm -f "${BOOTDIR}/${symlinkName}" @@ -367,7 +365,7 @@ copy_image_with_preserve() { # print_info 5 " Same base version. May have to delete old image to make room." - if [ "${currDestImageExists}" -eq '1' ] + if [ "${currDestImageExists}" = '1' ] then if [ -e "${BOOTDIR}/${currDestImage}.old" ] then @@ -395,14 +393,14 @@ copy_image_with_preserve() { cp "${newSrceImage}" "${BOOTDIR}/${currDestImage}" || gen_die "Could not copy the ${symlinkName} image to ${BOOTDIR}!" - if [ "${SYMLINK}" -eq '1' ] + if [ "${SYMLINK}" = '1' ] then print_info 5 " Make new symlink(s) (from ${BOOTDIR}):" print_info 5 " ${symlinkName} -> ${currDestImage}" pushd ${BOOTDIR} >/dev/null ln -s "${currDestImage}" "${symlinkName}" || gen_die "Could not create the ${symlinkName} symlink!" - if [ "${prevDestImageExists}" -eq '1' ] + if [ "${prevDestImageExists}" = '1' ] then print_info 5 " ${symlinkName}.old -> ${prevDestImage}" ln -s "${prevDestImage}" "${symlinkName}.old" || @@ -486,7 +484,7 @@ set_config_with_override() { fi fi - if [ "$VarType" -eq "1" ] + if [ "${VarType}" = "1" ] then if isTrue "${Result}" then @@ -500,7 +498,7 @@ set_config_with_override() { } check_distfiles() { - for i in $BUSYBOX_SRCTAR $DEVICE_MAPPER_SRCTAR $MULTIPATH_SRCTAR $LVM_SRCTAR $DMRAID_SRCTAR $E2FSPROGS_SRCTAR $ISCSI_SRCTAR + for i in $BUSYBOX_SRCTAR $DEVICE_MAPPER_SRCTAR $MULTIPATH_SRCTAR $LVM_SRCTAR $DMRAID_SRCTAR $E2FSPROGS_SRCTAR $ISCSI_SRCTAR $GPG_SRCTAR do if [ ! -f "${i}" ] then diff --git a/gen_initramfs.sh b/gen_initramfs.sh index 820dc047..ac32516e 100755 --- a/gen_initramfs.sh +++ b/gen_initramfs.sh @@ -34,7 +34,9 @@ append_base_layout() { date '+%Y%m%d' > ${TEMP}/initramfs-base-temp/etc/build_date cd "${TEMP}/initramfs-base-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing baselayout cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-base-temp" > /dev/null } @@ -54,14 +56,16 @@ append_busybox() { chmod +x "${TEMP}/initramfs-busybox-temp/usr/share/udhcpc/default.script" # Set up a few default symlinks - for i in '[' ash sh mount uname echo cut cat; do + for i in ${BUSYBOX_APPLETS:-[ ash sh mount uname echo cut cat}; do rm -f ${TEMP}/initramfs-busybox-temp/bin/$i > /dev/null - ln ${TEMP}/initramfs-busybox-temp/bin/busybox ${TEMP}/initramfs-busybox-temp/bin/$i || + ln -s busybox ${TEMP}/initramfs-busybox-temp/bin/$i || gen_die "Busybox error: could not link ${i}!" done cd "${TEMP}/initramfs-busybox-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing busybox cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-busybox-temp" > /dev/null } @@ -72,11 +76,13 @@ append_blkid(){ fi cd ${TEMP} mkdir -p "${TEMP}/initramfs-blkid-temp/bin/" - [ "${DISKLABEL}" -eq '1' ] && { /bin/bzip2 -dc "${BLKID_BINCACHE}" > "${TEMP}/initramfs-blkid-temp/bin/blkid" || + [ "${DISKLABEL}" = '1' ] && { /bin/bzip2 -dc "${BLKID_BINCACHE}" > "${TEMP}/initramfs-blkid-temp/bin/blkid" || gen_die "Could not extract blkid binary cache!"; } chmod a+x "${TEMP}/initramfs-blkid-temp/bin/blkid" cd "${TEMP}/initramfs-blkid-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing blkid cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-blkid-temp" > /dev/null } @@ -89,7 +95,8 @@ append_blkid(){ # mkdir -p "${TEMP}/initramfs-fuse-temp/lib/" # tar -C "${TEMP}/initramfs-fuse-temp/lib/" -xjf "${FUSE_BINCACHE}" # cd "${TEMP}/initramfs-fuse-temp/" -# find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" +# find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ +# || gen_die "compressing fuse cpio" # rm -rf "${TEMP}/initramfs-fuse-temp" > /dev/null #} @@ -104,7 +111,9 @@ append_unionfs_fuse() { gen_die 'Could not extract unionfs-fuse binary cache!' chmod a+x "${TEMP}/initramfs-unionfs-fuse-temp/sbin/unionfs" cd "${TEMP}/initramfs-unionfs-fuse-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing unionfs fuse cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-unionfs-fuse-temp" > /dev/null } @@ -122,7 +131,8 @@ append_unionfs_fuse() { # cp -f /etc/suspend.conf "${TEMP}/initramfs-suspend-temp/etc" || # gen_die 'Could not copy /etc/suspend.conf' # cd "${TEMP}/initramfs-suspend-temp/" -# find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" +# find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ +# || gen_die "compressing suspend cpio" # rm -r "${TEMP}/initramfs-suspend-temp/" #} @@ -175,7 +185,9 @@ append_multipath(){ cp /etc/scsi_id.config "${TEMP}/initramfs-multipath-temp/etc/" || gen_die 'could not copy scsi_id.config' fi cd "${TEMP}/initramfs-multipath-temp" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing multipath cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-multipath-temp/" } @@ -197,7 +209,9 @@ append_dmraid(){ ln -sf raid456.kp raid45.ko cd "${TEMP}/initramfs-dmraid-temp/" fi - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing dmraid cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-dmraid-temp/" } @@ -214,7 +228,9 @@ append_iscsi(){ gen_die "Could not extract iscsi binary cache!" chmod a+x "${TEMP}/initramfs-iscsi-temp/bin/iscsistart" cd "${TEMP}/initramfs-iscsi-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing iscsi cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-iscsi-temp" > /dev/null } @@ -228,16 +244,16 @@ append_lvm(){ mkdir -p "${TEMP}/initramfs-lvm-temp/etc/lvm/" if [ -e '/sbin/lvm.static' ] then - print_info 1 ' LVM: Adding support (using local static binaries)...' + print_info 1 ' LVM: Adding support (using local static binary /sbin/lvm.static)...' cp /sbin/lvm.static "${TEMP}/initramfs-lvm-temp/bin/lvm" || gen_die 'Could not copy over lvm!' elif [ -e '/sbin/lvm' ] && LC_ALL="C" ldd /sbin/lvm|grep -q 'not a dynamic executable' then - print_info 1 ' LVM: Adding support (using local static binaries)...' + print_info 1 ' LVM: Adding support (using local static binary /sbin/lvm)...' cp /sbin/lvm "${TEMP}/initramfs-lvm-temp/bin/lvm" || gen_die 'Could not copy over lvm!' else - print_info 1 ' LVM: Adding support (compiling binaries)...' + print_info 1 ' LVM: Adding support (compiling binaries)...' compile_lvm /bin/tar -jxpf "${LVM_BINCACHE}" -C "${TEMP}/initramfs-lvm-temp" || gen_die "Could not extract lvm binary cache!"; @@ -257,7 +273,9 @@ append_lvm(){ # fi fi cd "${TEMP}/initramfs-lvm-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing lvm cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-lvm-temp/" } @@ -270,7 +288,7 @@ append_evms(){ mkdir -p "${TEMP}/initramfs-evms-temp/etc/" mkdir -p "${TEMP}/initramfs-evms-temp/bin/" mkdir -p "${TEMP}/initramfs-evms-temp/sbin/" - if [ "${EVMS}" -eq '1' ] + if [ "${EVMS}" = '1' ] then print_info 1 ' EVMS: Adding support...' mkdir -p ${TEMP}/initramfs-evms-temp/lib @@ -308,7 +326,9 @@ append_evms(){ done fi cd "${TEMP}/initramfs-evms-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing evms cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-evms-temp/" } @@ -319,13 +339,15 @@ append_mdadm(){ fi cd ${TEMP} mkdir -p "${TEMP}/initramfs-mdadm-temp/etc/" - if [ "${MDADM}" -eq '1' ] + if [ "${MDADM}" = '1' ] then cp -a /etc/mdadm.conf "${TEMP}/initramfs-mdadm-temp/etc" \ || gen_die "Could not copy mdadm.conf!" fi cd "${TEMP}/initramfs-mdadm-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing mdadm cpio" + cd "${TEMP}" rm -rf "${TEMP}/initramfs-mdadm-temp" > /dev/null } @@ -352,6 +374,7 @@ append_splash(){ cd "${TEMP}/initramfs-splash-temp/" find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ || gen_die "compressing splash cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-splash-temp/" else print_warning 1 ' >> No splash detected; skipping!' @@ -360,7 +383,8 @@ append_splash(){ append_overlay(){ cd ${INITRAMFS_OVERLAY} - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing overlay cpio" } append_luks() { @@ -423,9 +447,29 @@ append_firmware() { fi find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ || gen_die "appending firmware to cpio" + cd "${TEMP}" rm -r "${TEMP}/initramfs-firmware-temp/" } +append_gpg() { + if [ -d "${TEMP}/initramfs-gpg-temp" ] + then + rm -r "${TEMP}/initramfs-gpg-temp" + fi + cd ${TEMP} + mkdir -p "${TEMP}/initramfs-gpg-temp/sbin/" + if [ ! -e ${GPG_BINCACHE} ] ; then + print_info 1 ' GPG: Adding support (compiling binaries)...' + compile_gpg + fi + bzip2 -dc "${GPG_BINCACHE}" > "${TEMP}/initramfs-gpg-temp/sbin/gpg" || + gen_die 'Could not extract gpg binary cache!' + chmod a+x "${TEMP}/initramfs-gpg-temp/sbin/gpg" + cd "${TEMP}/initramfs-gpg-temp/" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + rm -rf "${TEMP}/initramfs-gpg-temp" > /dev/null +} + print_list() { local x @@ -474,7 +518,8 @@ append_modules() { print_list ${!group_modules} > "${TEMP}/initramfs-modules-${KV}-temp/etc/modules/${group}" done cd "${TEMP}/initramfs-modules-${KV}-temp/" - find . | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing modules cpio" cd "${TEMP}" rm -r "${TEMP}/initramfs-modules-${KV}-temp/" } @@ -579,7 +624,8 @@ append_auxilary() { fi cd "${TEMP}/initramfs-aux-temp/" - find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" + find . -print | cpio ${CPIO_ARGS} --append -F "${CPIO}" \ + || gen_die "compressing auxilary cpio" cd "${TEMP}" rm -r "${TEMP}/initramfs-aux-temp/" } @@ -592,7 +638,7 @@ append_data() { if [ $# -eq 1 ] || isTrue ${var} then print_info 1 " >> Appending ${name} cpio data..." - ${func} + ${func} || gen_die "${func}() failed" fi } @@ -614,8 +660,9 @@ create_initramfs() { append_data 'mdadm' "${MDADM}" append_data 'luks' "${LUKS}" append_data 'multipath' "${MULTIPATH}" + append_data 'gpg' "${GPG}" - if [ "${NORAMDISKMODULES}" -eq '0' ] + if [ "${NORAMDISKMODULES}" = '0' ] then append_data 'modules' else diff --git a/gen_package.sh b/gen_package.sh index 60cbce02..a0a6bd04 100755 --- a/gen_package.sh +++ b/gen_package.sh @@ -31,7 +31,7 @@ gen_minkernpackage() { if ! isTrue "${INTEGRATED_INITRAMFS}" then - [ "${BUILD_RAMDISK}" -ne 0 ] && { cp "${TMPDIR}/initramfs-${KV}" "${TEMP}/minkernpackage/initramfs-${ARCH}-${KV}" || gen_die 'Could not copy the initramfs for the kernel package!'; } + [ "${BUILD_RAMDISK}" != '0' ] && { cp "${TMPDIR}/initramfs-${KV}" "${TEMP}/minkernpackage/initramfs-${ARCH}-${KV}" || gen_die 'Could not copy the initramfs for the kernel package!'; } fi if [ "${KERNCACHE}" != "" ] @@ -2,7 +2,7 @@ # $Id$ PATH="${PATH}:/sbin:/usr/sbin" -GK_V='3.4.10.908' +GK_V='3.4.11.1' # Set the default for TMPDIR. May be modified by genkernel.conf or the # --tempdir command line option. @@ -86,7 +86,7 @@ do done # Check if no action is specified... -if [ "${BUILD_KERNEL}" -eq '0' -a "${BUILD_RAMDISK}" -eq '0' ] +if [ "${BUILD_KERNEL}" = '0' -a "${BUILD_RAMDISK}" = '0' ] then usage exit 1 @@ -200,7 +200,7 @@ then gen_kerncache_is_valid fi -if [ ${BUILD_KERNEL} -eq '1' -a "${KERNCACHE_IS_VALID}" == "0" ] +if [ ${BUILD_KERNEL} = '1' -a "${KERNCACHE_IS_VALID}" = '0' ] then # Configure kernel config_kernel @@ -217,12 +217,12 @@ then compile_kernel # Compile modules - if [ ${BUILD_MODULES} -eq '1' -a ${BUILD_STATIC} -eq '0' ] + if [ "${BUILD_MODULES}" = '1' -a "${BUILD_STATIC}" = '0' ] then compile_modules fi - if [ ${SAVE_CONFIG} -eq '1' ] + if [ "${SAVE_CONFIG}" = '1' ] then print_info 1 "Copying config for successful build to /etc/kernels/kernel-config-${ARCH}-${KV}" [ ! -e '/etc/kernels' ] && mkdir -p /etc/kernels @@ -240,7 +240,7 @@ fi if [ "${KERNCACHE}" != "" -a "${KERNCACHE_IS_VALID}" != "0" ] then - [ ${BUILD_STATIC} -eq '0' ] && gen_kerncache_extract_modules + [ "${BUILD_STATIC}" = '0' ] && gen_kerncache_extract_modules gen_kerncache_extract_config fi @@ -254,13 +254,13 @@ then CALLBACK_COUNT=0 trap "CALLBACK_ESCAPE=1" TERM KILL INT QUIT ABRT - while [[ ${CALLBACK_ESCAPE} -eq '0' && ${CALLBACK_COUNT} -lt 5 ]] + while [[ "${CALLBACK_ESCAPE}" = '0' && ${CALLBACK_COUNT} -lt 5 ]] do sleep 1; echo -n '.'; let CALLBACK_COUNT=${CALLBACK_COUNT}+1 done - if [ "${CALLBACK_ESCAPE}" -eq '0' ] + if [ "${CALLBACK_ESCAPE}" = '0' ] then echo echo @@ -268,7 +268,7 @@ then CMD_STATUS="${PIPESTATUS[0]}" echo print_info 1 "<<< Callback exit status: ${CMD_STATUS}" - [ "${CMD_STATUS}" -ne 0 ] && gen_die '--callback failed!' + [ "${CMD_STATUS}" != '0' ] && gen_die '--callback failed!' else echo print_info 1 ">>> Callback cancelled..." @@ -277,11 +277,11 @@ then print_info 1 "" 1 0 fi -if [ "${BUILD_RAMDISK}" -eq '1' ] +if [ "${BUILD_RAMDISK}" = '1' ] then - [ "${DISKLABEL}" -eq '1' ] && compile_e2fsprogs + [ "${DISKLABEL}" = '1' ] && compile_e2fsprogs - if [ "${BUSYBOX}" -eq '1' ] + if [ "${BUSYBOX}" = '1' ] then # Compile Busybox compile_busybox @@ -298,7 +298,7 @@ else print_info 1 'initrd: Not building since only the kernel was requested...' fi -if isTrue "${INTEGRATED_INITRAMFS}" #|| [ ${BUILD_KERNEL} -eq '1' -a "${KERNCACHE_IS_VALID}" == "0" ] +if isTrue "${INTEGRATED_INITRAMFS}" #|| [ "${BUILD_KERNEL}" = '1' -a "${KERNCACHE_IS_VALID}" == "0" ] then # We build the kernel a second time to include the initramfs compile_kernel @@ -311,14 +311,17 @@ fi # Clean up... [ -n "${CTEMP}" ] && rm -rf "${TEMP}" -if [ "${BUILD_KERNEL}" -eq '1' ] +if [ "${BUILD_KERNEL}" = '1' ] then - set_bootloader + if ! isTrue "${CMD_NOINSTALL}" + then + set_bootloader + fi print_info 1 '' print_info 1 "Kernel compiled successfully!" print_info 1 '' print_info 1 'Required Kernel Parameters:' - if [ "${BUILD_RAMDISK}" -eq '0' ] + if [ "${BUILD_RAMDISK}" = '0' ] then print_info 1 ' root=/dev/$ROOT' print_info 1 ' [ And "vga=0x317 splash=verbose" if you use a framebuffer ]' @@ -338,17 +341,17 @@ then fi fi -if [ "${BUILD_RAMDISK}" -eq '1' ] +if [ "${BUILD_RAMDISK}" = '1' ] then echo print_info 1 'WARNING... WARNING... WARNING...' print_info 1 'Additional kernel cmdline arguments that *may* be required to boot properly...' - [ "${SPLASH}" -eq '1' ] && print_info 1 "add \"vga=791 splash=silent,theme:${SPLASH_THEME} console=tty1 quiet\" if you use a splash framebuffer ]" - [ "${LVM}" -eq '1' ] && print_info 1 'add "dolvm" for lvm support' - [ "${EVMS}" -eq '1' ] && print_info 1 'add "doevms" for evms support' - [ "${DMRAID}" -eq '1' ] && print_info 1 'add "dodmraid" for dmraid support' - [ "${DMRAID}" -eq '1' ] && print_info 1 ' or "dodmraid=<additional options>"' - [ "${ISCSI}" -eq '1' ] && print_info 1 'add at least "iscsi_initiatorname=<initiator name> iscsi_target=<target name> and iscsi_address=<target ip>" for iscsi support' + [ "${SPLASH}" = '1' ] && print_info 1 "add \"vga=791 splash=silent,theme:${SPLASH_THEME} console=tty1 quiet\" if you use a splash framebuffer ]" + [ "${LVM}" = '1' ] && print_info 1 'add "dolvm" for lvm support' + [ "${EVMS}" = '1' ] && print_info 1 'add "doevms" for evms support' + [ "${DMRAID}" = '1' ] && print_info 1 'add "dodmraid" for dmraid support' + [ "${DMRAID}" = '1' ] && print_info 1 ' or "dodmraid=<additional options>"' + [ "${ISCSI}" = '1' ] && print_info 1 'add at least "iscsi_initiatorname=<initiator name> iscsi_target=<target name> and iscsi_address=<target ip>" for iscsi support' fi [ "${BOOTRW}" != '' ] && mount -o remount,ro ${BOOTDIR} diff --git a/genkernel.8 b/genkernel.8 deleted file mode 100644 index 4dba331e..00000000 --- a/genkernel.8 +++ /dev/null @@ -1,329 +0,0 @@ -.TH GENKERNEL "8" "June 2006" "genkernel 3.3" "Gentoo Linux" -.SH NAME -genkernel \- the Gentoo Linux automatic kernel compiler. -.SH SYNOPSIS -\fBgenkernel\fR \fI[options...] action\fR -.SH INTRODUCTION -Genkernel is designed to allow users who are not previously used to -compiling a kernel to use a similar setup to that one that is used on -the Gentoo LiveCDs which auto-detects your hardware. -.PP -Some users may also be interested in using genkernel for hardware -which requires initialization and a working kernel before it can be -booted because genkernel also automatically compiles your kernel -modules, allowing hardware which needs to be loaded with module -parameters to be used. -.SH USAGE -All that is needed to run genkernel is just ``genkernel'' with an action -and any flags you might need: -.PP -# genkernel --menuconfig --no-clean --no-install all -.PP -This would produce a kernel, asking you what how to configure it -to your desire, leaving alone any existing compiled object files, but not -installing anything. -.SH ACTIONS -An action tells genkernel what you want it to do - the following -actions are supported: -.PP -.I \fBall\fR -.RS -Build all steps - the kernel, modules, and the ramdisk. -.RE -.I \fBbzImage\fR -.RS -Build only the kernel. -.RE -.I \fBkernel\fR -.RS -Build only the kernel and the modules. -.RE -.I \fBinitramfs\fR -.RS -Build only the ramdisk. -.RE -.SH OPTIONS -Genkernel supports the following options which alter its -behaviour. Certain options have ``\fB--no-\fR'' variants which -do the opposite thing. You can specify your options in any order. -.PP -.BR Debugging \ Options -.TP -\fB\-\-loglevel=\fR<0-5> -This controls the out verbosity level of genkernel output - if this is set -to 0, minimal debugging is done; if this is set to 5 as much output as -possible is given. -.TP -\fB\-\-logfile=\fR<outfile> -This outputs debugging data to the file <outfile>. By default this is -.I /var/log/genkernel.log\fR. -.TP -\fB\-\-\fR[no\-]\fBcolor\fR -Turns on, or off, output in color using escape sequences. -.PP -.BR Kernel \ Configuration -.TP -\fB\-\-\fR[no\-]\fBmenuconfig\fR -Runs, or does not run "make menuconfig" after running "make oldconfig". -.TP -\fB\-\-\fR[no\-]\fBsave\-config\fR -Saves, or does not save the kernel configuration to -.I /etc/kernels -if the kernel is successfully compiled. -.TP -\fB\-\-gconfig\fR -Run "make gconfig" after "make oldconfig". -.TP -\fB\-\-xconfig\fR -Run "make xconfig" after "make oldconfig". -.PP -.BR Kernel \ Compilation -.TP -\fB\-\-\fR[no\-]\fBclean\fR -Runs, or does not run, "make clean" before compilation - this erases any -compiled object files in the kernel source tree but does not have an impact -on the kernel configuration. Specifying \fB\-\-no\-clean\fR implies -\fB\-\-no\-mrproper\fR. -.TP -\fB\-\-\fR[no\-]\fBmrproper\fR -Runs, or does not run, "make mrproper" before compilation - this erases both -any compiled object files in the kernel source tree as well as the kernel -configuration. -.TP -\fB\-\-\fR[no\-]\fBinstall\fR -Installs, or does not install the kernel to -.I /boot -after building. The default is --install. If MOUNTBOOT is set in -.I /etc/genkernel.conf -then -.I /boot -will be automatically mounted if it is -not already mounted before the ramdisk and kernel images are copied over. -.TP -\fB\-\-\fR[no\-]\fBsymlink\fR -Manages, or does not manage, symlinks in -.I /boot -like the manual kernel "make install" process does. A -.I kernel -(or, depending on options, -.I kernelz\fR) -symlink will link to the most recently built kernel image and a -.I kernel.old -(or -.I kernelz.old\fR) -symlink will link to the second most recently built image, if one exists. -Similar symlinks (both * and *.old) are managed for -.I initramfs\fR -and -.I System.map\f. -The corresponding work products (i.e., the actual kernel and initamfs images, -and System.map) are also managed accordingly. NOTE: Specifying --symlink -does nothing unless --install is also specified. -.TP -\fB\-\-no\-initrdmodules\fR -Don't copy any modules to the ramdisk. -.TP -\fB\-\-oldconfig\fR -Implies \fB\-\-no\-clean\fR, and thus \fB\-\-no\-mrproper\fR, running a -"make oldconfig". -.TP -\fB\-\-callback=\fR<...> -Run the specified arguments in the current environment after the kernel and -modules have been compiled. -.PP -.BR Kernel \ Locations -.TP -\fB\-\-kerneldir=\fR<dir> -This specifies the location of the kernel sources; the default is -/usr/src/linux. -.TP -\fB\-\-kernel\-config=\fR<file> -This specifies a kernel configuration file to use for compilation; by -default genkernel uses the config from the previous build of the same kernel -version or a default kernel config if there isn't a previous config. -.PP -.BR Low-Level \ Compilation \ Options -.TP -\fB\-\-kernel\-cc=\fR<compiler> -Compiler to use for the kernel compilation (e.g. distcc). -.TP -\fB\-\-kernel\-as=\fR<assembler> -Assembler to use for the kernel compilation. -.TP -\fB\-\-kernel\-ld=\fR<linker> -Linker to use for the kernel compilation. -.TP -\fB\-\-kernel\-make=\fR<makeprg> -GNU Make to use for the kernel compilation. -.TP -\fB\-\-utils\-cc=\fR<compiler> -Compiler to use for utilities. -.TP -\fB\-\-utils\-as=\fR<assembler> -Assembler to use for utilities. -.TP -\fB\-\-utils\-ld=\fR<linker> -Linker to use for utilities. -.TP -\fB\-\-utils\-make=\fR<makeprog> -GNU Make to use for utilities. -.TP -\fB\-\-makeopts=\fR<makeopts> -GNU Make options such as \fB\-j2\fR, etc. -.PP -.BR Initialization -.TP -\fB\-\-\fR[no\-]\fBsplash=\fR<theme> -If the extra argument is specified, splash is forced using <theme> -rather than the default theme specified in your splash -configuration. If \fB\-\-no-splash\fR is specified, then -splash is disabled. -.TP -\fB\-\-splash-res=\fR<resolutions> -Optionally select splash resolutions to include. -.TP -\fB\-\-do\-keymap\-auto\fR -Force keymap selection at boot. -.TP -\fB\-\-dmraid\fR -Add DMRAID support. -.TP -\fB\-\-evms\fR -Add in EVMS support from static binaries if they exist on the system: -you should run "emerge evms" first. -.TP -\fB\-\-lvm\fR -.RS -Add in LVM support from static binaries if they exist on the system, -or compile static LVM binaries if static ones do not exist. -.RE -.TP -\fB\-\-luks\fR -.RS -Add in Luks support from static binaries if they exist on the -system. -.RE -.TP -\fB\-\-static\fR -This builds a monolithic kernel without any modules on any initial ramdisks. -.TP -\fB\-\-linuxrc=\fR<file> -Use <file> for the linuxrc instead of the genkernel linuxrc. -.PP -.BR Internals -.TP -\fB\-\-arch\-override=\fR<arch> -Force the architecture settings described by the <arch> profile -instead of autodetecting the running architecture. -.TP -\fB\-\-tempdir=\fR<dir> -Sets genkernel's temporary working directory to <dir>. -.PP -.BR Output \ Settings -.TP -\fB\-\-kernname=\fR<...> -Tag the kernel and initrd with a name, if not defined this option defaults to genkernel -.TP -\fB\-\-minkernpackage=\fR<tbz2> -File to output a .tar.bz2'd kernel and initrd: no modules outside of the -initrd will be included... -.TP -\fB\-\-modulespackage=\fR<tbz2> -File to output a .tar.bz2'd modules after the callbacks have run -.TP -\fB\-\-kerncache=\fR<tbz2> -File to output a .tar.bz2'd kernel, contents of /lib/modules/ and the kernel config. -\fBNOTE\fR: This is created before the callbacks are run. -.TP -\fB\-\-no\-kernel\-sources=\fR<tbz2> -This option is only valid if kerncache is defined -If there is a valid kerncache no checks will be made -against a kernel source tree. -.TP -\fB\-\-initramfs\-overlay=\fR<dir> -Directory structure to include in the initramfs, -only available on 2.6 kernels -.SH RAMDISK OPTIONS -The following options can be passed as kernel parameters from the -bootloader, which the ramdisk scripts would recognize. -.TP -\fBreal_root=\fR<...> -Specifies the device node of the root filesystem to mount. -.TP -\fBcrypt_root=\fR<...> -This specifies the device encrypted by Luks, which contains the root -filesystem to mount. -.TP -\fBcrypt_swap=\fR<...> -This specifies the swap device encrypted by Luks. -.TP -\fBroot_key=\fR<...> -In case your root is encrypted with a key, you can use a device like a usb pen to store the key. -This value should be the key path relative to the mount point. -.TP -\fBroot_keydev=\fR<...> -If necessary provide the name of the device that carries the root_key. -If unset while using root_key, it will automatically look for the device in every boot. -.TP -\fBswap_key=\fR<...> -Same as root_key for swap. -.TP -\fBswap_keydev=\fR<...> -Same as root_keydev for swap. -.TP -\fBcrypt_silent\fR -Set this to silent all the output related to the cryptographic software, and in case your encrypted device isn't open with the key, it opens a shell in the initrd quietly. -.TP -\fBdodmraid=\fR<...> -Passes arguments to dmraid on bootup. -.TP -\fBreal_init=\fR<...> -Passes arguments to init on bootup. -.TP -\fBscandelay=\fR<...> -Pauses for 10 seconds before running devfsd if no argument is specified; -otherwise pauses for the number of specified seconds. -.TP -\fBip=\fR<...> -Normally used to tell the kernel that it should start a network interface. If present, the initrd will try to mount a livecd over NFS. -.TP -\fBnfsroot=\fR<...> -If present, the initrd will try to mount a livecd from that location. Otherwise the location will be deduced from the DCHP request (option root\-path) -.TP -\fBdoevms\fR -Activate EVMS volumes on bootup -.TP -\fBdolvm\fR -Activate LVM volumes on bootup -.TP -\fBdoscsi\fR -Activate SCSI devices on bootup, necessary when SCSI support is compiled as modules and you're using SCSI or SATA devices. - -.SH NETBOOTING -The initrd scripts have limited support for network booting. -This is activated if the ip=<...> kernel parameter was given. Please refer to the genkernel guide at http://www.gentoo.org/doc/en/genkernel.xml for more information. - -The initrd scripts will extract any *.tar.gz files found in the \fB/add\fR directory of the livecd into the root filesystem during boot. This way it is easy to extend a netbooted LiveCD i.e. add custom tools, or other kernel modules. -.SH REPORTING BUGS -If you believe you have found a bug in the genkernel scripts, then please -file a bug on the Gentoo Linux Bugzilla: -.I http://bugs.gentoo.org\fR, -assigning your bug to genkernel@gentoo.org. We cannot assist you -with kernel compilation failures unless they are caused by a genkernel -bug. -.PP -Kernel issues for Gentoo-supported kernels, including compilation -failures should go to -.I http://bugs.gentoo.org -and should be assigned to kernel@gentoo.org. Please check if an -existing bug documents the same issue before opening a new bug. Issues -for kernel sources not supported by Gentoo should go to their relevant -authors. -.SH AUTHORS -.nf -Tim Yamin <plasmaroo@gentoo.org> -Eric Edgar <rocket@gentoo.org> -NFS Support by Thomas Seiler <thseiler@gmail.com> -.fi -.SH SEE ALSO -\fB/etc/genkernel.conf\fR \- genkernel configuration file diff --git a/genkernel.conf b/genkernel.conf index a71ce69b..2bc81838 100644 --- a/genkernel.conf +++ b/genkernel.conf @@ -53,6 +53,12 @@ USECOLOR="yes" # compile static LVM binaries if static ones do not exist. # LVM="no" +# Add in Luks support. Needs sys-fs/cryptsetup with -dynamic installed. +# LUKS="no" + +# Add in GnuPG support +# GPG="no" + # Add in EVMS support from static binaries if they exist on the system: you # should run "emerge evms" first. # EVMS="no" @@ -130,7 +136,7 @@ DISKLABEL="yes" #BOOTDIR="/boot" # Default share directory location -GK_SHARE="/usr/share/genkernel" +GK_SHARE="${GK_SHARE:-/usr/share/genkernel}" # Location of the default cache CACHE_DIR="/var/cache/genkernel" @@ -151,6 +157,7 @@ BUSYBOX_VER="VERSION_BUSYBOX" BUSYBOX_SRCTAR="${DISTDIR}/busybox-${BUSYBOX_VER}.tar.bz2" BUSYBOX_DIR="busybox-${BUSYBOX_VER}" BUSYBOX_BINCACHE="%%CACHE%%/busybox-${BUSYBOX_VER}-%%ARCH%%.tar.bz2" +# BUSYBOX_APPLETS="[ ash sh mount uname echo cut cat" DEVICE_MAPPER_VER="VERSION_DMAP" DEVICE_MAPPER_DIR="device-mapper.${DEVICE_MAPPER_VER}" @@ -186,3 +193,8 @@ UNIONFS_FUSE_VER="VERSION_UNIONFS_FUSE" UNIONFS_FUSE_DIR="unionfs-fuse-${UNIONFS_FUSE_VER}" UNIONFS_FUSE_SRCTAR="${DISTDIR}/unionfs-fuse-${UNIONFS_FUSE_VER}.tar.bz2" UNIONFS_FUSE_BINCACHE="%%CACHE%%/unionfs-fuse-${UNIONFS_FUSE_VER}-%%ARCH%%.bz2" + +GPG_VER="VERSION_GPG" +GPG_DIR="gnupg-${GPG_VER}" +GPG_SRCTAR="${DISTDIR}/gnupg-${GPG_VER}.tar.bz2" +GPG_BINCACHE="%%CACHE%%/gnupg-${GPG_VER}-%%ARCH%%.bz2" diff --git a/maintenance/docmatcher.py b/maintenance/docmatcher.py new file mode 100644 index 00000000..4b6b94e0 --- /dev/null +++ b/maintenance/docmatcher.py @@ -0,0 +1,281 @@ +#! /usr/bin/python +# Copyright (C) 2010 Gentoo Foundation +# Written by Sebastian Pipping <sebastian@pipping.org> +# Licensed under GPL v2 or later + +from __future__ import print_function +import re +import sys +import os + + +NON_VARIABLES = ('UTF', 'USE', 'TCP', 'SMP', 'PXE', 'PPC', 'MAC', + 'GTK', 'GNU', 'CPU', 'DOS', 'NIC', 'NFS', 'ISO', 'TIMEOUT', + 'TFTP', 'SYSTEM', 'SPARC', 'RAID', 'LABEL', 'PROMPT', 'KERNEL', + 'GRP', 'DOCTYPE', 'DHCP', 'DEFAULT', 'ATARAID', 'APPEND') + +EXTRA_VARIABLES = ['ARCH_OVERRIDE', 'BOOTLOADER', 'CLEAR_CACHE_DIR', 'DEFAULT_KERNEL_SOURCE', 'DISTDIR', 'GK_SHARE', 'BUSYBOX_APPLETS'] +for app in ('DEVICE_MAPPER', 'UNIONFS_FUSE', 'BUSYBOX', 'DMRAID', 'LVM', 'ISCSI', 'FUSE', 'GPG'): + for prop in ('DIR', 'SRCTAR', 'VER'): + EXTRA_VARIABLES.append('%s_%s' % (app, prop)) +EXTRA_VARIABLES = tuple(EXTRA_VARIABLES) + +IGNORE_OPTIONS = ('help', 'version') + + +def exract_gen_cmdline_sh(): + f = open('gen_cmdline.sh', 'r') + gen_cmdline_sh = f.read() + f.close() + + usage_lines = list() + parsing_lines = list() + dest = None + + for line in gen_cmdline_sh.split('\n'): + if line in ('longusage() {', 'usage() {'): + dest = usage_lines + elif line == 'parse_cmdline() {': + dest = parsing_lines + + if dest is not None: + dest.append(line) + + if line == '}': + dest = None + + del gen_cmdline_sh + + + parsing_code = '\n'.join(parsing_lines) + del parsing_lines + + gen_cmdline_sh_parsing_long_params = set() + for match in re.finditer('--([a-z][a-z0-9-]+)', parsing_code): + para_name = match.group(1) + if para_name in IGNORE_OPTIONS: + continue + gen_cmdline_sh_parsing_long_params.add(para_name) + + gen_cmdline_sh_variables = set() + for match in re.finditer('^\s*([A-Z_]+)=', parsing_code, re.MULTILINE): + var_name = match.group(1) + if var_name.startswith('CMD_'): + continue + gen_cmdline_sh_variables.add(var_name) + + del parsing_code + + + gen_cmdline_sh_usage_long_params = set() + for match in re.finditer('--([a-z][a-z0-9-]+)', '\n'.join(usage_lines)): + para_name = match.group(1) + if para_name in IGNORE_OPTIONS: + continue + gen_cmdline_sh_usage_long_params.add(para_name) + del usage_lines + + return gen_cmdline_sh_parsing_long_params, gen_cmdline_sh_usage_long_params, gen_cmdline_sh_variables + + +def extract_genkernel_8_txt(): + f = open(os.path.join('doc', 'genkernel.8.txt'), 'r') + genkernel_8_txt = f.read() + f.close() + + # Preprocess + genkernel_8_txt = genkernel_8_txt.replace('*[*no-*]*','[no-]') + + yes_no = re.compile('^\\[(no-)\\]([a-z0-9-]+)$') + + genkernel_8_txt_long_params = set() + for match in re.finditer('--((?:[a-z]|\\[no-\\])[a-z0-9-]+)', genkernel_8_txt): + para_name = match.group(1) + + # Black list + if para_name == 'no-': + continue + + m = yes_no.match(para_name) + if m: + p_yes = m.group(2) + p_no = m.group(1) + m.group(2) + genkernel_8_txt_long_params.add(p_yes) + genkernel_8_txt_long_params.add(p_no) + else: + genkernel_8_txt_long_params.add(para_name) + + del genkernel_8_txt + + return genkernel_8_txt_long_params + + +def extract_genkernel_xml(genkernel_xml_path, variables_blacklist): + f = open(genkernel_xml_path, 'r') + genkernel_xml = f.read() + f.close() + + # Preprocess + genkernel_xml = genkernel_xml.replace('<c>','').replace('</c>','').replace('<b>','').replace('</b>','') + + yes_no = re.compile('^(no-)([a-z0-9-]+)$') + + genkernel_xml_long_params = set() + for match in re.finditer('--([a-z][a-z0-9-]+)', genkernel_xml): + para_name = match.group(1) + + if para_name in IGNORE_OPTIONS: + continue + + # Fix doc error "--no install" + if para_name == 'no': + para_name = 'no-install' + + m = yes_no.match(para_name) + if m and para_name != 'no-ramdisk-modules': + p_yes = m.group(2) + p_no = m.group(1) + m.group(2) + genkernel_xml_long_params.add(p_yes) + genkernel_xml_long_params.add(p_no) + else: + genkernel_xml_long_params.add(para_name) + + genkernel_xml_variables = set() + for match in re.finditer('[A-Z_]{3,}', genkernel_xml): + var_name = match.group(0) + if var_name in variables_blacklist: + continue + genkernel_xml_variables.add(var_name) + + del genkernel_xml + + return genkernel_xml_long_params, genkernel_xml_variables + + +def extract_gen_determineargs_sh(): + f = open('gen_determineargs.sh', 'r') + gen_determineargs_sh = f.read() + f.close() + + gen_determineargs_sh_variables = set() + for match in re.finditer('set_config_with_override\s+[0-9]+\s+([A-Z_]+)', gen_determineargs_sh): + var_name = match.group(1) + gen_determineargs_sh_variables.add(var_name) + + for match in re.finditer('([A-Z_]+)=`(?:arch|cache)_replace "\\$\\{\\1\\}"`', gen_determineargs_sh): + var_name = match.group(1) + gen_determineargs_sh_variables.add(var_name) + + del gen_determineargs_sh + + return gen_determineargs_sh_variables + + +def extract_genkernel_conf(variables_blacklist): + f = open('genkernel.conf', 'r') + genkernel_conf = f.read() + f.close() + + genkernel_conf_variables = set() + for match in re.finditer('^#*\\s*([A-Z_]{3,})', genkernel_conf, re.MULTILINE): + var_name = match.group(1) + if var_name in variables_blacklist: + continue + genkernel_conf_variables.add(var_name) + + del genkernel_conf + + return genkernel_conf_variables + + +def print_set(s): + if s: + print('\n'.join(('- ' + e) for e in sorted(s))) + else: + print(' NONE') + print() + + +def usage(): + print('USAGE: %s GENTOO/xml/htdocs/doc/en/genkernel.xml' % os.path.basename(sys.argv[0])) + + +def main(): + if len(sys.argv) != 2: + usage() + sys.exit(1) + + gen_cmdline_sh_parsing_long_params, gen_cmdline_sh_usage_long_params, gen_cmdline_sh_variables = exract_gen_cmdline_sh() + genkernel_8_txt_long_params = extract_genkernel_8_txt() + gen_determineargs_sh_variables = extract_gen_determineargs_sh() + + variables_blacklist = set(NON_VARIABLES).difference(gen_determineargs_sh_variables) + known_variales = set(EXTRA_VARIABLES).union(gen_determineargs_sh_variables).union(gen_cmdline_sh_variables) + + genkernel_xml_long_params, genkernel_xml_variables = extract_genkernel_xml(sys.argv[1], variables_blacklist) + genkernel_conf_variables = extract_genkernel_conf(variables_blacklist) + + + # Status quo + print('Options used by parser in *gen_cmdline.sh*:') + print_set(gen_cmdline_sh_parsing_long_params) + + print('Options mentioned in usage of *gen_cmdline.sh*:') + print_set(gen_cmdline_sh_usage_long_params) + + print('Options mentioned in *man page*:') + print_set(genkernel_8_txt_long_params) + + print('Options mentioned in *web page*:') + print_set(genkernel_xml_long_params) + + + print('Variables set by *gen_cmdline.sh*:') + print_set(gen_cmdline_sh_variables) + + print('Variables read by *gen_determineargs.sh*:') + print_set(gen_determineargs_sh_variables) + + print('Variables mentioned in *web page*:') + print_set(genkernel_xml_variables) + + print('Variables used in *genkernel.conf*:') + print_set(genkernel_conf_variables) + + + # Future work (due extensions) + print('Options missing from the *man page*:') + print_set(gen_cmdline_sh_parsing_long_params.difference(genkernel_8_txt_long_params)) + + print('Options missing from *--help*:') + print_set(gen_cmdline_sh_parsing_long_params.difference(gen_cmdline_sh_usage_long_params)) + + print('Options missing from *web page*:') + print_set(gen_cmdline_sh_parsing_long_params.difference(genkernel_xml_long_params)) + + print('Variables missing from *web page*:') + print_set(known_variales.difference(genkernel_xml_variables)) + + print('Variables missing from *genkernel.conf*:') + print_set(known_variales.difference(genkernel_conf_variables)) + + + # Future work (due removal and updates) + print('Removed options still mentioned in the *man page*:') + print_set(genkernel_8_txt_long_params.difference(gen_cmdline_sh_parsing_long_params)) + + print('Removed options still mentioned in *--help*:') + print_set(gen_cmdline_sh_usage_long_params.difference(gen_cmdline_sh_parsing_long_params)) + + print('Removed options still mentioned in *web page*:') + print_set(genkernel_xml_long_params.difference(gen_cmdline_sh_parsing_long_params)) + + print('Removed variables still mentioned in *web page*:') + print_set(genkernel_xml_variables.difference(known_variales)) + + print('Removed variables still mentioned in *genkernel.conf*:') + print_set(genkernel_conf_variables.difference(known_variales)) + + +if __name__ == '__main__': + main() diff --git a/patches/busybox/1.18.1/1.18.1-mdadm.diff b/patches/busybox/1.18.1/1.18.1-mdadm.diff new file mode 100644 index 00000000..0f3107eb --- /dev/null +++ b/patches/busybox/1.18.1/1.18.1-mdadm.diff @@ -0,0 +1,5874 @@ +Based on: + +> Forward-port the mdadm tool from the Gentoo Busybox-1.1.3. +> Should handle all types of metadata 0.90, 1.0, 1.1, 1.2. +> If /etc/mdadm.conf does not exist in the initrd, it is created first, by +> scanning devices, and then it is used. + +--- a/Config.in 2010-12-21 06:31:04.000000000 +0200 ++++ mdadm/Config.in 2011-01-12 21:33:01.000000000 +0200 +@@ -749,6 +749,7 @@ source findutils/Config.in + source init/Config.in + source loginutils/Config.in + source e2fsprogs/Config.in ++source mdadm/Config.in + source modutils/Config.in + source util-linux/Config.in + source miscutils/Config.in +--- a/include/applets.src.h 2010-12-21 06:31:04.000000000 +0200 ++++ mdadm/include/applets.src.h 2011-01-12 21:33:01.000000000 +0200 +@@ -206,6 +206,7 @@ IF_KILLALL5(APPLET_ODDNAME(killall5, kil + IF_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_DROP)) + IF_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_DROP)) + IF_LENGTH(APPLET_NOFORK(length, length, _BB_DIR_USR_BIN, _BB_SUID_DROP, length)) ++IF_MDADM(APPLET(mdadm, _BB_DIR_SBIN, _BB_SUID_DROP)) + IF_LESS(APPLET(less, _BB_DIR_USR_BIN, _BB_SUID_DROP)) + IF_SETARCH(APPLET_ODDNAME(linux32, setarch, _BB_DIR_BIN, _BB_SUID_DROP, linux32)) + IF_SETARCH(APPLET_ODDNAME(linux64, setarch, _BB_DIR_BIN, _BB_SUID_DROP, linux64)) +--- a/include/usage.src.h 2010-12-21 06:29:45.000000000 +0200 ++++ mdadm/include/usage.src.h 2011-01-12 21:33:01.000000000 +0200 +@@ -2404,6 +2404,11 @@ INSERT + "\n -w Warn about improperly formatted checksum lines" \ + ) + ++#define mdadm_trivial_usage \ ++ "" ++#define mdadm_full_usage \ ++ "Assemble or Examine the mdadm arrays." ++ + #define mdev_trivial_usage \ + "[-s]" + #define mdev_full_usage "\n\n" \ +--- a/Makefile 2010-12-21 06:31:43.000000000 +0200 ++++ mdadm/Makefile 2011-01-12 21:33:01.000000000 +0200 +@@ -478,6 +478,7 @@ libs-y := \ + loginutils/ \ + mailutils/ \ + miscutils/ \ ++ mdadm/ \ + modutils/ \ + networking/ \ + networking/libiproute/ \ +--- a/mdadm/bitmap.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/bitmap.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,287 @@ ++/* ++ * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 ++ * ++ * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc. ++ */ ++#ifndef BITMAP_H ++#define BITMAP_H 1 ++ ++#define BITMAP_MAJOR_LO 3 ++/* version 4 insists the bitmap is in little-endian order ++ * with version 3, it is host-endian which is non-portable ++ */ ++#define BITMAP_MAJOR_HI 4 ++#define BITMAP_MAJOR_HOSTENDIAN 3 ++ ++#define BITMAP_MINOR 39 ++ ++/* ++ * in-memory bitmap: ++ * ++ * Use 16 bit block counters to track pending writes to each "chunk". ++ * The 2 high order bits are special-purpose, the first is a flag indicating ++ * whether a resync is needed. The second is a flag indicating whether a ++ * resync is active. ++ * This means that the counter is actually 14 bits: ++ * ++ * +--------+--------+------------------------------------------------+ ++ * | resync | resync | counter | ++ * | needed | active | | ++ * | (0-1) | (0-1) | (0-16383) | ++ * +--------+--------+------------------------------------------------+ ++ * ++ * The "resync needed" bit is set when: ++ * a '1' bit is read from storage at startup. ++ * a write request fails on some drives ++ * a resync is aborted on a chunk with 'resync active' set ++ * It is cleared (and resync-active set) when a resync starts across all drives ++ * of the chunk. ++ * ++ * ++ * The "resync active" bit is set when: ++ * a resync is started on all drives, and resync_needed is set. ++ * resync_needed will be cleared (as long as resync_active wasn't already set). ++ * It is cleared when a resync completes. ++ * ++ * The counter counts pending write requests, plus the on-disk bit. ++ * When the counter is '1' and the resync bits are clear, the on-disk ++ * bit can be cleared aswell, thus setting the counter to 0. ++ * When we set a bit, or in the counter (to start a write), if the fields is ++ * 0, we first set the disk bit and set the counter to 1. ++ * ++ * If the counter is 0, the on-disk bit is clear and the stipe is clean ++ * Anything that dirties the stipe pushes the counter to 2 (at least) ++ * and sets the on-disk bit (lazily). ++ * If a periodic sweep find the counter at 2, it is decremented to 1. ++ * If the sweep find the counter at 1, the on-disk bit is cleared and the ++ * counter goes to zero. ++ * ++ * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block ++ * counters as a fallback when "page" memory cannot be allocated: ++ * ++ * Normal case (page memory allocated): ++ * ++ * page pointer (32-bit) ++ * ++ * [ ] ------+ ++ * | ++ * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) ++ * c1 c2 c2048 ++ * ++ * Hijacked case (page memory allocation failed): ++ * ++ * hijacked page pointer (32-bit) ++ * ++ * [ ][ ] (no page memory allocated) ++ * counter #1 (16-bit) counter #2 (16-bit) ++ * ++ */ ++ ++#ifdef __KERNEL__ ++ ++#define PAGE_BITS (PAGE_SIZE << 3) ++#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3) ++ ++typedef __u16 bitmap_counter_t; ++#define COUNTER_BITS 16 ++#define COUNTER_BIT_SHIFT 4 ++#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8) ++#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3) ++ ++#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1))) ++#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2))) ++#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1) ++#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK) ++#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK) ++#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX) ++ ++/* how many counters per page? */ ++#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS) ++/* same, except a shift value for more efficient bitops */ ++#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT) ++/* same, except a mask value for more efficient bitops */ ++#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1) ++ ++#define BITMAP_BLOCK_SIZE 512 ++#define BITMAP_BLOCK_SHIFT 9 ++ ++/* how many blocks per chunk? (this is variable) */ ++#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT) ++#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT) ++#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1) ++ ++/* when hijacked, the counters and bits represent even larger "chunks" */ ++/* there will be 1024 chunks represented by each counter in the page pointers */ ++#define PAGEPTR_BLOCK_RATIO(bitmap) \ ++ (CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1) ++#define PAGEPTR_BLOCK_SHIFT(bitmap) \ ++ (CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1) ++#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1) ++ ++/* ++ * on-disk bitmap: ++ * ++ * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap ++ * file a page at a time. There's a superblock at the start of the file. ++ */ ++ ++/* map chunks (bits) to file pages - offset by the size of the superblock */ ++#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3)) ++ ++#endif ++ ++/* ++ * bitmap structures: ++ */ ++ ++#define BITMAP_MAGIC 0x6d746962 ++ ++/* use these for bitmap->flags and bitmap->sb->state bit-fields */ ++enum bitmap_state { ++ BITMAP_ACTIVE = 0x001, /* the bitmap is in use */ ++ BITMAP_STALE = 0x002 /* the bitmap file is out of date or had -EIO */ ++}; ++ ++/* the superblock at the front of the bitmap file -- little endian */ ++typedef struct bitmap_super_s { ++ __u32 magic; /* 0 BITMAP_MAGIC */ ++ __u32 version; /* 4 the bitmap major for now, could change... */ ++ __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */ ++ __u64 events; /* 24 event counter for the bitmap (1)*/ ++ __u64 events_cleared;/*32 event counter when last bit cleared (2) */ ++ __u64 sync_size; /* 40 the size of the md device's sync range(3) */ ++ __u32 state; /* 48 bitmap state information */ ++ __u32 chunksize; /* 52 the bitmap chunk size in bytes */ ++ __u32 daemon_sleep; /* 56 seconds between disk flushes */ ++ __u32 write_behind; /* 60 number of outstanding write-behind writes */ ++ ++ __u8 pad[256 - 64]; /* set to zero */ ++} bitmap_super_t; ++ ++/* notes: ++ * (1) This event counter is updated before the eventcounter in the md superblock ++ * When a bitmap is loaded, it is only accepted if this event counter is equal ++ * to, or one greater than, the event counter in the superblock. ++ * (2) This event counter is updated when the other one is *if*and*only*if* the ++ * array is not degraded. As bits are not cleared when the array is degraded, ++ * this represents the last time that any bits were cleared. ++ * If a device is being added that has an event count with this value or ++ * higher, it is accepted as conforming to the bitmap. ++ * (3)This is the number of sectors represented by the bitmap, and is the range that ++ * resync happens across. For raid1 and raid5/6 it is the size of individual ++ * devices. For raid10 it is the size of the array. ++ */ ++ ++#ifdef __KERNEL__ ++ ++/* the in-memory bitmap is represented by bitmap_pages */ ++struct bitmap_page { ++ /* ++ * map points to the actual memory page ++ */ ++ char *map; ++ /* ++ * in emergencies (when map cannot be alloced), hijack the map ++ * pointer and use it as two counters itself ++ */ ++ unsigned int hijacked; ++ /* ++ * count of dirty bits on the page ++ */ ++ int count; ++}; ++ ++/* keep track of bitmap file pages that have pending writes on them */ ++struct page_list { ++ struct list_head list; ++ struct page *page; ++}; ++ ++/* the main bitmap structure - one per mddev */ ++struct bitmap { ++ struct bitmap_page *bp; ++ unsigned long pages; /* total number of pages in the bitmap */ ++ unsigned long missing_pages; /* number of pages not yet allocated */ ++ ++ mddev_t *mddev; /* the md device that the bitmap is for */ ++ ++ int counter_bits; /* how many bits per block counter */ ++ ++ /* bitmap chunksize -- how much data does each bit represent? */ ++ unsigned long chunksize; ++ unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */ ++ unsigned long chunks; /* total number of data chunks for the array */ ++ ++ /* We hold a count on the chunk currently being synced, and drop ++ * it when the last block is started. If the resync is aborted ++ * midway, we need to be able to drop that count, so we remember ++ * the counted chunk.. ++ */ ++ unsigned long syncchunk; ++ ++ __u64 events_cleared; ++ ++ /* bitmap spinlock */ ++ spinlock_t lock; ++ ++ struct file *file; /* backing disk file */ ++ struct page *sb_page; /* cached copy of the bitmap file superblock */ ++ struct page **filemap; /* list of cache pages for the file */ ++ unsigned long *filemap_attr; /* attributes associated w/ filemap pages */ ++ unsigned long file_pages; /* number of pages in the file */ ++ ++ unsigned long flags; ++ ++ /* ++ * the bitmap daemon - periodically wakes up and sweeps the bitmap ++ * file, cleaning up bits and flushing out pages to disk as necessary ++ */ ++ mdk_thread_t *daemon; ++ unsigned long daemon_sleep; /* how many seconds between updates? */ ++ ++ /* ++ * bitmap write daemon - this daemon performs writes to the bitmap file ++ * this thread is only needed because of a limitation in ext3 (jbd) ++ * that does not allow a task to have two journal transactions ongoing ++ * simultaneously (even if the transactions are for two different ++ * filesystems) -- in the case of bitmap, that would be the filesystem ++ * that the bitmap file resides on and the filesystem that is mounted ++ * on the md device -- see current->journal_info in jbd/transaction.c ++ */ ++ mdk_thread_t *write_daemon; ++ mdk_thread_t *writeback_daemon; ++ spinlock_t write_lock; ++ struct semaphore write_ready; ++ struct semaphore write_done; ++ unsigned long writes_pending; ++ wait_queue_head_t write_wait; ++ struct list_head write_pages; ++ struct list_head complete_pages; ++ mempool_t *write_pool; ++}; ++ ++/* the bitmap API */ ++ ++/* these are used only by md/bitmap */ ++int bitmap_create(mddev_t *mddev); ++void bitmap_destroy(mddev_t *mddev); ++int bitmap_active(struct bitmap *bitmap); ++ ++char *file_path(struct file *file, char *buf, int count); ++void bitmap_print_sb(struct bitmap *bitmap); ++int bitmap_update_sb(struct bitmap *bitmap); ++ ++int bitmap_setallbits(struct bitmap *bitmap); ++ ++/* these are exported */ ++void bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); ++void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, ++ int success); ++int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks); ++void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); ++void bitmap_close_sync(struct bitmap *bitmap); ++ ++int bitmap_unplug(struct bitmap *bitmap); ++#endif ++ ++#endif +diff -pruN a/mdadm/config.c mdadm/mdadm/config.c +--- a/mdadm/config.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/config.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,824 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include "mdadm.h" ++#include "dlink.h" ++#include <sys/dir.h> ++#include <glob.h> ++#include <fnmatch.h> ++#include <ctype.h> ++#include <pwd.h> ++#include <grp.h> ++ ++mapping_t r5layout[] = { ++ { "left-asymmetric", 0}, ++ { "right-asymmetric", 1}, ++ { "left-symmetric", 2}, ++ { "right-symmetric", 3}, ++ ++ { "default", 2}, ++ { "la", 0}, ++ { "ra", 1}, ++ { "ls", 2}, ++ { "rs", 3}, ++ { NULL, 0} ++}; ++ ++mapping_t pers[] = { ++ { "linear", -1}, ++ { "raid0", 0}, ++ { "0", 0}, ++ { "stripe", 0}, ++ { "raid1", 1}, ++ { "1", 1}, ++ { "mirror", 1}, ++ { "raid4", 4}, ++ { "4", 4}, ++ { "raid5", 5}, ++ { "5", 5}, ++ { "multipath", -4}, ++ { "mp", -4}, ++ { "raid6", 6}, ++ { "6", 6}, ++ { "raid10", 10}, ++ { "10", 10}, ++ { "faulty", -5}, ++ { NULL, 0} ++}; ++/* ++ * Read the config file ++ * ++ * conf_get_uuids gets a list of devicename+uuid pairs ++ * conf_get_devs gets device names after expanding wildcards ++ * ++ * Each keeps the returned list and frees it when asked to make ++ * a new list. ++ * ++ * The format of the config file needs to be fairly extensible. ++ * Now, arrays only have names and uuids and devices merely are. ++ * But later arrays might want names, and devices might want superblock ++ * versions, and who knows what else. ++ * I like free format, abhore backslash line continuation, adore ++ * indentation for structure and am ok about # comments. ++ * ++ * So, each line that isn't blank or a #comment must either start ++ * with a key word, and not be indented, or must start with a ++ * non-key-word and must be indented. ++ * ++ * Keywords are DEVICE and ARRAY ++ * DEV{ICE} introduces some devices that might contain raid components. ++ * e.g. ++ * DEV style=0 /dev/sda* /dev/hd* ++ * DEV style=1 /dev/sd[b-f]* ++ * ARR{AY} describes an array giving md device and attributes like uuid=whatever ++ * e.g. ++ * ARRAY /dev/md0 uuid=whatever name=something ++ * Spaces separate words on each line. Quoting, with "" or '' protects them, ++ * but may not wrap over lines ++ * ++ */ ++ ++#ifndef CONFFILE ++#define CONFFILE "/etc/mdadm.conf" ++#endif ++#ifndef CONFFILE2 ++/* for Debian compatibility .... */ ++#define CONFFILE2 "/etc/mdadm/mdadm.conf" ++#endif ++char DefaultConfFile[] = CONFFILE; ++char DefaultAltConfFile[] = CONFFILE2; ++ ++enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev, Homehost, LTEnd }; ++char *keywords[] = { ++ [Devices] = "devices", ++ [Array] = "array", ++ [Mailaddr] = "mailaddr", ++ [Mailfrom] = "mailfrom", ++ [Program] = "program", ++ [CreateDev]= "create", ++ [Homehost] = "homehost", ++ [LTEnd] = NULL ++}; ++ ++/* ++ * match_keyword returns an index into the keywords array, or -1 for no match ++ * case is ignored, and at least three characters must be given ++ */ ++ ++int match_keyword(char *word) ++{ ++ int len = strlen(word); ++ int n; ++ ++ if (len < 3) return -1; ++ for (n=0; keywords[n]; n++) { ++ if (strncasecmp(word, keywords[n], len)==0) ++ return n; ++ } ++ return -1; ++} ++ ++/* conf_word gets one word from the conf file. ++ * if "allow_key", then accept words at the start of a line, ++ * otherwise stop when such a word is found. ++ * We assume that the file pointer is at the end of a word, so the ++ * next character is a space, or a newline. If not, it is the start of a line. ++ */ ++ ++char *conf_word(FILE *file, int allow_key) ++{ ++ int wsize = 100; ++ int len = 0; ++ int c; ++ int quote; ++ int wordfound = 0; ++ char *word = malloc(wsize); ++ ++ if (!word) abort(); ++ ++ while (wordfound==0) { ++ /* at the end of a word.. */ ++ c = getc(file); ++ if (c == '#') ++ while (c != EOF && c != '\n') ++ c = getc(file); ++ if (c == EOF) break; ++ if (c == '\n') continue; ++ ++ if (c != ' ' && c != '\t' && ! allow_key) { ++ ungetc(c, file); ++ break; ++ } ++ /* looks like it is safe to get a word here, if there is one */ ++ quote = 0; ++ /* first, skip any spaces */ ++ while (c == ' ' || c == '\t') ++ c = getc(file); ++ if (c != EOF && c != '\n' && c != '#') { ++ /* we really have a character of a word, so start saving it */ ++ while (c != EOF && c != '\n' && (quote || (c!=' ' && c != '\t'))) { ++ wordfound = 1; ++ if (quote && c == quote) quote = 0; ++ else if (quote == 0 && (c == '\'' || c == '"')) ++ quote = c; ++ else { ++ if (len == wsize-1) { ++ wsize += 100; ++ word = realloc(word, wsize); ++ if (!word) abort(); ++ } ++ word[len++] = c; ++ } ++ c = getc(file); ++ } ++ } ++ if (c != EOF) ungetc(c, file); ++ } ++ word[len] = 0; ++/* printf("word is <%s>\n", word); */ ++ if (!wordfound) { ++ free(word); ++ word = NULL; ++ } ++ return word; ++} ++ ++/* ++ * conf_line reads one logical line from the conffile. ++ * It skips comments and continues until it finds a line that starts ++ * with a non blank/comment. This character is pushed back for the next call ++ * A doubly linked list of words is returned. ++ * the first word will be a keyword. Other words will have had quotes removed. ++ */ ++ ++char *conf_line(FILE *file) ++{ ++ char *w; ++ char *list; ++ ++ w = conf_word(file, 1); ++ if (w == NULL) return NULL; ++ ++ list = dl_strdup(w); ++ free(w); ++ dl_init(list); ++ ++ while ((w = conf_word(file,0))){ ++ char *w2 = dl_strdup(w); ++ free(w); ++ dl_add(list, w2); ++ } ++/* printf("got a line\n");*/ ++ return list; ++} ++ ++void free_line(char *line) ++{ ++ char *w; ++ for (w=dl_next(line); w != line; w=dl_next(line)) { ++ dl_del(w); ++ dl_free(w); ++ } ++ dl_free(line); ++} ++ ++ ++struct conf_dev { ++ struct conf_dev *next; ++ char *name; ++} *cdevlist = NULL; ++ ++mddev_dev_t load_partitions(void) ++{ ++ FILE *f = fopen("/proc/partitions", "r"); ++ char buf[1024]; ++ mddev_dev_t rv = NULL; ++ if (f == NULL) { ++ fprintf(stderr, Name ": cannot open /proc/partitions\n"); ++ return NULL; ++ } ++ while (fgets(buf, 1024, f)) { ++ int major, minor; ++ char *name, *mp; ++ mddev_dev_t d; ++ ++ buf[1023] = '\0'; ++ if (buf[0] != ' ') ++ continue; ++ major = strtoul(buf, &mp, 10); ++ if (mp == buf || *mp != ' ') ++ continue; ++ minor = strtoul(mp, NULL, 10); ++ ++ name = map_dev(major, minor, 1); ++ if (!name) ++ continue; ++ d = malloc(sizeof(*d)); ++ d->devname = strdup(name); ++ d->next = rv; ++ d->used = 0; ++ rv = d; ++ } ++ fclose(f); ++ return rv; ++} ++ ++struct createinfo createinfo = { ++ .autof = 2, /* by default, create devices with standard names */ ++ .symlinks = 1, ++#ifdef DEBIAN ++ .gid = 6, /* disk */ ++ .mode = 0660, ++#else ++ .mode = 0600, ++#endif ++}; ++ ++int parse_auto(char *str, char *msg, int config) ++{ ++ int autof; ++ if (str == NULL || *str == 0) ++ autof = 2; ++ else if (strcasecmp(str,"no")==0) ++ autof = 1; ++ else if (strcasecmp(str,"yes")==0) ++ autof = 2; ++ else if (strcasecmp(str,"md")==0) ++ autof = config?5:3; ++ else { ++ /* There might be digits, and maybe a hypen, at the end */ ++ char *e = str + strlen(str); ++ int num = 4; ++ int len; ++ while (e > str && isdigit(e[-1])) ++ e--; ++ if (*e) { ++ num = atoi(e); ++ if (num <= 0) num = 1; ++ } ++ if (e > str && e[-1] == '-') ++ e--; ++ len = e - str; ++ if ((len == 2 && strncasecmp(str,"md",2)==0)) { ++ autof = config ? 5 : 3; ++ } else if ((len == 3 && strncasecmp(str,"yes",3)==0)) { ++ autof = 2; ++ } else if ((len == 3 && strncasecmp(str,"mdp",3)==0)) { ++ autof = config ? 6 : 4; ++ } else if ((len == 1 && strncasecmp(str,"p",1)==0) || ++ (len >= 4 && strncasecmp(str,"part",4)==0)) { ++ autof = 6; ++ } else { ++ fprintf(stderr, Name ": %s arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n" ++ " optionally followed by a number.\n", ++ msg, str); ++ exit(2); ++ } ++ autof |= num << 3; ++ } ++ return autof; ++} ++ ++static void createline(char *line) ++{ ++ char *w; ++ char *ep; ++ ++ for (w=dl_next(line); w!=line; w=dl_next(w)) { ++ if (strncasecmp(w, "auto=", 5) == 0) ++ createinfo.autof = parse_auto(w+5, "auto=", 1); ++ else if (strncasecmp(w, "owner=", 6) == 0) { ++ if (w[6] == 0) { ++ fprintf(stderr, Name ": missing owner name\n"); ++ continue; ++ } ++ createinfo.uid = strtoul(w+6, &ep, 10); ++ if (*ep != 0) { ++ struct passwd *pw; ++ /* must be a name */ ++ pw = getpwnam(w+6); ++ if (pw) ++ createinfo.uid = pw->pw_uid; ++ else ++ fprintf(stderr, Name ": CREATE user %s not found\n", w+6); ++ } ++ } else if (strncasecmp(w, "group=", 6) == 0) { ++ if (w[6] == 0) { ++ fprintf(stderr, Name ": missing group name\n"); ++ continue; ++ } ++ createinfo.gid = strtoul(w+6, &ep, 10); ++ if (*ep != 0) { ++ struct group *gr; ++ /* must be a name */ ++ gr = getgrnam(w+6); ++ if (gr) ++ createinfo.gid = gr->gr_gid; ++ else ++ fprintf(stderr, Name ": CREATE group %s not found\n", w+6); ++ } ++ } else if (strncasecmp(w, "mode=", 5) == 0) { ++ if (w[5] == 0) { ++ fprintf(stderr, Name ": missing CREATE mode\n"); ++ continue; ++ } ++ createinfo.mode = strtoul(w+5, &ep, 8); ++ if (*ep != 0) { ++ createinfo.mode = 0600; ++ fprintf(stderr, Name ": unrecognised CREATE mode %s\n", ++ w+5); ++ } ++ } else if (strncasecmp(w, "metadata=", 9) == 0) { ++ /* style of metadata to use by default */ ++ int i; ++ for (i=0; superlist[i] && !createinfo.supertype; i++) ++ createinfo.supertype = ++ superlist[i]->match_metadata_desc(w+9); ++ if (!createinfo.supertype) ++ fprintf(stderr, Name ": metadata format %s unknown, ignoring\n", ++ w+9); ++ } else if (strncasecmp(w, "symlinks=yes", 12) == 0) ++ createinfo.symlinks = 1; ++ else if (strncasecmp(w, "symlinks=no", 11) == 0) ++ createinfo.symlinks = 0; ++ else { ++ fprintf(stderr, Name ": unrecognised word on CREATE line: %s\n", ++ w); ++ } ++ } ++} ++ ++void devline(char *line) ++{ ++ char *w; ++ struct conf_dev *cd; ++ ++ for (w=dl_next(line); w != line; w=dl_next(w)) { ++ if (w[0] == '/' || strcasecmp(w, "partitions") == 0) { ++ cd = malloc(sizeof(*cd)); ++ cd->name = strdup(w); ++ cd->next = cdevlist; ++ cdevlist = cd; ++ } else { ++ fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n", ++ w); ++ } ++ } ++} ++ ++mddev_ident_t mddevlist = NULL; ++mddev_ident_t *mddevlp = &mddevlist; ++ ++void arrayline(char *line) ++{ ++ char *w; ++ ++ struct mddev_ident_s mis; ++ mddev_ident_t mi; ++ ++ mis.uuid_set = 0; ++ mis.super_minor = UnSet; ++ mis.level = UnSet; ++ mis.raid_disks = UnSet; ++ mis.spare_disks = 0; ++ mis.devices = NULL; ++ mis.devname = NULL; ++ mis.spare_group = NULL; ++ mis.autof = 0; ++ mis.next = NULL; ++ mis.st = NULL; ++ mis.bitmap_fd = -1; ++ mis.bitmap_file = NULL; ++ mis.name[0] = 0; ++ ++ for (w=dl_next(line); w!=line; w=dl_next(w)) { ++ if (w[0] == '/') { ++ if (mis.devname) ++ fprintf(stderr, Name ": only give one device per ARRAY line: %s and %s\n", ++ mis.devname, w); ++ else mis.devname = w; ++ } else if (strncasecmp(w, "uuid=", 5)==0 ) { ++ if (mis.uuid_set) ++ fprintf(stderr, Name ": only specify uuid once, %s ignored.\n", ++ w); ++ else { ++ if (parse_uuid(w+5, mis.uuid)) ++ mis.uuid_set = 1; ++ else ++ fprintf(stderr, Name ": bad uuid: %s\n", w); ++ } ++ } else if (strncasecmp(w, "super-minor=", 12)==0 ) { ++ if (mis.super_minor != UnSet) ++ fprintf(stderr, Name ": only specify super-minor once, %s ignored.\n", ++ w); ++ else { ++ char *endptr; ++ mis.super_minor= strtol(w+12, &endptr, 10); ++ if (w[12]==0 || endptr[0]!=0 || mis.super_minor < 0) { ++ fprintf(stderr, Name ": invalid super-minor number: %s\n", ++ w); ++ mis.super_minor = UnSet; ++ } ++ } ++ } else if (strncasecmp(w, "name=", 5)==0) { ++ if (mis.name[0]) ++ fprintf(stderr, Name ": only specify name once, %s ignored.\n", ++ w); ++ else if (strlen(w+5) > 32) ++ fprintf(stderr, Name ": name too long, ignoring %s\n", w); ++ else ++ strcpy(mis.name, w+5); ++ ++ } else if (strncasecmp(w, "bitmap=", 7) == 0) { ++ if (mis.bitmap_file) ++ fprintf(stderr, Name ": only specify bitmap file once. %s ignored\n", ++ w); ++ else ++ mis.bitmap_file = strdup(w+7); ++ ++ } else if (strncasecmp(w, "devices=", 8 ) == 0 ) { ++ if (mis.devices) ++ fprintf(stderr, Name ": only specify devices once (use a comma separated list). %s ignored\n", ++ w); ++ else ++ mis.devices = strdup(w+8); ++ } else if (strncasecmp(w, "spare-group=", 12) == 0 ) { ++ if (mis.spare_group) ++ fprintf(stderr, Name ": only specify one spare group per array. %s ignored.\n", ++ w); ++ else ++ mis.spare_group = strdup(w+12); ++ } else if (strncasecmp(w, "level=", 6) == 0 ) { ++ /* this is mainly for compatability with --brief output */ ++ mis.level = map_name(pers, w+6); ++ } else if (strncasecmp(w, "disks=", 6) == 0 ) { ++ /* again, for compat */ ++ mis.raid_disks = atoi(w+6); ++ } else if (strncasecmp(w, "num-devices=", 12) == 0 ) { ++ /* again, for compat */ ++ mis.raid_disks = atoi(w+12); ++ } else if (strncasecmp(w, "spares=", 7) == 0 ) { ++ /* for warning if not all spares present */ ++ mis.spare_disks = atoi(w+7); ++ } else if (strncasecmp(w, "metadata=", 9) == 0) { ++ /* style of metadata on the devices. */ ++ int i; ++ ++ for(i=0; superlist[i] && !mis.st; i++) ++ mis.st = superlist[i]->match_metadata_desc(w+9); ++ ++ if (!mis.st) ++ fprintf(stderr, Name ": metadata format %s unknown, ignored.\n", w+9); ++ } else if (strncasecmp(w, "auto=", 5) == 0 ) { ++ /* whether to create device special files as needed */ ++ mis.autof = parse_auto(w+5, "auto type", 0); ++ } else { ++ fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n", ++ w); ++ } ++ } ++ if (mis.devname == NULL) ++ fprintf(stderr, Name ": ARRAY line with no device\n"); ++ else if (mis.uuid_set == 0 && mis.devices == NULL && mis.super_minor == UnSet && mis.name[0] == 0) ++ fprintf(stderr, Name ": ARRAY line %s has no identity information.\n", mis.devname); ++ else { ++ mi = malloc(sizeof(*mi)); ++ *mi = mis; ++ mi->devname = strdup(mis.devname); ++ mi->next = NULL; ++ *mddevlp = mi; ++ mddevlp = &mi->next; ++ } ++} ++ ++static char *alert_email = NULL; ++void mailline(char *line) ++{ ++ char *w; ++ ++ for (w=dl_next(line); w != line ; w=dl_next(w)) { ++ if (alert_email == NULL) ++ alert_email = strdup(w); ++ else ++ fprintf(stderr, Name ": excess address on MAIL line: %s - ignored\n", ++ w); ++ } ++} ++ ++static char *alert_mail_from = NULL; ++void mailfromline(char *line) ++{ ++ char *w; ++ ++ for (w=dl_next(line); w != line ; w=dl_next(w)) { ++ if (alert_mail_from == NULL) ++ alert_mail_from = strdup(w); ++ else { ++ char *t= NULL; ++ asprintf(&t, "%s %s", alert_mail_from, w); ++ free(alert_mail_from); ++ alert_mail_from = t; ++ } ++ } ++} ++ ++ ++static char *alert_program = NULL; ++void programline(char *line) ++{ ++ char *w; ++ ++ for (w=dl_next(line); w != line ; w=dl_next(w)) { ++ if (alert_program == NULL) ++ alert_program = strdup(w); ++ else ++ fprintf(stderr, Name ": excess program on PROGRAM line: %s - ignored\n", ++ w); ++ } ++} ++ ++static char *home_host = NULL; ++void homehostline(char *line) ++{ ++ char *w; ++ ++ for (w=dl_next(line); w != line ; w=dl_next(w)) { ++ if (home_host == NULL) ++ home_host = strdup(w); ++ else ++ fprintf(stderr, Name ": excess host name on HOMEHOST line: %s - ignored\n", ++ w); ++ } ++} ++ ++ ++int loaded = 0; ++ ++static char *conffile = NULL; ++void set_conffile(char *file) ++{ ++ conffile = file; ++} ++ ++void load_conffile(void) ++{ ++ FILE *f; ++ char *line; ++ ++ if (loaded) return; ++ if (conffile == NULL) ++ conffile = DefaultConfFile; ++ ++ if (strcmp(conffile, "none") == 0) { ++ loaded = 1; ++ return; ++ } ++ if (strcmp(conffile, "partitions")==0) { ++ char *list = dl_strdup("DEV"); ++ dl_init(list); ++ dl_add(list, dl_strdup("partitions")); ++ devline(list); ++ free_line(list); ++ loaded = 1; ++ return; ++ } ++ f = fopen(conffile, "r"); ++ /* Debian chose to relocate mdadm.conf into /etc/mdadm/. ++ * To allow Debian users to compile from clean source and still ++ * have a working mdadm, we read /etc/mdadm/mdadm.conf ++ * if /etc/mdadm.conf doesn't exist ++ */ ++ if (f == NULL && ++ conffile == DefaultConfFile) { ++ f = fopen(DefaultAltConfFile, "r"); ++ if (f) ++ conffile = DefaultAltConfFile; ++ } ++ if (f == NULL) ++ return; ++ ++ loaded = 1; ++ while ((line=conf_line(f))) { ++ switch(match_keyword(line)) { ++ case Devices: ++ devline(line); ++ break; ++ case Array: ++ arrayline(line); ++ break; ++ case Mailaddr: ++ mailline(line); ++ break; ++ case Mailfrom: ++ mailfromline(line); ++ break; ++ case Program: ++ programline(line); ++ break; ++ case CreateDev: ++ createline(line); ++ break; ++ case Homehost: ++ homehostline(line); ++ break; ++ default: ++ fprintf(stderr, Name ": Unknown keyword %s\n", line); ++ } ++ free_line(line); ++ } ++ ++ fclose(f); ++ ++/* printf("got file\n"); */ ++} ++ ++char *conf_get_mailaddr(void) ++{ ++ load_conffile(); ++ return alert_email; ++} ++ ++char *conf_get_mailfrom(void) ++{ ++ load_conffile(); ++ return alert_mail_from; ++} ++ ++char *conf_get_program(void) ++{ ++ load_conffile(); ++ return alert_program; ++} ++ ++char *conf_get_homehost(void) ++{ ++ load_conffile(); ++ return home_host; ++} ++ ++struct createinfo *conf_get_create_info(void) ++{ ++ load_conffile(); ++ return &createinfo; ++} ++ ++mddev_ident_t conf_get_ident(char *dev) ++{ ++ mddev_ident_t rv; ++ load_conffile(); ++ rv = mddevlist; ++ while (dev && rv && strcmp(dev, rv->devname)!=0) ++ rv = rv->next; ++ return rv; ++} ++ ++mddev_dev_t conf_get_devs() ++{ ++ glob_t globbuf; ++ struct conf_dev *cd; ++ int flags = 0; ++ static mddev_dev_t dlist = NULL; ++ unsigned int i; ++ ++ while (dlist) { ++ mddev_dev_t t = dlist; ++ dlist = dlist->next; ++ free(t->devname); ++ free(t); ++ } ++ ++ load_conffile(); ++ ++ if (cdevlist == NULL) ++ /* default to 'partitions */ ++ dlist = load_partitions(); ++ ++ for (cd=cdevlist; cd; cd=cd->next) { ++ if (strcasecmp(cd->name, "partitions")==0 && dlist == NULL) ++ dlist = load_partitions(); ++ else { ++ glob(cd->name, flags, NULL, &globbuf); ++ flags |= GLOB_APPEND; ++ } ++ } ++ if (flags & GLOB_APPEND) { ++ for (i=0; i<globbuf.gl_pathc; i++) { ++ mddev_dev_t t = malloc(sizeof(*t)); ++ t->devname = strdup(globbuf.gl_pathv[i]); ++ t->next = dlist; ++ t->used = 0; ++ dlist = t; ++/* printf("one dev is %s\n", t->devname);*/ ++ } ++ globfree(&globbuf); ++ } ++ ++ return dlist; ++} ++ ++int conf_test_dev(char *devname) ++{ ++ struct conf_dev *cd; ++ if (cdevlist == NULL) ++ /* allow anything by default */ ++ return 1; ++ for (cd = cdevlist ; cd ; cd = cd->next) { ++ if (strcasecmp(cd->name, "partitions") == 0) ++ return 1; ++ if (fnmatch(cd->name, devname, FNM_PATHNAME) == 0) ++ return 1; ++ } ++ return 0; ++} ++ ++ ++int match_oneof(char *devices, char *devname) ++{ ++ /* check if one of the comma separated patterns in devices ++ * matches devname ++ */ ++ ++ ++ while (devices && *devices) { ++ char patn[1024]; ++ char *p = devices; ++ devices = strchr(devices, ','); ++ if (!devices) ++ devices = p + strlen(p); ++ if (devices-p < 1024) { ++ strncpy(patn, p, devices-p); ++ patn[devices-p] = 0; ++ if (fnmatch(patn, devname, FNM_PATHNAME)==0) ++ return 1; ++ } ++ if (*devices == ',') ++ devices++; ++ } ++ return 0; ++} +--- a/mdadm/Config.in 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/Config.in 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# For a description of the syntax of this configuration file, ++# see scripts/kbuild/config-language.txt. ++# ++ ++menu "Linux mdadm Utilities" ++ ++config MDADM ++ bool "mdadm" ++ default n ++ help ++ assemble or examine raid array ++ ++endmenu ++ +--- a/mdadm/dlink.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/dlink.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,79 @@ ++ ++/* doubly linked lists */ ++/* This is free software. No strings attached. No copyright claimed */ ++ ++#include <unistd.h> ++#include <stdlib.h> ++#include <string.h> ++#ifdef __dietlibc__ ++char *strncpy(char *dest, const char *src, size_t n) __THROW; ++#endif ++#include "dlink.h" ++ ++ ++void *dl_head() ++{ ++ void *h; ++ h = dl_alloc(0); ++ dl_next(h) = h; ++ dl_prev(h) = h; ++ return h; ++} ++ ++void dl_free(void *v) ++{ ++ struct __dl_head *vv = v; ++ free(vv-1); ++} ++ ++void dl_init(void *v) ++{ ++ dl_next(v) = v; ++ dl_prev(v) = v; ++} ++ ++void dl_insert(void *head, void *val) ++{ ++ dl_next(val) = dl_next(head); ++ dl_prev(val) = head; ++ dl_next(dl_prev(val)) = val; ++ dl_prev(dl_next(val)) = val; ++} ++ ++void dl_add(void *head, void *val) ++{ ++ dl_prev(val) = dl_prev(head); ++ dl_next(val) = head; ++ dl_next(dl_prev(val)) = val; ++ dl_prev(dl_next(val)) = val; ++} ++ ++void dl_del(void *val) ++{ ++ if (dl_prev(val) == 0 || dl_next(val) == 0) ++ return; ++ dl_prev(dl_next(val)) = dl_prev(val); ++ dl_next(dl_prev(val)) = dl_next(val); ++ dl_prev(val) = dl_next(val) = 0; ++} ++ ++char *dl_strndup(char *s, int l) ++{ ++ char *n; ++ if (s == NULL) ++ return NULL; ++ n = dl_newv(char, l+1); ++ if (n == NULL) ++ return NULL; ++ else ++ { ++ strncpy(n, s, l); ++ n[l] = 0; ++ return n; ++ } ++} ++ ++char *dl_strdup(char *s) ++{ ++ return dl_strndup(s, (int)strlen(s)); ++} +--- a/mdadm/dlink.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/dlink.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,25 @@ ++ ++/* doubley linked lists */ ++/* This is free software. No strings attached. No copyright claimed */ ++ ++struct __dl_head ++{ ++ void * dh_prev; ++ void * dh_next; ++}; ++ ++#define dl_alloc(size) ((void*)(((char*)calloc(1,(size)+sizeof(struct __dl_head)))+sizeof(struct __dl_head))) ++#define dl_new(t) ((t*)dl_alloc(sizeof(t))) ++#define dl_newv(t,n) ((t*)dl_alloc(sizeof(t)*n)) ++ ++#define dl_next(p) *(&(((struct __dl_head*)(p))[-1].dh_next)) ++#define dl_prev(p) *(&(((struct __dl_head*)(p))[-1].dh_prev)) ++ ++void *dl_head(void); ++char *dl_strdup(char *); ++char *dl_strndup(char *, int); ++void dl_insert(void*, void*); ++void dl_add(void*, void*); ++void dl_del(void*); ++void dl_free(void*); ++void dl_init(void*); +--- a/mdadm/Kbuild 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/Kbuild 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,9 @@ ++# Makefile for busybox ++# ++# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> ++# ++# Licensed under the GPL v2, see the file LICENSE in this tarball. ++ ++lib-y:= ++MDADM-y:= config.o util.o dlink.o sha1.o super0.o super1.o mdexamine.o mdassemble.o ++lib-$(CONFIG_MDADM) += mdadm.o $(MDADM-y) +--- a/mdadm/md5.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/md5.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,134 @@ ++/* Declaration of functions and data types used for MD5 sum computing ++ library functions. ++ Copyright (C) 1995-1997,1999-2005 Free Software Foundation, Inc. ++ ++ NOTE: The canonical source of this file is maintained with the GNU C ++ Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. ++ ++ 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ++ ++#ifndef _MD5_H ++#define _MD5_H 1 ++ ++#include <stdio.h> ++ ++# include <inttypes.h> ++#if HAVE_STDINT_H || _LIBC ++# include <stdint.h> ++#endif ++ ++#ifndef __GNUC_PREREQ ++# if defined __GNUC__ && defined __GNUC_MINOR__ ++# define __GNUC_PREREQ(maj, min) \ ++ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) ++# else ++# define __GNUC_PREREQ(maj, min) 0 ++# endif ++#endif ++ ++#ifndef __THROW ++# if defined __cplusplus && __GNUC_PREREQ (2,8) ++# define __THROW throw () ++# else ++# define __THROW ++# endif ++#endif ++ ++#ifndef __attribute__ ++# if ! __GNUC_PREREQ (2,8) || __STRICT_ANSI__ ++# define __attribute__(x) ++# endif ++#endif ++ ++#ifndef _LIBC ++# define __md5_buffer md5_buffer ++# define __md5_finish_ctx md5_finish_ctx ++# define __md5_init_ctx md5_init_ctx ++# define __md5_process_block md5_process_block ++# define __md5_process_bytes md5_process_bytes ++# define __md5_read_ctx md5_read_ctx ++# define __md5_stream md5_stream ++#endif ++ ++typedef uint32_t md5_uint32; ++ ++/* Structure to save state of computation between the single steps. */ ++struct md5_ctx ++{ ++ md5_uint32 A; ++ md5_uint32 B; ++ md5_uint32 C; ++ md5_uint32 D; ++ ++ md5_uint32 total[2]; ++ md5_uint32 buflen; ++ char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32)))); ++}; ++ ++/* ++ * The following three functions are build up the low level used in ++ * the functions `md5_stream' and `md5_buffer'. ++ */ ++ ++/* Initialize structure containing state of computation. ++ (RFC 1321, 3.3: Step 3) */ ++extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; ++ ++/* Starting with the result of former calls of this function (or the ++ initialization function update the context for the next LEN bytes ++ starting at BUFFER. ++ It is necessary that LEN is a multiple of 64!!! */ ++extern void __md5_process_block (const void *buffer, size_t len, ++ struct md5_ctx *ctx) __THROW; ++ ++/* Starting with the result of former calls of this function (or the ++ initialization function update the context for the next LEN bytes ++ starting at BUFFER. ++ It is NOT required that LEN is a multiple of 64. */ ++extern void __md5_process_bytes (const void *buffer, size_t len, ++ struct md5_ctx *ctx) __THROW; ++ ++/* Process the remaining bytes in the buffer and put result from CTX ++ in first 16 bytes following RESBUF. The result is always in little ++ endian byte order, so that a byte-wise output yields to the wanted ++ ASCII representation of the message digest. ++ ++ IMPORTANT: On some systems it is required that RESBUF be correctly ++ aligned for a 32 bits value. */ ++extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW; ++ ++ ++/* Put result from CTX in first 16 bytes following RESBUF. The result is ++ always in little endian byte order, so that a byte-wise output yields ++ to the wanted ASCII representation of the message digest. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW; ++ ++ ++/* Compute MD5 message digest for bytes read from STREAM. The ++ resulting message digest number will be written into the 16 bytes ++ beginning at RESBLOCK. */ ++extern int __md5_stream (FILE *stream, void *resblock) __THROW; ++ ++/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The ++ result is always in little endian byte order, so that a byte-wise ++ output yields to the wanted ASCII representation of the message ++ digest. */ ++extern void *__md5_buffer (const char *buffer, size_t len, ++ void *resblock) __THROW; ++ ++#endif /* md5.h */ +--- a/mdadm/mdadm.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/mdadm.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * mdadm support for busybox. ++ * added by Alan Hourihane <alanh@fairlite.demon.co.uk> ++ */ ++#include <string.h> ++ ++extern int mdassemble_main(int argc, char **argv); ++extern int mdexamine_main(int argc, char **argv); ++ ++int mdadm_main(int argc, char **argv) { ++ if (argc >= 2) { ++ if (!strncmp(argv[1],"--assemble",10)) ++ return mdassemble_main(argc, argv); ++ if (!strncmp(argv[1],"--examine",9)) ++ return mdexamine_main(argc, argv); ++ } ++ return 0; ++} +--- a/mdadm/mdadm.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/mdadm.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,540 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include <unistd.h> ++#ifndef __dietlibc__ ++extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); ++#else ++# if defined(__NO_STAT64) || __WORDSIZE != 32 ++# define lseek64 lseek ++# endif ++#endif ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <stdlib.h> ++#include <time.h> ++#include <sys/time.h> ++#include <getopt.h> ++#include <fcntl.h> ++#include <stdio.h> ++#include <errno.h> ++#include <string.h> ++#include <syslog.h> ++#ifdef __dietlibc__ ++#include <strings.h> ++/* dietlibc has deprecated random and srandom!! */ ++#define random rand ++#define srandom srand ++#endif ++ ++ ++#include <linux/kdev_t.h> ++/*#include <linux/fs.h> */ ++#include <sys/mount.h> ++#include <asm/types.h> ++#include <sys/ioctl.h> ++#define MD_MAJOR 9 ++#define MdpMinorShift 6 ++ ++#ifndef BLKGETSIZE64 ++#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ ++#endif ++ ++#define DEFAULT_BITMAP_CHUNK 4096 ++#define DEFAULT_BITMAP_DELAY 5 ++#define DEFAULT_MAX_WRITE_BEHIND 256 ++ ++#include "md_u.h" ++#include "md_p.h" ++#include "bitmap.h" ++ ++#include <endian.h> ++/* Redhat don't like to #include <asm/byteorder.h>, and ++ * some time include <linux/byteorder/xxx_endian.h> isn't enough, ++ * and there is no standard conversion function so... */ ++/* And dietlibc doesn't think byteswap is ok, so.. */ ++/* #include <byteswap.h> */ ++#define bswap_16(x) (((x) & 0x00ffU) << 8 | \ ++ ((x) & 0xff00U) >> 8) ++#define bswap_32(x) (((x) & 0x000000ffU) << 24 | \ ++ ((x) & 0xff000000U) >> 24 | \ ++ ((x) & 0x0000ff00U) << 8 | \ ++ ((x) & 0x00ff0000U) >> 8) ++#define bswap_64(x) (((x) & 0x00000000000000ffULL) << 56 | \ ++ ((x) & 0xff00000000000000ULL) >> 56 | \ ++ ((x) & 0x000000000000ff00ULL) << 40 | \ ++ ((x) & 0x00ff000000000000ULL) >> 40 | \ ++ ((x) & 0x0000000000ff0000ULL) << 24 | \ ++ ((x) & 0x0000ff0000000000ULL) >> 24 | \ ++ ((x) & 0x00000000ff000000ULL) << 8 | \ ++ ((x) & 0x000000ff00000000ULL) >> 8) ++ ++#if BYTE_ORDER == LITTLE_ENDIAN ++#define __cpu_to_le16(_x) (_x) ++#define __cpu_to_le32(_x) (_x) ++#define __cpu_to_le64(_x) (_x) ++#define __le16_to_cpu(_x) (_x) ++#define __le32_to_cpu(_x) (_x) ++#define __le64_to_cpu(_x) (_x) ++#elif BYTE_ORDER == BIG_ENDIAN ++#define __cpu_to_le16(_x) bswap_16(_x) ++#define __cpu_to_le32(_x) bswap_32(_x) ++#define __cpu_to_le64(_x) bswap_64(_x) ++#define __le16_to_cpu(_x) bswap_16(_x) ++#define __le32_to_cpu(_x) bswap_32(_x) ++#define __le64_to_cpu(_x) bswap_64(_x) ++#else ++# error "unknown endianness." ++#endif ++ ++ ++ ++/* general information that might be extracted from a superblock */ ++struct mdinfo { ++ mdu_array_info_t array; ++ mdu_disk_info_t disk; ++ __u64 events; ++ int uuid[4]; ++ char name[33]; ++ unsigned long long data_offset; ++ unsigned long long component_size; ++ int reshape_active; ++ unsigned long long reshape_progress; ++ int new_level, delta_disks, new_layout, new_chunk; ++}; ++ ++struct createinfo { ++ int uid; ++ int gid; ++ int autof; ++ int mode; ++ int symlinks; ++ struct supertype *supertype; ++}; ++ ++#define Name "mdadm" ++ ++enum mode { ++ ASSEMBLE=1, ++ BUILD, ++ CREATE, ++ MANAGE, ++ MISC, ++ MONITOR, ++ GROW, ++ INCREMENTAL, ++ AUTODETECT, ++}; ++ ++extern char short_options[]; ++extern char short_bitmap_auto_options[]; ++extern struct option long_options[]; ++extern char Version[], Usage[], Help[], OptionHelp[], ++ Help_create[], Help_build[], Help_assemble[], Help_grow[], ++ Help_incr[], ++ Help_manage[], Help_misc[], Help_monitor[], Help_config[]; ++ ++/* for option that don't have short equivilents, we assign arbitrary ++ * small numbers. '1' means an undecorated option, so we start at '2'. ++ */ ++enum special_options { ++ AssumeClean = 2, ++ BitmapChunk, ++ WriteBehind, ++ ReAdd, ++ NoDegraded, ++ Sparc22, ++ BackupFile, ++ HomeHost, ++ AutoHomeHost, ++ Symlinks, ++ AutoDetect, ++}; ++ ++/* structures read from config file */ ++/* List of mddevice names and identifiers ++ * Identifiers can be: ++ * uuid=128-hex-uuid ++ * super-minor=decimal-minor-number-from-superblock ++ * devices=comma,separated,list,of,device,names,with,wildcards ++ * ++ * If multiple fields are present, the intersection of all matching ++ * devices is considered ++ */ ++#define UnSet (0xfffe) ++typedef struct mddev_ident_s { ++ char *devname; ++ ++ int uuid_set; ++ int uuid[4]; ++ char name[33]; ++ ++ unsigned int super_minor; ++ ++ char *devices; /* comma separated list of device ++ * names with wild cards ++ */ ++ int level; ++ unsigned int raid_disks; ++ unsigned int spare_disks; ++ struct supertype *st; ++ int autof; /* 1 for normal, 2 for partitioned */ ++ char *spare_group; ++ char *bitmap_file; ++ int bitmap_fd; ++ ++ struct mddev_ident_s *next; ++} *mddev_ident_t; ++ ++/* List of device names - wildcards expanded */ ++typedef struct mddev_dev_s { ++ char *devname; ++ char disposition; /* 'a' for add, 'r' for remove, 'f' for fail. ++ * Not set for names read from .config ++ */ ++ char writemostly; ++ char re_add; ++ char used; /* set when used */ ++ struct mddev_dev_s *next; ++} *mddev_dev_t; ++ ++typedef struct mapping { ++ char *name; ++ int num; ++} mapping_t; ++ ++ ++struct mdstat_ent { ++ char *dev; ++ int devnum; ++ int active; ++ char *level; ++ char *pattern; /* U or up, _ for down */ ++ int percent; /* -1 if no resync */ ++ int resync; /* 1 if resync, 0 if recovery */ ++ struct mdstat_ent *next; ++}; ++ ++extern struct mdstat_ent *mdstat_read(int hold, int start); ++extern void free_mdstat(struct mdstat_ent *ms); ++extern void mdstat_wait(int seconds); ++extern int mddev_busy(int devnum); ++ ++struct map_ent { ++ struct map_ent *next; ++ int devnum; ++ int major,minor; ++ int uuid[4]; ++ char *path; ++}; ++extern int map_update(struct map_ent **mpp, int devnum, int major, int minor, ++ int uuid[4], char *path); ++extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]); ++extern void map_read(struct map_ent **melp); ++extern int map_write(struct map_ent *mel); ++extern void map_delete(struct map_ent **mapp, int devnum); ++extern void map_free(struct map_ent *map); ++extern void map_add(struct map_ent **melp, ++ int devnum, int major, int minor, int uuid[4], char *path); ++ ++/* Data structure for holding info read from sysfs */ ++struct sysdev { ++ char name[20]; ++ int role; ++ int major, minor; ++ unsigned long long offset, size; ++ int state; ++ int errors; ++ struct sysdev *next; ++}; ++struct sysarray { ++ char name[20]; ++ struct sysdev *devs; ++ int chunk; ++ unsigned long long component_size; ++ int layout; ++ int level; ++ int spares; ++ int cache_size; ++ int mismatch_cnt; ++ int major_version, minor_version; ++}; ++/* various details can be requested */ ++#define GET_LEVEL 1 ++#define GET_LAYOUT 2 ++#define GET_COMPONENT 4 ++#define GET_CHUNK 8 ++#define GET_CACHE 16 ++#define GET_MISMATCH 32 ++#define GET_VERSION 64 ++ ++#define GET_DEVS 1024 /* gets role, major, minor */ ++#define GET_OFFSET 2048 ++#define GET_SIZE 4096 ++#define GET_STATE 8192 ++#define GET_ERROR 16384 ++ ++/* If fd >= 0, get the array it is open on, ++ * else use devnum. >=0 -> major9. <0..... ++ */ ++extern void sysfs_free(struct sysarray *sra); ++extern struct sysarray *sysfs_read(int fd, int devnum, unsigned long options); ++extern int sysfs_set_str(struct sysarray *sra, struct sysdev *dev, ++ char *name, char *val); ++extern int sysfs_set_num(struct sysarray *sra, struct sysdev *dev, ++ char *name, unsigned long long val); ++extern int sysfs_get_ll(struct sysarray *sra, struct sysdev *dev, ++ char *name, unsigned long long *val); ++ ++ ++extern int save_stripes(int *source, unsigned long long *offsets, ++ int raid_disks, int chunk_size, int level, int layout, ++ int nwrites, int *dest, ++ unsigned long long start, unsigned long long length); ++extern int restore_stripes(int *dest, unsigned long long *offsets, ++ int raid_disks, int chunk_size, int level, int layout, ++ int source, unsigned long long read_offset, ++ unsigned long long start, unsigned long long length); ++ ++#ifndef Sendmail ++#define Sendmail "/usr/lib/sendmail -t" ++#endif ++ ++#define SYSLOG_FACILITY LOG_DAEMON ++ ++extern char *map_num(mapping_t *map, int num); ++extern int map_name(mapping_t *map, char *name); ++extern mapping_t r5layout[], pers[], modes[], faultylayout[]; ++ ++extern char *map_dev(int major, int minor, int create); ++ ++ ++extern struct superswitch { ++ void (*examine_super)(void *sbv, char *homehost); ++ void (*brief_examine_super)(void *sbv); ++ void (*detail_super)(void *sbv, char *homehost); ++ void (*export_super)(void *sbv); ++ void (*brief_detail_super)(void *sbv); ++ void (*uuid_from_super)(int uuid[4], void *sbv); ++ void (*getinfo_super)(struct mdinfo *info, void *sbv); ++ int (*match_home)(void *sbv, char *homehost); ++ int (*update_super)(struct mdinfo *info, void *sbv, char *update, ++ char *devname, int verbose, ++ int uuid_set, char *homehost); ++ int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name, char *homehost, int *uuid); ++ void (*add_to_super)(void *sbv, mdu_disk_info_t *dinfo); ++ int (*store_super)(struct supertype *st, int fd, void *sbv); ++ int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname); ++ int (*compare_super)(void **firstp, void *secondv); ++ int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname); ++ struct supertype * (*match_metadata_desc)(char *arg); ++ __u64 (*avail_size)(struct supertype *st, __u64 size); ++ int (*add_internal_bitmap)(struct supertype *st, void *sbv, int *chunkp, ++ int delay, int write_behind, ++ unsigned long long size, int may_change, int major); ++ void (*locate_bitmap)(struct supertype *st, int fd, void *sbv); ++ int (*write_bitmap)(struct supertype *st, int fd, void *sbv); ++ int major; ++ int swapuuid; /* true if uuid is bigending rather than hostendian */ ++} super0, super1, *superlist[]; ++ ++struct supertype { ++ struct superswitch *ss; ++ int minor_version; ++ int max_devs; ++}; ++ ++extern struct supertype *super_by_version(int vers, int minor); ++extern struct supertype *guess_super(int fd); ++extern int get_dev_size(int fd, char *dname, unsigned long long *sizep); ++extern void get_one_disk(int mdfd, mdu_array_info_t *ainf, ++ mdu_disk_info_t *disk); ++ ++#if __GNUC__ < 3 ++struct stat64; ++#endif ++ ++#define HAVE_NFTW we assume ++#define HAVE_FTW ++ ++#ifdef UCLIBC ++# include <features.h> ++# ifndef __UCLIBC_HAS_FTW__ ++# undef HAVE_FTW ++# undef HAVE_NFTW ++# endif ++#endif ++ ++#ifdef __dietlibc__ ++# undef HAVE_NFTW ++#endif ++ ++#ifndef HAVE_NFTW ++# define FTW_PHYS 1 ++# ifndef HAVE_FTW ++ struct FTW {}; ++# endif ++#endif ++ ++#ifdef HAVE_FTW ++# include <ftw.h> ++#endif ++ ++extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s); ++ ++ ++extern int Manage_ro(char *devname, int fd, int readonly); ++extern int Manage_runstop(char *devname, int fd, int runstop, int quiet); ++extern int Manage_resize(char *devname, int fd, long long size, int raid_disks); ++extern int Manage_reconfig(char *devname, int fd, int layout); ++extern int Manage_subdevs(char *devname, int fd, ++ mddev_dev_t devlist, int verbose); ++extern int autodetect(void); ++extern int Grow_Add_device(char *devname, int fd, char *newdev); ++extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force); ++extern int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, ++ long long size, ++ int level, int layout, int chunksize, int raid_disks); ++extern int Grow_restart(struct supertype *st, struct mdinfo *info, ++ int *fdlist, int cnt, char *backup_file); ++ ++ ++extern int Assemble(struct supertype *st, char *mddev, int mdfd, ++ mddev_ident_t ident, ++ mddev_dev_t devlist, char *backup_file, ++ int readonly, int runstop, ++ char *update, char *homehost, ++ int verbose, int force); ++ ++extern int Build(char *mddev, int mdfd, int chunk, int level, int layout, ++ int raiddisks, ++ mddev_dev_t devlist, int assume_clean, ++ char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int verbose); ++ ++ ++extern int Create(struct supertype *st, char *mddev, int mdfd, ++ int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks, ++ char *name, char *homehost, int *uuid, ++ int subdevs, mddev_dev_t devlist, ++ int runstop, int verbose, int force, int assume_clean, ++ char *bitmap_file, int bitmap_chunk, int write_behind, int delay); ++ ++extern int Detail(char *dev, int brief, int export, int test, char *homehost); ++extern int Query(char *dev); ++ ++extern int md_get_version(int fd); ++extern int get_linux_version(void); ++extern int parse_uuid(char *str, int uuid[4]); ++extern int check_ext2(int fd, char *name); ++extern int check_reiser(int fd, char *name); ++extern int check_raid(int fd, char *name); ++ ++extern int get_mdp_major(void); ++extern int dev_open(char *dev, int flags); ++extern int is_standard(char *dev, int *nump); ++ ++extern int parse_auto(char *str, char *msg, int config); ++extern mddev_ident_t conf_get_ident(char *dev); ++extern mddev_dev_t conf_get_devs(void); ++extern int conf_test_dev(char *devname); ++extern struct createinfo *conf_get_create_info(void); ++extern void set_conffile(char *file); ++extern char *conf_get_mailaddr(void); ++extern char *conf_get_mailfrom(void); ++extern char *conf_get_program(void); ++extern char *conf_get_homehost(void); ++extern char *conf_line(FILE *file); ++extern char *conf_word(FILE *file, int allow_key); ++extern void free_line(char *line); ++extern int match_oneof(char *devices, char *devname); ++extern void uuid_from_super(int uuid[4], mdp_super_t *super); ++extern int same_uuid(int a[4], int b[4], int swapuuid); ++extern void copy_uuid(void *a, int b[4], int swapuuid); ++/* extern int compare_super(mdp_super_t *first, mdp_super_t *second);*/ ++extern unsigned long calc_csum(void *super, int bytes); ++extern int enough(int level, int raid_disks, int layout, int clean, ++ char *avail, int avail_disks); ++extern int ask(char *mesg); ++extern unsigned long long get_component_size(int fd); ++extern void remove_partitions(int fd); ++ ++ ++extern char *human_size(long long bytes); ++char *human_size_brief(long long bytes); ++ ++extern void put_md_name(char *name); ++extern char *get_md_name(int dev); ++ ++extern char DefaultConfFile[]; ++ ++extern int open_mddev(char *dev, int autof); ++extern int open_mddev_devnum(char *devname, int devnum, char *name, ++ char *chosen_name); ++ ++ ++#define LEVEL_MULTIPATH (-4) ++#define LEVEL_LINEAR (-1) ++#define LEVEL_FAULTY (-5) ++ ++ ++/* faulty stuff */ ++ ++#define WriteTransient 0 ++#define ReadTransient 1 ++#define WritePersistent 2 ++#define ReadPersistent 3 ++#define WriteAll 4 /* doesn't go to device */ ++#define ReadFixable 5 ++#define Modes 6 ++ ++#define ClearErrors 31 ++#define ClearFaults 30 ++ ++#define AllPersist 100 /* internal use only */ ++#define NoPersist 101 ++ ++#define ModeMask 0x1f ++#define ModeShift 5 ++ ++ ++#ifdef __TINYC__ ++#undef minor ++#undef major ++#undef makedev ++#define minor(x) ((x)&0xff) ++#define major(x) (((x)>>8)&0xff) ++#define makedev(M,m) (((M)<<8) | (m)) ++#endif ++ ++/* for raid5 */ ++#define ALGORITHM_LEFT_ASYMMETRIC 0 ++#define ALGORITHM_RIGHT_ASYMMETRIC 1 ++#define ALGORITHM_LEFT_SYMMETRIC 2 ++#define ALGORITHM_RIGHT_SYMMETRIC 3 +--- a/mdadm/mdassemble.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/mdassemble.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,908 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include "mdadm.h" ++#include <ctype.h> ++ ++static int name_matches(char *found, char *required, char *homehost) ++{ ++ /* See if the name found matches the required name, possibly ++ * prefixed with 'homehost' ++ */ ++ char fnd[33]; ++ ++ strncpy(fnd, found, 32); ++ fnd[32] = 0; ++ if (strcmp(found, required)==0) ++ return 1; ++ if (homehost) { ++ int l = strlen(homehost); ++ if (l < 32 && fnd[l] == ':' && ++ strcmp(fnd+l+1, required)==0) ++ return 1; ++ } ++ return 0; ++} ++ ++int open_mddev(char *dev, int autof/*unused */) ++{ ++ int mdfd = open(dev, O_RDWR, 0); ++ if (mdfd < 0) ++ fprintf(stderr, Name ": error opening %s: %s\n", ++ dev, strerror(errno)); ++ else if (md_get_version(mdfd) <= 0) { ++ fprintf(stderr, Name ": %s does not appear to be an md device\n", ++ dev); ++ close(mdfd); ++ mdfd = -1; ++ } ++ return mdfd; ++} ++ ++int Assemble(struct supertype *st, char *mddev, int mdfd, ++ mddev_ident_t ident, ++ mddev_dev_t devlist, char *backup_file, ++ int readonly, int runstop, ++ char *update, char *homehost, ++ int verbose, int force) ++{ ++ /* ++ * The task of Assemble is to find a collection of ++ * devices that should (according to their superblocks) ++ * form an array, and to give this collection to the MD driver. ++ * In Linux-2.4 and later, this involves submitting a ++ * SET_ARRAY_INFO ioctl with no arg - to prepare ++ * the array - and then submit a number of ++ * ADD_NEW_DISK ioctls to add disks into ++ * the array. Finally RUN_ARRAY might ++ * be submitted to start the array. ++ * ++ * Much of the work of Assemble is in finding and/or ++ * checking the disks to make sure they look right. ++ * ++ * If mddev is not set, then scan must be set and we ++ * read through the config file for dev+uuid mapping ++ * We recurse, setting mddev, for each device that ++ * - isn't running ++ * - has a valid uuid (or any uuid if !uuidset) ++ * ++ * If mddev is set, we try to determine state of md. ++ * check version - must be at least 0.90.0 ++ * check kernel version. must be at least 2.4. ++ * If not, we can possibly fall back on START_ARRAY ++ * Try to GET_ARRAY_INFO. ++ * If possible, give up ++ * If not, try to STOP_ARRAY just to make sure ++ * ++ * If !uuidset and scan, look in conf-file for uuid ++ * If not found, give up ++ * If !devlist and scan and uuidset, get list of devs from conf-file ++ * ++ * For each device: ++ * Check superblock - discard if bad ++ * Check uuid (set if we don't have one) - discard if no match ++ * Check superblock similarity if we have a superblock - discard if different ++ * Record events, devicenum ++ * This should give us a list of devices for the array ++ * We should collect the most recent event number ++ * ++ * Count disks with recent enough event count ++ * While force && !enough disks ++ * Choose newest rejected disks, update event count ++ * mark clean and rewrite superblock ++ * If recent kernel: ++ * SET_ARRAY_INFO ++ * foreach device with recent events : ADD_NEW_DISK ++ * if runstop == 1 || "enough" disks and runstop==0 -> RUN_ARRAY ++ * If old kernel: ++ * Check the device numbers in superblock are right ++ * update superblock if any changes ++ * START_ARRAY ++ * ++ */ ++ int clean = 0; ++ int old_linux = 0; ++ int vers = 0; /* Keep gcc quite - it really is initialised */ ++ void *first_super = NULL, *super = NULL; ++ struct { ++ char *devname; ++ unsigned int major, minor; ++ unsigned int oldmajor, oldminor; ++ long long events; ++ int uptodate; ++ int state; ++ int raid_disk; ++ int disk_nr; ++ } *devices; ++ int *best = NULL; /* indexed by raid_disk */ ++ unsigned int bestcnt = 0; ++ int devcnt = 0; ++ unsigned int okcnt, sparecnt; ++ unsigned int req_cnt; ++ unsigned int i; ++ int most_recent = 0; ++ int chosen_drive; ++ int change = 0; ++ int inargv = 0; ++ int bitmap_done; ++ int start_partial_ok = (runstop >= 0) && (force || devlist==NULL || mdfd < 0); ++ unsigned int num_devs; ++ mddev_dev_t tmpdev; ++ struct mdinfo info; ++ char *avail; ++ int nextspare = 0; ++ ++ if (mdfd < 0) ++ return 2; ++ ++ if (get_linux_version() < 2004000) ++ old_linux = 1; ++ ++ if (mdfd >= 0) { ++ vers = md_get_version(mdfd); ++ if (vers <= 0) { ++ fprintf(stderr, Name ": %s appears not to be an md device.\n", mddev); ++ return 1; ++ } ++ if (vers < 9000) { ++ fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n" ++ " Upgrade your kernel or try --build\n"); ++ return 1; ++ } ++ ++ if (ioctl(mdfd, GET_ARRAY_INFO, &info.array)>=0) { ++ fprintf(stderr, Name ": device %s already active - cannot assemble it\n", ++ mddev); ++ return 1; ++ } ++ ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */ ++ } ++ /* ++ * If any subdevs are listed, then any that don't ++ * match ident are discarded. Remainder must all match and ++ * become the array. ++ * If no subdevs, then we scan all devices in the config file, but ++ * there must be something in the identity ++ */ ++ ++ if (!devlist && ++ ident->uuid_set == 0 && ++ ident->super_minor < 0 && ++ ident->devices == NULL) { ++ fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n", ++ mddev ? mddev : "further assembly"); ++ return 1; ++ } ++ if (devlist == NULL) ++ devlist = conf_get_devs(); ++ else if (mdfd >= 0) ++ inargv = 1; ++ ++ tmpdev = devlist; num_devs = 0; ++ while (tmpdev) { ++ if (tmpdev->used) ++ tmpdev->used = 2; ++ else ++ num_devs++; ++ tmpdev = tmpdev->next; ++ } ++ devices = malloc(num_devs * sizeof(*devices)); ++ ++ if (!st && ident->st) st = ident->st; ++ ++ if (verbose>0) ++ fprintf(stderr, Name ": looking for devices for %s\n", ++ mddev ? mddev : "further assembly"); ++ ++ /* first walk the list of devices to find a consistent set ++ * that match the criterea, if that is possible. ++ * We flag the one we like with 'used'. ++ */ ++ for (tmpdev = devlist; ++ tmpdev; ++ tmpdev = tmpdev->next) { ++ char *devname = tmpdev->devname; ++ int dfd; ++ struct stat stb; ++ struct supertype *tst = st; ++ ++ if (tmpdev->used > 1) continue; ++ ++ if (ident->devices && ++ !match_oneof(ident->devices, devname)) { ++ if ((inargv && verbose>=0) || verbose > 0) ++ fprintf(stderr, Name ": %s is not one of %s\n", devname, ident->devices); ++ continue; ++ } ++ ++ if (super) { ++ free(super); ++ super = NULL; ++ } ++ ++ dfd = dev_open(devname, O_RDONLY|O_EXCL); ++ if (dfd < 0) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": cannot open device %s: %s\n", ++ devname, strerror(errno)); ++ tmpdev->used = 2; ++ } else if (fstat(dfd, &stb)< 0) { ++ /* Impossible! */ ++ fprintf(stderr, Name ": fstat failed for %s: %s\n", ++ devname, strerror(errno)); ++ tmpdev->used = 2; ++ } else if ((stb.st_mode & S_IFMT) != S_IFBLK) { ++ fprintf(stderr, Name ": %s is not a block device.\n", ++ devname); ++ tmpdev->used = 2; ++ } else if (!tst && (tst = guess_super(dfd)) == NULL) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": no recogniseable superblock on %s\n", ++ devname); ++ tmpdev->used = 2; ++ } else if (tst->ss->load_super(tst,dfd, &super, NULL)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf( stderr, Name ": no RAID superblock on %s\n", ++ devname); ++ } else { ++ tst->ss->getinfo_super(&info, super); ++ } ++ if (dfd >= 0) close(dfd); ++ ++ if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) && ++ (!super || same_uuid(info.uuid, ident->uuid, tst->ss->swapuuid)==0)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s has wrong uuid.\n", ++ devname); ++ continue; ++ } ++ if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && ++ (!super || name_matches(info.name, ident->name, homehost)==0)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s has wrong name.\n", ++ devname); ++ continue; ++ } ++ if (ident->super_minor != UnSet && ++ (!super || ident->super_minor != info.array.md_minor)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s has wrong super-minor.\n", ++ devname); ++ continue; ++ } ++ if (ident->level != UnSet && ++ (!super|| ident->level != info.array.level)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s has wrong raid level.\n", ++ devname); ++ continue; ++ } ++ if (ident->raid_disks != UnSet && ++ (!super || ident->raid_disks!= info.array.raid_disks)) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s requires wrong number of drives.\n", ++ devname); ++ continue; ++ } ++ if (mdfd < 0) { ++ if (tst == NULL || super == NULL) ++ continue; ++ if (update == NULL && ++ tst->ss->match_home(super, homehost)==0) { ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s is not built for host %s.\n", ++ devname, homehost); ++ /* Auto-assemble, and this is not a usable host */ ++ /* if update != NULL, we are updating the host ++ * name... */ ++ continue; ++ } ++ } ++ /* If we are this far, then we are nearly commited to this device. ++ * If the super_block doesn't exist, or doesn't match others, ++ * then we probably cannot continue ++ * However if one of the arrays is for the homehost, and ++ * the other isn't that can disambiguate. ++ */ ++ ++ if (!super) { ++ fprintf(stderr, Name ": %s has no superblock - assembly aborted\n", ++ devname); ++ free(first_super); ++ return 1; ++ } ++ ++ if (st == NULL) ++ st = tst; ++ if (st->ss != tst->ss || ++ st->minor_version != tst->minor_version || ++ st->ss->compare_super(&first_super, super) != 0) { ++ /* Some mismatch. If exactly one array matches this host, ++ * we can resolve on that one. ++ * Or, if we are auto assembling, we just ignore the second ++ * for now. ++ */ ++ if (mdfd < 0) ++ continue; ++ if (homehost) { ++ int first = st->ss->match_home(first_super, homehost); ++ int last = tst->ss->match_home(super, homehost); ++ if (first+last == 1) { ++ /* We can do something */ ++ if (first) {/* just ignore this one */ ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s misses out due to wrong homehost\n", ++ devname); ++ continue; ++ } else { /* reject all those sofar */ ++ mddev_dev_t td; ++ if ((inargv && verbose >= 0) || verbose > 0) ++ fprintf(stderr, Name ": %s overrides previous devices due to good homehost\n", ++ devname); ++ for (td=devlist; td != tmpdev; td=td->next) ++ if (td->used == 1) ++ td->used = 0; ++ tmpdev->used = 1; ++ continue; ++ } ++ } ++ } ++ fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n", ++ devname); ++ free(super); ++ free(first_super); ++ return 1; ++ } ++ ++ tmpdev->used = 1; ++ } ++ ++ /* Ok, no bad inconsistancy, we can try updating etc */ ++ bitmap_done = 0; ++ for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) { ++ char *devname = tmpdev->devname; ++ struct stat stb; ++ /* looks like a good enough match to update the super block if needed */ ++ { ++ int dfd; ++ dfd = dev_open(devname, O_RDWR|O_EXCL); ++ ++ remove_partitions(dfd); ++ ++ if (super) { ++ free(super); ++ super = NULL; ++ } ++ ++ st->ss->load_super(st, dfd, &super, NULL); ++ st->ss->getinfo_super(&info, super); ++ close(dfd); ++ } ++ ++ stat(devname, &stb); ++ ++ if (verbose > 0) ++ fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n", ++ devname, mddev, info.disk.raid_disk); ++ devices[devcnt].devname = devname; ++ devices[devcnt].major = major(stb.st_rdev); ++ devices[devcnt].minor = minor(stb.st_rdev); ++ devices[devcnt].oldmajor = info.disk.major; ++ devices[devcnt].oldminor = info.disk.minor; ++ devices[devcnt].events = info.events; ++ devices[devcnt].raid_disk = info.disk.raid_disk; ++ devices[devcnt].disk_nr = info.disk.number; ++ devices[devcnt].uptodate = 0; ++ devices[devcnt].state = info.disk.state; ++ if (most_recent < devcnt) { ++ if (devices[devcnt].events ++ > devices[most_recent].events) ++ most_recent = devcnt; ++ } ++ if (info.array.level == -4) ++ /* with multipath, the raid_disk from the superblock is meaningless */ ++ i = devcnt; ++ else ++ i = devices[devcnt].raid_disk; ++ if (i+1 == 0) { ++ if (nextspare < info.array.raid_disks) ++ nextspare = info.array.raid_disks; ++ i = nextspare++; ++ } else { ++ if (i >= info.array.raid_disks && ++ i >= nextspare) ++ nextspare = i+1; ++ } ++ if (i < 10000) { ++ if (i >= bestcnt) { ++ unsigned int newbestcnt = i+10; ++ int *newbest = malloc(sizeof(int)*newbestcnt); ++ unsigned int c; ++ for (c=0; c < newbestcnt; c++) ++ if (c < bestcnt) ++ newbest[c] = best[c]; ++ else ++ newbest[c] = -1; ++ if (best)free(best); ++ best = newbest; ++ bestcnt = newbestcnt; ++ } ++ if (best[i] >=0 && ++ devices[best[i]].events == devices[devcnt].events && ++ devices[best[i]].minor != devices[devcnt].minor && ++ st->ss->major == 0 && ++ info.array.level != -4) { ++ /* two different devices with identical superblock. ++ * Could be a mis-detection caused by overlapping ++ * partitions. fail-safe. ++ */ ++ fprintf(stderr, Name ": WARNING %s and %s appear" ++ " to have very similar superblocks.\n" ++ " If they are really different, " ++ "please --zero the superblock on one\n" ++ " If they are the same or overlap," ++ " please remove one from %s.\n", ++ devices[best[i]].devname, devname, ++ inargv ? "the list" : ++ "the\n DEVICE list in mdadm.conf" ++ ); ++ return 1; ++ } ++ if (best[i] == -1 ++ || devices[best[i]].events < devices[devcnt].events) ++ best[i] = devcnt; ++ } ++ devcnt++; ++ } ++ ++ if (super) ++ free(super); ++ super = NULL; ++ ++ if (update && strcmp(update, "byteorder")==0) ++ st->minor_version = 90; ++ ++ if (devcnt == 0) { ++ fprintf(stderr, Name ": no devices found for %s\n", ++ mddev); ++ free(first_super); ++ return 1; ++ } ++ ++ st->ss->getinfo_super(&info, first_super); ++ clean = info.array.state & 1; ++ ++ /* now we have some devices that might be suitable. ++ * I wonder how many ++ */ ++ avail = malloc(info.array.raid_disks); ++ memset(avail, 0, info.array.raid_disks); ++ okcnt = 0; ++ sparecnt=0; ++ for (i=0; i< bestcnt ;i++) { ++ int j = best[i]; ++ int event_margin = 1; /* always allow a difference of '1' ++ * like the kernel does ++ */ ++ if (j < 0) continue; ++ /* note: we ignore error flags in multipath arrays ++ * as they don't make sense ++ */ ++ if (info.array.level != -4) ++ if (!(devices[j].state & (1<<MD_DISK_SYNC))) { ++ if (!(devices[j].state & (1<<MD_DISK_FAULTY))) ++ sparecnt++; ++ continue; ++ } ++ if (devices[j].events+event_margin >= ++ devices[most_recent].events) { ++ devices[j].uptodate = 1; ++ if (i < info.array.raid_disks) { ++ okcnt++; ++ avail[i]=1; ++ } else ++ sparecnt++; ++ } ++ } ++ while (force && !enough(info.array.level, info.array.raid_disks, ++ info.array.layout, 1, ++ avail, okcnt)) { ++ /* Choose the newest best drive which is ++ * not up-to-date, update the superblock ++ * and add it. ++ */ ++ int fd; ++ long long current_events; ++ chosen_drive = -1; ++ for (i=0; i<info.array.raid_disks && i < bestcnt; i++) { ++ int j = best[i]; ++ if (j>=0 && ++ !devices[j].uptodate && ++ devices[j].events > 0 && ++ (chosen_drive < 0 || ++ devices[j].events > devices[chosen_drive].events)) ++ chosen_drive = j; ++ } ++ if (chosen_drive < 0) ++ break; ++ current_events = devices[chosen_drive].events; ++ add_another: ++ if (verbose >= 0) ++ fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n", ++ devices[chosen_drive].devname, devices[chosen_drive].raid_disk, ++ (int)(devices[chosen_drive].events), ++ (int)(devices[most_recent].events)); ++ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL); ++ if (fd < 0) { ++ fprintf(stderr, Name ": Couldn't open %s for write - not updating\n", ++ devices[chosen_drive].devname); ++ devices[chosen_drive].events = 0; ++ continue; ++ } ++ if (st->ss->load_super(st,fd, &super, NULL)) { ++ close(fd); ++ fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n", ++ devices[chosen_drive].devname); ++ devices[chosen_drive].events = 0; ++ continue; ++ } ++ info.events = devices[most_recent].events; ++ st->ss->update_super(&info, super, "force-one", ++ devices[chosen_drive].devname, verbose, ++ 0, NULL); ++ ++ if (st->ss->store_super(st, fd, super)) { ++ close(fd); ++ fprintf(stderr, Name ": Could not re-write superblock on %s\n", ++ devices[chosen_drive].devname); ++ devices[chosen_drive].events = 0; ++ free(super); ++ continue; ++ } ++ close(fd); ++ devices[chosen_drive].events = devices[most_recent].events; ++ devices[chosen_drive].uptodate = 1; ++ avail[chosen_drive] = 1; ++ okcnt++; ++ free(super); ++ ++ /* If there are any other drives of the same vintage, ++ * add them in as well. We can't lose and we might gain ++ */ ++ for (i=0; i<info.array.raid_disks && i < bestcnt ; i++) { ++ int j = best[i]; ++ if (j >= 0 && ++ !devices[j].uptodate && ++ devices[j].events > 0 && ++ devices[j].events == current_events) { ++ chosen_drive = j; ++ goto add_another; ++ } ++ } ++ } ++ ++ /* Now we want to look at the superblock which the kernel will base things on ++ * and compare the devices that we think are working with the devices that the ++ * superblock thinks are working. ++ * If there are differences and --force is given, then update this chosen ++ * superblock. ++ */ ++ chosen_drive = -1; ++ super = NULL; ++ for (i=0; chosen_drive < 0 && i<bestcnt; i++) { ++ int j = best[i]; ++ int fd; ++ ++ if (j<0) ++ continue; ++ if (!devices[j].uptodate) ++ continue; ++ chosen_drive = j; ++ if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) { ++ fprintf(stderr, Name ": Cannot open %s: %s\n", ++ devices[j].devname, strerror(errno)); ++ return 1; ++ } ++ if (st->ss->load_super(st,fd, &super, NULL)) { ++ close(fd); ++ fprintf(stderr, Name ": RAID superblock has disappeared from %s\n", ++ devices[j].devname); ++ return 1; ++ } ++ close(fd); ++ } ++ if (super == NULL) { ++ fprintf(stderr, Name ": No suitable drives found for %s\n", mddev); ++ return 1; ++ } ++ st->ss->getinfo_super(&info, super); ++ for (i=0; i<bestcnt; i++) { ++ int j = best[i]; ++ unsigned int desired_state; ++ ++ if (i < info.array.raid_disks) ++ desired_state = (1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC); ++ else ++ desired_state = 0; ++ ++ if (j<0) ++ continue; ++ if (!devices[j].uptodate) ++ continue; ++ info.disk.number = devices[j].disk_nr; ++ info.disk.raid_disk = i; ++ info.disk.state = desired_state; ++ ++ if (devices[j].uptodate && ++ st->ss->update_super(&info, super, "assemble", NULL, verbose, 0, NULL)) { ++ if (force) { ++ if (verbose >= 0) ++ fprintf(stderr, Name ": " ++ "clearing FAULTY flag for device %d in %s for %s\n", ++ j, mddev, devices[j].devname); ++ change = 1; ++ } else { ++ if (verbose >= -1) ++ fprintf(stderr, Name ": " ++ "device %d in %s has wrong state in superblock, but %s seems ok\n", ++ i, mddev, devices[j].devname); ++ } ++ } ++#if 0 ++ if (!devices[j].uptodate && ++ !(super.disks[i].state & (1 << MD_DISK_FAULTY))) { ++ fprintf(stderr, Name ": devices %d of %s is not marked FAULTY in superblock, but cannot be found\n", ++ i, mddev); ++ } ++#endif ++ } ++ if (force && !clean && ++ !enough(info.array.level, info.array.raid_disks, ++ info.array.layout, clean, ++ avail, okcnt)) { ++ change += st->ss->update_super(&info, super, "force-array", ++ devices[chosen_drive].devname, verbose, ++ 0, NULL); ++ clean = 1; ++ } ++ ++ if (change) { ++ int fd; ++ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL); ++ if (fd < 0) { ++ fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n", ++ devices[chosen_drive].devname); ++ return 1; ++ } ++ if (st->ss->store_super(st, fd, super)) { ++ close(fd); ++ fprintf(stderr, Name ": Could not re-write superblock on %s\n", ++ devices[chosen_drive].devname); ++ return 1; ++ } ++ close(fd); ++ } ++ ++ /* count number of in-sync devices according to the superblock. ++ * We must have this number to start the array without -s or -R ++ */ ++ req_cnt = info.array.working_disks; ++ ++ /* Almost ready to actually *do* something */ ++ if (!old_linux) { ++ int rv; ++ if ((vers % 100) >= 1) { /* can use different versions */ ++ mdu_array_info_t inf; ++ memset(&inf, 0, sizeof(inf)); ++ inf.major_version = st->ss->major; ++ inf.minor_version = st->minor_version; ++ rv = ioctl(mdfd, SET_ARRAY_INFO, &inf); ++ } else ++ rv = ioctl(mdfd, SET_ARRAY_INFO, NULL); ++ ++ if (rv) { ++ fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n", ++ mddev, strerror(errno)); ++ return 1; ++ } ++ if (ident->bitmap_fd >= 0) { ++ if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) { ++ fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n"); ++ return 1; ++ } ++ } else if (ident->bitmap_file) { ++ /* From config file */ ++ int bmfd = open(ident->bitmap_file, O_RDWR); ++ if (bmfd < 0) { ++ fprintf(stderr, Name ": Could not open bitmap file %s\n", ++ ident->bitmap_file); ++ return 1; ++ } ++ if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) { ++ fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev); ++ close(bmfd); ++ return 1; ++ } ++ close(bmfd); ++ } ++ ++ /* First, add the raid disks, but add the chosen one last */ ++ for (i=0; i<= bestcnt; i++) { ++ int j; ++ if (i < bestcnt) { ++ j = best[i]; ++ if (j == chosen_drive) ++ continue; ++ } else ++ j = chosen_drive; ++ ++ if (j >= 0 /* && devices[j].uptodate */) { ++ mdu_disk_info_t disk; ++ memset(&disk, 0, sizeof(disk)); ++ disk.major = devices[j].major; ++ disk.minor = devices[j].minor; ++ if (ioctl(mdfd, ADD_NEW_DISK, &disk)!=0) { ++ fprintf(stderr, Name ": failed to add %s to %s: %s\n", ++ devices[j].devname, ++ mddev, ++ strerror(errno)); ++ if (i < info.array.raid_disks || i == bestcnt) ++ okcnt--; ++ else ++ sparecnt--; ++ } else if (verbose > 0) ++ fprintf(stderr, Name ": added %s to %s as %d\n", ++ devices[j].devname, mddev, devices[j].raid_disk); ++ } else if (verbose > 0 && i < info.array.raid_disks) ++ fprintf(stderr, Name ": no uptodate device for slot %d of %s\n", ++ i, mddev); ++ } ++ ++ if (runstop == 1 || ++ (runstop <= 0 && ++ ( enough(info.array.level, info.array.raid_disks, ++ info.array.layout, clean, avail, okcnt) && ++ (okcnt >= req_cnt || start_partial_ok) ++ ))) { ++ if (ioctl(mdfd, RUN_ARRAY, NULL)==0) { ++ if (verbose >= 0) { ++ fprintf(stderr, Name ": %s has been started with %d drive%s", ++ mddev, okcnt, okcnt==1?"":"s"); ++ if (okcnt < info.array.raid_disks) ++ fprintf(stderr, " (out of %d)", info.array.raid_disks); ++ if (sparecnt) ++ fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); ++ fprintf(stderr, ".\n"); ++ } ++ return 0; ++ } ++ fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n", ++ mddev, strerror(errno)); ++ ++ if (!enough(info.array.level, info.array.raid_disks, ++ info.array.layout, 1, avail, okcnt)) ++ fprintf(stderr, Name ": Not enough devices to " ++ "start the array.\n"); ++ else if (!enough(info.array.level, ++ info.array.raid_disks, ++ info.array.layout, clean, ++ avail, okcnt)) ++ fprintf(stderr, Name ": Not enough devices to " ++ "start the array while not clean " ++ "- consider --force.\n"); ++ ++ return 1; ++ } ++ if (runstop == -1) { ++ fprintf(stderr, Name ": %s assembled from %d drive%s", ++ mddev, okcnt, okcnt==1?"":"s"); ++ if (okcnt != info.array.raid_disks) ++ fprintf(stderr, " (out of %d)", info.array.raid_disks); ++ fprintf(stderr, ", but not started.\n"); ++ return 0; ++ } ++ if (verbose >= -1) { ++ fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s"); ++ if (sparecnt) ++ fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); ++ if (!enough(info.array.level, info.array.raid_disks, ++ info.array.layout, 1, avail, okcnt)) ++ fprintf(stderr, " - not enough to start the array.\n"); ++ else if (!enough(info.array.level, ++ info.array.raid_disks, ++ info.array.layout, clean, ++ avail, okcnt)) ++ fprintf(stderr, " - not enough to start the " ++ "array while not clean - consider " ++ "--force.\n"); ++ else { ++ if (req_cnt == info.array.raid_disks) ++ fprintf(stderr, " - need all %d to start it", req_cnt); ++ else ++ fprintf(stderr, " - need %d of %d to start", req_cnt, info.array.raid_disks); ++ fprintf(stderr, " (use --run to insist).\n"); ++ } ++ } ++ return 1; ++ } else { ++ /* The "chosen_drive" is a good choice, and if necessary, the superblock has ++ * been updated to point to the current locations of devices. ++ * so we can just start the array ++ */ ++ unsigned long dev; ++ dev = makedev(devices[chosen_drive].major, ++ devices[chosen_drive].minor); ++ if (ioctl(mdfd, START_ARRAY, dev)) { ++ fprintf(stderr, Name ": Cannot start array: %s\n", ++ strerror(errno)); ++ } ++ ++ } ++ return 0; ++} ++ ++int mdfd = -1; ++int runstop = 0; ++int readonly = 0; ++int verbose = 0; ++int force = 0; ++ ++int mdassemble_main(int argc, char **argv) { ++ mddev_ident_t array_list = conf_get_ident(NULL); ++ int minor; ++ if (!array_list) { ++ fprintf(stderr, Name ": No arrays found in config file\n"); ++ return 1; ++ } else { ++ for (; array_list; array_list = array_list->next) { ++ mdu_array_info_t array; ++ if (!strncmp("/dev/md", array_list->devname, 7)) { ++ errno = 0; ++ minor = strtoul(array_list->devname + 7, NULL, 0); ++ if (!errno) { ++ mknod(array_list->devname, S_IFBLK|0600, makedev(MD_MAJOR, minor)); ++ } ++ } ++ mdfd = open_mddev(array_list->devname, array_list->autof); ++ if (mdfd < 0) { ++ ++ fprintf(stderr, Name ": failed to open array\n"); ++ continue; ++ } ++ if (ioctl(mdfd, GET_ARRAY_INFO, &array) < 0) { ++ Assemble(array_list->st, array_list->devname, mdfd, ++ array_list, NULL, NULL, ++ readonly, runstop, NULL, NULL, verbose, force); ++ } ++ close(mdfd); ++ } ++ } ++ return 0; ++} ++ +--- a/mdadm/mdexamine.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/mdexamine.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,157 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include "mdadm.h" ++#include "dlink.h" ++ ++#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) ++#error no endian defined ++#endif ++#include "md_u.h" ++#include "md_p.h" ++ ++static int Examine(mddev_dev_t devlist, int brief, int scan, ++ int SparcAdjust, struct supertype *forcest, ++ char *homehost) ++{ ++ ++ /* Read the raid superblock from a device and ++ * display important content. ++ * ++ * If cannot be found, print reason: too small, bad magic ++ * ++ * Print: ++ * version, ctime, level, size, raid+spare+ ++ * prefered minor ++ * uuid ++ * ++ * utime, state etc ++ * ++ * If (brief) gather devices for same array and just print a mdadm.conf line including devices= ++ * if devlist==NULL, use conf_get_devs() ++ */ ++ int fd; ++ void *super = NULL; ++ int rv = 0; ++ int err = 0; ++ ++ struct array { ++ void *super; ++ struct supertype *st; ++ struct mdinfo info; ++ void *devs; ++ struct array *next; ++ int spares; ++ } *arrays = NULL; ++ ++ for (; devlist ; devlist=devlist->next) { ++ struct supertype *st = forcest; ++ ++ fd = dev_open(devlist->devname, O_RDONLY); ++ if (fd < 0) { ++ if (!scan) { ++ fprintf(stderr,Name ": cannot open %s: %s\n", ++ devlist->devname, strerror(errno)); ++ rv = 1; ++ } ++ err = 1; ++ } ++ else { ++ if (!st) ++ st = guess_super(fd); ++ if (st) ++ err = st->ss->load_super(st, fd, &super, (brief||scan)?NULL:devlist->devname); ++ else { ++ if (!brief) { ++ fprintf(stderr, Name ": No md superblock detected on %s.\n", devlist->devname); ++ rv = 1; ++ } ++ err = 1; ++ } ++ close(fd); ++ } ++ if (err) ++ continue; ++ ++ if (SparcAdjust) ++ st->ss->update_super(NULL, super, "sparc2.2", devlist->devname, 0, 0, NULL); ++ /* Ok, its good enough to try, though the checksum could be wrong */ ++ if (brief) { ++ struct array *ap; ++ char *d; ++ for (ap=arrays; ap; ap=ap->next) { ++ if (st->ss == ap->st->ss && st->ss->compare_super(&ap->super, super)==0) ++ break; ++ } ++ if (!ap) { ++ ap = malloc(sizeof(*ap)); ++ ap->super = super; ++ ap->devs = dl_head(); ++ ap->next = arrays; ++ ap->spares = 0; ++ ap->st = st; ++ arrays = ap; ++ st->ss->getinfo_super(&ap->info, super); ++ } else { ++ st->ss->getinfo_super(&ap->info, super); ++ free(super); ++ } ++ if (!(ap->info.disk.state & MD_DISK_SYNC)) ++ ap->spares++; ++ d = dl_strdup(devlist->devname); ++ dl_add(ap->devs, d); ++ } ++ } ++ if (brief) { ++ struct array *ap; ++ for (ap=arrays; ap; ap=ap->next) { ++ char sep='='; ++ char *d; ++ ap->st->ss->brief_examine_super(ap->super); ++ if (ap->spares) printf(" spares=%d", ap->spares); ++ if (brief > 1) { ++ printf(" devices"); ++ for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) { ++ printf("%c%s", sep, d); ++ sep=','; ++ } ++ } ++ free(ap->super); ++ /* FIXME free ap */ ++ if (ap->spares || brief > 1) ++ printf("\n"); ++ } ++ } ++ return rv; ++} ++ ++int mdexamine_main(int argc, char **argv) { ++ return Examine(conf_get_devs(), 1, 0, 0, NULL, NULL); ++} ++ +--- a/mdadm/md_p.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/md_p.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,194 @@ ++/* ++ md_p.h : physical layout of Linux RAID devices ++ Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman ++ ++ 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, or (at your option) ++ any later version. ++ ++ You should have received a copy of the GNU General Public License ++ (for example /usr/src/linux/COPYING); if not, write to the Free ++ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#ifndef _MD_P_H ++#define _MD_P_H ++ ++/* ++ * RAID superblock. ++ * ++ * The RAID superblock maintains some statistics on each RAID configuration. ++ * Each real device in the RAID set contains it near the end of the device. ++ * Some of the ideas are copied from the ext2fs implementation. ++ * ++ * We currently use 4096 bytes as follows: ++ * ++ * word offset function ++ * ++ * 0 - 31 Constant generic RAID device information. ++ * 32 - 63 Generic state information. ++ * 64 - 127 Personality specific information. ++ * 128 - 511 12 32-words descriptors of the disks in the raid set. ++ * 512 - 911 Reserved. ++ * 912 - 1023 Disk specific descriptor. ++ */ ++ ++/* ++ * If x is the real device size in bytes, we return an apparent size of: ++ * ++ * y = (x & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES ++ * ++ * and place the 4kB superblock at offset y. ++ */ ++#define MD_RESERVED_BYTES (64 * 1024) ++#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512) ++#define MD_RESERVED_BLOCKS (MD_RESERVED_BYTES / BLOCK_SIZE) ++ ++#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS) ++#define MD_NEW_SIZE_BLOCKS(x) ((x & ~(MD_RESERVED_BLOCKS - 1)) - MD_RESERVED_BLOCKS) ++ ++#define MD_SB_BYTES 4096 ++#define MD_SB_WORDS (MD_SB_BYTES / 4) ++#define MD_SB_BLOCKS (MD_SB_BYTES / BLOCK_SIZE) ++#define MD_SB_SECTORS (MD_SB_BYTES / 512) ++ ++/* ++ * The following are counted in 32-bit words ++ */ ++#define MD_SB_GENERIC_OFFSET 0 ++#define MD_SB_PERSONALITY_OFFSET 64 ++#define MD_SB_DISKS_OFFSET 128 ++#define MD_SB_DESCRIPTOR_OFFSET 992 ++ ++#define MD_SB_GENERIC_CONSTANT_WORDS 32 ++#define MD_SB_GENERIC_STATE_WORDS 32 ++#define MD_SB_GENERIC_WORDS (MD_SB_GENERIC_CONSTANT_WORDS + MD_SB_GENERIC_STATE_WORDS) ++#define MD_SB_PERSONALITY_WORDS 64 ++#define MD_SB_DESCRIPTOR_WORDS 32 ++#define MD_SB_DISKS 27 ++#define MD_SB_DISKS_WORDS (MD_SB_DISKS*MD_SB_DESCRIPTOR_WORDS) ++#define MD_SB_RESERVED_WORDS (1024 - MD_SB_GENERIC_WORDS - MD_SB_PERSONALITY_WORDS - MD_SB_DISKS_WORDS - MD_SB_DESCRIPTOR_WORDS) ++#define MD_SB_EQUAL_WORDS (MD_SB_GENERIC_WORDS + MD_SB_PERSONALITY_WORDS + MD_SB_DISKS_WORDS) ++ ++/* ++ * Device "operational" state bits ++ */ ++#define MD_DISK_FAULTY 0 /* disk is faulty / operational */ ++#define MD_DISK_ACTIVE 1 /* disk is running or spare disk */ ++#define MD_DISK_SYNC 2 /* disk is in sync with the raid set */ ++#define MD_DISK_REMOVED 3 /* disk is in sync with the raid set */ ++ ++#define MD_DISK_WRITEMOSTLY 9 /* disk is "write-mostly" is RAID1 config. ++ * read requests will only be sent here in ++ * dire need ++ */ ++ ++typedef struct mdp_device_descriptor_s { ++ __u32 number; /* 0 Device number in the entire set */ ++ __u32 major; /* 1 Device major number */ ++ __u32 minor; /* 2 Device minor number */ ++ __u32 raid_disk; /* 3 The role of the device in the raid set */ ++ __u32 state; /* 4 Operational state */ ++ __u32 reserved[MD_SB_DESCRIPTOR_WORDS - 5]; ++} mdp_disk_t; ++ ++#define MD_SB_MAGIC 0xa92b4efc ++ ++/* ++ * Superblock state bits ++ */ ++#define MD_SB_CLEAN 0 ++#define MD_SB_ERRORS 1 ++ ++#define MD_SB_BITMAP_PRESENT 8 /* bitmap may be present nearby */ ++ ++typedef struct mdp_superblock_s { ++ /* ++ * Constant generic information ++ */ ++ __u32 md_magic; /* 0 MD identifier */ ++ __u32 major_version; /* 1 major version to which the set conforms */ ++ __u32 minor_version; /* 2 minor version ... */ ++ __u32 patch_version; /* 3 patchlevel version ... */ ++ __u32 gvalid_words; /* 4 Number of used words in this section */ ++ __u32 set_uuid0; /* 5 Raid set identifier */ ++ __u32 ctime; /* 6 Creation time */ ++ __u32 level; /* 7 Raid personality */ ++ __u32 size; /* 8 Apparent size of each individual disk */ ++ __u32 nr_disks; /* 9 total disks in the raid set */ ++ __u32 raid_disks; /* 10 disks in a fully functional raid set */ ++ __u32 md_minor; /* 11 preferred MD minor device number */ ++ __u32 not_persistent; /* 12 does it have a persistent superblock */ ++ __u32 set_uuid1; /* 13 Raid set identifier #2 */ ++ __u32 set_uuid2; /* 14 Raid set identifier #3 */ ++ __u32 set_uuid3; /* 15 Raid set identifier #4 */ ++ __u32 gstate_creserved[MD_SB_GENERIC_CONSTANT_WORDS - 16]; ++ ++ /* ++ * Generic state information ++ */ ++ __u32 utime; /* 0 Superblock update time */ ++ __u32 state; /* 1 State bits (clean, ...) */ ++ __u32 active_disks; /* 2 Number of currently active disks */ ++ __u32 working_disks; /* 3 Number of working disks */ ++ __u32 failed_disks; /* 4 Number of failed disks */ ++ __u32 spare_disks; /* 5 Number of spare disks */ ++ __u32 sb_csum; /* 6 checksum of the whole superblock */ ++#if __BYTE_ORDER == __BIG_ENDIAN ++ __u32 events_hi; /* 7 high-order of superblock update count */ ++ __u32 events_lo; /* 8 low-order of superblock update count */ ++ __u32 cp_events_hi; /* 9 high-order of checkpoint update count */ ++ __u32 cp_events_lo; /* 10 low-order of checkpoint update count */ ++#else ++ __u32 events_lo; /* 7 low-order of superblock update count */ ++ __u32 events_hi; /* 8 high-order of superblock update count */ ++ __u32 cp_events_lo; /* 9 low-order of checkpoint update count */ ++ __u32 cp_events_hi; /* 10 high-order of checkpoint update count */ ++#endif ++ __u32 recovery_cp; /* 11 recovery checkpoint sector count */ ++ /* There are only valid for minor_version > 90 */ ++ __u64 reshape_position; /* 12,13 next address in array-space for reshape */ ++ __u32 new_level; /* 14 new level we are reshaping to */ ++ __u32 delta_disks; /* 15 change in number of raid_disks */ ++ __u32 new_layout; /* 16 new layout */ ++ __u32 new_chunk; /* 17 new chunk size (bytes) */ ++ __u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 18]; ++ ++ /* ++ * Personality information ++ */ ++ __u32 layout; /* 0 the array's physical layout */ ++ __u32 chunk_size; /* 1 chunk size in bytes */ ++ __u32 root_pv; /* 2 LV root PV */ ++ __u32 root_block; /* 3 LV root block */ ++ __u32 pstate_reserved[MD_SB_PERSONALITY_WORDS - 4]; ++ ++ /* ++ * Disks information ++ */ ++ mdp_disk_t disks[MD_SB_DISKS]; ++ ++ /* ++ * Reserved ++ */ ++ __u32 reserved[MD_SB_RESERVED_WORDS]; ++ ++ /* ++ * Active descriptor ++ */ ++ mdp_disk_t this_disk; ++ ++} mdp_super_t; ++ ++#ifdef __TINYC__ ++typedef unsigned long long __u64; ++#endif ++ ++static inline __u64 md_event(mdp_super_t *sb) { ++ __u64 ev = sb->events_hi; ++ return (ev<<32)| sb->events_lo; ++} ++ ++#endif ++ +--- a/mdadm/md_u.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/md_u.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,123 @@ ++/* ++ md_u.h : user <=> kernel API between Linux raidtools and RAID drivers ++ Copyright (C) 1998 Ingo Molnar ++ ++ 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, or (at your option) ++ any later version. ++ ++ You should have received a copy of the GNU General Public License ++ (for example /usr/src/linux/COPYING); if not, write to the Free ++ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#ifndef _MD_U_H ++#define _MD_U_H ++ ++/* ioctls */ ++ ++/* status */ ++#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) ++#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) ++#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) ++#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) ++#define RAID_AUTORUN _IO (MD_MAJOR, 0x14) ++#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) ++ ++/* configuration */ ++#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) ++#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) ++#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) ++#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) ++#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) ++#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) ++#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) ++#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) ++#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) ++#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) ++#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) ++ ++/* usage */ ++#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) ++#define START_ARRAY _IO (MD_MAJOR, 0x31) ++#define STOP_ARRAY _IO (MD_MAJOR, 0x32) ++#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) ++#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) ++ ++typedef struct mdu_version_s { ++ int major; ++ int minor; ++ int patchlevel; ++} mdu_version_t; ++ ++typedef struct mdu_array_info_s { ++ /* ++ * Generic constant information ++ */ ++ int major_version; ++ int minor_version; ++ int patch_version; ++ int ctime; ++ int level; ++ int size; ++ int nr_disks; ++ int raid_disks; ++ int md_minor; ++ int not_persistent; ++ ++ /* ++ * Generic state information ++ */ ++ int utime; /* 0 Superblock update time */ ++ int state; /* 1 State bits (clean, ...) */ ++ int active_disks; /* 2 Number of currently active disks */ ++ int working_disks; /* 3 Number of working disks */ ++ int failed_disks; /* 4 Number of failed disks */ ++ int spare_disks; /* 5 Number of spare disks */ ++ ++ /* ++ * Personality information ++ */ ++ int layout; /* 0 the array's physical layout */ ++ int chunk_size; /* 1 chunk size in bytes */ ++ ++} mdu_array_info_t; ++ ++typedef struct mdu_disk_info_s { ++ /* ++ * configuration/status of one particular disk ++ */ ++ int number; ++ int major; ++ int minor; ++ int raid_disk; ++ int state; ++ ++} mdu_disk_info_t; ++ ++typedef struct mdu_start_info_s { ++ /* ++ * configuration/status of one particular disk ++ */ ++ int major; ++ int minor; ++ int raid_disk; ++ int state; ++ ++} mdu_start_info_t; ++ ++typedef struct mdu_bitmap_file_s ++{ ++ char pathname[4096]; ++} mdu_bitmap_file_t; ++ ++typedef struct mdu_param_s ++{ ++ int personality; /* 1,2,3,4 */ ++ int chunk_size; /* in bytes */ ++ int max_fault; /* unused for now */ ++} mdu_param_t; ++ ++#endif ++ +--- a/mdadm/sha1.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/sha1.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,423 @@ ++/* sha1.c - Functions to compute SHA1 message digest of files or ++ memory blocks according to the NIST specification FIPS-180-1. ++ ++ Copyright (C) 2000, 2001, 2003, 2004, 2005 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ++ ++/* Written by Scott G. Miller ++ Credits: ++ Robert Klep <robert@ilse.nl> -- Expansion function fix ++*/ ++ ++#ifdef HAVE_CONFIG_H ++# include <config.h> ++#endif ++ ++#include "sha1.h" ++ ++#include <stddef.h> ++#include <string.h> ++ ++#if USE_UNLOCKED_IO ++# include "unlocked-io.h" ++#endif ++ ++/* SWAP does an endian swap on architectures that are little-endian, ++ as SHA1 needs some data in a big-endian form. */ ++ ++#ifdef WORDS_BIGENDIAN ++# define SWAP(n) (n) ++#else ++# define SWAP(n) \ ++ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) ++#endif ++ ++#define BLOCKSIZE 4096 ++#if BLOCKSIZE % 64 != 0 ++# error "invalid BLOCKSIZE" ++#endif ++ ++/* This array contains the bytes used to pad the buffer to the next ++ 64-byte boundary. (RFC 1321, 3.1: Step 1) */ ++static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; ++ ++ ++/* ++ Takes a pointer to a 160 bit block of data (five 32 bit ints) and ++ intializes it to the start constants of the SHA1 algorithm. This ++ must be called before using hash in the call to sha1_hash. ++*/ ++void ++sha1_init_ctx (struct sha1_ctx *ctx) ++{ ++ ctx->A = 0x67452301; ++ ctx->B = 0xefcdab89; ++ ctx->C = 0x98badcfe; ++ ctx->D = 0x10325476; ++ ctx->E = 0xc3d2e1f0; ++ ++ ctx->total[0] = ctx->total[1] = 0; ++ ctx->buflen = 0; ++} ++ ++/* Put result from CTX in first 20 bytes following RESBUF. The result ++ must be in little endian byte order. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++void * ++sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) ++{ ++ ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); ++ ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); ++ ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); ++ ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); ++ ((md5_uint32 *) resbuf)[4] = SWAP (ctx->E); ++ ++ return resbuf; ++} ++ ++/* Process the remaining bytes in the internal buffer and the usual ++ prolog according to the standard and write the result to RESBUF. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++void * ++sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) ++{ ++ /* Take yet unprocessed bytes into account. */ ++ md5_uint32 bytes = ctx->buflen; ++ size_t pad; ++ ++ /* Now count remaining bytes. */ ++ ctx->total[0] += bytes; ++ if (ctx->total[0] < bytes) ++ ++ctx->total[1]; ++ ++ pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; ++ memcpy (&ctx->buffer[bytes], fillbuf, pad); ++ ++ /* Put the 64-bit file length in *bits* at the end of the buffer. */ ++ *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3); ++ *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | ++ (ctx->total[0] >> 29)); ++ ++ /* Process last bytes. */ ++ sha1_process_block (ctx->buffer, bytes + pad + 8, ctx); ++ ++ return sha1_read_ctx (ctx, resbuf); ++} ++ ++/* Compute SHA1 message digest for bytes read from STREAM. The ++ resulting message digest number will be written into the 16 bytes ++ beginning at RESBLOCK. */ ++int ++sha1_stream (FILE *stream, void *resblock) ++{ ++ struct sha1_ctx ctx; ++ char buffer[BLOCKSIZE + 72]; ++ size_t sum; ++ ++ /* Initialize the computation context. */ ++ sha1_init_ctx (&ctx); ++ ++ /* Iterate over full file contents. */ ++ while (1) ++ { ++ /* We read the file in blocks of BLOCKSIZE bytes. One call of the ++ computation function processes the whole buffer so that with the ++ next round of the loop another block can be read. */ ++ size_t n; ++ sum = 0; ++ ++ /* Read block. Take care for partial reads. */ ++ while (1) ++ { ++ n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); ++ ++ sum += n; ++ ++ if (sum == BLOCKSIZE) ++ break; ++ ++ if (n == 0) ++ { ++ /* Check for the error flag IFF N == 0, so that we don't ++ exit the loop after a partial read due to e.g., EAGAIN ++ or EWOULDBLOCK. */ ++ if (ferror (stream)) ++ return 1; ++ goto process_partial_block; ++ } ++ ++ /* We've read at least one byte, so ignore errors. But always ++ check for EOF, since feof may be true even though N > 0. ++ Otherwise, we could end up calling fread after EOF. */ ++ if (feof (stream)) ++ goto process_partial_block; ++ } ++ ++ /* Process buffer with BLOCKSIZE bytes. Note that ++ BLOCKSIZE % 64 == 0 ++ */ ++ sha1_process_block (buffer, BLOCKSIZE, &ctx); ++ } ++ ++ process_partial_block:; ++ ++ /* Process any remaining bytes. */ ++ if (sum > 0) ++ sha1_process_bytes (buffer, sum, &ctx); ++ ++ /* Construct result in desired memory. */ ++ sha1_finish_ctx (&ctx, resblock); ++ return 0; ++} ++ ++/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The ++ result is always in little endian byte order, so that a byte-wise ++ output yields to the wanted ASCII representation of the message ++ digest. */ ++void * ++sha1_buffer (const char *buffer, size_t len, void *resblock) ++{ ++ struct sha1_ctx ctx; ++ ++ /* Initialize the computation context. */ ++ sha1_init_ctx (&ctx); ++ ++ /* Process whole buffer but last len % 64 bytes. */ ++ sha1_process_bytes (buffer, len, &ctx); ++ ++ /* Put result in desired memory area. */ ++ return sha1_finish_ctx (&ctx, resblock); ++} ++ ++void ++sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) ++{ ++ /* When we already have some bits in our internal buffer concatenate ++ both inputs first. */ ++ if (ctx->buflen != 0) ++ { ++ size_t left_over = ctx->buflen; ++ size_t add = 128 - left_over > len ? len : 128 - left_over; ++ ++ memcpy (&ctx->buffer[left_over], buffer, add); ++ ctx->buflen += add; ++ ++ if (ctx->buflen > 64) ++ { ++ sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); ++ ++ ctx->buflen &= 63; ++ /* The regions in the following copy operation cannot overlap. */ ++ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ++ ctx->buflen); ++ } ++ ++ buffer = (const char *) buffer + add; ++ len -= add; ++ } ++ ++ /* Process available complete blocks. */ ++ if (len >= 64) ++ { ++#if !_STRING_ARCH_unaligned ++# define alignof(type) offsetof (struct { char c; type x; }, x) ++# define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0) ++ if (UNALIGNED_P (buffer)) ++ while (len > 64) ++ { ++ sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); ++ buffer = (const char *) buffer + 64; ++ len -= 64; ++ } ++ else ++#endif ++ { ++ sha1_process_block (buffer, len & ~63, ctx); ++ buffer = (const char *) buffer + (len & ~63); ++ len &= 63; ++ } ++ } ++ ++ /* Move remaining bytes in internal buffer. */ ++ if (len > 0) ++ { ++ size_t left_over = ctx->buflen; ++ ++ memcpy (&ctx->buffer[left_over], buffer, len); ++ left_over += len; ++ if (left_over >= 64) ++ { ++ sha1_process_block (ctx->buffer, 64, ctx); ++ left_over -= 64; ++ memcpy (ctx->buffer, &ctx->buffer[64], left_over); ++ } ++ ctx->buflen = left_over; ++ } ++} ++ ++/* --- Code below is the primary difference between md5.c and sha1.c --- */ ++ ++/* SHA1 round constants */ ++#define K1 0x5a827999L ++#define K2 0x6ed9eba1L ++#define K3 0x8f1bbcdcL ++#define K4 0xca62c1d6L ++ ++/* Round functions. Note that F2 is the same as F4. */ ++#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) ++#define F2(B,C,D) (B ^ C ^ D) ++#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) ++#define F4(B,C,D) (B ^ C ^ D) ++ ++/* Process LEN bytes of BUFFER, accumulating context into CTX. ++ It is assumed that LEN % 64 == 0. ++ Most of this code comes from GnuPG's cipher/sha1.c. */ ++ ++void ++sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) ++{ ++ const md5_uint32 *words = buffer; ++ size_t nwords = len / sizeof (md5_uint32); ++ const md5_uint32 *endp = words + nwords; ++ md5_uint32 x[16]; ++ md5_uint32 a = ctx->A; ++ md5_uint32 b = ctx->B; ++ md5_uint32 c = ctx->C; ++ md5_uint32 d = ctx->D; ++ md5_uint32 e = ctx->E; ++ ++ /* First increment the byte count. RFC 1321 specifies the possible ++ length of the file up to 2^64 bits. Here we only compute the ++ number of bytes. Do a double word increment. */ ++ ctx->total[0] += len; ++ if (ctx->total[0] < len) ++ ++ctx->total[1]; ++ ++#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) ++ ++#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ ++ ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ ++ , (x[I&0x0f] = rol(tm, 1)) ) ++ ++#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ ++ + F( B, C, D ) \ ++ + K \ ++ + M; \ ++ B = rol( B, 30 ); \ ++ } while(0) ++ ++ while (words < endp) ++ { ++ md5_uint32 tm; ++ int t; ++ for (t = 0; t < 16; t++) ++ { ++ x[t] = SWAP (*words); ++ words++; ++ } ++ ++ R( a, b, c, d, e, F1, K1, x[ 0] ); ++ R( e, a, b, c, d, F1, K1, x[ 1] ); ++ R( d, e, a, b, c, F1, K1, x[ 2] ); ++ R( c, d, e, a, b, F1, K1, x[ 3] ); ++ R( b, c, d, e, a, F1, K1, x[ 4] ); ++ R( a, b, c, d, e, F1, K1, x[ 5] ); ++ R( e, a, b, c, d, F1, K1, x[ 6] ); ++ R( d, e, a, b, c, F1, K1, x[ 7] ); ++ R( c, d, e, a, b, F1, K1, x[ 8] ); ++ R( b, c, d, e, a, F1, K1, x[ 9] ); ++ R( a, b, c, d, e, F1, K1, x[10] ); ++ R( e, a, b, c, d, F1, K1, x[11] ); ++ R( d, e, a, b, c, F1, K1, x[12] ); ++ R( c, d, e, a, b, F1, K1, x[13] ); ++ R( b, c, d, e, a, F1, K1, x[14] ); ++ R( a, b, c, d, e, F1, K1, x[15] ); ++ R( e, a, b, c, d, F1, K1, M(16) ); ++ R( d, e, a, b, c, F1, K1, M(17) ); ++ R( c, d, e, a, b, F1, K1, M(18) ); ++ R( b, c, d, e, a, F1, K1, M(19) ); ++ R( a, b, c, d, e, F2, K2, M(20) ); ++ R( e, a, b, c, d, F2, K2, M(21) ); ++ R( d, e, a, b, c, F2, K2, M(22) ); ++ R( c, d, e, a, b, F2, K2, M(23) ); ++ R( b, c, d, e, a, F2, K2, M(24) ); ++ R( a, b, c, d, e, F2, K2, M(25) ); ++ R( e, a, b, c, d, F2, K2, M(26) ); ++ R( d, e, a, b, c, F2, K2, M(27) ); ++ R( c, d, e, a, b, F2, K2, M(28) ); ++ R( b, c, d, e, a, F2, K2, M(29) ); ++ R( a, b, c, d, e, F2, K2, M(30) ); ++ R( e, a, b, c, d, F2, K2, M(31) ); ++ R( d, e, a, b, c, F2, K2, M(32) ); ++ R( c, d, e, a, b, F2, K2, M(33) ); ++ R( b, c, d, e, a, F2, K2, M(34) ); ++ R( a, b, c, d, e, F2, K2, M(35) ); ++ R( e, a, b, c, d, F2, K2, M(36) ); ++ R( d, e, a, b, c, F2, K2, M(37) ); ++ R( c, d, e, a, b, F2, K2, M(38) ); ++ R( b, c, d, e, a, F2, K2, M(39) ); ++ R( a, b, c, d, e, F3, K3, M(40) ); ++ R( e, a, b, c, d, F3, K3, M(41) ); ++ R( d, e, a, b, c, F3, K3, M(42) ); ++ R( c, d, e, a, b, F3, K3, M(43) ); ++ R( b, c, d, e, a, F3, K3, M(44) ); ++ R( a, b, c, d, e, F3, K3, M(45) ); ++ R( e, a, b, c, d, F3, K3, M(46) ); ++ R( d, e, a, b, c, F3, K3, M(47) ); ++ R( c, d, e, a, b, F3, K3, M(48) ); ++ R( b, c, d, e, a, F3, K3, M(49) ); ++ R( a, b, c, d, e, F3, K3, M(50) ); ++ R( e, a, b, c, d, F3, K3, M(51) ); ++ R( d, e, a, b, c, F3, K3, M(52) ); ++ R( c, d, e, a, b, F3, K3, M(53) ); ++ R( b, c, d, e, a, F3, K3, M(54) ); ++ R( a, b, c, d, e, F3, K3, M(55) ); ++ R( e, a, b, c, d, F3, K3, M(56) ); ++ R( d, e, a, b, c, F3, K3, M(57) ); ++ R( c, d, e, a, b, F3, K3, M(58) ); ++ R( b, c, d, e, a, F3, K3, M(59) ); ++ R( a, b, c, d, e, F4, K4, M(60) ); ++ R( e, a, b, c, d, F4, K4, M(61) ); ++ R( d, e, a, b, c, F4, K4, M(62) ); ++ R( c, d, e, a, b, F4, K4, M(63) ); ++ R( b, c, d, e, a, F4, K4, M(64) ); ++ R( a, b, c, d, e, F4, K4, M(65) ); ++ R( e, a, b, c, d, F4, K4, M(66) ); ++ R( d, e, a, b, c, F4, K4, M(67) ); ++ R( c, d, e, a, b, F4, K4, M(68) ); ++ R( b, c, d, e, a, F4, K4, M(69) ); ++ R( a, b, c, d, e, F4, K4, M(70) ); ++ R( e, a, b, c, d, F4, K4, M(71) ); ++ R( d, e, a, b, c, F4, K4, M(72) ); ++ R( c, d, e, a, b, F4, K4, M(73) ); ++ R( b, c, d, e, a, F4, K4, M(74) ); ++ R( a, b, c, d, e, F4, K4, M(75) ); ++ R( e, a, b, c, d, F4, K4, M(76) ); ++ R( d, e, a, b, c, F4, K4, M(77) ); ++ R( c, d, e, a, b, F4, K4, M(78) ); ++ R( b, c, d, e, a, F4, K4, M(79) ); ++ ++ a = ctx->A += a; ++ b = ctx->B += b; ++ c = ctx->C += c; ++ d = ctx->D += d; ++ e = ctx->E += e; ++ } ++} +--- a/mdadm/sha1.h 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/sha1.h 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,87 @@ ++/* Declarations of functions and data types used for SHA1 sum ++ library functions. ++ Copyright (C) 2000, 2001, 2003, 2005 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ++ ++#ifndef SHA1_H ++# define SHA1_H 1 ++ ++# include <stdio.h> ++# include "md5.h" ++ ++/* Structure to save state of computation between the single steps. */ ++struct sha1_ctx ++{ ++ md5_uint32 A; ++ md5_uint32 B; ++ md5_uint32 C; ++ md5_uint32 D; ++ md5_uint32 E; ++ ++ md5_uint32 total[2]; ++ md5_uint32 buflen; ++ char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32)))); ++}; ++ ++ ++/* Initialize structure containing state of computation. */ ++extern void sha1_init_ctx (struct sha1_ctx *ctx); ++ ++/* Starting with the result of former calls of this function (or the ++ initialization function update the context for the next LEN bytes ++ starting at BUFFER. ++ It is necessary that LEN is a multiple of 64!!! */ ++extern void sha1_process_block (const void *buffer, size_t len, ++ struct sha1_ctx *ctx); ++ ++/* Starting with the result of former calls of this function (or the ++ initialization function update the context for the next LEN bytes ++ starting at BUFFER. ++ It is NOT required that LEN is a multiple of 64. */ ++extern void sha1_process_bytes (const void *buffer, size_t len, ++ struct sha1_ctx *ctx); ++ ++/* Process the remaining bytes in the buffer and put result from CTX ++ in first 20 bytes following RESBUF. The result is always in little ++ endian byte order, so that a byte-wise output yields to the wanted ++ ASCII representation of the message digest. ++ ++ IMPORTANT: On some systems it is required that RESBUF be correctly ++ aligned for a 32 bits value. */ ++extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf); ++ ++ ++/* Put result from CTX in first 20 bytes following RESBUF. The result is ++ always in little endian byte order, so that a byte-wise output yields ++ to the wanted ASCII representation of the message digest. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf); ++ ++ ++/* Compute SHA1 message digest for bytes read from STREAM. The ++ resulting message digest number will be written into the 20 bytes ++ beginning at RESBLOCK. */ ++extern int sha1_stream (FILE *stream, void *resblock); ++ ++/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The ++ result is always in little endian byte order, so that a byte-wise ++ output yields to the wanted ASCII representation of the message ++ digest. */ ++extern void *sha1_buffer (const char *buffer, size_t len, void *resblock); ++ ++#endif +--- a/mdadm/super0.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/super0.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,562 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#define HAVE_STDINT_H 1 ++#include "mdadm.h" ++/* ++ * All handling for the 0.90.0 version superblock is in ++ * this file. ++ * This includes: ++ * - finding, loading, and writing the superblock. ++ * - initialising a new superblock ++ * - printing the superblock for --examine ++ * - printing part of the superblock for --detail ++ * .. other stuff ++ */ ++ ++ ++static unsigned long calc_sb0_csum(mdp_super_t *super) ++{ ++ unsigned long csum = super->sb_csum; ++ unsigned long newcsum; ++ super->sb_csum= 0 ; ++ newcsum = calc_csum(super, MD_SB_BYTES); ++ super->sb_csum = csum; ++ return newcsum; ++} ++ ++ ++void super0_swap_endian(struct mdp_superblock_s *sb) ++{ ++ /* as super0 superblocks are host-endian, it is sometimes ++ * useful to be able to swap the endianness ++ * as (almost) everything is u32's we byte-swap every 4byte ++ * number. ++ * We then also have to swap the events_hi and events_lo ++ */ ++ char *sbc = (char *)sb; ++ __u32 t32; ++ int i; ++ ++ for (i=0; i < MD_SB_BYTES ; i+=4) { ++ char t = sbc[i]; ++ sbc[i] = sbc[i+3]; ++ sbc[i+3] = t; ++ t=sbc[i+1]; ++ sbc[i+1]=sbc[i+2]; ++ sbc[i+2]=t; ++ } ++ t32 = sb->events_hi; ++ sb->events_hi = sb->events_lo; ++ sb->events_lo = t32; ++ ++ t32 = sb->cp_events_hi; ++ sb->cp_events_hi = sb->cp_events_lo; ++ sb->cp_events_lo = t32; ++ ++} ++ ++static void brief_examine_super0(void *sbv) ++{ ++ mdp_super_t *sb = sbv; ++ char *c=map_num(pers, sb->level); ++ char devname[20]; ++ ++ sprintf(devname, "/dev/md%d", sb->md_minor); ++ ++ printf("ARRAY %s level=%s num-devices=%d UUID=", ++ devname, ++ c?c:"-unknown-", sb->raid_disks); ++ if (sb->minor_version >= 90) ++ printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1, ++ sb->set_uuid2, sb->set_uuid3); ++ else ++ printf("%08x", sb->set_uuid0); ++ printf("\n"); ++} ++ ++static int match_home0(void *sbv, char *homehost) ++{ ++ mdp_super_t *sb = sbv; ++ char buf[20]; ++ char *hash = sha1_buffer(homehost, ++ strlen(homehost), ++ buf); ++ ++ return (memcmp(&sb->set_uuid2, hash, 8)==0); ++} ++ ++static void uuid_from_super0(int uuid[4], void * sbv) ++{ ++ mdp_super_t *super = sbv; ++ uuid[0] = super->set_uuid0; ++ if (super->minor_version >= 90) { ++ uuid[1] = super->set_uuid1; ++ uuid[2] = super->set_uuid2; ++ uuid[3] = super->set_uuid3; ++ } else { ++ uuid[1] = 0; ++ uuid[2] = 0; ++ uuid[3] = 0; ++ } ++} ++ ++static void getinfo_super0(struct mdinfo *info, void *sbv) ++{ ++ mdp_super_t *sb = sbv; ++ int working = 0; ++ int i; ++ ++ info->array.major_version = sb->major_version; ++ info->array.minor_version = sb->minor_version; ++ info->array.patch_version = sb->patch_version; ++ info->array.raid_disks = sb->raid_disks; ++ info->array.level = sb->level; ++ info->array.layout = sb->layout; ++ info->array.md_minor = sb->md_minor; ++ info->array.ctime = sb->ctime; ++ info->array.utime = sb->utime; ++ info->array.chunk_size = sb->chunk_size; ++ info->array.state = sb->state; ++ info->component_size = sb->size*2; ++ ++ info->disk.state = sb->this_disk.state; ++ info->disk.major = sb->this_disk.major; ++ info->disk.minor = sb->this_disk.minor; ++ info->disk.raid_disk = sb->this_disk.raid_disk; ++ info->disk.number = sb->this_disk.number; ++ ++ info->events = md_event(sb); ++ info->data_offset = 0; ++ ++ uuid_from_super0(info->uuid, sbv); ++ ++ if (sb->minor_version > 90 && (sb->reshape_position+1) != 0) { ++ info->reshape_active = 1; ++ info->reshape_progress = sb->reshape_position; ++ info->new_level = sb->new_level; ++ info->delta_disks = sb->delta_disks; ++ info->new_layout = sb->new_layout; ++ info->new_chunk = sb->new_chunk; ++ } else ++ info->reshape_active = 0; ++ ++ sprintf(info->name, "%d", sb->md_minor); ++ /* work_disks is calculated rather than read directly */ ++ for (i=0; i < MD_SB_DISKS; i++) ++ if ((sb->disks[i].state & (1<<MD_DISK_SYNC)) && ++ (sb->disks[i].raid_disk < info->array.raid_disks) && ++ (sb->disks[i].state & (1<<MD_DISK_ACTIVE)) && ++ !(sb->disks[i].state & (1<<MD_DISK_FAULTY))) ++ working ++; ++ info->array.working_disks = working; ++} ++ ++ ++static int update_super0(struct mdinfo *info, void *sbv, char *update, ++ char *devname, int verbose, ++ int uuid_set, char *homehost) ++{ ++ /* NOTE: for 'assemble' and 'force' we need to return non-zero if any change was made. ++ * For others, the return value is ignored. ++ */ ++ int rv = 0; ++ mdp_super_t *sb = sbv; ++ if (strcmp(update, "sparc2.2")==0 ) { ++ /* 2.2 sparc put the events in the wrong place ++ * So we copy the tail of the superblock ++ * up 4 bytes before continuing ++ */ ++ __u32 *sb32 = (__u32*)sb; ++ memcpy(sb32+MD_SB_GENERIC_CONSTANT_WORDS+7, ++ sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1, ++ (MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4); ++ if (verbose >= 0) ++ fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n", ++ devname); ++ } ++ if (strcmp(update, "super-minor") ==0) { ++ sb->md_minor = info->array.md_minor; ++ if (verbose > 0) ++ fprintf(stderr, Name ": updating superblock of %s with minor number %d\n", ++ devname, info->array.md_minor); ++ } ++ if (strcmp(update, "summaries") == 0) { ++ int i; ++ /* set nr_disks, active_disks, working_disks, ++ * failed_disks, spare_disks based on disks[] ++ * array in superblock. ++ * Also make sure extra slots aren't 'failed' ++ */ ++ sb->nr_disks = sb->active_disks = ++ sb->working_disks = sb->failed_disks = ++ sb->spare_disks = 0; ++ for (i=0; i < MD_SB_DISKS ; i++) ++ if (sb->disks[i].major || ++ sb->disks[i].minor) { ++ int state = sb->disks[i].state; ++ if (state & (1<<MD_DISK_REMOVED)) ++ continue; ++ sb->nr_disks++; ++ if (state & (1<<MD_DISK_ACTIVE)) ++ sb->active_disks++; ++ if (state & (1<<MD_DISK_FAULTY)) ++ sb->failed_disks++; ++ else ++ sb->working_disks++; ++ if (state == 0) ++ sb->spare_disks++; ++ } else if (i >= sb->raid_disks && sb->disks[i].number == 0) ++ sb->disks[i].state = 0; ++ } ++ if (strcmp(update, "force-one")==0) { ++ /* Not enough devices for a working array, so ++ * bring this one up-to-date. ++ */ ++ __u32 ehi = sb->events_hi, elo = sb->events_lo; ++ sb->events_hi = (info->events>>32) & 0xFFFFFFFF; ++ sb->events_lo = (info->events) & 0xFFFFFFFF; ++ if (sb->events_hi != ehi || ++ sb->events_lo != elo) ++ rv = 1; ++ } ++ if (strcmp(update, "force-array")==0) { ++ /* degraded array and 'force' requested, so ++ * maybe need to mark it 'clean' ++ */ ++ if ((sb->level == 5 || sb->level == 4 || sb->level == 6) && ++ (sb->state & (1 << MD_SB_CLEAN)) == 0) { ++ /* need to force clean */ ++ sb->state |= (1 << MD_SB_CLEAN); ++ rv = 1; ++ } ++ } ++ if (strcmp(update, "assemble")==0) { ++ int d = info->disk.number; ++ int wonly = sb->disks[d].state & (1<<MD_DISK_WRITEMOSTLY); ++ if ((sb->disks[d].state & ~(1<<MD_DISK_WRITEMOSTLY)) ++ != info->disk.state) { ++ sb->disks[d].state = info->disk.state | wonly; ++ rv = 1; ++ } ++ } ++ if (strcmp(update, "linear-grow-new") == 0) { ++ memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); ++ sb->disks[info->disk.number].number = info->disk.number; ++ sb->disks[info->disk.number].major = info->disk.major; ++ sb->disks[info->disk.number].minor = info->disk.minor; ++ sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; ++ sb->disks[info->disk.number].state = info->disk.state; ++ sb->this_disk = sb->disks[info->disk.number]; ++ } ++ if (strcmp(update, "linear-grow-update") == 0) { ++ sb->raid_disks = info->array.raid_disks; ++ sb->nr_disks = info->array.nr_disks; ++ sb->active_disks = info->array.active_disks; ++ sb->working_disks = info->array.working_disks; ++ memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); ++ sb->disks[info->disk.number].number = info->disk.number; ++ sb->disks[info->disk.number].major = info->disk.major; ++ sb->disks[info->disk.number].minor = info->disk.minor; ++ sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; ++ sb->disks[info->disk.number].state = info->disk.state; ++ } ++ if (strcmp(update, "resync") == 0) { ++ /* make sure resync happens */ ++ sb->state &= ~(1<<MD_SB_CLEAN); ++ sb->recovery_cp = 0; ++ } ++ if (strcmp(update, "homehost") == 0 && ++ homehost) { ++ uuid_set = 0; ++ update = "uuid"; ++ info->uuid[0] = sb->set_uuid0; ++ info->uuid[1] = sb->set_uuid1; ++ } ++ if (strcmp(update, "uuid") == 0) { ++ if (!uuid_set && homehost) { ++ char buf[20]; ++ char *hash = sha1_buffer(homehost, ++ strlen(homehost), ++ buf); ++ memcpy(info->uuid+2, hash, 8); ++ } ++ sb->set_uuid0 = info->uuid[0]; ++ sb->set_uuid1 = info->uuid[1]; ++ sb->set_uuid2 = info->uuid[2]; ++ sb->set_uuid3 = info->uuid[3]; ++ if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) { ++ struct bitmap_super_s *bm; ++ bm = (struct bitmap_super_s*)(sb+1); ++ uuid_from_super0((int*)bm->uuid, sbv); ++ } ++ } ++ if (strcmp(update, "_reshape_progress")==0) ++ sb->reshape_position = info->reshape_progress; ++ ++ sb->sb_csum = calc_sb0_csum(sb); ++ return rv; ++} ++ ++static int store_super0(struct supertype *st, int fd, void *sbv) ++{ ++ unsigned long long dsize; ++ unsigned long long offset; ++ mdp_super_t *super = sbv; ++ ++ if (!get_dev_size(fd, NULL, &dsize)) ++ return 1; ++ ++ if (dsize < MD_RESERVED_SECTORS*2*512) ++ return 2; ++ ++ offset = MD_NEW_SIZE_SECTORS(dsize>>9); ++ ++ offset *= 512; ++ ++ if (lseek64(fd, offset, 0)< 0LL) ++ return 3; ++ ++ if (write(fd, super, sizeof(*super)) != sizeof(*super)) ++ return 4; ++ ++ if (super->state & (1<<MD_SB_BITMAP_PRESENT)) { ++ struct bitmap_super_s * bm = (struct bitmap_super_s*)(super+1); ++ if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) ++ if (write(fd, bm, sizeof(*bm)) != sizeof(*bm)) ++ return 5; ++ } ++ ++ fsync(fd); ++ return 0; ++} ++ ++static int compare_super0(void **firstp, void *secondv) ++{ ++ /* ++ * return: ++ * 0 same, or first was empty, and second was copied ++ * 1 second had wrong number ++ * 2 wrong uuid ++ * 3 wrong other info ++ */ ++ mdp_super_t *first = *firstp; ++ mdp_super_t *second = secondv; ++ ++ int uuid1[4], uuid2[4]; ++ if (second->md_magic != MD_SB_MAGIC) ++ return 1; ++ if (!first) { ++ first = malloc(MD_SB_BYTES + sizeof(struct bitmap_super_s)); ++ memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s)); ++ *firstp = first; ++ return 0; ++ } ++ ++ uuid_from_super0(uuid1, first); ++ uuid_from_super0(uuid2, second); ++ if (!same_uuid(uuid1, uuid2, 0)) ++ return 2; ++ if (first->major_version != second->major_version || ++ first->minor_version != second->minor_version || ++ first->patch_version != second->patch_version || ++ first->gvalid_words != second->gvalid_words || ++ first->ctime != second->ctime || ++ first->level != second->level || ++ first->size != second->size || ++ first->raid_disks != second->raid_disks ) ++ return 3; ++ ++ return 0; ++} ++ ++ ++static int load_super0(struct supertype *st, int fd, void **sbp, char *devname) ++{ ++ /* try to read in the superblock ++ * Return: ++ * 0 on success ++ * 1 on cannot get superblock ++ * 2 on superblock meaningless ++ */ ++ unsigned long long dsize; ++ unsigned long long offset; ++ mdp_super_t *super; ++ int uuid[4]; ++ struct bitmap_super_s *bsb; ++ ++ if (!get_dev_size(fd, devname, &dsize)) ++ return 1; ++ ++ if (dsize < MD_RESERVED_SECTORS*512 * 2) { ++ if (devname) ++ fprintf(stderr, Name ++ ": %s is too small for md: size is %llu sectors.\n", ++ devname, dsize); ++ return 1; ++ } ++ ++ offset = MD_NEW_SIZE_SECTORS(dsize>>9); ++ ++ offset *= 512; ++ ++ ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */ ++ ++ if (lseek64(fd, offset, 0)< 0LL) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot seek to superblock on %s: %s\n", ++ devname, strerror(errno)); ++ return 1; ++ } ++ ++ super = malloc(MD_SB_BYTES + sizeof(bitmap_super_t)); ++ ++ if (read(fd, super, sizeof(*super)) != MD_SB_BYTES) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot read superblock on %s\n", ++ devname); ++ free(super); ++ return 1; ++ } ++ ++ if (st->ss && st->minor_version == 9) ++ super0_swap_endian(super); ++ ++ if (super->md_magic != MD_SB_MAGIC) { ++ if (devname) ++ fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n", ++ devname, MD_SB_MAGIC, super->md_magic); ++ free(super); ++ return 2; ++ } ++ ++ if (super->major_version != 0) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot interpret superblock on %s - version is %d\n", ++ devname, super->major_version); ++ free(super); ++ return 2; ++ } ++ *sbp = super; ++ if (st->ss == NULL) { ++ st->ss = &super0; ++ st->minor_version = 90; ++ st->max_devs = MD_SB_DISKS; ++ } ++ ++ /* Now check on the bitmap superblock */ ++ if ((super->state & (1<<MD_SB_BITMAP_PRESENT)) == 0) ++ return 0; ++ /* Read the bitmap superblock and make sure it looks ++ * valid. If it doesn't clear the bit. An --assemble --force ++ * should get that written out. ++ */ ++ if (read(fd, super+1, sizeof(struct bitmap_super_s)) ++ != sizeof(struct bitmap_super_s)) ++ goto no_bitmap; ++ ++ uuid_from_super0(uuid, super); ++ bsb = (struct bitmap_super_s *)(super+1); ++ if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC || ++ memcmp(bsb->uuid, uuid, 16) != 0) ++ goto no_bitmap; ++ return 0; ++ ++ no_bitmap: ++ super->state &= ~(1<<MD_SB_BITMAP_PRESENT); ++ ++ return 0; ++} ++ ++static struct supertype *match_metadata_desc0(char *arg) ++{ ++ struct supertype *st = malloc(sizeof(*st)); ++ if (!st) return st; ++ ++ st->ss = &super0; ++ st->minor_version = 90; ++ st->max_devs = MD_SB_DISKS; ++ if (strcmp(arg, "0") == 0 || ++ strcmp(arg, "0.90") == 0 || ++ strcmp(arg, "default") == 0 ++ ) ++ return st; ++ ++ st->minor_version = 9; /* flag for 'byte-swapped' */ ++ if (strcmp(arg, "0.swap")==0) ++ return st; ++ ++ free(st); ++ return NULL; ++} ++ ++void locate_bitmap0(struct supertype *st, int fd, void *sbv) ++{ ++ unsigned long long dsize; ++ unsigned long long offset; ++ ++ if (!get_dev_size(fd, NULL, &dsize)) ++ return; ++ ++ if (dsize < MD_RESERVED_SECTORS*512 * 2) ++ return; ++ ++ offset = MD_NEW_SIZE_SECTORS(dsize>>9); ++ ++ offset *= 512; ++ ++ offset += MD_SB_BYTES; ++ ++ lseek64(fd, offset, 0); ++} ++ ++struct superswitch super0 = { ++ .examine_super = NULL, ++ .brief_examine_super = brief_examine_super0, ++ .detail_super = NULL, ++ .brief_detail_super = NULL, ++ .export_super = NULL, ++ .match_home = match_home0, ++ .uuid_from_super = uuid_from_super0, ++ .getinfo_super = getinfo_super0, ++ .update_super = update_super0, ++ .init_super = NULL, ++ .add_to_super = NULL, ++ .store_super = store_super0, ++ .write_init_super = NULL, ++ .compare_super = compare_super0, ++ .load_super = load_super0, ++ .match_metadata_desc = match_metadata_desc0, ++ .avail_size = NULL, ++ .add_internal_bitmap = NULL, ++ .locate_bitmap = locate_bitmap0, ++ .write_bitmap = NULL, ++ .major = 0, ++ .swapuuid = 0, ++}; +--- a/mdadm/super1.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/super1.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,731 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include "mdadm.h" ++/* ++ * The version-1 superblock : ++ * All numeric fields are little-endian. ++ * ++ * total size: 256 bytes plus 2 per device. ++ * 1K allows 384 devices. ++ */ ++struct mdp_superblock_1 { ++ /* constant array information - 128 bytes */ ++ __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ ++ __u32 major_version; /* 1 */ ++ __u32 feature_map; /* 0 for now */ ++ __u32 pad0; /* always set to 0 when writing */ ++ ++ __u8 set_uuid[16]; /* user-space generated. */ ++ char set_name[32]; /* set and interpreted by user-space */ ++ ++ __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ ++ __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ ++ __u32 layout; /* only for raid5 currently */ ++ __u64 size; /* used size of component devices, in 512byte sectors */ ++ ++ __u32 chunksize; /* in 512byte sectors */ ++ __u32 raid_disks; ++ __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts ++ * NOTE: signed, so bitmap can be before superblock ++ * only meaningful of feature_map[0] is set. ++ */ ++ ++ /* These are only valid with feature bit '4' */ ++ __u32 new_level; /* new level we are reshaping to */ ++ __u64 reshape_position; /* next address in array-space for reshape */ ++ __u32 delta_disks; /* change in number of raid_disks */ ++ __u32 new_layout; /* new layout */ ++ __u32 new_chunk; /* new chunk size (bytes) */ ++ __u8 pad1[128-124]; /* set to 0 when written */ ++ ++ /* constant this-device information - 64 bytes */ ++ __u64 data_offset; /* sector start of data, often 0 */ ++ __u64 data_size; /* sectors in this device that can be used for data */ ++ __u64 super_offset; /* sector start of this superblock */ ++ __u64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ ++ __u32 dev_number; /* permanent identifier of this device - not role in raid */ ++ __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */ ++ __u8 device_uuid[16]; /* user-space setable, ignored by kernel */ ++ __u8 devflags; /* per-device flags. Only one defined...*/ ++#define WriteMostly1 1 /* mask for writemostly flag in above */ ++ __u8 pad2[64-57]; /* set to 0 when writing */ ++ ++ /* array state information - 64 bytes */ ++ __u64 utime; /* 40 bits second, 24 btes microseconds */ ++ __u64 events; /* incremented when superblock updated */ ++ __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ ++ __u32 sb_csum; /* checksum upto devs[max_dev] */ ++ __u32 max_dev; /* size of devs[] array to consider */ ++ __u8 pad3[64-32]; /* set to 0 when writing */ ++ ++ /* device state information. Indexed by dev_number. ++ * 2 bytes per device ++ * Note there are no per-device state flags. State information is rolled ++ * into the 'roles' value. If a device is spare or faulty, then it doesn't ++ * have a meaningful role. ++ */ ++ __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ ++}; ++ ++struct misc_dev_info { ++ __u64 device_size; ++}; ++ ++/* feature_map bits */ ++#define MD_FEATURE_BITMAP_OFFSET 1 ++#define MD_FEATURE_RECOVERY_OFFSET 2 /* recovery_offset is present and ++ * must be honoured ++ */ ++#define MD_FEATURE_RESHAPE_ACTIVE 4 ++ ++#define MD_FEATURE_ALL (1|2|4) ++ ++#ifndef offsetof ++#define offsetof(t,f) ((size_t)&(((t*)0)->f)) ++#endif ++static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) ++{ ++ unsigned int disk_csum, csum; ++ unsigned long long newcsum; ++ int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2; ++ unsigned int *isuper = (unsigned int*)sb; ++ int i; ++ ++/* make sure I can count... */ ++ if (offsetof(struct mdp_superblock_1,data_offset) != 128 || ++ offsetof(struct mdp_superblock_1, utime) != 192 || ++ sizeof(struct mdp_superblock_1) != 256) { ++ fprintf(stderr, "WARNING - superblock isn't sized correctly\n"); ++ } ++ ++ disk_csum = sb->sb_csum; ++ sb->sb_csum = 0; ++ newcsum = 0; ++ for (i=0; size>=4; size -= 4 ) { ++ newcsum += __le32_to_cpu(*isuper); ++ isuper++; ++ } ++ ++ if (size == 2) ++ newcsum += __le16_to_cpu(*(unsigned short*) isuper); ++ ++ csum = (newcsum & 0xffffffff) + (newcsum >> 32); ++ sb->sb_csum = disk_csum; ++ return __cpu_to_le32(csum); ++} ++ ++static void brief_examine_super1(void *sbv) ++{ ++ struct mdp_superblock_1 *sb = sbv; ++ int i; ++ unsigned long long sb_offset; ++ char *nm; ++ char *c=map_num(pers, __le32_to_cpu(sb->level)); ++ ++ nm = strchr(sb->set_name, ':'); ++ if (nm) ++ nm++; ++ else if (sb->set_name[0]) ++ nm = sb->set_name; ++ else ++ nm = "??"; ++ ++ printf("ARRAY /dev/md%s level=%s ", nm, c?c:"-unknown-"); ++ sb_offset = __le64_to_cpu(sb->super_offset); ++ if (sb_offset <= 4) ++ printf("metadata=1.1 "); ++ else if (sb_offset <= 8) ++ printf("metadata=1.2 "); ++ else ++ printf("metadata=1.0 "); ++ printf("num-devices=%d UUID=", __le32_to_cpu(sb->raid_disks)); ++ for (i=0; i<16; i++) { ++ if ((i&3)==0 && i != 0) printf(":"); ++ printf("%02x", sb->set_uuid[i]); ++ } ++ if (sb->set_name[0]) ++ printf(" name=%.32s", sb->set_name); ++ printf("\n"); ++} ++ ++static int match_home1(void *sbv, char *homehost) ++{ ++ struct mdp_superblock_1 *sb = sbv; ++ int l = homehost ? strlen(homehost) : 0; ++ ++ return (l > 0 && l < 32 && ++ sb->set_name[l] == ':' && ++ strncmp(sb->set_name, homehost, l) == 0); ++} ++ ++static void uuid_from_super1(int uuid[4], void * sbv) ++{ ++ struct mdp_superblock_1 *super = sbv; ++ char *cuuid = (char*)uuid; ++ int i; ++ for (i=0; i<16; i++) ++ cuuid[i] = super->set_uuid[i]; ++} ++ ++static void getinfo_super1(struct mdinfo *info, void *sbv) ++{ ++ struct mdp_superblock_1 *sb = sbv; ++ int working = 0; ++ int i; ++ int role; ++ ++ info->array.major_version = 1; ++ info->array.minor_version = __le32_to_cpu(sb->feature_map); ++ info->array.patch_version = 0; ++ info->array.raid_disks = __le32_to_cpu(sb->raid_disks); ++ info->array.level = __le32_to_cpu(sb->level); ++ info->array.layout = __le32_to_cpu(sb->layout); ++ info->array.md_minor = -1; ++ info->array.ctime = __le64_to_cpu(sb->ctime); ++ info->array.utime = __le64_to_cpu(sb->utime); ++ info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512; ++ info->array.state = ++ (__le64_to_cpu(sb->resync_offset) >= __le64_to_cpu(sb->size)) ++ ? 1 : 0; ++ ++ info->data_offset = __le64_to_cpu(sb->data_offset); ++ info->component_size = __le64_to_cpu(sb->size); ++ ++ info->disk.major = 0; ++ info->disk.minor = 0; ++ info->disk.number = __le32_to_cpu(sb->dev_number); ++ if (__le32_to_cpu(sb->dev_number) >= __le32_to_cpu(sb->max_dev) || ++ __le32_to_cpu(sb->max_dev) > 512) ++ role = 0xfffe; ++ else ++ role = __le16_to_cpu(sb->dev_roles[__le32_to_cpu(sb->dev_number)]); ++ ++ info->disk.raid_disk = -1; ++ switch(role) { ++ case 0xFFFF: ++ info->disk.state = 2; /* spare: ACTIVE, not sync, not faulty */ ++ break; ++ case 0xFFFE: ++ info->disk.state = 1; /* faulty */ ++ break; ++ default: ++ info->disk.state = 6; /* active and in sync */ ++ info->disk.raid_disk = role; ++ } ++ info->events = __le64_to_cpu(sb->events); ++ ++ memcpy(info->uuid, sb->set_uuid, 16); ++ ++ strncpy(info->name, sb->set_name, 32); ++ info->name[32] = 0; ++ ++ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) { ++ info->reshape_active = 1; ++ info->reshape_progress = __le64_to_cpu(sb->reshape_position); ++ info->new_level = __le32_to_cpu(sb->new_level); ++ info->delta_disks = __le32_to_cpu(sb->delta_disks); ++ info->new_layout = __le32_to_cpu(sb->new_layout); ++ info->new_chunk = __le32_to_cpu(sb->new_chunk)<<9; ++ } else ++ info->reshape_active = 0; ++ ++ for (i=0; i< __le32_to_cpu(sb->max_dev); i++) { ++ role = __le16_to_cpu(sb->dev_roles[i]); ++ if (/*role == 0xFFFF || */role < info->array.raid_disks) ++ working++; ++ } ++ ++ info->array.working_disks = working; ++} ++ ++static int update_super1(struct mdinfo *info, void *sbv, char *update, ++ char *devname, int verbose, ++ int uuid_set, char *homehost) ++{ ++ /* NOTE: for 'assemble' and 'force' we need to return non-zero if any change was made. ++ * For others, the return value is ignored. ++ */ ++ int rv = 0; ++ struct mdp_superblock_1 *sb = sbv; ++ ++ if (strcmp(update, "force-one")==0) { ++ /* Not enough devices for a working array, ++ * so bring this one up-to-date ++ */ ++ if (sb->events != __cpu_to_le64(info->events)) ++ rv = 1; ++ sb->events = __cpu_to_le64(info->events); ++ } ++ if (strcmp(update, "force-array")==0) { ++ /* Degraded array and 'force' requests to ++ * maybe need to mark it 'clean'. ++ */ ++ switch(__le32_to_cpu(sb->level)) { ++ case 5: case 4: case 6: ++ /* need to force clean */ ++ if (sb->resync_offset != ~0ULL) ++ rv = 1; ++ sb->resync_offset = ~0ULL; ++ } ++ } ++ if (strcmp(update, "assemble")==0) { ++ int d = info->disk.number; ++ int want; ++ if (info->disk.state == 6) ++ want = __cpu_to_le32(info->disk.raid_disk); ++ else ++ want = 0xFFFF; ++ if (sb->dev_roles[d] != want) { ++ sb->dev_roles[d] = want; ++ rv = 1; ++ } ++ } ++ if (strcmp(update, "linear-grow-new") == 0) { ++ int i; ++ int rfd; ++ int max = __le32_to_cpu(sb->max_dev); ++ ++ for (i=0 ; i < max ; i++) ++ if (__le16_to_cpu(sb->dev_roles[i]) >= 0xfffe) ++ break; ++ sb->dev_number = __cpu_to_le32(i); ++ info->disk.number = i; ++ if (max >= __le32_to_cpu(sb->max_dev)) ++ sb->max_dev = __cpu_to_le32(max+1); ++ ++ if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 || ++ read(rfd, sb->device_uuid, 16) != 16) { ++ *(__u32*)(sb->device_uuid) = random(); ++ *(__u32*)(sb->device_uuid+4) = random(); ++ *(__u32*)(sb->device_uuid+8) = random(); ++ *(__u32*)(sb->device_uuid+12) = random(); ++ } ++ ++ sb->dev_roles[i] = ++ __cpu_to_le16(info->disk.raid_disk); ++ } ++ if (strcmp(update, "linear-grow-update") == 0) { ++ sb->raid_disks = __cpu_to_le32(info->array.raid_disks); ++ sb->dev_roles[info->disk.number] = ++ __cpu_to_le16(info->disk.raid_disk); ++ } ++ if (strcmp(update, "resync") == 0) { ++ /* make sure resync happens */ ++ sb->resync_offset = 0ULL; ++ } ++ if (strcmp(update, "uuid") == 0) { ++ copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); ++ ++ if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) { ++ struct bitmap_super_s *bm; ++ bm = (struct bitmap_super_s*)(sbv+1024); ++ memcpy(bm->uuid, sb->set_uuid, 16); ++ } ++ } ++ if (strcmp(update, "homehost") == 0 && ++ homehost) { ++ char *c; ++ update = "name"; ++ c = strchr(sb->set_name, ':'); ++ if (c) ++ strncpy(info->name, c+1, 31 - (c-sb->set_name)); ++ else ++ strncpy(info->name, sb->set_name, 32); ++ info->name[32] = 0; ++ } ++ if (strcmp(update, "name") == 0) { ++ if (info->name[0] == 0) ++ sprintf(info->name, "%d", info->array.md_minor); ++ memset(sb->set_name, 0, sizeof(sb->set_name)); ++ if (homehost && ++ strchr(info->name, ':') == NULL && ++ strlen(homehost)+1+strlen(info->name) < 32) { ++ strcpy(sb->set_name, homehost); ++ strcat(sb->set_name, ":"); ++ strcat(sb->set_name, info->name); ++ } else ++ strcpy(sb->set_name, info->name); ++ } ++ if (strcmp(update, "devicesize") == 0 && ++ __le64_to_cpu(sb->super_offset) < ++ __le64_to_cpu(sb->data_offset)) { ++ /* set data_size to device size less data_offset */ ++ struct misc_dev_info *misc = (struct misc_dev_info*) ++ (sbv + 1024 + sizeof(struct bitmap_super_s)); ++ printf("Size was %llu\n", (unsigned long long) ++ __le64_to_cpu(sb->data_size)); ++ sb->data_size = __cpu_to_le64( ++ misc->device_size - __le64_to_cpu(sb->data_offset)); ++ printf("Size is %llu\n", (unsigned long long) ++ __le64_to_cpu(sb->data_size)); ++ } ++ if (strcmp(update, "_reshape_progress")==0) ++ sb->reshape_position = __cpu_to_le64(info->reshape_progress); ++ ++ sb->sb_csum = calc_sb_1_csum(sb); ++ return rv; ++} ++ ++static void locate_bitmap1(struct supertype *st, int fd, void *sbv); ++ ++static int store_super1(struct supertype *st, int fd, void *sbv) ++{ ++ struct mdp_superblock_1 *sb = sbv; ++ unsigned long long sb_offset; ++ int sbsize; ++ unsigned long long dsize; ++ ++ if (!get_dev_size(fd, NULL, &dsize)) ++ return 1; ++ ++ dsize >>= 9; ++ ++ if (dsize < 24) ++ return 2; ++ ++ /* ++ * Calculate the position of the superblock. ++ * It is always aligned to a 4K boundary and ++ * depending on minor_version, it can be: ++ * 0: At least 8K, but less than 12K, from end of device ++ * 1: At start of device ++ * 2: 4K from start of device. ++ */ ++ switch(st->minor_version) { ++ case 0: ++ sb_offset = dsize; ++ sb_offset -= 8*2; ++ sb_offset &= ~(4*2-1); ++ break; ++ case 1: ++ sb_offset = 0; ++ break; ++ case 2: ++ sb_offset = 4*2; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ ++ ++ if (sb_offset != __le64_to_cpu(sb->super_offset) && ++ 0 != __le64_to_cpu(sb->super_offset) ++ ) { ++ fprintf(stderr, Name ": internal error - sb_offset is wrong\n"); ++ abort(); ++ } ++ ++ if (lseek64(fd, sb_offset << 9, 0)< 0LL) ++ return 3; ++ ++ sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev); ++ ++ if (write(fd, sb, sbsize) != sbsize) ++ return 4; ++ ++ if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { ++ struct bitmap_super_s *bm = (struct bitmap_super_s*) ++ (((char*)sb)+1024); ++ if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { ++ locate_bitmap1(st, fd, sbv); ++ if (write(fd, bm, sizeof(*bm)) != sizeof(*bm)) ++ return 5; ++ } ++ } ++ fsync(fd); ++ return 0; ++} ++ ++static int load_super1(struct supertype *st, int fd, void **sbp, char *devname); ++ ++static int compare_super1(void **firstp, void *secondv) ++{ ++ /* ++ * return: ++ * 0 same, or first was empty, and second was copied ++ * 1 second had wrong number ++ * 2 wrong uuid ++ * 3 wrong other info ++ */ ++ struct mdp_superblock_1 *first = *firstp; ++ struct mdp_superblock_1 *second = secondv; ++ ++ if (second->magic != __cpu_to_le32(MD_SB_MAGIC)) ++ return 1; ++ if (second->major_version != __cpu_to_le32(1)) ++ return 1; ++ ++ if (!first) { ++ first = malloc(1024+sizeof(bitmap_super_t) + ++ sizeof(struct misc_dev_info)); ++ memcpy(first, second, 1024+sizeof(bitmap_super_t) + ++ sizeof(struct misc_dev_info)); ++ *firstp = first; ++ return 0; ++ } ++ if (memcmp(first->set_uuid, second->set_uuid, 16)!= 0) ++ return 2; ++ ++ if (first->ctime != second->ctime || ++ first->level != second->level || ++ first->layout != second->layout || ++ first->size != second->size || ++ first->chunksize != second->chunksize || ++ first->raid_disks != second->raid_disks) ++ return 3; ++ return 0; ++} ++ ++static int load_super1(struct supertype *st, int fd, void **sbp, char *devname) ++{ ++ unsigned long long dsize; ++ unsigned long long sb_offset; ++ struct mdp_superblock_1 *super; ++ int uuid[4]; ++ struct bitmap_super_s *bsb; ++ struct misc_dev_info *misc; ++ ++ ++ if (st->ss == NULL) { ++ int bestvers = -1; ++ __u64 bestctime = 0; ++ /* guess... choose latest ctime */ ++ st->ss = &super1; ++ for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) { ++ switch(load_super1(st, fd, sbp, devname)) { ++ case 0: super = *sbp; ++ if (bestvers == -1 || ++ bestctime < __le64_to_cpu(super->ctime)) { ++ bestvers = st->minor_version; ++ bestctime = __le64_to_cpu(super->ctime); ++ } ++ free(super); ++ *sbp = NULL; ++ break; ++ case 1: st->ss = NULL; return 1; /*bad device */ ++ case 2: break; /* bad, try next */ ++ } ++ } ++ if (bestvers != -1) { ++ int rv; ++ st->minor_version = bestvers; ++ st->ss = &super1; ++ st->max_devs = 384; ++ rv = load_super1(st, fd, sbp, devname); ++ if (rv) st->ss = NULL; ++ return rv; ++ } ++ st->ss = NULL; ++ return 2; ++ } ++ if (!get_dev_size(fd, devname, &dsize)) ++ return 1; ++ dsize >>= 9; ++ ++ if (dsize < 24) { ++ if (devname) ++ fprintf(stderr, Name ": %s is too small for md: size is %llu sectors.\n", ++ devname, dsize); ++ return 1; ++ } ++ ++ /* ++ * Calculate the position of the superblock. ++ * It is always aligned to a 4K boundary and ++ * depending on minor_version, it can be: ++ * 0: At least 8K, but less than 12K, from end of device ++ * 1: At start of device ++ * 2: 4K from start of device. ++ */ ++ switch(st->minor_version) { ++ case 0: ++ sb_offset = dsize; ++ sb_offset -= 8*2; ++ sb_offset &= ~(4*2-1); ++ break; ++ case 1: ++ sb_offset = 0; ++ break; ++ case 2: ++ sb_offset = 4*2; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */ ++ ++ ++ if (lseek64(fd, sb_offset << 9, 0)< 0LL) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot seek to superblock on %s: %s\n", ++ devname, strerror(errno)); ++ return 1; ++ } ++ ++ super = malloc(1024 + sizeof(bitmap_super_t) + ++ sizeof(struct misc_dev_info)); ++ ++ if (read(fd, super, 1024) != 1024) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot read superblock on %s\n", ++ devname); ++ free(super); ++ return 1; ++ } ++ ++ if (__le32_to_cpu(super->magic) != MD_SB_MAGIC) { ++ if (devname) ++ fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n", ++ devname, MD_SB_MAGIC, __le32_to_cpu(super->magic)); ++ free(super); ++ return 2; ++ } ++ ++ if (__le32_to_cpu(super->major_version) != 1) { ++ if (devname) ++ fprintf(stderr, Name ": Cannot interpret superblock on %s - version is %d\n", ++ devname, __le32_to_cpu(super->major_version)); ++ free(super); ++ return 2; ++ } ++ if (__le64_to_cpu(super->super_offset) != sb_offset) { ++ if (devname) ++ fprintf(stderr, Name ": No superblock found on %s (super_offset is wrong)\n", ++ devname); ++ free(super); ++ return 2; ++ } ++ *sbp = super; ++ ++ bsb = (struct bitmap_super_s *)(((char*)super)+1024); ++ ++ misc = (struct misc_dev_info*) (bsb+1); ++ misc->device_size = dsize; ++ ++ /* Now check on the bitmap superblock */ ++ if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) ++ return 0; ++ /* Read the bitmap superblock and make sure it looks ++ * valid. If it doesn't clear the bit. An --assemble --force ++ * should get that written out. ++ */ ++ locate_bitmap1(st, fd, super); ++ if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s)) ++ != sizeof(struct bitmap_super_s)) ++ goto no_bitmap; ++ ++ uuid_from_super1(uuid, super); ++ if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC || ++ memcmp(bsb->uuid, uuid, 16) != 0) ++ goto no_bitmap; ++ return 0; ++ ++ no_bitmap: ++ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & ~1); ++ return 0; ++} ++ ++ ++static struct supertype *match_metadata_desc1(char *arg) ++{ ++ struct supertype *st = malloc(sizeof(*st)); ++ if (!st) return st; ++ ++ st->ss = &super1; ++ st->max_devs = 384; ++ if (strcmp(arg, "1") == 0 || ++ strcmp(arg, "1.0") == 0 || ++ strcmp(arg, "default/large") == 0) { ++ st->minor_version = 0; ++ return st; ++ } ++ if (strcmp(arg, "1.1") == 0) { ++ st->minor_version = 1; ++ return st; ++ } ++ if (strcmp(arg, "1.2") == 0) { ++ st->minor_version = 2; ++ return st; ++ } ++ ++ free(st); ++ return NULL; ++} ++ ++static void locate_bitmap1(struct supertype *st, int fd, void *sbv) ++{ ++ unsigned long long offset; ++ struct mdp_superblock_1 *sb; ++ int mustfree = 0; ++ ++ if (!sbv) { ++ if (st->ss->load_super(st, fd, &sbv, NULL)) ++ return; /* no error I hope... */ ++ mustfree = 1; ++ } ++ sb = sbv; ++ ++ offset = __le64_to_cpu(sb->super_offset); ++ offset += (int32_t) __le32_to_cpu(sb->bitmap_offset); ++ if (mustfree) ++ free(sb); ++ lseek64(fd, offset<<9, 0); ++} ++ ++struct superswitch super1 = { ++ .examine_super = NULL, ++ .brief_examine_super = brief_examine_super1, ++ .detail_super = NULL, ++ .brief_detail_super = NULL, ++ .export_super = NULL, ++ .match_home = match_home1, ++ .uuid_from_super = uuid_from_super1, ++ .getinfo_super = getinfo_super1, ++ .update_super = update_super1, ++ .init_super = NULL, ++ .add_to_super = NULL, ++ .store_super = store_super1, ++ .write_init_super = NULL, ++ .compare_super = compare_super1, ++ .load_super = load_super1, ++ .match_metadata_desc = match_metadata_desc1, ++ .avail_size = NULL, ++ .add_internal_bitmap = NULL, ++ .locate_bitmap = locate_bitmap1, ++ .write_bitmap = NULL, ++ .major = 1, ++#if __BYTE_ORDER == BIG_ENDIAN ++ .swapuuid = 0, ++#else ++ .swapuuid = 1, ++#endif ++}; +--- a/mdadm/util.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdadm/mdadm/util.c 2011-01-12 21:33:01.000000000 +0200 +@@ -0,0 +1,652 @@ ++/* ++ * mdadm - manage Linux "md" devices aka RAID arrays. ++ * ++ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de> ++ * ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Neil Brown ++ * Email: <neilb@cse.unsw.edu.au> ++ * Paper: Neil Brown ++ * School of Computer Science and Engineering ++ * The University of New South Wales ++ * Sydney, 2052 ++ * Australia ++ */ ++ ++#include "mdadm.h" ++#include "md_p.h" ++#include <sys/utsname.h> ++#include <ctype.h> ++ ++/* ++ * following taken from linux/blkpg.h because they aren't ++ * anywhere else and it isn't safe to #include linux/ * stuff. ++ */ ++ ++#define BLKPG _IO(0x12,105) ++ ++/* The argument structure */ ++struct blkpg_ioctl_arg { ++ int op; ++ int flags; ++ int datalen; ++ void *data; ++}; ++ ++/* The subfunctions (for the op field) */ ++#define BLKPG_ADD_PARTITION 1 ++#define BLKPG_DEL_PARTITION 2 ++ ++/* Sizes of name fields. Unused at present. */ ++#define BLKPG_DEVNAMELTH 64 ++#define BLKPG_VOLNAMELTH 64 ++ ++/* The data structure for ADD_PARTITION and DEL_PARTITION */ ++struct blkpg_partition { ++ long long start; /* starting offset in bytes */ ++ long long length; /* length in bytes */ ++ int pno; /* partition number */ ++ char devname[BLKPG_DEVNAMELTH]; /* partition name, like sda5 or c0d1p2, ++ to be used in kernel messages */ ++ char volname[BLKPG_VOLNAMELTH]; /* volume label */ ++}; ++ ++/* ++ * Parse a 128 bit uuid in 4 integers ++ * format is 32 hexx nibbles with options :.<space> separator ++ * If not exactly 32 hex digits are found, return 0 ++ * else return 1 ++ */ ++int parse_uuid(char *str, int uuid[4]) ++{ ++ int hit = 0; /* number of Hex digIT */ ++ int i; ++ char c; ++ for (i=0; i<4; i++) uuid[i]=0; ++ ++ while ((c= *str++)) { ++ int n; ++ if (c>='0' && c<='9') ++ n = c-'0'; ++ else if (c>='a' && c <= 'f') ++ n = 10 + c - 'a'; ++ else if (c>='A' && c <= 'F') ++ n = 10 + c - 'A'; ++ else if (strchr(":. -", c)) ++ continue; ++ else return 0; ++ ++ if (hit<32) { ++ uuid[hit/8] <<= 4; ++ uuid[hit/8] += n; ++ } ++ hit++; ++ } ++ if (hit == 32) ++ return 1; ++ return 0; ++ ++} ++ ++ ++/* ++ * Get the md version number. ++ * We use the RAID_VERSION ioctl if it is supported ++ * If not, but we have a block device with major '9', we assume ++ * 0.36.0 ++ * ++ * Return version number as 24 but number - assume version parts ++ * always < 255 ++ */ ++ ++int md_get_version(int fd) ++{ ++ struct stat stb; ++ mdu_version_t vers; ++ ++ if (fstat(fd, &stb)<0) ++ return -1; ++ if ((S_IFMT&stb.st_mode) != S_IFBLK) ++ return -1; ++ ++ if (ioctl(fd, RAID_VERSION, &vers) == 0) ++ return (vers.major*10000) + (vers.minor*100) + vers.patchlevel; ++ if (errno == EACCES) ++ return -1; ++ if (major(stb.st_rdev) == MD_MAJOR) ++ return (3600); ++ return -1; ++} ++ ++ ++int get_linux_version() ++{ ++ struct utsname name; ++ char *cp; ++ int a,b,c; ++ if (uname(&name) <0) ++ return -1; ++ ++ cp = name.release; ++ a = strtoul(cp, &cp, 10); ++ if (*cp != '.') return -1; ++ b = strtoul(cp+1, &cp, 10); ++ if (*cp != '.') return -1; ++ c = strtoul(cp+1, NULL, 10); ++ ++ return (a*1000000)+(b*1000)+c; ++} ++ ++void remove_partitions(int fd) ++{ ++ /* remove partitions from this block devices. ++ * This is used for components added to an array ++ */ ++#ifdef BLKPG_DEL_PARTITION ++ struct blkpg_ioctl_arg a; ++ struct blkpg_partition p; ++ ++ a.op = BLKPG_DEL_PARTITION; ++ a.data = (void*)&p; ++ a.datalen = sizeof(p); ++ a.flags = 0; ++ memset(a.data, 0, a.datalen); ++ for (p.pno=0; p.pno < 16; p.pno++) ++ ioctl(fd, BLKPG, &a); ++#endif ++} ++ ++int enough(int level, int raid_disks, int layout, int clean, ++ char *avail, int avail_disks) ++{ ++ int copies, first; ++ switch (level) { ++ case 10: ++ /* This is the tricky one - we need to check ++ * which actual disks are present. ++ */ ++ copies = (layout&255)* ((layout>>8) & 255); ++ first=0; ++ do { ++ /* there must be one of the 'copies' form 'first' */ ++ int n = copies; ++ int cnt=0; ++ while (n--) { ++ if (avail[first]) ++ cnt++; ++ first = (first+1) % raid_disks; ++ } ++ if (cnt == 0) ++ return 0; ++ ++ } while (first != 0); ++ return 1; ++ ++ case -4: ++ return avail_disks>= 1; ++ case -1: ++ case 0: ++ return avail_disks == raid_disks; ++ case 1: ++ return avail_disks >= 1; ++ case 4: ++ case 5: ++ if (clean) ++ return avail_disks >= raid_disks-1; ++ else ++ return avail_disks >= raid_disks; ++ case 6: ++ if (clean) ++ return avail_disks >= raid_disks-2; ++ else ++ return avail_disks >= raid_disks; ++ default: ++ return 0; ++ } ++} ++ ++int same_uuid(int a[4], int b[4], int swapuuid) ++{ ++ if (swapuuid) { ++ /* parse uuids are hostendian. ++ * uuid's from some superblocks are big-ending ++ * if there is a difference, we need to swap.. ++ */ ++ unsigned char *ac = (unsigned char *)a; ++ unsigned char *bc = (unsigned char *)b; ++ int i; ++ for (i=0; i<16; i+= 4) { ++ if (ac[i+0] != bc[i+3] || ++ ac[i+1] != bc[i+2] || ++ ac[i+2] != bc[i+1] || ++ ac[i+3] != bc[i+0]) ++ return 0; ++ } ++ return 1; ++ } else { ++ if (a[0]==b[0] && ++ a[1]==b[1] && ++ a[2]==b[2] && ++ a[3]==b[3]) ++ return 1; ++ return 0; ++ } ++} ++void copy_uuid(void *a, int b[4], int swapuuid) ++{ ++ if (swapuuid) { ++ /* parse uuids are hostendian. ++ * uuid's from some superblocks are big-ending ++ * if there is a difference, we need to swap.. ++ */ ++ unsigned char *ac = (unsigned char *)a; ++ unsigned char *bc = (unsigned char *)b; ++ int i; ++ for (i=0; i<16; i+= 4) { ++ ac[i+0] = bc[i+3]; ++ ac[i+1] = bc[i+2]; ++ ac[i+2] = bc[i+1]; ++ ac[i+3] = bc[i+0]; ++ } ++ } else ++ memcpy(a, b, 16); ++} ++ ++char *map_num(mapping_t *map, int num) ++{ ++ while (map->name) { ++ if (map->num == num) ++ return map->name; ++ map++; ++ } ++ return NULL; ++} ++ ++int map_name(mapping_t *map, char *name) ++{ ++ while (map->name) { ++ if (strcmp(map->name, name)==0) ++ return map->num; ++ map++; ++ } ++ return UnSet; ++} ++ ++ ++int is_standard(char *dev, int *nump) ++{ ++ /* tests if dev is a "standard" md dev name. ++ * i.e if the last component is "/dNN" or "/mdNN", ++ * where NN is a string of digits ++ */ ++ char *d = strrchr(dev, '/'); ++ int type=0; ++ int num; ++ if (!d) ++ return 0; ++ if (strncmp(d, "/d",2)==0) ++ d += 2, type=1; /* /dev/md/dN{pM} */ ++ else if (strncmp(d, "/md_d", 5)==0) ++ d += 5, type=1; /* /dev/md_dNpM */ ++ else if (strncmp(d, "/md", 3)==0) ++ d += 3, type=-1; /* /dev/mdN */ ++ else if (d-dev > 3 && strncmp(d-2, "md/", 3)==0) ++ d += 1, type=-1; /* /dev/md/N */ ++ else ++ return 0; ++ if (!*d) ++ return 0; ++ num = atoi(d); ++ while (isdigit(*d)) ++ d++; ++ if (*d) ++ return 0; ++ if (nump) *nump = num; ++ ++ return type; ++} ++ ++ ++/* ++ * convert a major/minor pair for a block device into a name in /dev, if possible. ++ * On the first call, walk /dev collecting name. ++ * Put them in a simple linked listfor now. ++ */ ++struct devmap { ++ int major, minor; ++ char *name; ++ struct devmap *next; ++} *devlist = NULL; ++int devlist_ready = 0; ++ ++int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s) ++{ ++ struct stat st; ++ if (S_ISLNK(stb->st_mode)) { ++ stat(name, &st); ++ stb = &st; ++ } ++ ++ if ((stb->st_mode&S_IFMT)== S_IFBLK) { ++ char *n = strdup(name); ++ struct devmap *dm = malloc(sizeof(*dm)); ++ if (strncmp(n, "/dev/./", 7)==0) ++ strcpy(n+4, name+6); ++ if (dm) { ++ dm->major = major(stb->st_rdev); ++ dm->minor = minor(stb->st_rdev); ++ dm->name = n; ++ dm->next = devlist; ++ devlist = dm; ++ } ++ } ++ return 0; ++} ++ ++#ifndef HAVE_NFTW ++#ifdef HAVE_FTW ++int add_dev_1(const char *name, const struct stat *stb, int flag) ++{ ++ return add_dev(name, stb, flag, NULL); ++} ++int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, int flag, struct FTW *s), int nopenfd, int flags) ++{ ++ return ftw(path, add_dev_1, nopenfd); ++} ++#else ++int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, int flag, struct FTW *s), int nopenfd, int flags) ++{ ++ return 0; ++} ++#endif /* HAVE_FTW */ ++#endif /* HAVE_NFTW */ ++ ++/* ++ * Find a block device with the right major/minor number. ++ * If we find multiple names, choose the shortest. ++ * If we find a non-standard name, it is probably there ++ * deliberately so prefer it over a standard name. ++ * This applies only to names for MD devices. ++ */ ++char *map_dev(int major, int minor, int create) ++{ ++ struct devmap *p; ++ char *std = NULL, *nonstd=NULL; ++ int did_check = 0; ++ ++ if (major == 0 && minor == 0) ++ return NULL; ++ ++ retry: ++ if (!devlist_ready) { ++ char *dev = "/dev"; ++ struct stat stb; ++ while(devlist) { ++ struct devmap *d = devlist; ++ devlist = d->next; ++ free(d->name); ++ free(d); ++ } ++ if (lstat(dev, &stb)==0 && ++ S_ISLNK(stb.st_mode)) ++ dev = "/dev/."; ++ nftw(dev, add_dev, 10, FTW_PHYS); ++ devlist_ready=1; ++ did_check = 1; ++ } ++ ++ for (p=devlist; p; p=p->next) ++ if (p->major == major && ++ p->minor == minor) { ++ if (is_standard(p->name, NULL)) { ++ if (std == NULL || ++ strlen(p->name) < strlen(std)) ++ std = p->name; ++ } else { ++ if (nonstd == NULL || ++ strlen(p->name) < strlen(nonstd)) ++ nonstd = p->name; ++ } ++ } ++ if (!std && !nonstd && !did_check) { ++ devlist_ready = 0; ++ goto retry; ++ } ++ if (create && !std && !nonstd) { ++ static char buf[30]; ++ snprintf(buf, sizeof(buf), "%d:%d", major, minor); ++ nonstd = buf; ++ } ++ ++ return nonstd ? nonstd : std; ++} ++ ++unsigned long calc_csum(void *super, int bytes) ++{ ++ unsigned long long newcsum = 0; ++ int i; ++ unsigned int csum; ++ unsigned int *superc = (unsigned int*) super; ++ ++ for(i=0; i<bytes/4; i++) ++ newcsum+= superc[i]; ++ csum = (newcsum& 0xffffffff) + (newcsum>>32); ++#ifdef __alpha__ ++/* The in-kernel checksum calculation is always 16bit on ++ * the alpha, though it is 32 bit on i386... ++ * I wonder what it is elsewhere... (it uses and API in ++ * a way that it shouldn't). ++ */ ++ csum = (csum & 0xffff) + (csum >> 16); ++ csum = (csum & 0xffff) + (csum >> 16); ++#endif ++ return csum; ++} ++ ++char *human_size(long long bytes) ++{ ++ static char buf[30]; ++ ++ /* We convert bytes to either centi-M{ega,ibi}bytes or ++ * centi-G{igi,ibi}bytes, with appropriate rounding, ++ * and then print 1/100th of those as a decimal. ++ * We allow upto 2048Megabytes before converting to ++ * gigabytes, as that shows more precision and isn't ++ * too large a number. ++ * Terrabytes are not yet handled. ++ */ ++ ++ if (bytes < 5000*1024) ++ buf[0]=0; ++ else if (bytes < 2*1024LL*1024LL*1024LL) { ++ long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2; ++ long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; ++ snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)", ++ cMiB/100 , cMiB % 100, ++ cMB/100, cMB % 100); ++ } else { ++ long cGiB = (bytes / ( (1LL<<30) / 200LL ) +1) /2; ++ long cGB = (bytes / (1000000000LL/200LL ) +1) /2; ++ snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)", ++ cGiB/100 , cGiB % 100, ++ cGB/100, cGB % 100); ++ } ++ return buf; ++} ++ ++char *human_size_brief(long long bytes) ++{ ++ static char buf[30]; ++ ++ ++ if (bytes < 5000*1024) ++ snprintf(buf, sizeof(buf), "%ld.%02ldKiB", ++ (long)(bytes>>10), (long)(((bytes&1023)*100+512)/1024) ++ ); ++ else if (bytes < 2*1024LL*1024LL*1024LL) ++ snprintf(buf, sizeof(buf), "%ld.%02ldMiB", ++ (long)(bytes>>20), ++ (long)((bytes&0xfffff)+0x100000/200)/(0x100000/100) ++ ); ++ else ++ snprintf(buf, sizeof(buf), "%ld.%02ldGiB", ++ (long)(bytes>>30), ++ (long)(((bytes>>10)&0xfffff)+0x100000/200)/(0x100000/100) ++ ); ++ return buf; ++} ++ ++int get_mdp_major(void) ++{ ++static int mdp_major = -1; ++ FILE *fl; ++ char *w; ++ int have_block = 0; ++ int have_devices = 0; ++ int last_num = -1; ++ ++ if (mdp_major != -1) ++ return mdp_major; ++ fl = fopen("/proc/devices", "r"); ++ if (!fl) ++ return -1; ++ while ((w = conf_word(fl, 1))) { ++ if (have_block && strcmp(w, "devices:")==0) ++ have_devices = 1; ++ have_block = (strcmp(w, "Block")==0); ++ if (isdigit(w[0])) ++ last_num = atoi(w); ++ if (have_devices && strcmp(w, "mdp")==0) ++ mdp_major = last_num; ++ free(w); ++ } ++ fclose(fl); ++ return mdp_major; ++} ++ ++int dev_open(char *dev, int flags) ++{ ++ /* like 'open', but if 'dev' matches %d:%d, create a temp ++ * block device and open that ++ */ ++ char *e; ++ int fd = -1; ++ char devname[32]; ++ int major; ++ int minor; ++ ++ if (!dev) return -1; ++ ++ major = strtoul(dev, &e, 0); ++ if (e > dev && *e == ':' && e[1] && ++ (minor = strtoul(e+1, &e, 0)) >= 0 && ++ *e == 0) { ++ snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d", major, minor); ++ if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) { ++ fd = open(devname, flags); ++ unlink(devname); ++ } ++ } else ++ fd = open(dev, flags); ++ return fd; ++} ++ ++struct superswitch *superlist[] = { &super0, &super1, NULL }; ++ ++struct supertype *super_by_version(int vers, int minor) ++{ ++ struct supertype *st = malloc(sizeof(*st)); ++ if (!st) return st; ++ if (vers == 0) { ++ st->ss = &super0; ++ st->max_devs = MD_SB_DISKS; ++ } ++ ++ if (vers == 1) { ++ st->ss = &super1; ++ st->max_devs = 384; ++ } ++ st->minor_version = minor; ++ return st; ++} ++ ++struct supertype *guess_super(int fd) ++{ ++ /* try each load_super to find the best match, ++ * and return the best superswitch ++ */ ++ struct superswitch *ss; ++ struct supertype *st; ++ unsigned long besttime = 0; ++ int bestsuper = -1; ++ ++ void *sbp = NULL; ++ int i; ++ ++ st = malloc(sizeof(*st)); ++ memset(st, 0, sizeof(*st)); ++ for (i=0 ; superlist[i]; i++) { ++ int rv; ++ ss = superlist[i]; ++ st->ss = NULL; ++ rv = ss->load_super(st, fd, &sbp, NULL); ++ if (rv == 0) { ++ struct mdinfo info; ++ ss->getinfo_super(&info, sbp); ++ if (bestsuper == -1 || ++ besttime < info.array.ctime) { ++ bestsuper = i; ++ besttime = info.array.ctime; ++ } ++ free(sbp); ++ } ++ } ++ if (bestsuper != -1) { ++ int rv; ++ st->ss = NULL; ++ rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL); ++ if (rv == 0) { ++ free(sbp); ++ return st; ++ } ++ } ++ free(st); ++ return NULL; ++} ++ ++/* Return size of device in bytes */ ++int get_dev_size(int fd, char *dname, unsigned long long *sizep) ++{ ++ unsigned long long ldsize; ++#ifdef BLKGETSIZE64 ++ if (ioctl(fd, BLKGETSIZE64, &ldsize) != 0) ++#endif ++ { ++ unsigned long dsize; ++ if (ioctl(fd, BLKGETSIZE, &dsize) == 0) { ++ ldsize = dsize; ++ ldsize <<= 9; ++ } else { ++ if (dname) ++ fprintf(stderr, Name ": Cannot get size of %s: %s\b", ++ dname, strerror(errno)); ++ return 0; ++ } ++ } ++ *sizep = ldsize; ++ return 1; ++} diff --git a/patches/busybox/1.18.1/1.18.1-mdstart.diff b/patches/busybox/1.18.1/1.18.1-mdstart.diff new file mode 100644 index 00000000..6e4bf3fc --- /dev/null +++ b/patches/busybox/1.18.1/1.18.1-mdstart.diff @@ -0,0 +1,122 @@ +Based on: + +> Forward-port the old mdstart tool from the Gentoo Busybox-1.1.3. +> Only fires the RAID_AUTORUN ioctl on existing /dev/md nodes. + +diff -pruN a/include/applets.src.h mdstart/include/applets.src.h +--- a/include/applets.src.h 2011-01-20 01:08:05.470632138 +0100 ++++ mdstart/include/applets.src.h 2011-01-20 01:09:13.198003320 +0100 +@@ -235,6 +235,7 @@ IF_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUI + IF_MATCHPATHCON(APPLET(matchpathcon, _BB_DIR_USR_SBIN, _BB_SUID_DROP)) + IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_DROP, md5sum)) + IF_MDEV(APPLET(mdev, _BB_DIR_SBIN, _BB_SUID_DROP)) ++IF_MDSTART(APPLET(mdstart, _BB_DIR_SBIN, _BB_SUID_DROP)) + IF_MICROCOM(APPLET(microcom, _BB_DIR_USR_BIN, _BB_SUID_DROP)) + IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, _BB_DIR_BIN, _BB_SUID_DROP, mkdir)) + IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, _BB_DIR_SBIN, _BB_SUID_DROP, mkfs_vfat)) +diff -pruN a/include/usage.src.h mdstart/include/usage.src.h +--- a/include/usage.src.h 2010-12-21 06:29:45.000000000 +0200 ++++ mdstart/include/usage.src.h 2011-01-12 21:29:47.000000000 +0200 +@@ -847,6 +847,11 @@ INSERT + "$ dirname /tmp/foo/\n" \ + "/tmp\n" + ++#define mdstart_trivial_usage \ ++ "{[PARTITION] MD-NODE}..." ++#define mdstart_full_usage \ ++ Run the RAID_AUTORUN ioctl on the given MD number" ++ + #define dmesg_trivial_usage \ + "[-c] [-n LEVEL] [-s SIZE]" + #define dmesg_full_usage "\n\n" \ +diff -pruN a/util-linux/Config.src mdstart/util-linux/Config.src +--- a/util-linux/Config.src 2010-12-20 02:41:27.000000000 +0200 ++++ mdstart/util-linux/Config.src 2011-01-12 21:30:09.000000000 +0200 +@@ -456,6 +456,13 @@ config FEATURE_MDEV_LOAD_FIRMWARE + /lib/firmware/ and if it exists, send it to the kernel for + loading into the hardware. + ++config MDSTART ++ bool "mdstart" ++ default n ++ help ++ Allows you to autostart /dev/md devices if using an initramfs to ++ boot. ++ + config MKSWAP + bool "mkswap" + default y +diff -pruN a/util-linux/Kbuild.src mdstart/util-linux/Kbuild.src +--- a/util-linux/Kbuild.src 2010-12-20 02:41:27.000000000 +0200 ++++ mdstart/util-linux/Kbuild.src 2011-01-12 21:30:09.000000000 +0200 +@@ -24,6 +24,7 @@ lib-$(CONFIG_HWCLOCK) += hwclo + lib-$(CONFIG_IPCRM) += ipcrm.o + lib-$(CONFIG_IPCS) += ipcs.o + lib-$(CONFIG_LOSETUP) += losetup.o ++lib-$(CONFIG_MDSTART) += mdStart.o + lib-$(CONFIG_LSPCI) += lspci.o + lib-$(CONFIG_LSUSB) += lsusb.o + lib-$(CONFIG_MDEV) += mdev.o +diff -pruN a/util-linux/mdStart.c mdstart/util-linux/mdStart.c +--- a/util-linux/mdStart.c 1970-01-01 03:00:00.000000000 +0300 ++++ mdstart/util-linux/mdStart.c 2011-01-12 21:30:09.000000000 +0200 +@@ -0,0 +1,59 @@ ++/* ++ * Linux 2.6(+) RAID Autostarter ++ * ++ * Copyright (C) 2005 by Tim Yamin <plasmaroo@gentoo.org> <plasm@roo.me.uk> ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <sys/ioctl.h> ++#include <linux/major.h> ++#include <linux/raid/md_u.h> ++ ++extern int ++mdstart_main(int argc, char *argv[]) ++{ ++ int i, fd, part = 0, retval = 0; ++ ++ if(argc < 2) ++ { ++ bb_show_usage(); ++ } ++ ++ for(i = 1; i < argc; i++) ++ { ++ if(sscanf(argv[i], "%d", &part) == 1) ++ continue; ++ ++ fd = open(argv[i], 0, 0); ++ if (fd >= 0) ++ { ++ ioctl(fd, RAID_AUTORUN, part); ++ close(fd); ++ } else ++ { ++ printf("Error: Failed to open %s!\n", argv[i]); ++ retval=1; ++ } ++ ++ part = 0; ++ } ++ ++ return retval; ++} diff --git a/patches/busybox/1.18.1/1.18.1-openvt.diff b/patches/busybox/1.18.1/1.18.1-openvt.diff new file mode 100644 index 00000000..b8a9f8ac --- /dev/null +++ b/patches/busybox/1.18.1/1.18.1-openvt.diff @@ -0,0 +1,19 @@ +Based on: + +> Allow a slightly wider range of valid vt numbers. Forward-ported from Gentoo +> Busybox 1.1.3. + +> The previous spin of this patch on 1.1.3 had a 'wait(NULL);' right before +> return EXIT_SUCCESS. I don't think it's needed anymore, so I left it out. + +--- a/console-tools/openvt.c 2010-11-22 22:24:58.000000000 +0200 ++++ b/console-tools/openvt.c 2010-11-29 15:32:18.000000000 +0200 +@@ -124,7 +124,7 @@ int openvt_main(int argc UNUSED_PARAM, c + + if (flags & OPT_c) { + /* Check for illegal vt number: < 1 or > 63 */ +- vtno = xatou_range(str_c, 1, 63); ++ vtno = xatou_range(str_c, 0, 63); + } else { + vtno = find_free_vtno(); + } diff --git a/patches/busybox/1.18.1/README b/patches/busybox/1.18.1/README new file mode 100644 index 00000000..27c23fe7 --- /dev/null +++ b/patches/busybox/1.18.1/README @@ -0,0 +1,16 @@ +1.18.1-mdadm.diff: +This adds a minimal mdadm implementation to busybox for scanning for and +activating mdraid arrays. You can blame robbat2 for this one :) +Patch ported from 1.7.4 to 1.18.1 by Denis Kaganovich. + +1.18.1-mdstart.diff: +This adds a 'mdstart' command to busybox, which is used for the activation of +individual mdraid arrays. It originated with 1.1.3+gentoo or earlier. +Patch ported from 1.7.4 to 1.18.1 by Denis Kaganovich. + +1.18.1-openvt.diff: +It is unknown what problem this patch fixes. It may no longer be needed. +Patch ported from 1.7.4 to 1.18.1 by Denis Kaganovich. + +busybox-1.7.4-signal-hack.patch: +It is unknown what this patch does. It may no longer be needed. diff --git a/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch b/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch new file mode 100644 index 00000000..ba118305 --- /dev/null +++ b/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch @@ -0,0 +1,28 @@ +workaround while we get it fixed upstream + +http://bugs.gentoo.org/201114 + +--- libbb/u_signal_names.c ++++ libbb/u_signal_names.c +@@ -66,7 +66,7 @@ + #ifdef SIGTERM + [SIGTERM ] = "TERM", + #endif +-#ifdef SIGSTKFLT ++#if defined(SIGSTKFLT) && SIGSTKFLT < 32 + [SIGSTKFLT] = "STKFLT", + #endif + #ifdef SIGCHLD +@@ -90,10 +90,10 @ + #ifdef SIGURG + [SIGURG ] = "URG", + #endif +-#ifdef SIGXCPU ++#if defined(SIGXCPU) && SIGXCPU < 32 + [SIGXCPU ] = "XCPU", + #endif +-#ifdef SIGXFSZ ++#if defined(SIGXFSZ) && SIGXFSZ < 32 + [SIGXFSZ ] = "XFSZ", + #endif + #ifdef SIGVTALRM diff --git a/patches/busybox/1.7.4/1.7.4-make-3.82.diff b/patches/busybox/1.7.4/1.7.4-make-3.82.diff new file mode 100644 index 00000000..0559761f --- /dev/null +++ b/patches/busybox/1.7.4/1.7.4-make-3.82.diff @@ -0,0 +1,42 @@ +From d508d972c7f808eec5139255f661d37817c79260 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping <sebastian@pipping.org> +Date: Mon, 29 Nov 2010 09:52:22 +0100 +Subject: [PATCH] Split implicit and normal rules for make 3.82 + +--- + Makefile | 12 ++++++++++-- + 1 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index c1fe21b..a2bfe4b 100644 +--- Makefile ++++ Makefile +@@ -402,7 +402,12 @@ ifeq ($(config-targets),1) + -include $(srctree)/arch/$(ARCH)/Makefile + export KBUILD_DEFCONFIG + +-config %config: scripts_basic outputmakefile FORCE ++config: scripts_basic outputmakefile FORCE ++ $(Q)mkdir -p include ++ $(Q)$(MAKE) $(build)=scripts/kconfig $@ ++ $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease ++ ++%config: scripts_basic outputmakefile FORCE + $(Q)mkdir -p include + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease +@@ -1239,7 +1244,10 @@ endif + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) + + # Modules +-/ %/: prepare scripts FORCE ++/: prepare scripts FORCE ++ $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ ++ $(build)=$(build-dir) ++%/: prepare scripts FORCE + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) + %.ko: prepare scripts FORCE +-- +1.7.3.2 + diff --git a/patches/lvm/2.02.28/filter-sysfs-inc-sys-stat.patch b/patches/lvm/2.02.28/filter-sysfs-inc-sys-stat.patch new file mode 100644 index 00000000..2988e92e --- /dev/null +++ b/patches/lvm/2.02.28/filter-sysfs-inc-sys-stat.patch @@ -0,0 +1,11 @@ +diff -ur LVM2.2.02.28/lib/filters/filter-sysfs.c LVM2.2.02.28.new/lib/filters/filter-sysfs.c +--- LVM2.2.02.28/lib/filters/filter-sysfs.c 2007-08-22 16:38:16.000000000 +0200 ++++ LVM2.2.02.28.new/lib/filters/filter-sysfs.c 2011-01-13 20:45:38.751542669 +0100 +@@ -15,6 +15,7 @@ + #include "lib.h" + #include "filter-sysfs.h" + #include "lvm-string.h" ++#include <sys/stat.h> + + #ifdef linux + diff --git a/patches/lvm/2.02.28/no-export-dynamic.patch b/patches/lvm/2.02.28/no-export-dynamic.patch new file mode 100644 index 00000000..19a4e13a --- /dev/null +++ b/patches/lvm/2.02.28/no-export-dynamic.patch @@ -0,0 +1,22 @@ +diff -ur LVM2.2.02.28/configure LVM2.2.02.28.new/configure +--- LVM2.2.02.28/configure 2007-08-14 20:58:30.000000000 +0200 ++++ LVM2.2.02.28.new/configure 2011-01-13 20:45:08.429184861 +0100 +@@ -1949,7 +1949,6 @@ + CLDWHOLEARCHIVE="-Wl,-whole-archive" + CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive" + LDDEPS="$LDDEPS .export.sym" +- LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + LIB_SUFFIX="so" + DEVMAPPER=yes + ODIRECT=yes +diff -ur LVM2.2.02.28/configure.in LVM2.2.02.28.new/configure.in +--- LVM2.2.02.28/configure.in 2007-08-14 20:58:31.000000000 +0200 ++++ LVM2.2.02.28.new/configure.in 2011-01-13 20:45:14.365688659 +0100 +@@ -38,7 +38,6 @@ + CLDWHOLEARCHIVE="-Wl,-whole-archive" + CLDNOWHOLEARCHIVE="-Wl,-no-whole-archive" + LDDEPS="$LDDEPS .export.sym" +- LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + LIB_SUFFIX="so" + DEVMAPPER=yes + ODIRECT=yes diff --git a/patches/lvm/2.02.74/lvm2-2.02.72-no-export-dynamic.patch b/patches/lvm/2.02.74/lvm2-2.02.72-no-export-dynamic.patch new file mode 100644 index 00000000..05c7bf30 --- /dev/null +++ b/patches/lvm/2.02.74/lvm2-2.02.72-no-export-dynamic.patch @@ -0,0 +1,37 @@ +X-Gentoo-Bug: 332905 +X-Patch-URL: https://bugs.gentoo.org/attachment.cgi?id=243283&action=view +X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=332905 + +diff -ur LVM2.2.02.72.orig/daemons/dmeventd/Makefile.in LVM2.2.02.72/daemons/dmeventd/Makefile.in +--- LVM2.2.02.72.orig/daemons/dmeventd/Makefile.in 2010-05-14 16:36:56.000000000 +0300 ++++ LVM2.2.02.72/daemons/dmeventd/Makefile.in 2010-08-17 03:00:24.000000000 +0300 +@@ -61,7 +61,7 @@ + $(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic + + dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a +- $(CC) $(CFLAGS) $(LDFLAGS) -static -L. -L$(interfacebuilddir) -o $@ \ ++ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--no-export-dynamic -static -L. -L$(interfacebuilddir) -o $@ \ + dmeventd.o $(DL_LIBS) $(LVMLIBS) $(LIBS) $(STATIC_LIBS) + + ifeq ("@PKGCONFIG@", "yes") +diff -ur LVM2.2.02.72.orig/tools/Makefile.in LVM2.2.02.72/tools/Makefile.in +--- LVM2.2.02.72.orig/tools/Makefile.in 2010-06-25 21:23:10.000000000 +0300 ++++ LVM2.2.02.72/tools/Makefile.in 2010-08-17 03:01:07.000000000 +0300 +@@ -126,7 +126,7 @@ + -o $@ dmsetup.o -ldevmapper $(LIBS) + + dmsetup.static: dmsetup.o $(interfacebuilddir)/libdevmapper.a +- $(CC) $(CFLAGS) $(LDFLAGS) -static -L$(interfacebuilddir) \ ++ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--no-export-dynamic -static -L$(interfacebuilddir) \ + -o $@ dmsetup.o -ldevmapper $(STATIC_LIBS) $(LIBS) + + all: device-mapper +@@ -136,7 +136,7 @@ + $(LVMLIBS) $(READLINE_LIBS) $(LIBS) -rdynamic + + lvm.static: $(OBJECTS) lvm-static.o $(top_builddir)/lib/liblvm-internal.a $(interfacebuilddir)/libdevmapper.a +- $(CC) $(CFLAGS) $(LDFLAGS) -static -L$(interfacebuilddir) -o $@ \ ++ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--no-export-dynamic -static -L$(interfacebuilddir) -o $@ \ + $(OBJECTS) lvm-static.o $(LVMLIBS) $(STATIC_LIBS) $(LIBS) + + liblvm2cmd.a: $(top_builddir)/lib/liblvm-internal.a $(OBJECTS) lvmcmdlib.o lvm2cmd.o |