Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 259650 Details for
Bug 331971
[patch] sys-kernel/genkernel-3.4.10.907 - upgrade busybox
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
busybox-migration-1.18.1.patch
busybox-migration-1.18.1.patch (text/plain), 426.48 KB, created by
Denis Kaganovich
on 2011-01-12 20:08:30 UTC
(
hide
)
Description:
busybox-migration-1.18.1.patch
Filename:
MIME Type:
Creator:
Denis Kaganovich
Created:
2011-01-12 20:08:30 UTC
Size:
426.48 KB
patch
obsolete
>diff -pruN genkernel.a/defaults/busy-config genkernel.b/defaults/busy-config >--- genkernel.a/defaults/busy-config 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/defaults/busy-config 2011-01-12 21:49:05.000000000 +0200 >@@ -1,7 +1,7 @@ > # > # Automatically generated make config: don't edit >-# Busybox version: 1.7.4 >-# Tue Mar 11 13:29:47 2008 >+# Busybox version: 1.18.1 >+# Wed Jan 12 21:45:31 2011 > # > CONFIG_HAVE_DOT_CONFIG=y > >@@ -12,19 +12,35 @@ CONFIG_HAVE_DOT_CONFIG=y > # > # General Configuration > # >-# CONFIG_NITPICK is not set > # CONFIG_DESKTOP is not set >-# CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set >+# CONFIG_EXTRA_COMPAT is not set >+# CONFIG_INCLUDE_SUSv2 is not set >+# CONFIG_USE_PORTABLE_CODE is not set >+CONFIG_PLATFORM_LINUX=y >+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y > # CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set > # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set > CONFIG_SHOW_USAGE=y > # CONFIG_FEATURE_VERBOSE_USAGE is not set > CONFIG_FEATURE_COMPRESS_USAGE=y > CONFIG_FEATURE_INSTALLER=y >+# CONFIG_INSTALL_NO_USR is not set > # CONFIG_LOCALE_SUPPORT is not set >-CONFIG_GETOPT_LONG=y >+CONFIG_UNICODE_SUPPORT=y >+# CONFIG_UNICODE_USING_LOCALE is not set >+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set >+CONFIG_SUBST_WCHAR=63 >+CONFIG_LAST_SUPPORTED_WCHAR=767 >+# CONFIG_UNICODE_COMBINING_WCHARS is not set >+# CONFIG_UNICODE_WIDE_WCHARS is not set >+# CONFIG_UNICODE_BIDI_SUPPORT is not set >+# CONFIG_UNICODE_NEUTRAL_TABLE is not set >+# CONFIG_UNICODE_PRESERVE_BROKEN is not set >+CONFIG_LONG_OPTS=y > CONFIG_FEATURE_DEVPTS=y > # CONFIG_FEATURE_CLEAN_UP is not set >+# CONFIG_FEATURE_WTMP is not set >+# CONFIG_FEATURE_UTMP is not set > # CONFIG_FEATURE_PIDFILE is not set > # CONFIG_FEATURE_SUID is not set > # CONFIG_FEATURE_SUID_CONFIG is not set >@@ -39,29 +55,35 @@ CONFIG_FEATURE_HAVE_RPC=y > # Build Options > # > CONFIG_STATIC=y >+# CONFIG_PIE is not set >+# CONFIG_NOMMU is not set > # CONFIG_BUILD_LIBBUSYBOX is not set >-# CONFIG_FEATURE_FULL_LIBBUSYBOX is not set >+# CONFIG_FEATURE_INDIVIDUAL is not set > # CONFIG_FEATURE_SHARED_BUSYBOX is not set > CONFIG_LFS=y >-# CONFIG_BUILD_AT_ONCE is not set >+CONFIG_CROSS_COMPILER_PREFIX="" >+CONFIG_EXTRA_CFLAGS="" > > # > # Debugging Options > # > # CONFIG_DEBUG is not set >+# CONFIG_DEBUG_PESSIMIZE is not set > # CONFIG_WERROR is not set > CONFIG_NO_DEBUG_LIB=y > # CONFIG_DMALLOC is not set > # CONFIG_EFENCE is not set >-# CONFIG_INCLUDE_SUSv2 is not set > > # >-# Installation Options >+# Installation Options ("make install" behavior) > # >-# CONFIG_INSTALL_NO_USR is not set > CONFIG_INSTALL_APPLET_SYMLINKS=y > # CONFIG_INSTALL_APPLET_HARDLINKS is not set >+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set > # CONFIG_INSTALL_APPLET_DONT is not set >+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set >+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set >+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set > CONFIG_PREFIX="./_install" > > # >@@ -71,17 +93,22 @@ CONFIG_PASSWORD_MINLEN=6 > CONFIG_MD5_SIZE_VS_SPEED=2 > # CONFIG_FEATURE_FAST_TOP is not set > # CONFIG_FEATURE_ETC_NETWORKS is not set >+CONFIG_FEATURE_USE_TERMIOS=y > CONFIG_FEATURE_EDITING=y > CONFIG_FEATURE_EDITING_MAX_LEN=1024 >-# CONFIG_FEATURE_EDITING_FANCY_KEYS is not set > # CONFIG_FEATURE_EDITING_VI is not set > CONFIG_FEATURE_EDITING_HISTORY=15 > # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set > CONFIG_FEATURE_TAB_COMPLETION=y > # CONFIG_FEATURE_USERNAME_COMPLETION is not set > # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set >+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set >+CONFIG_FEATURE_NON_POSIX_CP=y >+# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set >+CONFIG_FEATURE_COPYBUF_KB=4 > CONFIG_MONOTONIC_SYSCALL=y > CONFIG_IOCTL_HEX2STR_ERROR=y >+CONFIG_FEATURE_HWIB=y > > # > # Applets >@@ -90,64 +117,82 @@ CONFIG_IOCTL_HEX2STR_ERROR=y > # > # Archival Utilities > # >+CONFIG_FEATURE_SEAMLESS_XZ=y >+CONFIG_FEATURE_SEAMLESS_LZMA=y >+CONFIG_FEATURE_SEAMLESS_BZ2=y >+CONFIG_FEATURE_SEAMLESS_GZ=y >+CONFIG_FEATURE_SEAMLESS_Z=y > # CONFIG_AR is not set > # CONFIG_FEATURE_AR_LONG_FILENAMES is not set >-# CONFIG_BUNZIP2 is not set >+# CONFIG_FEATURE_AR_CREATE is not set >+CONFIG_BUNZIP2=y >+CONFIG_BZIP2=y > # CONFIG_CPIO is not set >+# CONFIG_FEATURE_CPIO_O is not set >+# CONFIG_FEATURE_CPIO_P is not set > # CONFIG_DPKG is not set > # CONFIG_DPKG_DEB is not set > # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set > CONFIG_GUNZIP=y >-# CONFIG_FEATURE_GUNZIP_UNCOMPRESS is not set > CONFIG_GZIP=y >+# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set >+CONFIG_LZOP=y >+# CONFIG_LZOP_COMPR_HIGH is not set > # CONFIG_RPM2CPIO is not set > # CONFIG_RPM is not set >-# CONFIG_FEATURE_RPM_BZ2 is not set > CONFIG_TAR=y > CONFIG_FEATURE_TAR_CREATE=y >-CONFIG_FEATURE_TAR_BZIP2=y >-# CONFIG_FEATURE_TAR_LZMA is not set >+CONFIG_FEATURE_TAR_AUTODETECT=y > # CONFIG_FEATURE_TAR_FROM is not set >-CONFIG_FEATURE_TAR_GZIP=y >-# CONFIG_FEATURE_TAR_COMPRESS is not set > # CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set > # CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set > CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y > # CONFIG_FEATURE_TAR_LONG_OPTIONS is not set >+# CONFIG_FEATURE_TAR_TO_COMMAND is not set >+CONFIG_FEATURE_TAR_UNAME_GNAME=y >+CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y >+# CONFIG_FEATURE_TAR_SELINUX is not set > # CONFIG_UNCOMPRESS is not set > # CONFIG_UNLZMA is not set > # CONFIG_FEATURE_LZMA_FAST is not set >+# CONFIG_LZMA is not set >+# CONFIG_UNXZ is not set >+# CONFIG_XZ is not set > # CONFIG_UNZIP is not set > > # >-# Common options for cpio and tar >-# >-# CONFIG_FEATURE_UNARCHIVE_TAPE is not set >-# CONFIG_FEATURE_DEB_TAR_GZ is not set >-# CONFIG_FEATURE_DEB_TAR_BZ2 is not set >-# CONFIG_FEATURE_DEB_TAR_LZMA is not set >- >-# > # Coreutils > # > CONFIG_BASENAME=y >-# CONFIG_CAL is not set > CONFIG_CAT=y >+CONFIG_DATE=y >+CONFIG_FEATURE_DATE_ISOFMT=y >+# CONFIG_FEATURE_DATE_NANO is not set >+CONFIG_FEATURE_DATE_COMPAT=y >+CONFIG_TEST=y >+# CONFIG_FEATURE_TEST_64 is not set >+# CONFIG_TR is not set >+# CONFIG_FEATURE_TR_CLASSES is not set >+# CONFIG_FEATURE_TR_EQUIV is not set >+CONFIG_BASE64=y >+# CONFIG_CAL is not set > # CONFIG_CATV is not set > CONFIG_CHGRP=y > CONFIG_CHMOD=y > CONFIG_CHOWN=y >+CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y > CONFIG_CHROOT=y > # CONFIG_CKSUM is not set > # CONFIG_COMM is not set > CONFIG_CP=y >+CONFIG_FEATURE_CP_LONG_OPTIONS=y > CONFIG_CUT=y >-CONFIG_DATE=y >-CONFIG_FEATURE_DATE_ISOFMT=y > CONFIG_DD=y > CONFIG_FEATURE_DD_SIGNAL_HANDLING=y >+CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y > # CONFIG_FEATURE_DD_IBS_OBS is not set > CONFIG_DF=y >+CONFIG_FEATURE_DF_FANCY=y > CONFIG_DIRNAME=y > # CONFIG_DOS2UNIX is not set > # CONFIG_UNIX2DOS is not set >@@ -163,6 +208,7 @@ CONFIG_ENV=y > # CONFIG_EXPR_MATH_SUPPORT_64 is not set > CONFIG_FALSE=y > # CONFIG_FOLD is not set >+CONFIG_FSYNC=y > CONFIG_HEAD=y > # CONFIG_FEATURE_FANCY_HEAD is not set > # CONFIG_HOSTID is not set >@@ -199,10 +245,14 @@ CONFIG_READLINK=y > # CONFIG_REALPATH is not set > CONFIG_RM=y > CONFIG_RMDIR=y >+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y > # CONFIG_SEQ is not set > # CONFIG_SHA1SUM is not set >+CONFIG_SHA256SUM=y >+CONFIG_SHA512SUM=y > CONFIG_SLEEP=y > # CONFIG_FEATURE_FANCY_SLEEP is not set >+# CONFIG_FEATURE_FLOAT_SLEEP is not set > CONFIG_SORT=y > CONFIG_FEATURE_SORT_BIG=y > # CONFIG_SPLIT is not set >@@ -212,16 +262,12 @@ CONFIG_FEATURE_SORT_BIG=y > CONFIG_STTY=y > # CONFIG_SUM is not set > CONFIG_SYNC=y >+CONFIG_TAC=y > CONFIG_TAIL=y > # CONFIG_FEATURE_FANCY_TAIL is not set > # CONFIG_TEE is not set > # CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set >-CONFIG_TEST=y >-# CONFIG_FEATURE_TEST_64 is not set > CONFIG_TOUCH=y >-# CONFIG_TR is not set >-# CONFIG_FEATURE_TR_CLASSES is not set >-# CONFIG_FEATURE_TR_EQUIV is not set > CONFIG_TRUE=y > CONFIG_TTY=y > CONFIG_UNAME=y >@@ -251,15 +297,21 @@ CONFIG_FEATURE_AUTOWIDTH=y > # Common options for df, du, ls > # > CONFIG_FEATURE_HUMAN_READABLE=y >+ >+# >+# Common options for md5sum, sha1sum, sha256sum, sha512sum >+# > # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set > > # > # Console Utilities > # > CONFIG_CHVT=y >+CONFIG_FGCONSOLE=y > CONFIG_CLEAR=y > # CONFIG_DEALLOCVT is not set > CONFIG_DUMPKMAP=y >+CONFIG_KBD_MODE=y > CONFIG_LOADFONT=y > CONFIG_LOADKMAP=y > # CONFIG_OPENVT is not set >@@ -268,8 +320,18 @@ CONFIG_RESET=y > # CONFIG_FEATURE_RESIZE_PRINT is not set > # CONFIG_SETCONSOLE is not set > # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set >+CONFIG_SETFONT=y >+CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y >+CONFIG_DEFAULT_SETFONT_DIR="" > # CONFIG_SETKEYCODES is not set > # CONFIG_SETLOGCONS is not set >+CONFIG_SHOWKEY=y >+ >+# >+# Common options for loadfont and setfont >+# >+CONFIG_FEATURE_LOADFONT_PSF2=y >+CONFIG_FEATURE_LOADFONT_RAW=y > > # > # Debian Utilities >@@ -287,18 +349,18 @@ CONFIG_WHICH=y > # > # Editors > # >+# CONFIG_PATCH is not set > # CONFIG_AWK is not set >-# CONFIG_FEATURE_AWK_MATH is not set >+# CONFIG_FEATURE_AWK_LIBM is not set > # CONFIG_CMP is not set > # CONFIG_DIFF is not set >-# CONFIG_FEATURE_DIFF_BINARY is not set >+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set > # CONFIG_FEATURE_DIFF_DIR is not set >-# CONFIG_FEATURE_DIFF_MINIMAL is not set > # CONFIG_ED is not set >-# CONFIG_PATCH is not set > CONFIG_SED=y > # CONFIG_VI is not set >-CONFIG_FEATURE_VI_MAX_LEN= >+CONFIG_FEATURE_VI_MAX_LEN=0 >+# CONFIG_FEATURE_VI_8BIT is not set > # CONFIG_FEATURE_VI_COLON is not set > # CONFIG_FEATURE_VI_YANKMARK is not set > # CONFIG_FEATURE_VI_SEARCH is not set >@@ -308,6 +370,7 @@ CONFIG_FEATURE_VI_MAX_LEN= > # CONFIG_FEATURE_VI_SETOPTS is not set > # CONFIG_FEATURE_VI_SET is not set > # CONFIG_FEATURE_VI_WIN_RESIZE is not set >+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set > # CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set > # CONFIG_FEATURE_ALLOW_EXEC is not set > >@@ -336,6 +399,7 @@ CONFIG_FEATURE_FIND_SIZE=y > # CONFIG_FEATURE_FIND_PATH is not set > # CONFIG_FEATURE_FIND_REGEX is not set > # CONFIG_FEATURE_FIND_CONTEXT is not set >+CONFIG_FEATURE_FIND_LINKS=y > CONFIG_GREP=y > # CONFIG_FEATURE_GREP_EGREP_ALIAS is not set > CONFIG_FEATURE_GREP_FGREP_ALIAS=y >@@ -349,32 +413,46 @@ CONFIG_XARGS=y > # > # Init Utilities > # >+CONFIG_BOOTCHARTD=y >+CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y >+CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y >+CONFIG_HALT=y >+# CONFIG_FEATURE_CALL_TELINIT is not set >+CONFIG_TELINIT_PATH="" > CONFIG_INIT=y >-# CONFIG_DEBUG_INIT is not set > CONFIG_FEATURE_USE_INITTAB=y >+# CONFIG_FEATURE_KILL_REMOVED is not set >+CONFIG_FEATURE_KILL_DELAY=0 > # CONFIG_FEATURE_INIT_SCTTY is not set > # CONFIG_FEATURE_INIT_SYSLOG is not set > # CONFIG_FEATURE_EXTRA_QUIET is not set > # CONFIG_FEATURE_INIT_COREDUMPS is not set > CONFIG_FEATURE_INITRD=y >-CONFIG_HALT=y >+CONFIG_INIT_TERMINAL_TYPE="linux" > CONFIG_MESG=y > > # > # Login/Password Management Utilities > # >+# CONFIG_ADD_SHELL is not set >+# CONFIG_REMOVE_SHELL is not set > # CONFIG_FEATURE_SHADOWPASSWDS is not set >-# CONFIG_USE_BB_SHADOW is not set > # CONFIG_USE_BB_PWD_GRP is not set >+# CONFIG_USE_BB_SHADOW is not set >+# CONFIG_USE_BB_CRYPT is not set >+# CONFIG_USE_BB_CRYPT_SHA is not set >+# CONFIG_ADDUSER is not set >+# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set >+# CONFIG_FEATURE_CHECK_NAMES is not set >+CONFIG_FIRST_SYSTEM_ID=0 >+CONFIG_LAST_SYSTEM_ID=0 > # CONFIG_ADDGROUP is not set >+# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set > # CONFIG_FEATURE_ADDUSER_TO_GROUP is not set >+# CONFIG_DELUSER is not set > # CONFIG_DELGROUP is not set > # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set >-# CONFIG_ADDUSER is not set >-# CONFIG_DELUSER is not set > # CONFIG_GETTY is not set >-# CONFIG_FEATURE_UTMP is not set >-# CONFIG_FEATURE_WTMP is not set > # CONFIG_LOGIN is not set > # CONFIG_PAM is not set > # CONFIG_LOGIN_SCRIPTS is not set >@@ -396,34 +474,52 @@ CONFIG_CHPASSWD=y > # CONFIG_CHATTR is not set > # CONFIG_FSCK is not set > # CONFIG_LSATTR is not set >+# CONFIG_TUNE2FS is not set >+ >+# >+# Linux mdadm Utilities >+# >+CONFIG_MDADM=y > > # > # Linux Module Utilities > # >+# CONFIG_MODINFO is not set >+# CONFIG_MODPROBE_SMALL is not set >+# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set >+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set > CONFIG_INSMOD=y >-# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set >-# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set >-# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set >-# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set >-# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set > CONFIG_RMMOD=y > CONFIG_LSMOD=y > # CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set > CONFIG_MODPROBE=y >-CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS=y >-CONFIG_FEATURE_MODPROBE_FANCY_ALIAS=y >+CONFIG_FEATURE_MODPROBE_BLACKLIST=y >+# CONFIG_DEPMOD is not set > > # > # Options common to multiple modutils > # >+# CONFIG_FEATURE_2_4_MODULES is not set >+CONFIG_FEATURE_INSMOD_TRY_MMAP=y >+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set >+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set >+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set >+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set >+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set > CONFIG_FEATURE_CHECK_TAINTED_MODULE=y >-CONFIG_FEATURE_2_4_MODULES=y >-CONFIG_FEATURE_2_6_MODULES=y >-# CONFIG_FEATURE_QUERY_MODULE_INTERFACE is not set >+CONFIG_FEATURE_MODUTILS_ALIAS=y >+CONFIG_FEATURE_MODUTILS_SYMBOLS=y >+CONFIG_DEFAULT_MODULES_DIR="/lib/modules" >+CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" > > # > # Linux System Utilities > # >+CONFIG_BLOCKDEV=y >+CONFIG_REV=y >+CONFIG_ACPID=y >+CONFIG_FEATURE_ACPID_COMPAT=y >+CONFIG_BLKID=y > CONFIG_DMESG=y > CONFIG_FEATURE_DMESG_PRETTY=y > # CONFIG_FBSET is not set >@@ -438,39 +534,59 @@ CONFIG_FDISK_SUPPORT_LARGE_DISKS=y > # CONFIG_FEATURE_SGI_LABEL is not set > # CONFIG_FEATURE_SUN_LABEL is not set > # CONFIG_FEATURE_OSF_LABEL is not set >+# CONFIG_FEATURE_GPT_LABEL is not set > # CONFIG_FEATURE_FDISK_ADVANCED is not set >+CONFIG_FINDFS=y >+CONFIG_FLOCK=y > CONFIG_FREERAMDISK=y > # CONFIG_FSCK_MINIX is not set >+CONFIG_MKFS_EXT2=y > # CONFIG_MKFS_MINIX is not set > # CONFIG_FEATURE_MINIX2 is not set >+CONFIG_MKFS_REISER=y >+# CONFIG_MKFS_VFAT is not set > # CONFIG_GETOPT is not set >+# CONFIG_FEATURE_GETOPT_LONG is not set > CONFIG_HEXDUMP=y >+CONFIG_FEATURE_HEXDUMP_REVERSE=y >+CONFIG_HD=y > # CONFIG_HWCLOCK is not set > # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set > # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set > # CONFIG_IPCRM is not set > # CONFIG_IPCS is not set > CONFIG_LOSETUP=y >-CONFIG_MDADM=y >+CONFIG_LSPCI=y >+CONFIG_LSUSB=y > CONFIG_MDEV=y > # CONFIG_FEATURE_MDEV_CONF is not set >+# CONFIG_FEATURE_MDEV_RENAME is not set >+# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set > # CONFIG_FEATURE_MDEV_EXEC is not set > CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y > CONFIG_MDSTART=y > # CONFIG_MKSWAP is not set >-# CONFIG_FEATURE_MKSWAP_V0 is not set >+# CONFIG_FEATURE_MKSWAP_UUID is not set > CONFIG_MORE=y >-CONFIG_FEATURE_USE_TERMIOS=y > CONFIG_MOUNT=y >+CONFIG_FEATURE_MOUNT_FAKE=y >+CONFIG_FEATURE_MOUNT_VERBOSE=y >+# CONFIG_FEATURE_MOUNT_HELPERS is not set >+CONFIG_FEATURE_MOUNT_LABEL=y > CONFIG_FEATURE_MOUNT_NFS=y >-# CONFIG_FEATURE_MOUNT_CIFS is not set >+CONFIG_FEATURE_MOUNT_CIFS=y > CONFIG_FEATURE_MOUNT_FLAGS=y > CONFIG_FEATURE_MOUNT_FSTAB=y > CONFIG_PIVOT_ROOT=y > CONFIG_RDATE=y >+CONFIG_RDEV=y > # CONFIG_READPROFILE is not set >+CONFIG_RTCWAKE=y >+CONFIG_SCRIPT=y >+CONFIG_SCRIPTREPLAY=y > # CONFIG_SETARCH is not set > CONFIG_SWAPONOFF=y >+CONFIG_FEATURE_SWAPON_PRI=y > CONFIG_SWITCH_ROOT=y > CONFIG_UMOUNT=y > # CONFIG_FEATURE_UMOUNT_ALL is not set >@@ -479,33 +595,88 @@ CONFIG_UMOUNT=y > # Common options for mount/umount > # > CONFIG_FEATURE_MOUNT_LOOP=y >+CONFIG_FEATURE_MOUNT_LOOP_CREATE=y > CONFIG_FEATURE_MTAB_SUPPORT=y >+CONFIG_VOLUMEID=y >+ >+# >+# Filesystem/Volume identification >+# >+CONFIG_FEATURE_VOLUMEID_EXT=y >+CONFIG_FEATURE_VOLUMEID_BTRFS=y >+CONFIG_FEATURE_VOLUMEID_REISERFS=y >+CONFIG_FEATURE_VOLUMEID_FAT=y >+CONFIG_FEATURE_VOLUMEID_HFS=y >+CONFIG_FEATURE_VOLUMEID_JFS=y >+CONFIG_FEATURE_VOLUMEID_XFS=y >+CONFIG_FEATURE_VOLUMEID_NTFS=y >+CONFIG_FEATURE_VOLUMEID_ISO9660=y >+CONFIG_FEATURE_VOLUMEID_UDF=y >+CONFIG_FEATURE_VOLUMEID_LUKS=y >+CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y >+CONFIG_FEATURE_VOLUMEID_CRAMFS=y >+CONFIG_FEATURE_VOLUMEID_ROMFS=y >+CONFIG_FEATURE_VOLUMEID_SYSV=y >+CONFIG_FEATURE_VOLUMEID_OCFS2=y >+CONFIG_FEATURE_VOLUMEID_LINUXRAID=y > > # > # Miscellaneous Utilities > # >+# CONFIG_CONSPY is not set >+# CONFIG_NANDWRITE is not set >+# CONFIG_NANDDUMP is not set >+# CONFIG_UBIATTACH is not set >+# CONFIG_UBIDETACH is not set > # CONFIG_ADJTIMEX is not set > # CONFIG_BBCONFIG is not set >+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set >+# CONFIG_BEEP is not set >+CONFIG_FEATURE_BEEP_FREQ=0 >+CONFIG_FEATURE_BEEP_LENGTH_MS=0 >+# CONFIG_CHAT is not set >+# CONFIG_FEATURE_CHAT_NOFAIL is not set >+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set >+# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set >+# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set >+# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set >+# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set >+# CONFIG_FEATURE_CHAT_CLR_ABORT is not set > # CONFIG_CHRT is not set > # CONFIG_CROND is not set >-# CONFIG_DEBUG_CROND_OPTION is not set >+# CONFIG_FEATURE_CROND_D is not set > # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set >+CONFIG_FEATURE_CROND_DIR="" > # CONFIG_CRONTAB is not set > # CONFIG_DC is not set >+# CONFIG_FEATURE_DC_LIBM is not set > # CONFIG_DEVFSD is not set > # CONFIG_DEVFSD_MODLOAD is not set > # CONFIG_DEVFSD_FG_NP is not set > # CONFIG_DEVFSD_VERBOSE is not set > # CONFIG_FEATURE_DEVFS is not set >+# CONFIG_DEVMEM is not set > # CONFIG_EJECT is not set >+# CONFIG_FEATURE_EJECT_SCSI is not set >+CONFIG_FBSPLASH=y >+# CONFIG_FLASHCP is not set >+# CONFIG_FLASH_LOCK is not set >+# CONFIG_FLASH_UNLOCK is not set >+# CONFIG_FLASH_ERASEALL is not set >+# CONFIG_IONICE is not set >+# CONFIG_INOTIFYD is not set > # CONFIG_LAST is not set >+# CONFIG_FEATURE_LAST_SMALL is not set >+# CONFIG_FEATURE_LAST_FANCY is not set > # CONFIG_LESS is not set >-CONFIG_FEATURE_LESS_MAXLINES= >+CONFIG_FEATURE_LESS_MAXLINES=0 > # CONFIG_FEATURE_LESS_BRACKETS is not set > # CONFIG_FEATURE_LESS_FLAGS is not set >-# CONFIG_FEATURE_LESS_FLAGCS is not set > # CONFIG_FEATURE_LESS_MARKS is not set > # CONFIG_FEATURE_LESS_REGEXP is not set >+# CONFIG_FEATURE_LESS_WINCH is not set >+# CONFIG_FEATURE_LESS_DASHCMD is not set >+# CONFIG_FEATURE_LESS_LINENUMS is not set > # CONFIG_HDPARM is not set > # CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set > # CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set >@@ -516,54 +687,76 @@ CONFIG_FEATURE_LESS_MAXLINES= > CONFIG_MAKEDEVS=y > CONFIG_FEATURE_MAKEDEVS_LEAF=y > # CONFIG_FEATURE_MAKEDEVS_TABLE is not set >+# CONFIG_MAN is not set >+CONFIG_MICROCOM=y > # CONFIG_MOUNTPOINT is not set > # CONFIG_MT is not set >-# CONFIG_RAIDAUTORUN is not set >-# CONFIG_READAHEAD is not set >+CONFIG_RAIDAUTORUN=y >+CONFIG_READAHEAD=y >+# CONFIG_RFKILL is not set > # CONFIG_RUNLEVEL is not set > # CONFIG_RX is not set >-# CONFIG_STRINGS is not set > # CONFIG_SETSID is not set >+# CONFIG_STRINGS is not set > # CONFIG_TASKSET is not set > # CONFIG_FEATURE_TASKSET_FANCY is not set > # CONFIG_TIME is not set >+# CONFIG_TIMEOUT is not set > # CONFIG_TTYSIZE is not set >+# CONFIG_VOLNAME is not set >+# CONFIG_WALL is not set > # CONFIG_WATCHDOG is not set > > # > # Networking Utilities > # >-# CONFIG_FEATURE_IPV6 is not set >+CONFIG_NBDCLIENT=y >+# CONFIG_NC is not set >+# CONFIG_NC_SERVER is not set >+# CONFIG_NC_EXTRA is not set >+# CONFIG_NC_110_COMPAT is not set >+CONFIG_FEATURE_IPV6=y >+# CONFIG_FEATURE_UNIX_LOCAL is not set >+# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set > # CONFIG_VERBOSE_RESOLUTION_ERRORS is not set > # CONFIG_ARP is not set > # CONFIG_ARPING is not set >+# CONFIG_BRCTL is not set >+# CONFIG_FEATURE_BRCTL_FANCY is not set >+# CONFIG_FEATURE_BRCTL_SHOW is not set > # CONFIG_DNSD is not set > # CONFIG_ETHER_WAKE is not set > # CONFIG_FAKEIDENTD is not set >+# CONFIG_FTPD is not set >+# CONFIG_FEATURE_FTP_WRITE is not set >+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set > # CONFIG_FTPGET is not set > # CONFIG_FTPPUT is not set > # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set > CONFIG_HOSTNAME=y > # CONFIG_HTTPD is not set >+# CONFIG_FEATURE_HTTPD_RANGES is not set > # CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set >-# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set > # CONFIG_FEATURE_HTTPD_SETUID is not set > # CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set > # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set >-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set > # CONFIG_FEATURE_HTTPD_CGI is not set > # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set > # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set > # CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set > # CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set >+# CONFIG_FEATURE_HTTPD_PROXY is not set >+# CONFIG_FEATURE_HTTPD_GZIP is not set > CONFIG_IFCONFIG=y > CONFIG_FEATURE_IFCONFIG_STATUS=y > # CONFIG_FEATURE_IFCONFIG_SLIP is not set >-# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set >+CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y > CONFIG_FEATURE_IFCONFIG_HW=y > # CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set >+# CONFIG_IFENSLAVE is not set >+# CONFIG_IFPLUGD is not set > # CONFIG_IFUPDOWN is not set >-CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" >+CONFIG_IFUPDOWN_IFSTATE_PATH="" > # CONFIG_FEATURE_IFUPDOWN_IP is not set > # CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set > # CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set >@@ -585,6 +778,7 @@ CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/i > # CONFIG_FEATURE_IP_TUNNEL is not set > # CONFIG_FEATURE_IP_RULE is not set > # CONFIG_FEATURE_IP_SHORT_FORMS is not set >+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set > # CONFIG_IPADDR is not set > # CONFIG_IPLINK is not set > # CONFIG_IPROUTE is not set >@@ -594,112 +788,192 @@ CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/i > # CONFIG_FEATURE_IPCALC_FANCY is not set > # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set > # CONFIG_NAMEIF is not set >-# CONFIG_NC is not set >-# CONFIG_NC_SERVER is not set >-# CONFIG_NC_EXTRA is not set >+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set > # CONFIG_NETSTAT is not set > # CONFIG_FEATURE_NETSTAT_WIDE is not set >+# CONFIG_FEATURE_NETSTAT_PRG is not set > # CONFIG_NSLOOKUP is not set >+# CONFIG_NTPD is not set >+# CONFIG_FEATURE_NTPD_SERVER is not set > CONFIG_PING=y > # CONFIG_PING6 is not set >-# CONFIG_PSCAN is not set > CONFIG_FEATURE_FANCY_PING=y >+# CONFIG_PSCAN is not set > CONFIG_ROUTE=y > # CONFIG_SLATTACH is not set >+# CONFIG_TCPSVD is not set > # CONFIG_TELNET is not set > # CONFIG_FEATURE_TELNET_TTYPE is not set > # CONFIG_FEATURE_TELNET_AUTOLOGIN is not set > # CONFIG_TELNETD is not set > # CONFIG_FEATURE_TELNETD_STANDALONE is not set >+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set > # CONFIG_TFTP is not set >+# CONFIG_TFTPD is not set > # CONFIG_FEATURE_TFTP_GET is not set > # CONFIG_FEATURE_TFTP_PUT is not set > # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set >-# CONFIG_DEBUG_TFTP is not set >+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set >+# CONFIG_TFTP_DEBUG is not set > # CONFIG_TRACEROUTE is not set >+# CONFIG_TRACEROUTE6 is not set > # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set > # CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set > # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set >-# CONFIG_APP_UDHCPD is not set >-# CONFIG_APP_DHCPRELAY is not set >-# CONFIG_APP_DUMPLEASES is not set >+# CONFIG_TUNCTL is not set >+# CONFIG_FEATURE_TUNCTL_UG is not set >+# CONFIG_UDHCPD is not set >+# CONFIG_DHCPRELAY is not set >+# CONFIG_DUMPLEASES is not set > # CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set >-CONFIG_APP_UDHCPC=y >-# CONFIG_FEATURE_UDHCP_DEBUG is not set >-# CONFIG_FEATURE_RFC3397 is not set >-# CONFIG_VCONFIG is not set >+CONFIG_DHCPD_LEASES_FILE="" >+CONFIG_UDHCPC=y >+CONFIG_FEATURE_UDHCPC_ARPING=y >+CONFIG_FEATURE_UDHCP_PORT=y >+CONFIG_UDHCP_DEBUG=9 >+# CONFIG_FEATURE_UDHCP_RFC3397 is not set >+CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" >+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 >+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" >+# CONFIG_UDPSVD is not set >+CONFIG_VCONFIG=y > CONFIG_WGET=y > # CONFIG_FEATURE_WGET_STATUSBAR is not set > # CONFIG_FEATURE_WGET_AUTHENTICATION is not set > # CONFIG_FEATURE_WGET_LONG_OPTIONS is not set >+CONFIG_FEATURE_WGET_TIMEOUT=y > # CONFIG_ZCIP is not set > > # >+# Print Utilities >+# >+# CONFIG_LPD is not set >+# CONFIG_LPR is not set >+# CONFIG_LPQ is not set >+ >+# >+# Mail Utilities >+# >+# CONFIG_MAKEMIME is not set >+CONFIG_FEATURE_MIME_CHARSET="" >+# CONFIG_POPMAILDIR is not set >+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set >+# CONFIG_REFORMIME is not set >+# CONFIG_FEATURE_REFORMIME_COMPAT is not set >+# CONFIG_SENDMAIL is not set >+ >+# > # Process Utilities > # >+CONFIG_IOSTAT=y >+CONFIG_MPSTAT=y >+CONFIG_PMAP=y >+CONFIG_POWERTOP=y >+# CONFIG_SMEMCAP is not set > CONFIG_FREE=y > # CONFIG_FUSER is not set > CONFIG_KILL=y > CONFIG_KILLALL=y > # CONFIG_KILLALL5 is not set > # CONFIG_NMETER is not set >+# CONFIG_PGREP is not set > # CONFIG_PIDOF is not set > # CONFIG_FEATURE_PIDOF_SINGLE is not set > # CONFIG_FEATURE_PIDOF_OMIT is not set >+# CONFIG_PKILL is not set > CONFIG_PS=y > # CONFIG_FEATURE_PS_WIDE is not set >+# CONFIG_FEATURE_PS_TIME is not set >+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set >+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set > # CONFIG_RENICE is not set > # CONFIG_BB_SYSCTL is not set > # CONFIG_TOP is not set > # CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set > # CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set >+# CONFIG_FEATURE_TOP_SMP_CPU is not set > # CONFIG_FEATURE_TOP_DECIMALS is not set >-CONFIG_UPTIME=y >+# CONFIG_FEATURE_TOP_SMP_PROCESS is not set >+# CONFIG_FEATURE_TOPMEM is not set >+CONFIG_FEATURE_SHOW_THREADS=y >+# CONFIG_UPTIME is not set > # CONFIG_WATCH is not set > > # >-# Shells >+# Runit Utilities > # >-CONFIG_FEATURE_SH_IS_ASH=y >-# CONFIG_FEATURE_SH_IS_HUSH is not set >-# CONFIG_FEATURE_SH_IS_LASH is not set >-# CONFIG_FEATURE_SH_IS_MSH is not set >-# CONFIG_FEATURE_SH_IS_NONE is not set >-CONFIG_ASH=y >+# CONFIG_RUNSV is not set >+# CONFIG_RUNSVDIR is not set >+# CONFIG_FEATURE_RUNSVDIR_LOG is not set >+# CONFIG_SV is not set >+CONFIG_SV_DEFAULT_SERVICE_DIR="" >+# CONFIG_SVLOGD is not set >+# CONFIG_CHPST is not set >+# CONFIG_SETUIDGID is not set >+# CONFIG_ENVUIDGID is not set >+# CONFIG_ENVDIR is not set >+# CONFIG_SOFTLIMIT is not set >+# CONFIG_CHCON is not set >+# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set >+# CONFIG_GETENFORCE is not set >+# CONFIG_GETSEBOOL is not set >+# CONFIG_LOAD_POLICY is not set >+# CONFIG_MATCHPATHCON is not set >+# CONFIG_RESTORECON is not set >+# CONFIG_RUNCON is not set >+# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set >+# CONFIG_SELINUXENABLED is not set >+# CONFIG_SETENFORCE is not set >+# CONFIG_SETFILES is not set >+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set >+# CONFIG_SETSEBOOL is not set >+# CONFIG_SESTATUS is not set > > # >-# Ash Shell Options >+# Shells > # >+CONFIG_ASH=y >+CONFIG_ASH_BASH_COMPAT=y > CONFIG_ASH_JOB_CONTROL=y >-# CONFIG_ASH_READ_NCHARS is not set >-CONFIG_ASH_READ_TIMEOUT=y > CONFIG_ASH_ALIAS=y >-CONFIG_ASH_MATH_SUPPORT=y >-# CONFIG_ASH_MATH_SUPPORT_64 is not set > # CONFIG_ASH_GETOPTS is not set > # CONFIG_ASH_BUILTIN_ECHO is not set >+# CONFIG_ASH_BUILTIN_PRINTF is not set > CONFIG_ASH_BUILTIN_TEST=y > # CONFIG_ASH_CMDCMD is not set >-CONFIG_ASH_MAIL=y >+# CONFIG_ASH_MAIL is not set > CONFIG_ASH_OPTIMIZE_FOR_SIZE=y > # CONFIG_ASH_RANDOM_SUPPORT is not set > # CONFIG_ASH_EXPAND_PRMT is not set >+# CONFIG_CTTYHACK is not set > # CONFIG_HUSH is not set >+# CONFIG_HUSH_BASH_COMPAT is not set >+# CONFIG_HUSH_BRACE_EXPANSION is not set > # CONFIG_HUSH_HELP is not set > # CONFIG_HUSH_INTERACTIVE is not set >+# CONFIG_HUSH_SAVEHISTORY is not set > # CONFIG_HUSH_JOB is not set > # CONFIG_HUSH_TICK is not set > # CONFIG_HUSH_IF is not set > # CONFIG_HUSH_LOOPS is not set >-# CONFIG_LASH is not set >+# CONFIG_HUSH_CASE is not set >+# CONFIG_HUSH_FUNCTIONS is not set >+# CONFIG_HUSH_LOCAL is not set >+# CONFIG_HUSH_RANDOM_SUPPORT is not set >+# CONFIG_HUSH_EXPORT_N is not set >+# CONFIG_HUSH_MODE_X is not set > # CONFIG_MSH is not set >- >-# >-# Bourne Shell Options >-# >+CONFIG_FEATURE_SH_IS_ASH=y >+# CONFIG_FEATURE_SH_IS_HUSH is not set >+# CONFIG_FEATURE_SH_IS_NONE is not set >+# CONFIG_FEATURE_BASH_IS_ASH is not set >+# CONFIG_FEATURE_BASH_IS_HUSH is not set >+CONFIG_FEATURE_BASH_IS_NONE=y >+CONFIG_SH_MATH_SUPPORT=y >+CONFIG_SH_MATH_SUPPORT_64=y > # CONFIG_FEATURE_SH_EXTRA_QUIET is not set > # CONFIG_FEATURE_SH_STANDALONE is not set >-# CONFIG_CTTYHACK is not set >+CONFIG_FEATURE_SH_NOFORK=y > > # > # System Logging Utilities >@@ -707,41 +981,12 @@ CONFIG_ASH_OPTIMIZE_FOR_SIZE=y > # CONFIG_SYSLOGD is not set > # CONFIG_FEATURE_ROTATE_LOGFILE is not set > # CONFIG_FEATURE_REMOTE_LOG is not set >+# CONFIG_FEATURE_SYSLOGD_DUP is not set >+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 > # CONFIG_FEATURE_IPC_SYSLOG is not set >-CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE= >+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 > # CONFIG_LOGREAD is not set > # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set > # CONFIG_KLOGD is not set >+# CONFIG_FEATURE_KLOGD_KLOGCTL is not set > # CONFIG_LOGGER is not set >- >-# >-# Runit Utilities >-# >-# CONFIG_RUNSV is not set >-# CONFIG_RUNSVDIR is not set >-# CONFIG_SV is not set >-# CONFIG_SVLOGD is not set >-# CONFIG_CHPST is not set >-# CONFIG_SETUIDGID is not set >-# CONFIG_ENVUIDGID is not set >-# CONFIG_ENVDIR is not set >-# CONFIG_SOFTLIMIT is not set >-# CONFIG_CHCON is not set >-# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set >-# CONFIG_GETENFORCE is not set >-# CONFIG_GETSEBOOL is not set >-# CONFIG_LOAD_POLICY is not set >-# CONFIG_MATCHPATHCON is not set >-# CONFIG_RESTORECON is not set >-# CONFIG_RUNCON is not set >-# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set >-# CONFIG_SELINUXENABLED is not set >-# CONFIG_SETENFORCE is not set >-# CONFIG_SETFILES is not set >-# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set >- >-# >-# ipsvd utilities >-# >-# CONFIG_TCPSVD is not set >-# CONFIG_UDPSVD is not set >diff -pruN genkernel.a/netboot/busy-config genkernel.b/netboot/busy-config >--- genkernel.a/netboot/busy-config 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/netboot/busy-config 2011-01-12 21:50:48.000000000 +0200 >@@ -1,7 +1,7 @@ > # > # Automatically generated make config: don't edit >-# Busybox version: 1.7.4 >-# Thu Apr 16 15:04:31 2009 >+# Busybox version: 1.18.1 >+# Wed Jan 12 21:49:31 2011 > # > CONFIG_HAVE_DOT_CONFIG=y > >@@ -12,8 +12,11 @@ CONFIG_HAVE_DOT_CONFIG=y > # > # General Configuration > # >-CONFIG_NITPICK=y > # CONFIG_DESKTOP is not set >+# CONFIG_EXTRA_COMPAT is not set >+# CONFIG_INCLUDE_SUSv2 is not set >+# CONFIG_USE_PORTABLE_CODE is not set >+CONFIG_PLATFORM_LINUX=y > # CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set > CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y > # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set >@@ -21,10 +24,23 @@ CONFIG_SHOW_USAGE=y > CONFIG_FEATURE_VERBOSE_USAGE=y > CONFIG_FEATURE_COMPRESS_USAGE=y > CONFIG_FEATURE_INSTALLER=y >+# CONFIG_INSTALL_NO_USR is not set > # CONFIG_LOCALE_SUPPORT is not set >-CONFIG_GETOPT_LONG=y >+CONFIG_UNICODE_SUPPORT=y >+# CONFIG_UNICODE_USING_LOCALE is not set >+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set >+CONFIG_SUBST_WCHAR=63 >+CONFIG_LAST_SUPPORTED_WCHAR=767 >+# CONFIG_UNICODE_COMBINING_WCHARS is not set >+# CONFIG_UNICODE_WIDE_WCHARS is not set >+# CONFIG_UNICODE_BIDI_SUPPORT is not set >+# CONFIG_UNICODE_NEUTRAL_TABLE is not set >+# CONFIG_UNICODE_PRESERVE_BROKEN is not set >+CONFIG_LONG_OPTS=y > CONFIG_FEATURE_DEVPTS=y > # CONFIG_FEATURE_CLEAN_UP is not set >+# CONFIG_FEATURE_WTMP is not set >+# CONFIG_FEATURE_UTMP is not set > # CONFIG_FEATURE_PIDFILE is not set > CONFIG_FEATURE_SUID=y > # CONFIG_FEATURE_SUID_CONFIG is not set >@@ -39,29 +55,35 @@ CONFIG_FEATURE_HAVE_RPC=y > # Build Options > # > CONFIG_STATIC=y >+# CONFIG_PIE is not set >+# CONFIG_NOMMU is not set > # CONFIG_BUILD_LIBBUSYBOX is not set >-# CONFIG_FEATURE_FULL_LIBBUSYBOX is not set >+# CONFIG_FEATURE_INDIVIDUAL is not set > # CONFIG_FEATURE_SHARED_BUSYBOX is not set > CONFIG_LFS=y >-# CONFIG_BUILD_AT_ONCE is not set >+CONFIG_CROSS_COMPILER_PREFIX="" >+CONFIG_EXTRA_CFLAGS="" > > # > # Debugging Options > # > # CONFIG_DEBUG is not set >+# CONFIG_DEBUG_PESSIMIZE is not set > # CONFIG_WERROR is not set > CONFIG_NO_DEBUG_LIB=y > # CONFIG_DMALLOC is not set > # CONFIG_EFENCE is not set >-# CONFIG_INCLUDE_SUSv2 is not set > > # >-# Installation Options >+# Installation Options ("make install" behavior) > # >-# CONFIG_INSTALL_NO_USR is not set > CONFIG_INSTALL_APPLET_SYMLINKS=y > # CONFIG_INSTALL_APPLET_HARDLINKS is not set >+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set > # CONFIG_INSTALL_APPLET_DONT is not set >+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set >+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set >+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set > CONFIG_PREFIX="./_install" > > # >@@ -69,19 +91,24 @@ CONFIG_PREFIX="./_install" > # > CONFIG_PASSWORD_MINLEN=6 > CONFIG_MD5_SIZE_VS_SPEED=2 >-# CONFIG_FEATURE_FAST_TOP is not set >+CONFIG_FEATURE_FAST_TOP=y > # CONFIG_FEATURE_ETC_NETWORKS is not set >+CONFIG_FEATURE_USE_TERMIOS=y > CONFIG_FEATURE_EDITING=y > CONFIG_FEATURE_EDITING_MAX_LEN=1024 >-# CONFIG_FEATURE_EDITING_FANCY_KEYS is not set > # CONFIG_FEATURE_EDITING_VI is not set > CONFIG_FEATURE_EDITING_HISTORY=15 >-# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set >+CONFIG_FEATURE_EDITING_SAVEHISTORY=y > CONFIG_FEATURE_TAB_COMPLETION=y > # CONFIG_FEATURE_USERNAME_COMPLETION is not set > CONFIG_FEATURE_EDITING_FANCY_PROMPT=y >+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set >+CONFIG_FEATURE_NON_POSIX_CP=y >+CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y >+CONFIG_FEATURE_COPYBUF_KB=4 > CONFIG_MONOTONIC_SYSCALL=y > CONFIG_IOCTL_HEX2STR_ERROR=y >+CONFIG_FEATURE_HWIB=y > > # > # Applets >@@ -90,68 +117,82 @@ CONFIG_IOCTL_HEX2STR_ERROR=y > # > # Archival Utilities > # >+CONFIG_FEATURE_SEAMLESS_XZ=y >+CONFIG_FEATURE_SEAMLESS_LZMA=y >+CONFIG_FEATURE_SEAMLESS_BZ2=y >+CONFIG_FEATURE_SEAMLESS_GZ=y >+CONFIG_FEATURE_SEAMLESS_Z=y > CONFIG_AR=y > CONFIG_FEATURE_AR_LONG_FILENAMES=y >+CONFIG_FEATURE_AR_CREATE=y > CONFIG_BUNZIP2=y >+CONFIG_BZIP2=y > CONFIG_CPIO=y >+CONFIG_FEATURE_CPIO_O=y >+CONFIG_FEATURE_CPIO_P=y > CONFIG_DPKG=y > # CONFIG_DPKG_DEB is not set > # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set > CONFIG_GUNZIP=y >-CONFIG_FEATURE_GUNZIP_UNCOMPRESS=y > CONFIG_GZIP=y >-CONFIG_RPM2CPIO=y >-CONFIG_RPM=y >-# CONFIG_FEATURE_RPM_BZ2 is not set >+CONFIG_FEATURE_GZIP_LONG_OPTIONS=y >+CONFIG_LZOP=y >+CONFIG_LZOP_COMPR_HIGH=y >+# CONFIG_RPM2CPIO is not set >+# CONFIG_RPM is not set > CONFIG_TAR=y > CONFIG_FEATURE_TAR_CREATE=y >-CONFIG_FEATURE_TAR_BZIP2=y >-CONFIG_FEATURE_TAR_LZMA=y >+CONFIG_FEATURE_TAR_AUTODETECT=y > CONFIG_FEATURE_TAR_FROM=y >-CONFIG_FEATURE_TAR_GZIP=y >-CONFIG_FEATURE_TAR_COMPRESS=y > CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y >-# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set >+CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y > CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y > CONFIG_FEATURE_TAR_LONG_OPTIONS=y >+CONFIG_FEATURE_TAR_TO_COMMAND=y >+CONFIG_FEATURE_TAR_UNAME_GNAME=y >+CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y >+# CONFIG_FEATURE_TAR_SELINUX is not set > CONFIG_UNCOMPRESS=y > CONFIG_UNLZMA=y > CONFIG_FEATURE_LZMA_FAST=y >+CONFIG_LZMA=y >+CONFIG_UNXZ=y >+CONFIG_XZ=y > CONFIG_UNZIP=y > > # >-# Common options for cpio and tar >-# >-CONFIG_FEATURE_UNARCHIVE_TAPE=y >- >-# >-# Common options for dpkg and dpkg_deb >-# >-CONFIG_FEATURE_DEB_TAR_GZ=y >-# CONFIG_FEATURE_DEB_TAR_BZ2 is not set >-# CONFIG_FEATURE_DEB_TAR_LZMA is not set >- >-# > # Coreutils > # > CONFIG_BASENAME=y >-# CONFIG_CAL is not set > CONFIG_CAT=y >-# CONFIG_CATV is not set >+CONFIG_DATE=y >+CONFIG_FEATURE_DATE_ISOFMT=y >+CONFIG_FEATURE_DATE_NANO=y >+CONFIG_FEATURE_DATE_COMPAT=y >+CONFIG_TEST=y >+# CONFIG_FEATURE_TEST_64 is not set >+CONFIG_TR=y >+CONFIG_FEATURE_TR_CLASSES=y >+CONFIG_FEATURE_TR_EQUIV=y >+CONFIG_BASE64=y >+CONFIG_CAL=y >+CONFIG_CATV=y > CONFIG_CHGRP=y > CONFIG_CHMOD=y > CONFIG_CHOWN=y >+CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y > CONFIG_CHROOT=y >-# CONFIG_CKSUM is not set >-# CONFIG_COMM is not set >+CONFIG_CKSUM=y >+CONFIG_COMM=y > CONFIG_CP=y >+CONFIG_FEATURE_CP_LONG_OPTIONS=y > CONFIG_CUT=y >-CONFIG_DATE=y >-CONFIG_FEATURE_DATE_ISOFMT=y > CONFIG_DD=y > CONFIG_FEATURE_DD_SIGNAL_HANDLING=y >-# CONFIG_FEATURE_DD_IBS_OBS is not set >+CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y >+CONFIG_FEATURE_DD_IBS_OBS=y > CONFIG_DF=y >+CONFIG_FEATURE_DF_FANCY=y > CONFIG_DIRNAME=y > CONFIG_DOS2UNIX=y > CONFIG_UNIX2DOS=y >@@ -160,22 +201,23 @@ CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y > CONFIG_ECHO=y > CONFIG_FEATURE_FANCY_ECHO=y > CONFIG_ENV=y >-# CONFIG_FEATURE_ENV_LONG_OPTIONS is not set >-# CONFIG_EXPAND is not set >-# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set >+CONFIG_FEATURE_ENV_LONG_OPTIONS=y >+CONFIG_EXPAND=y >+CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y > CONFIG_EXPR=y > # CONFIG_EXPR_MATH_SUPPORT_64 is not set > CONFIG_FALSE=y >-# CONFIG_FOLD is not set >+CONFIG_FOLD=y >+CONFIG_FSYNC=y > CONFIG_HEAD=y > CONFIG_FEATURE_FANCY_HEAD=y >-# CONFIG_HOSTID is not set >+CONFIG_HOSTID=y > CONFIG_ID=y > CONFIG_INSTALL=y >-# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set >+CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y > CONFIG_LENGTH=y > CONFIG_LN=y >-# CONFIG_LOGNAME is not set >+CONFIG_LOGNAME=y > CONFIG_LS=y > CONFIG_FEATURE_LS_FILETYPES=y > CONFIG_FEATURE_LS_FOLLOWLINKS=y >@@ -187,54 +229,54 @@ CONFIG_FEATURE_LS_COLOR=y > # CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set > CONFIG_MD5SUM=y > CONFIG_MKDIR=y >-# CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set >+CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y > CONFIG_MKFIFO=y > CONFIG_MKNOD=y > CONFIG_MV=y >-# CONFIG_FEATURE_MV_LONG_OPTIONS is not set >+CONFIG_FEATURE_MV_LONG_OPTIONS=y > CONFIG_NICE=y > # CONFIG_NOHUP is not set >-# CONFIG_OD is not set >+CONFIG_OD=y > CONFIG_PRINTENV=y >-# CONFIG_PRINTF is not set >+CONFIG_PRINTF=y > CONFIG_PWD=y > CONFIG_READLINK=y >-# CONFIG_FEATURE_READLINK_FOLLOW is not set >-# CONFIG_REALPATH is not set >+CONFIG_FEATURE_READLINK_FOLLOW=y >+CONFIG_REALPATH=y > CONFIG_RM=y > CONFIG_RMDIR=y >+CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y > CONFIG_SEQ=y > CONFIG_SHA1SUM=y >+CONFIG_SHA256SUM=y >+CONFIG_SHA512SUM=y > CONFIG_SLEEP=y > # CONFIG_FEATURE_FANCY_SLEEP is not set >+# CONFIG_FEATURE_FLOAT_SLEEP is not set > CONFIG_SORT=y > CONFIG_FEATURE_SORT_BIG=y >-# CONFIG_SPLIT is not set >-# CONFIG_FEATURE_SPLIT_FANCY is not set >+CONFIG_SPLIT=y >+CONFIG_FEATURE_SPLIT_FANCY=y > CONFIG_STAT=y >-# CONFIG_FEATURE_STAT_FORMAT is not set >+CONFIG_FEATURE_STAT_FORMAT=y > CONFIG_STTY=y >-# CONFIG_SUM is not set >+CONFIG_SUM=y > CONFIG_SYNC=y >+CONFIG_TAC=y > CONFIG_TAIL=y > CONFIG_FEATURE_FANCY_TAIL=y > CONFIG_TEE=y > CONFIG_FEATURE_TEE_USE_BLOCK_IO=y >-CONFIG_TEST=y >-# CONFIG_FEATURE_TEST_64 is not set > CONFIG_TOUCH=y >-CONFIG_TR=y >-CONFIG_FEATURE_TR_CLASSES=y >-CONFIG_FEATURE_TR_EQUIV=y > CONFIG_TRUE=y > CONFIG_TTY=y > CONFIG_UNAME=y >-# CONFIG_UNEXPAND is not set >-# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set >+CONFIG_UNEXPAND=y >+CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y > CONFIG_UNIQ=y > CONFIG_USLEEP=y >-# CONFIG_UUDECODE is not set >-# CONFIG_UUENCODE is not set >+CONFIG_UUDECODE=y >+CONFIG_UUENCODE=y > CONFIG_WC=y > # CONFIG_FEATURE_WC_LARGE is not set > # CONFIG_WHO is not set >@@ -257,7 +299,7 @@ CONFIG_FEATURE_AUTOWIDTH=y > CONFIG_FEATURE_HUMAN_READABLE=y > > # >-# Common options for md5sum, sha1sum >+# Common options for md5sum, sha1sum, sha256sum, sha512sum > # > CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y > >@@ -265,19 +307,31 @@ CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y > # Console Utilities > # > CONFIG_CHVT=y >+CONFIG_FGCONSOLE=y > CONFIG_CLEAR=y > CONFIG_DEALLOCVT=y > CONFIG_DUMPKMAP=y >+CONFIG_KBD_MODE=y > CONFIG_LOADFONT=y > CONFIG_LOADKMAP=y > CONFIG_OPENVT=y > CONFIG_RESET=y >-# CONFIG_RESIZE is not set >-# CONFIG_FEATURE_RESIZE_PRINT is not set >+CONFIG_RESIZE=y >+CONFIG_FEATURE_RESIZE_PRINT=y > CONFIG_SETCONSOLE=y > # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set >+CONFIG_SETFONT=y >+CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y >+CONFIG_DEFAULT_SETFONT_DIR="" > CONFIG_SETKEYCODES=y >-# CONFIG_SETLOGCONS is not set >+CONFIG_SETLOGCONS=y >+CONFIG_SHOWKEY=y >+ >+# >+# Common options for loadfont and setfont >+# >+CONFIG_FEATURE_LOADFONT_PSF2=y >+CONFIG_FEATURE_LOADFONT_RAW=y > > # > # Debian Utilities >@@ -295,18 +349,18 @@ CONFIG_WHICH=y > # > # Editors > # >+CONFIG_PATCH=y > # CONFIG_AWK is not set >-# CONFIG_FEATURE_AWK_MATH is not set >+# CONFIG_FEATURE_AWK_LIBM is not set > CONFIG_CMP=y > CONFIG_DIFF=y >-CONFIG_FEATURE_DIFF_BINARY=y >+CONFIG_FEATURE_DIFF_LONG_OPTIONS=y > CONFIG_FEATURE_DIFF_DIR=y >-# CONFIG_FEATURE_DIFF_MINIMAL is not set >-# CONFIG_ED is not set >-# CONFIG_PATCH is not set >+CONFIG_ED=y > CONFIG_SED=y > CONFIG_VI=y > CONFIG_FEATURE_VI_MAX_LEN=1024 >+# CONFIG_FEATURE_VI_8BIT is not set > CONFIG_FEATURE_VI_COLON=y > CONFIG_FEATURE_VI_YANKMARK=y > CONFIG_FEATURE_VI_SEARCH=y >@@ -316,6 +370,7 @@ CONFIG_FEATURE_VI_READONLY=y > CONFIG_FEATURE_VI_SETOPTS=y > CONFIG_FEATURE_VI_SET=y > CONFIG_FEATURE_VI_WIN_RESIZE=y >+CONFIG_FEATURE_VI_ASK_TERMINAL=y > CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y > CONFIG_FEATURE_ALLOW_EXEC=y > >@@ -340,10 +395,11 @@ CONFIG_FEATURE_FIND_DEPTH=y > CONFIG_FEATURE_FIND_PAREN=y > CONFIG_FEATURE_FIND_SIZE=y > CONFIG_FEATURE_FIND_PRUNE=y >-# CONFIG_FEATURE_FIND_DELETE is not set >+CONFIG_FEATURE_FIND_DELETE=y > CONFIG_FEATURE_FIND_PATH=y > CONFIG_FEATURE_FIND_REGEX=y > # CONFIG_FEATURE_FIND_CONTEXT is not set >+CONFIG_FEATURE_FIND_LINKS=y > CONFIG_GREP=y > CONFIG_FEATURE_GREP_EGREP_ALIAS=y > CONFIG_FEATURE_GREP_FGREP_ALIAS=y >@@ -357,32 +413,46 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y > # > # Init Utilities > # >+# CONFIG_BOOTCHARTD is not set >+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set >+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set >+CONFIG_HALT=y >+# CONFIG_FEATURE_CALL_TELINIT is not set >+CONFIG_TELINIT_PATH="" > CONFIG_INIT=y >-# CONFIG_DEBUG_INIT is not set > CONFIG_FEATURE_USE_INITTAB=y >+# CONFIG_FEATURE_KILL_REMOVED is not set >+CONFIG_FEATURE_KILL_DELAY=0 > # CONFIG_FEATURE_INIT_SCTTY is not set > # CONFIG_FEATURE_INIT_SYSLOG is not set > CONFIG_FEATURE_EXTRA_QUIET=y > # CONFIG_FEATURE_INIT_COREDUMPS is not set > CONFIG_FEATURE_INITRD=y >-CONFIG_HALT=y >+CONFIG_INIT_TERMINAL_TYPE="linux" > CONFIG_MESG=y > > # > # Login/Password Management Utilities > # >+# CONFIG_ADD_SHELL is not set >+# CONFIG_REMOVE_SHELL is not set > CONFIG_FEATURE_SHADOWPASSWDS=y >-# CONFIG_USE_BB_SHADOW is not set > # CONFIG_USE_BB_PWD_GRP is not set >+# CONFIG_USE_BB_SHADOW is not set >+# CONFIG_USE_BB_CRYPT is not set >+# CONFIG_USE_BB_CRYPT_SHA is not set >+# CONFIG_ADDUSER is not set >+# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set >+# CONFIG_FEATURE_CHECK_NAMES is not set >+CONFIG_FIRST_SYSTEM_ID=0 >+CONFIG_LAST_SYSTEM_ID=0 > # CONFIG_ADDGROUP is not set >+# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set > # CONFIG_FEATURE_ADDUSER_TO_GROUP is not set >+# CONFIG_DELUSER is not set > # CONFIG_DELGROUP is not set > # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set >-# CONFIG_ADDUSER is not set >-# CONFIG_DELUSER is not set > CONFIG_GETTY=y >-# CONFIG_FEATURE_UTMP is not set >-# CONFIG_FEATURE_WTMP is not set > CONFIG_LOGIN=y > # CONFIG_PAM is not set > # CONFIG_LOGIN_SCRIPTS is not set >@@ -401,9 +471,10 @@ CONFIG_CHPASSWD=y > # > # Linux Ext2 FS Progs > # >-# CONFIG_CHATTR is not set >-# CONFIG_FSCK is not set >-# CONFIG_LSATTR is not set >+CONFIG_CHATTR=y >+CONFIG_FSCK=y >+CONFIG_LSATTR=y >+CONFIG_TUNE2FS=y > > # > # Linux mdadm Utilities >@@ -413,37 +484,49 @@ CONFIG_MDADM=y > # > # Linux Module Utilities > # >+CONFIG_MODINFO=y >+# CONFIG_MODPROBE_SMALL is not set >+# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set >+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set > CONFIG_INSMOD=y >-# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set >-# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set >-# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set >-# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set >-# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set > CONFIG_RMMOD=y > CONFIG_LSMOD=y > CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y > CONFIG_MODPROBE=y >-CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS=y >-CONFIG_FEATURE_MODPROBE_FANCY_ALIAS=y >+CONFIG_FEATURE_MODPROBE_BLACKLIST=y >+CONFIG_DEPMOD=y > > # > # Options common to multiple modutils > # >-CONFIG_FEATURE_CHECK_TAINTED_MODULE=y >-CONFIG_FEATURE_2_4_MODULES=y >-CONFIG_FEATURE_2_6_MODULES=y >-# CONFIG_FEATURE_QUERY_MODULE_INTERFACE is not set >+# CONFIG_FEATURE_2_4_MODULES is not set >+CONFIG_FEATURE_INSMOD_TRY_MMAP=y >+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set >+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set >+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set >+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set >+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set >+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set >+CONFIG_FEATURE_MODUTILS_ALIAS=y >+CONFIG_FEATURE_MODUTILS_SYMBOLS=y >+CONFIG_DEFAULT_MODULES_DIR="/lib/modules" >+CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" > > # > # Linux System Utilities > # >+CONFIG_BLOCKDEV=y >+CONFIG_REV=y >+CONFIG_ACPID=y >+CONFIG_FEATURE_ACPID_COMPAT=y >+CONFIG_BLKID=y > CONFIG_DMESG=y > CONFIG_FEATURE_DMESG_PRETTY=y >-# CONFIG_FBSET is not set >+CONFIG_FBSET=y > # CONFIG_FEATURE_FBSET_FANCY is not set >-# CONFIG_FEATURE_FBSET_READMODE is not set >+CONFIG_FEATURE_FBSET_READMODE=y > # CONFIG_FDFLUSH is not set >-# CONFIG_FDFORMAT is not set >+CONFIG_FDFORMAT=y > CONFIG_FDISK=y > CONFIG_FDISK_SUPPORT_LARGE_DISKS=y > CONFIG_FEATURE_FDISK_WRITABLE=y >@@ -451,38 +534,59 @@ CONFIG_FEATURE_AIX_LABEL=y > CONFIG_FEATURE_SGI_LABEL=y > CONFIG_FEATURE_SUN_LABEL=y > CONFIG_FEATURE_OSF_LABEL=y >+# CONFIG_FEATURE_GPT_LABEL is not set > CONFIG_FEATURE_FDISK_ADVANCED=y >+CONFIG_FINDFS=y >+CONFIG_FLOCK=y > CONFIG_FREERAMDISK=y > # CONFIG_FSCK_MINIX is not set >+CONFIG_MKFS_EXT2=y > # CONFIG_MKFS_MINIX is not set > # CONFIG_FEATURE_MINIX2 is not set >-# CONFIG_GETOPT is not set >+CONFIG_MKFS_REISER=y >+CONFIG_MKFS_VFAT=y >+CONFIG_GETOPT=y >+# CONFIG_FEATURE_GETOPT_LONG is not set > CONFIG_HEXDUMP=y >+CONFIG_FEATURE_HEXDUMP_REVERSE=y >+CONFIG_HD=y > # CONFIG_HWCLOCK is not set > # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set > # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set > # CONFIG_IPCRM is not set > # CONFIG_IPCS is not set > CONFIG_LOSETUP=y >+CONFIG_LSPCI=y >+CONFIG_LSUSB=y > CONFIG_MDEV=y > CONFIG_FEATURE_MDEV_CONF=y >+CONFIG_FEATURE_MDEV_RENAME=y >+CONFIG_FEATURE_MDEV_RENAME_REGEXP=y > CONFIG_FEATURE_MDEV_EXEC=y > CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y > CONFIG_MDSTART=y > CONFIG_MKSWAP=y >-# CONFIG_FEATURE_MKSWAP_V0 is not set >+CONFIG_FEATURE_MKSWAP_UUID=y > CONFIG_MORE=y >-CONFIG_FEATURE_USE_TERMIOS=y > CONFIG_MOUNT=y >+CONFIG_FEATURE_MOUNT_FAKE=y >+CONFIG_FEATURE_MOUNT_VERBOSE=y >+# CONFIG_FEATURE_MOUNT_HELPERS is not set >+CONFIG_FEATURE_MOUNT_LABEL=y > CONFIG_FEATURE_MOUNT_NFS=y > CONFIG_FEATURE_MOUNT_CIFS=y > CONFIG_FEATURE_MOUNT_FLAGS=y > CONFIG_FEATURE_MOUNT_FSTAB=y > CONFIG_PIVOT_ROOT=y > CONFIG_RDATE=y >+CONFIG_RDEV=y > # CONFIG_READPROFILE is not set >+CONFIG_RTCWAKE=y >+CONFIG_SCRIPT=y >+CONFIG_SCRIPTREPLAY=y > # CONFIG_SETARCH is not set > CONFIG_SWAPONOFF=y >+CONFIG_FEATURE_SWAPON_PRI=y > CONFIG_SWITCH_ROOT=y > CONFIG_UMOUNT=y > CONFIG_FEATURE_UMOUNT_ALL=y >@@ -491,33 +595,88 @@ CONFIG_FEATURE_UMOUNT_ALL=y > # Common options for mount/umount > # > CONFIG_FEATURE_MOUNT_LOOP=y >+CONFIG_FEATURE_MOUNT_LOOP_CREATE=y > CONFIG_FEATURE_MTAB_SUPPORT=y >+CONFIG_VOLUMEID=y >+ >+# >+# Filesystem/Volume identification >+# >+CONFIG_FEATURE_VOLUMEID_EXT=y >+CONFIG_FEATURE_VOLUMEID_BTRFS=y >+CONFIG_FEATURE_VOLUMEID_REISERFS=y >+CONFIG_FEATURE_VOLUMEID_FAT=y >+CONFIG_FEATURE_VOLUMEID_HFS=y >+CONFIG_FEATURE_VOLUMEID_JFS=y >+CONFIG_FEATURE_VOLUMEID_XFS=y >+CONFIG_FEATURE_VOLUMEID_NTFS=y >+CONFIG_FEATURE_VOLUMEID_ISO9660=y >+CONFIG_FEATURE_VOLUMEID_UDF=y >+CONFIG_FEATURE_VOLUMEID_LUKS=y >+CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y >+CONFIG_FEATURE_VOLUMEID_CRAMFS=y >+CONFIG_FEATURE_VOLUMEID_ROMFS=y >+CONFIG_FEATURE_VOLUMEID_SYSV=y >+CONFIG_FEATURE_VOLUMEID_OCFS2=y >+CONFIG_FEATURE_VOLUMEID_LINUXRAID=y > > # > # Miscellaneous Utilities > # >+# CONFIG_CONSPY is not set >+# CONFIG_NANDWRITE is not set >+# CONFIG_NANDDUMP is not set >+# CONFIG_UBIATTACH is not set >+# CONFIG_UBIDETACH is not set > # CONFIG_ADJTIMEX is not set > CONFIG_BBCONFIG=y >+CONFIG_FEATURE_COMPRESS_BBCONFIG=y >+# CONFIG_BEEP is not set >+CONFIG_FEATURE_BEEP_FREQ=0 >+CONFIG_FEATURE_BEEP_LENGTH_MS=0 >+CONFIG_CHAT=y >+CONFIG_FEATURE_CHAT_NOFAIL=y >+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set >+CONFIG_FEATURE_CHAT_IMPLICIT_CR=y >+CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y >+CONFIG_FEATURE_CHAT_SEND_ESCAPES=y >+CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y >+CONFIG_FEATURE_CHAT_CLR_ABORT=y > # CONFIG_CHRT is not set > # CONFIG_CROND is not set >-# CONFIG_DEBUG_CROND_OPTION is not set >+# CONFIG_FEATURE_CROND_D is not set > # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set >+CONFIG_FEATURE_CROND_DIR="" > # CONFIG_CRONTAB is not set > CONFIG_DC=y >+CONFIG_FEATURE_DC_LIBM=y > # CONFIG_DEVFSD is not set > # CONFIG_DEVFSD_MODLOAD is not set > # CONFIG_DEVFSD_FG_NP is not set > # CONFIG_DEVFSD_VERBOSE is not set > # CONFIG_FEATURE_DEVFS is not set >+# CONFIG_DEVMEM is not set > # CONFIG_EJECT is not set >+# CONFIG_FEATURE_EJECT_SCSI is not set >+# CONFIG_FBSPLASH is not set >+# CONFIG_FLASHCP is not set >+# CONFIG_FLASH_LOCK is not set >+# CONFIG_FLASH_UNLOCK is not set >+# CONFIG_FLASH_ERASEALL is not set >+CONFIG_IONICE=y >+# CONFIG_INOTIFYD is not set > # CONFIG_LAST is not set >+# CONFIG_FEATURE_LAST_SMALL is not set >+# CONFIG_FEATURE_LAST_FANCY is not set > # CONFIG_LESS is not set >-CONFIG_FEATURE_LESS_MAXLINES= >+CONFIG_FEATURE_LESS_MAXLINES=0 > # CONFIG_FEATURE_LESS_BRACKETS is not set > # CONFIG_FEATURE_LESS_FLAGS is not set >-# CONFIG_FEATURE_LESS_FLAGCS is not set > # CONFIG_FEATURE_LESS_MARKS is not set > # CONFIG_FEATURE_LESS_REGEXP is not set >+# CONFIG_FEATURE_LESS_WINCH is not set >+# CONFIG_FEATURE_LESS_DASHCMD is not set >+# CONFIG_FEATURE_LESS_LINENUMS is not set > # CONFIG_HDPARM is not set > # CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set > # CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set >@@ -528,54 +687,76 @@ CONFIG_FEATURE_LESS_MAXLINES= > CONFIG_MAKEDEVS=y > CONFIG_FEATURE_MAKEDEVS_LEAF=y > # CONFIG_FEATURE_MAKEDEVS_TABLE is not set >+CONFIG_MAN=y >+CONFIG_MICROCOM=y > CONFIG_MOUNTPOINT=y > CONFIG_MT=y >-# CONFIG_RAIDAUTORUN is not set >-# CONFIG_READAHEAD is not set >+CONFIG_RAIDAUTORUN=y >+CONFIG_READAHEAD=y >+# CONFIG_RFKILL is not set > # CONFIG_RUNLEVEL is not set > # CONFIG_RX is not set >-CONFIG_STRINGS=y > # CONFIG_SETSID is not set >+CONFIG_STRINGS=y > # CONFIG_TASKSET is not set > # CONFIG_FEATURE_TASKSET_FANCY is not set > CONFIG_TIME=y >+CONFIG_TIMEOUT=y > # CONFIG_TTYSIZE is not set >+CONFIG_VOLNAME=y >+CONFIG_WALL=y > # CONFIG_WATCHDOG is not set > > # > # Networking Utilities > # >-# CONFIG_FEATURE_IPV6 is not set >+CONFIG_NBDCLIENT=y >+CONFIG_NC=y >+CONFIG_NC_SERVER=y >+# CONFIG_NC_EXTRA is not set >+# CONFIG_NC_110_COMPAT is not set >+CONFIG_FEATURE_IPV6=y >+# CONFIG_FEATURE_UNIX_LOCAL is not set >+CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y > CONFIG_VERBOSE_RESOLUTION_ERRORS=y >-# CONFIG_ARP is not set >-# CONFIG_ARPING is not set >+CONFIG_ARP=y >+CONFIG_ARPING=y >+CONFIG_BRCTL=y >+CONFIG_FEATURE_BRCTL_FANCY=y >+CONFIG_FEATURE_BRCTL_SHOW=y > # CONFIG_DNSD is not set > # CONFIG_ETHER_WAKE is not set > # CONFIG_FAKEIDENTD is not set >+# CONFIG_FTPD is not set >+# CONFIG_FEATURE_FTP_WRITE is not set >+# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set > CONFIG_FTPGET=y > CONFIG_FTPPUT=y > # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set > CONFIG_HOSTNAME=y > # CONFIG_HTTPD is not set >+# CONFIG_FEATURE_HTTPD_RANGES is not set > # CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set >-# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set > # CONFIG_FEATURE_HTTPD_SETUID is not set > # CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set > # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set >-# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set > # CONFIG_FEATURE_HTTPD_CGI is not set > # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set > # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set > # CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set > # CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set >+# CONFIG_FEATURE_HTTPD_PROXY is not set >+# CONFIG_FEATURE_HTTPD_GZIP is not set > CONFIG_IFCONFIG=y > CONFIG_FEATURE_IFCONFIG_STATUS=y > # CONFIG_FEATURE_IFCONFIG_SLIP is not set > CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y > CONFIG_FEATURE_IFCONFIG_HW=y > CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y >+CONFIG_IFENSLAVE=y >+CONFIG_IFPLUGD=y > # CONFIG_IFUPDOWN is not set >-CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" >+CONFIG_IFUPDOWN_IFSTATE_PATH="" > # CONFIG_FEATURE_IFUPDOWN_IP is not set > # CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set > # CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set >@@ -597,6 +778,7 @@ CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/i > # CONFIG_FEATURE_IP_TUNNEL is not set > # CONFIG_FEATURE_IP_RULE is not set > # CONFIG_FEATURE_IP_SHORT_FORMS is not set >+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set > # CONFIG_IPADDR is not set > # CONFIG_IPLINK is not set > # CONFIG_IPROUTE is not set >@@ -606,154 +788,205 @@ CONFIG_IPCALC=y > CONFIG_FEATURE_IPCALC_FANCY=y > # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set > # CONFIG_NAMEIF is not set >-CONFIG_NC=y >-CONFIG_NC_SERVER=y >-# CONFIG_NC_EXTRA is not set >+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set > CONFIG_NETSTAT=y > # CONFIG_FEATURE_NETSTAT_WIDE is not set >+CONFIG_FEATURE_NETSTAT_PRG=y > CONFIG_NSLOOKUP=y >+CONFIG_NTPD=y >+CONFIG_FEATURE_NTPD_SERVER=y > CONFIG_PING=y >-# CONFIG_PING6 is not set >-# CONFIG_PSCAN is not set >+CONFIG_PING6=y > CONFIG_FEATURE_FANCY_PING=y >+# CONFIG_PSCAN is not set > CONFIG_ROUTE=y > # CONFIG_SLATTACH is not set >-# CONFIG_TELNET is not set >-# CONFIG_FEATURE_TELNET_TTYPE is not set >-# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set >-# CONFIG_TELNETD is not set >-# CONFIG_FEATURE_TELNETD_STANDALONE is not set >+# CONFIG_TCPSVD is not set >+CONFIG_TELNET=y >+CONFIG_FEATURE_TELNET_TTYPE=y >+CONFIG_FEATURE_TELNET_AUTOLOGIN=y >+CONFIG_TELNETD=y >+CONFIG_FEATURE_TELNETD_STANDALONE=y >+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set > # CONFIG_TFTP is not set >+# CONFIG_TFTPD is not set > # CONFIG_FEATURE_TFTP_GET is not set > # CONFIG_FEATURE_TFTP_PUT is not set > # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set >-# CONFIG_DEBUG_TFTP is not set >+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set >+# CONFIG_TFTP_DEBUG is not set > CONFIG_TRACEROUTE=y >+CONFIG_TRACEROUTE6=y > CONFIG_FEATURE_TRACEROUTE_VERBOSE=y > CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y > CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y >-# CONFIG_APP_UDHCPD is not set >-# CONFIG_APP_DHCPRELAY is not set >-# CONFIG_APP_DUMPLEASES is not set >+CONFIG_TUNCTL=y >+CONFIG_FEATURE_TUNCTL_UG=y >+# CONFIG_UDHCPD is not set >+# CONFIG_DHCPRELAY is not set >+# CONFIG_DUMPLEASES is not set > # CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set >-CONFIG_APP_UDHCPC=y >-# CONFIG_FEATURE_UDHCP_DEBUG is not set >-# CONFIG_FEATURE_RFC3397 is not set >+CONFIG_DHCPD_LEASES_FILE="" >+CONFIG_UDHCPC=y >+CONFIG_FEATURE_UDHCPC_ARPING=y >+CONFIG_FEATURE_UDHCP_PORT=y >+CONFIG_UDHCP_DEBUG=9 >+CONFIG_FEATURE_UDHCP_RFC3397=y >+CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" >+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 >+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" >+# CONFIG_UDPSVD is not set > CONFIG_VCONFIG=y > CONFIG_WGET=y > CONFIG_FEATURE_WGET_STATUSBAR=y > CONFIG_FEATURE_WGET_AUTHENTICATION=y >-# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set >+CONFIG_FEATURE_WGET_LONG_OPTIONS=y >+CONFIG_FEATURE_WGET_TIMEOUT=y > # CONFIG_ZCIP is not set > > # >+# Print Utilities >+# >+# CONFIG_LPD is not set >+# CONFIG_LPR is not set >+# CONFIG_LPQ is not set >+ >+# >+# Mail Utilities >+# >+# CONFIG_MAKEMIME is not set >+CONFIG_FEATURE_MIME_CHARSET="" >+# CONFIG_POPMAILDIR is not set >+# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set >+# CONFIG_REFORMIME is not set >+# CONFIG_FEATURE_REFORMIME_COMPAT is not set >+# CONFIG_SENDMAIL is not set >+ >+# > # Process Utilities > # >+CONFIG_IOSTAT=y >+CONFIG_MPSTAT=y >+CONFIG_PMAP=y >+CONFIG_POWERTOP=y >+CONFIG_SMEMCAP=y > CONFIG_FREE=y > # CONFIG_FUSER is not set > CONFIG_KILL=y > CONFIG_KILLALL=y > # CONFIG_KILLALL5 is not set > # CONFIG_NMETER is not set >+CONFIG_PGREP=y > CONFIG_PIDOF=y > CONFIG_FEATURE_PIDOF_SINGLE=y > CONFIG_FEATURE_PIDOF_OMIT=y >+CONFIG_PKILL=y > CONFIG_PS=y > CONFIG_FEATURE_PS_WIDE=y >+# CONFIG_FEATURE_PS_TIME is not set >+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set >+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set > CONFIG_RENICE=y > # CONFIG_BB_SYSCTL is not set > CONFIG_TOP=y > CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y > CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y >+CONFIG_FEATURE_TOP_SMP_CPU=y > # CONFIG_FEATURE_TOP_DECIMALS is not set >+CONFIG_FEATURE_TOP_SMP_PROCESS=y >+CONFIG_FEATURE_TOPMEM=y >+CONFIG_FEATURE_SHOW_THREADS=y > CONFIG_UPTIME=y > # CONFIG_WATCH is not set > > # >-# Shells >+# Runit Utilities > # >-CONFIG_FEATURE_SH_IS_ASH=y >-# CONFIG_FEATURE_SH_IS_HUSH is not set >-# CONFIG_FEATURE_SH_IS_LASH is not set >-# CONFIG_FEATURE_SH_IS_MSH is not set >-# CONFIG_FEATURE_SH_IS_NONE is not set >-CONFIG_ASH=y >+# CONFIG_RUNSV is not set >+# CONFIG_RUNSVDIR is not set >+# CONFIG_FEATURE_RUNSVDIR_LOG is not set >+# CONFIG_SV is not set >+CONFIG_SV_DEFAULT_SERVICE_DIR="" >+# CONFIG_SVLOGD is not set >+# CONFIG_CHPST is not set >+# CONFIG_SETUIDGID is not set >+# CONFIG_ENVUIDGID is not set >+# CONFIG_ENVDIR is not set >+# CONFIG_SOFTLIMIT is not set >+# CONFIG_CHCON is not set >+# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set >+# CONFIG_GETENFORCE is not set >+# CONFIG_GETSEBOOL is not set >+# CONFIG_LOAD_POLICY is not set >+# CONFIG_MATCHPATHCON is not set >+# CONFIG_RESTORECON is not set >+# CONFIG_RUNCON is not set >+# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set >+# CONFIG_SELINUXENABLED is not set >+# CONFIG_SETENFORCE is not set >+# CONFIG_SETFILES is not set >+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set >+# CONFIG_SETSEBOOL is not set >+# CONFIG_SESTATUS is not set > > # >-# Ash Shell Options >+# Shells > # >+CONFIG_ASH=y >+CONFIG_ASH_BASH_COMPAT=y > CONFIG_ASH_JOB_CONTROL=y >-CONFIG_ASH_READ_NCHARS=y >-CONFIG_ASH_READ_TIMEOUT=y > CONFIG_ASH_ALIAS=y >-CONFIG_ASH_MATH_SUPPORT=y >-# CONFIG_ASH_MATH_SUPPORT_64 is not set > # CONFIG_ASH_GETOPTS is not set > CONFIG_ASH_BUILTIN_ECHO=y >+CONFIG_ASH_BUILTIN_PRINTF=y > CONFIG_ASH_BUILTIN_TEST=y > # CONFIG_ASH_CMDCMD is not set > # CONFIG_ASH_MAIL is not set > CONFIG_ASH_OPTIMIZE_FOR_SIZE=y > CONFIG_ASH_RANDOM_SUPPORT=y > # CONFIG_ASH_EXPAND_PRMT is not set >+# CONFIG_CTTYHACK is not set > # CONFIG_HUSH is not set >+# CONFIG_HUSH_BASH_COMPAT is not set >+# CONFIG_HUSH_BRACE_EXPANSION is not set > # CONFIG_HUSH_HELP is not set > # CONFIG_HUSH_INTERACTIVE is not set >+# CONFIG_HUSH_SAVEHISTORY is not set > # CONFIG_HUSH_JOB is not set > # CONFIG_HUSH_TICK is not set > # CONFIG_HUSH_IF is not set > # CONFIG_HUSH_LOOPS is not set >-# CONFIG_LASH is not set >+# CONFIG_HUSH_CASE is not set >+# CONFIG_HUSH_FUNCTIONS is not set >+# CONFIG_HUSH_LOCAL is not set >+# CONFIG_HUSH_RANDOM_SUPPORT is not set >+# CONFIG_HUSH_EXPORT_N is not set >+# CONFIG_HUSH_MODE_X is not set > # CONFIG_MSH is not set >- >-# >-# Bourne Shell Options >-# >+CONFIG_FEATURE_SH_IS_ASH=y >+# CONFIG_FEATURE_SH_IS_HUSH is not set >+# CONFIG_FEATURE_SH_IS_NONE is not set >+# CONFIG_FEATURE_BASH_IS_ASH is not set >+# CONFIG_FEATURE_BASH_IS_HUSH is not set >+CONFIG_FEATURE_BASH_IS_NONE=y >+CONFIG_SH_MATH_SUPPORT=y >+CONFIG_SH_MATH_SUPPORT_64=y > # CONFIG_FEATURE_SH_EXTRA_QUIET is not set > # CONFIG_FEATURE_SH_STANDALONE is not set >-# CONFIG_CTTYHACK is not set >+CONFIG_FEATURE_SH_NOFORK=y > > # > # System Logging Utilities > # > CONFIG_SYSLOGD=y > # CONFIG_FEATURE_ROTATE_LOGFILE is not set >-# CONFIG_FEATURE_REMOTE_LOG is not set >+CONFIG_FEATURE_REMOTE_LOG=y >+CONFIG_FEATURE_SYSLOGD_DUP=y >+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256 > CONFIG_FEATURE_IPC_SYSLOG=y > CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 > CONFIG_LOGREAD=y >-# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set >+CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y > CONFIG_KLOGD=y >+CONFIG_FEATURE_KLOGD_KLOGCTL=y > CONFIG_LOGGER=y >- >-# >-# Runit Utilities >-# >-# CONFIG_RUNSV is not set >-# CONFIG_RUNSVDIR is not set >-# CONFIG_SV is not set >-# CONFIG_SVLOGD is not set >-# CONFIG_CHPST is not set >-# CONFIG_SETUIDGID is not set >-# CONFIG_ENVUIDGID is not set >-# CONFIG_ENVDIR is not set >-# CONFIG_SOFTLIMIT is not set >-# CONFIG_CHCON is not set >-# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set >-# CONFIG_GETENFORCE is not set >-# CONFIG_GETSEBOOL is not set >-# CONFIG_LOAD_POLICY is not set >-# CONFIG_MATCHPATHCON is not set >-# CONFIG_RESTORECON is not set >-# CONFIG_RUNCON is not set >-# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set >-# CONFIG_SELINUXENABLED is not set >-# CONFIG_SETENFORCE is not set >-# CONFIG_SETFILES is not set >-# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set >- >-# >-# ipsvd utilities >-# >-# CONFIG_TCPSVD is not set >-# CONFIG_UDPSVD is not set >diff -pruN genkernel.a/patches/busybox/1.18.1/1.18.1-mdadm.diff genkernel.b/patches/busybox/1.18.1/1.18.1-mdadm.diff >--- genkernel.a/patches/busybox/1.18.1/1.18.1-mdadm.diff 1970-01-01 03:00:00.000000000 +0300 >+++ genkernel.b/patches/busybox/1.18.1/1.18.1-mdadm.diff 2011-01-12 21:35:19.000000000 +0200 >@@ -0,0 +1,5876 @@ >+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. >+ >+> Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >+ >+--- 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 -pruN genkernel.a/patches/busybox/1.18.1/1.18.1-mdstart.diff genkernel.b/patches/busybox/1.18.1/1.18.1-mdstart.diff >--- genkernel.a/patches/busybox/1.18.1/1.18.1-mdstart.diff 1970-01-01 03:00:00.000000000 +0300 >+++ genkernel.b/patches/busybox/1.18.1/1.18.1-mdstart.diff 2011-01-12 21:32:10.000000000 +0200 >@@ -0,0 +1,113 @@ >+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. >+ >+> Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >+ >+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 -pruN genkernel.a/patches/busybox/1.18.1/1.18.1-openvt.diff genkernel.b/patches/busybox/1.18.1/1.18.1-openvt.diff >--- genkernel.a/patches/busybox/1.18.1/1.18.1-openvt.diff 1970-01-01 03:00:00.000000000 +0300 >+++ genkernel.b/patches/busybox/1.18.1/1.18.1-openvt.diff 2011-01-12 21:17:53.000000000 +0200 >@@ -0,0 +1,21 @@ >+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. >+ >+> Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >+ >+--- 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 -pruN genkernel.a/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch genkernel.b/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch >--- genkernel.a/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch 1970-01-01 03:00:00.000000000 +0300 >+++ genkernel.b/patches/busybox/1.18.1/busybox-1.7.4-signal-hack.patch 2010-11-29 21:39:38.000000000 +0200 >@@ -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 -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-ash-timeout.diff genkernel.b/patches/busybox/1.7.4/1.7.4-ash-timeout.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-ash-timeout.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-ash-timeout.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,123 +0,0 @@ >-'read -t' support, forward-ported from Gentoo Busybox 1.1.3. >-Used during the LiveCD boot when prompting for a keymap. >- >-Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >- >-diff -Nuar --exclude '*.orig' busybox-1.7.4/shell/ash.c busybox-1.7.4+gentoo/shell/ash.c >---- busybox-1.7.4/shell/ash.c 2007-11-03 16:06:35.000000000 -0700 >-+++ busybox-1.7.4+gentoo/shell/ash.c 2008-03-11 10:21:28.000000000 -0700 >-@@ -11485,11 +11485,13 @@ >- int startword; >- int status; >- int i; >-+#if ENABLE_ASH_READ_NCHARS || ENABLE_ASH_READ_TIMEOUT >-+ struct termios tty, old_tty; >-+#endif >- #if ENABLE_ASH_READ_NCHARS >- int nch_flag = 0; >- int nchars = 0; >- int silent = 0; >-- struct termios tty, old_tty; >- #endif >- #if ENABLE_ASH_READ_TIMEOUT >- fd_set set; >-@@ -11566,44 +11568,74 @@ >- ifs = bltinlookup("IFS"); >- if (ifs == NULL) >- ifs = defifs; >--#if ENABLE_ASH_READ_NCHARS >-+#if ENABLE_ASH_READ_NCHARS || ENABLE_ASH_READ_TIMEOUT >-+#if ENABLE_ASH_READ_NCHARS && ENABLE_ASH_READ_TIMEOUT >-+ if (nch_flag || silent || ts.tv_sec || ts.tv_usec) { >-+#elif ENABLE_ASH_READ_TIMEOUT >-+ if (ts.tv_sec || ts.tv_usec) { >-+#elif ENABLE_ASH_READ_NCHARS >- if (nch_flag || silent) { >-+#endif >- tcgetattr(0, &tty); >- old_tty = tty; >-- if (nch_flag) { >-+#if ENABLE_ASH_READ_NCHARS && ENABLE_ASH_READ_TIMEOUT >-+ if (nch_flag || ts.tv_sec || ts.tv_usec) >-+#elif ENABLE_ASH_READ_TIMEOUT >-+ if (ts.tv_sec || ts.tv_usec) >-+#elif ENABLE_ASH_READ_NCHARS >-+ if (nch_flag) >-+#endif >- tty.c_lflag &= ~ICANON; >-- tty.c_cc[VMIN] = nchars; >-- } >-- if (silent) { >-- tty.c_lflag &= ~(ECHO|ECHOK|ECHONL); >- >-- } >-+ >-+#if ENABLE_ASH_READ_NCHARS >-+ if (silent) >-+ tty.c_lflag &= ~(ECHO|ECHOK|ECHONL); >-+#endif >- tcsetattr(0, TCSANOW, &tty); >- } >- #endif >-+ i = 1; >-+ STARTSTACKSTR(p); >- #if ENABLE_ASH_READ_TIMEOUT >- if (ts.tv_sec || ts.tv_usec) { >- FD_ZERO(&set); >- FD_SET(0, &set); >- >- i = select(FD_SETSIZE, &set, NULL, NULL, &ts); >-- if (!i) { >-+ if (i == 1) >-+ { >-+ read(0, &c, 1); >-+ if(c == '\n' || c == 4) /* Handle newlines and EOF */ >-+ i = 0; /* Don't read further... */ >-+ else >-+ STPUTC(c, p); /* Ok, keep reading... */ >-+ } >- #if ENABLE_ASH_READ_NCHARS >-- if (nch_flag) >-- tcsetattr(0, TCSANOW, &old_tty); >-+ if (!silent && !nch_flag) >- #endif >-- return 1; >-+ tcsetattr(0, TCSANOW, &old_tty); >-+ >-+#if ENABLE_ASH_READ_NCHARS >-+ if(i == 0) >-+ { >-+ nchars = 0; >-+ nch_flag = 1; >-+ } else >-+ { >-+ if (nch_flag) >-+ nchars--; >- } >-+#endif >- } >- #endif >- status = 0; >- startword = 1; >- backslash = 0; >-- STARTSTACKSTR(p); >- #if ENABLE_ASH_READ_NCHARS >- while (!nch_flag || nchars--) >- #else >-- for (;;) >-+ for (;i > 0;) >- #endif >- { >- if (read(0, &c, 1) != 1) { >-@@ -11640,8 +11672,10 @@ >- } >- } >- #if ENABLE_ASH_READ_NCHARS >-- if (nch_flag || silent) >-+ if (silent || nch_flag) >- tcsetattr(0, TCSANOW, &old_tty); >-+ if (!silent && nch_flag) >-+ printf("\n"); >- #endif >- >- STACKSTRNUL(p); >diff -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-make-3.82.diff genkernel.b/patches/busybox/1.7.4/1.7.4-make-3.82.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-make-3.82.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-make-3.82.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,42 +0,0 @@ >-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 -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-mdadm.diff genkernel.b/patches/busybox/1.7.4/1.7.4-mdadm.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-mdadm.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-mdadm.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,5882 +0,0 @@ >-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. >- >-Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >- >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/Config.in busybox-1.7.4+gentoo+mdadm/Config.in >---- busybox-1.7.4+gentoo/Config.in 2007-09-03 04:48:58.000000000 -0700 >-+++ busybox-1.7.4+gentoo+mdadm/Config.in 2008-03-11 10:31:00.000000000 -0700 >-@@ -499,2 +499,3 @@ >- source e2fsprogs/Config.in >-+source mdadm/Config.in >- source modutils/Config.in >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/include/applets.h busybox-1.7.4+gentoo+mdadm/include/applets.h >---- busybox-1.7.4+gentoo/include/applets.h 2008-03-11 10:25:43.000000000 -0700 >-+++ busybox-1.7.4+gentoo+mdadm/include/applets.h 2008-03-11 10:32:22.000000000 -0700 >-@@ -223,2 +223,3 @@ >- USE_MD5SUM(APPLET_ODDNAME(md5sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, md5sum)) >-+USE_MDADM(APPLET(mdadm, _BB_DIR_SBIN, _BB_SUID_NEVER)) >- USE_MDEV(APPLET(mdev, _BB_DIR_SBIN, _BB_SUID_NEVER)) >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/include/usage.h busybox-1.7.4+gentoo+mdadm/include/usage.h >---- busybox-1.7.4+gentoo/include/usage.h 2008-03-11 10:19:04.000000000 -0700 >-+++ busybox-1.7.4+gentoo+mdadm/include/usage.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -2048,2 +2048,7 @@ >- >-+#define mdadm_trivial_usage \ >-+ "" >-+#define mdadm_full_usage \ >-+ "Assemble or Examine the mdadm arrays." >-+ >- #define mdev_trivial_usage \ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/Makefile busybox-1.7.4+gentoo+mdadm/Makefile >---- busybox-1.7.4+gentoo/Makefile 2007-11-23 20:34:41.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/Makefile 2008-03-11 10:31:49.000000000 -0700 >-@@ -442,6 +442,7 @@ >- libpwdgrp/ \ >- loginutils/ \ >- miscutils/ \ >-+ mdadm/ \ >- modutils/ \ >- networking/ \ >- networking/libiproute/ \ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/bitmap.h busybox-1.7.4+gentoo+mdadm/mdadm/bitmap.h >---- busybox-1.7.4+gentoo/mdadm/bitmap.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/bitmap.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/config.c busybox-1.7.4+gentoo+mdadm/mdadm/config.c >---- busybox-1.7.4+gentoo/mdadm/config.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/config.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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; >-+} >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/Config.in busybox-1.7.4+gentoo+mdadm/mdadm/Config.in >---- busybox-1.7.4+gentoo/mdadm/Config.in 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/Config.in 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-+ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/dlink.c busybox-1.7.4+gentoo+mdadm/mdadm/dlink.c >---- busybox-1.7.4+gentoo/mdadm/dlink.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/dlink.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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)); >-+} >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/dlink.h busybox-1.7.4+gentoo+mdadm/mdadm/dlink.h >---- busybox-1.7.4+gentoo/mdadm/dlink.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/dlink.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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*); >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/md5.h busybox-1.7.4+gentoo+mdadm/mdadm/md5.h >---- busybox-1.7.4+gentoo/mdadm/md5.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/md5.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 */ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/mdadm.c busybox-1.7.4+gentoo+mdadm/mdadm/mdadm.c >---- busybox-1.7.4+gentoo/mdadm/mdadm.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/mdadm.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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; >-+} >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/mdadm.h busybox-1.7.4+gentoo+mdadm/mdadm/mdadm.h >---- busybox-1.7.4+gentoo/mdadm/mdadm.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/mdadm.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/mdassemble.c busybox-1.7.4+gentoo+mdadm/mdadm/mdassemble.c >---- busybox-1.7.4+gentoo/mdadm/mdassemble.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/mdassemble.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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; >-+} >-+ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/mdexamine.c busybox-1.7.4+gentoo+mdadm/mdadm/mdexamine.c >---- busybox-1.7.4+gentoo/mdadm/mdexamine.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/mdexamine.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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); >-+} >-+ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/md_p.h busybox-1.7.4+gentoo+mdadm/mdadm/md_p.h >---- busybox-1.7.4+gentoo/mdadm/md_p.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/md_p.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-+ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/md_u.h busybox-1.7.4+gentoo+mdadm/mdadm/md_u.h >---- busybox-1.7.4+gentoo/mdadm/md_u.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/md_u.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-+ >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/sha1.c busybox-1.7.4+gentoo+mdadm/mdadm/sha1.c >---- busybox-1.7.4+gentoo/mdadm/sha1.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/sha1.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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; >-+ } >-+} >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/sha1.h busybox-1.7.4+gentoo+mdadm/mdadm/sha1.h >---- busybox-1.7.4+gentoo/mdadm/sha1.h 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/sha1.h 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/super0.c busybox-1.7.4+gentoo+mdadm/mdadm/super0.c >---- busybox-1.7.4+gentoo/mdadm/super0.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/super0.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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, >-+}; >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/super1.c busybox-1.7.4+gentoo+mdadm/mdadm/super1.c >---- busybox-1.7.4+gentoo/mdadm/super1.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/super1.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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 >-+}; >-diff -Nuar --exclude '*.orig' busybox-1.7.4+gentoo/mdadm/util.c busybox-1.7.4+gentoo+mdadm/mdadm/util.c >---- busybox-1.7.4+gentoo/mdadm/util.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/util.c 2008-03-11 10:31:00.000000000 -0700 >-@@ -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; >-+} >---- busybox-1.7.4+gentoo/mdadm/Kbuild 2008-03-01 18:44:05.526713152 -0800 >-+++ busybox-1.7.4+gentoo+mdadm/mdadm/Kbuild 2008-03-11 12:19:18.000000000 -0700 >-@@ -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) >diff -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-mdstart.diff genkernel.b/patches/busybox/1.7.4/1.7.4-mdstart.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-mdstart.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-mdstart.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,122 +0,0 @@ >-Forward-port the old mdstart tool from the Gentoo Busybox-1.1.3. >-Only fires the RAID_AUTORUN ioctl on existing /dev/md nodes. >- >-Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >- >-diff -Nuar --exclude '*.orig' busybox-1.7.4/include/applets.h busybox-1.7.4+gentoo/include/applets.h >---- busybox-1.7.4/include/applets.h 2007-09-03 04:48:46.000000000 -0700 >-+++ busybox-1.7.4+gentoo/include/applets.h 2008-03-11 10:25:43.000000000 -0700 >-@@ -222,6 +222,7 @@ >- USE_MATCHPATHCON(APPLET(matchpathcon, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) >- USE_MD5SUM(APPLET_ODDNAME(md5sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, md5sum)) >- USE_MDEV(APPLET(mdev, _BB_DIR_SBIN, _BB_SUID_NEVER)) >-+USE_MDSTART(APPLET(mdstart, _BB_DIR_SBIN, _BB_SUID_NEVER)) >- USE_MESG(APPLET(mesg, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) >- USE_MKDIR(APPLET_NOFORK(mkdir, mkdir, _BB_DIR_BIN, _BB_SUID_NEVER, mkdir)) >- //USE_MKE2FS(APPLET(mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) >-diff -Nuar --exclude '*.orig' busybox-1.7.4/include/usage.h busybox-1.7.4+gentoo/include/usage.h >---- busybox-1.7.4/include/usage.h 2007-09-03 04:48:46.000000000 -0700 >-+++ busybox-1.7.4+gentoo/include/usage.h 2008-03-11 10:19:04.000000000 -0700 >-@@ -2072,6 +2072,11 @@ >- "the last line match .* to override this.)\n\n" \ >- ) >- >-+#define mdstart_trivial_usage \ >-+ "{[PARTITION] MD-NODE}..." >-+#define mdstart_full_usage \ >-+ "Run the RAID_AUTORUN ioctl on the given MD number" >-+ >- #define mesg_trivial_usage \ >- "[y|n]" >- #define mesg_full_usage \ >-diff -Nuar --exclude '*.orig' busybox-1.7.4/util-linux/Config.in busybox-1.7.4+gentoo/util-linux/Config.in >---- busybox-1.7.4/util-linux/Config.in 2007-09-03 04:48:56.000000000 -0700 >-+++ busybox-1.7.4+gentoo/util-linux/Config.in 2008-03-11 10:26:20.000000000 -0700 >-@@ -305,6 +305,13 @@ >- /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 n >-diff -Nuar --exclude '*.orig' busybox-1.7.4/util-linux/Kbuild busybox-1.7.4+gentoo/util-linux/Kbuild >---- busybox-1.7.4/util-linux/Kbuild 2007-09-03 04:48:56.000000000 -0700 >-+++ busybox-1.7.4+gentoo/util-linux/Kbuild 2008-03-11 10:28:47.000000000 -0700 >-@@ -18,6 +18,7 @@ >- lib-$(CONFIG_IPCRM) +=ipcrm.o >- lib-$(CONFIG_IPCS) +=ipcs.o >- lib-$(CONFIG_LOSETUP) +=losetup.o >-+lib-$(CONFIG_MDSTART) +=mdStart.o >- lib-$(CONFIG_MDEV) +=mdev.o >- lib-$(CONFIG_MKFS_MINIX) +=mkfs_minix.o >- lib-$(CONFIG_MKSWAP) +=mkswap.o >-diff -Nuar --exclude '*.orig' busybox-1.7.4/util-linux/mdStart.c busybox-1.7.4+gentoo/util-linux/mdStart.c >---- busybox-1.7.4/util-linux/mdStart.c 1969-12-31 16:00:00.000000000 -0800 >-+++ busybox-1.7.4+gentoo/util-linux/mdStart.c 2008-03-11 10:19:04.000000000 -0700 >-@@ -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 -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-mount-umount-i-option.diff genkernel.b/patches/busybox/1.7.4/1.7.4-mount-umount-i-option.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-mount-umount-i-option.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-mount-umount-i-option.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,24 +0,0 @@ >-diff -ru busybox-1.7.4.orig/util-linux/mount.c busybox-1.7.4/util-linux/mount.c >---- busybox-1.7.4.orig/util-linux/mount.c 2007-09-03 06:48:56.000000000 -0500 >-+++ busybox-1.7.4/util-linux/mount.c 2008-11-13 21:12:06.000000000 -0600 >-@@ -1554,7 +1554,7 @@ >- >- // Parse remaining options >- >-- opt = getopt32(argv, "o:t:rwanfvs", &opt_o, &fstype); >-+ opt = getopt32(argv, "o:t:rwanfvsi", &opt_o, &fstype); >- if (opt & 0x1) append_mount_options(&cmdopts, opt_o); // -o >- //if (opt & 0x2) // -t >- if (opt & 0x4) append_mount_options(&cmdopts, "ro"); // -r >-diff -ru busybox-1.7.4.orig/util-linux/umount.c busybox-1.7.4/util-linux/umount.c >---- busybox-1.7.4.orig/util-linux/umount.c 2007-09-03 06:48:56.000000000 -0500 >-+++ busybox-1.7.4/util-linux/umount.c 2008-11-13 16:13:03.000000000 -0600 >-@@ -12,7 +12,7 @@ >- #include <getopt.h> >- #include "libbb.h" >- >--#define OPTION_STRING "flDnravdt:" >-+#define OPTION_STRING "flDnravdt:i" >- #define OPT_FORCE 1 >- #define OPT_LAZY 2 >- #define OPT_DONTFREELOOP 4 >diff -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-openvt.diff genkernel.b/patches/busybox/1.7.4/1.7.4-openvt.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-openvt.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-openvt.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,20 +0,0 @@ >-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. >- >-Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> >- >-diff -Nuar --exclude '*.orig' busybox-1.7.4/console-tools/openvt.c busybox-1.7.4+gentoo/console-tools/openvt.c >---- busybox-1.7.4/console-tools/openvt.c 2007-09-03 04:48:35.000000000 -0700 >-+++ busybox-1.7.4+gentoo/console-tools/openvt.c 2008-03-10 10:00:55.000000000 -0700 >-@@ -21,7 +21,7 @@ >- bb_show_usage(); >- >- /* check for illegal vt number: < 1 or > 63 */ >-- sprintf(vtname, VC_FORMAT, (int)xatou_range(argv[1], 1, 63)); >-+ sprintf(vtname, VC_FORMAT, (int)xatou_range(argv[1], 0, 63)); >- >- bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); >- /* grab new one */ >diff -pruN genkernel.a/patches/busybox/1.7.4/1.7.4-static-error.diff genkernel.b/patches/busybox/1.7.4/1.7.4-static-error.diff >--- genkernel.a/patches/busybox/1.7.4/1.7.4-static-error.diff 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/1.7.4-static-error.diff 1970-01-01 03:00:00.000000000 +0300 >@@ -1,23 +0,0 @@ >-diff -ur busybox-1.7.4.orig/applets/applets.c busybox-1.7.4/applets/applets.c >---- busybox-1.7.4.orig/applets/applets.c 2007-09-16 13:48:10.000000000 -0500 >-+++ busybox-1.7.4/applets/applets.c 2008-03-11 13:53:18.000000000 -0500 >-@@ -23,7 +23,6 @@ >- #warning Note that glibc is unsuitable for static linking anyway. >- #warning If you still want to do it, remove -Wl,--gc-sections >- #warning from top-level Makefile and remove this warning. >--#error Aborting compilation. >- #endif >- >- >-diff -ur busybox-1.7.4.orig/Makefile busybox-1.7.4/Makefile >---- busybox-1.7.4.orig/Makefile 2007-11-23 22:34:41.000000000 -0600 >-+++ busybox-1.7.4/Makefile 2008-03-12 06:35:25.000000000 -0500 >-@@ -570,7 +570,7 @@ >- quiet_cmd_busybox__ ?= LINK $@ >- cmd_busybox__ ?= $(srctree)/scripts/trylink $(CC) $(LDFLAGS) \ >- -o $@ -Wl,-Map -Wl,$@.map \ >-- -Wl,--warn-common -Wl,--sort-common -Wl,--gc-sections \ >-+ -Wl,--warn-common -Wl,--sort-common \ >- -Wl,--start-group $(busybox-all) -Wl,--end-group \ >- $(LDLIBS) >- >diff -pruN genkernel.a/patches/busybox/1.7.4/busybox-1.7.4-signal-hack.patch genkernel.b/patches/busybox/1.7.4/busybox-1.7.4-signal-hack.patch >--- genkernel.a/patches/busybox/1.7.4/busybox-1.7.4-signal-hack.patch 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/busybox-1.7.4-signal-hack.patch 1970-01-01 03:00:00.000000000 +0300 >@@ -1,28 +0,0 @@ >-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 -pruN genkernel.a/patches/busybox/1.7.4/README genkernel.b/patches/busybox/1.7.4/README >--- genkernel.a/patches/busybox/1.7.4/README 2011-01-12 21:05:44.000000000 +0200 >+++ genkernel.b/patches/busybox/1.7.4/README 1970-01-01 03:00:00.000000000 +0300 >@@ -1,23 +0,0 @@ >-1.7.4-ash-timeout.diff: >-This patch adds support for the -t option to the 'read' command in ash. It's >-used for prompting for the keymap. It originated with 1.1.3+gentoo or earlier. >- >-1.7.4-mdadm.diff: >-This adds a minimal mdadm implementation to busybox for scanning for and >-activating mdraid arrays. You can blame robbat2 for this one :) >- >-1.7.4-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. >- >-1.7.4-openvt.diff: >-It is unknown what problem this patch fixes. It may no longer be needed. >- >-1.7.4-static-error.diff: >-This allows us to build busybox statically, even though upstream frowns upon it. >-It's important that the removal of -Wl,--gc-sections remains, or ash will be >-broken in the resulting busybox. This patch is based on the busybox ebuild. >- >-busybox-1.7.4-signal-hack.patch: >-It is unknown what this patch does. It may no longer be needed. >-
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 331971
:
248723
|
248725
|
255835
|
255837
|
255839
|
255875
|
256047
|
256348
|
258432
|
258945
| 259650 |
262061