summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <d@falconindy.com>2011-06-05 21:42:09 +0200
committerDave Reisner <d@falconindy.com>2011-06-16 20:19:12 +0200
commitb117e2ae0cf948d4afe59eee6e503f30f184ddba (patch)
tree862a994d1a7a1302814981bf9ba2b5a4f4a88e63
parent3efc8b39b126c6eaaedcc1585a17105a5ab67a8f (diff)
downloadmkinitcpio-b117e2ae0cf948d4afe59eee6e503f30f184ddba.tar.gz
mkinitcpio-b117e2ae0cf948d4afe59eee6e503f30f184ddba.tar.xz
use bsdcpio to create images
This is a departure from using gen_init_cpio, which proved to be a huge bottleneck in performance. Tests for existance change from being a call to grep, to a simple shell test. In the process, we have to modify the behavior of the -s option, and we lose the -a option. Signed-off-by: Dave Reisner <d@falconindy.com>
-rw-r--r--functions41
-rwxr-xr-xmkinitcpio74
-rw-r--r--mkinitcpio.5.txt7
3 files changed, 58 insertions, 64 deletions
diff --git a/functions b/functions
index dc20566..662df7b 100644
--- a/functions
+++ b/functions
@@ -79,12 +79,12 @@ checked_modules ()
add_full_dir ()
{
- if [ -n "${1}" -a -d "${1}" ]; then
- for f in ${1}/*; do
- if [ -d "${f}" ]; then
- add_full_dir "${f}"
+ if [[ -n $1 && -d $1 ]]; then
+ for f in "$1"/*; do
+ if [[ -d "$f" ]]; then
+ add_full_dir "$f"
else
- add_file "${f}"
+ add_file "$f"
fi
done
fi
@@ -92,28 +92,23 @@ add_full_dir ()
add_dir ()
{
- #skip root directory and "." for relative directories... i.e. /foo/bar/./blah
- if [ -n "${1}" -a "${1}" != "/" -a "${1}" != "." ]; then
- if ! grep -q "dir ${1} " "${FILELIST}"; then
- add_dir $(get_dirname "${1}")
- msg " adding dir ${1}"
- echo "dir ${1} 755 0 0" >> "${FILELIST}"
- fi
+ if [[ ! -e "$TMPDIR/root/$1" ]]; then
+ msg " adding dir ${1}"
+ command install -dm755 "$TMPDIR/root/$1"
fi
}
-# what the hell does this do?
add_symlink ()
{
local fil dest dir
- if [ -h ${1} ]; then
+ if [[ -h $1 ]]; then
fil="${1##$BASEDIR}"
dest="${2##$BASEDIR}"
add_dir $(get_dirname "${dest}")
add_dir $(get_dirname "${fil}")
- if ! grep -q "slink ${fil} " "${FILELIST}"; then
+ if [[ ! -e "$TMPDIR/root/$dest" ]]; then
msg " adding link ${fil} -> ${dest}"
- echo "slink ${fil} ${dest} $(stat -c '%a' ${1}) 0 0" >> "${FILELIST}"
+ ln -s "$dest" "$TMPDIR/root/$fil"
fi
fi
#fail quietly
@@ -122,27 +117,27 @@ add_symlink ()
add_file ()
{
local fil lnk dir dest
- if [ -f "${1}" ]; then
- fil="${1}"
+ if [[ -f "$1" ]]; then
+ fil=$1
lnk=$(readlink -f "${fil}")
- if [ -n "${lnk}" ]; then
+ if [[ ${lnk} ]]; then
add_symlink "${fil}" "${lnk}"
fil="${lnk}"
fi
if [[ $2 ]]; then
- dest="${2}"
+ dest=$2
else
dest="${fil##$BASEDIR}"
- if [ "${dest}" = "${dest#/}" ]; then
+ if [[ "${dest}" = "${dest#/}" ]]; then
dest="/${dest}"
fi
fi
add_dir $(get_dirname "${dest}")
- if ! grep -q "file ${dest} " "${FILELIST}"; then
+ if [[ ! -e $TMPDIR/root/$dest ]]; then
msg " adding file ${dest}"
- echo "file ${dest} ${fil} $(stat -c '%a' ${fil}) 0 0" >> "${FILELIST}"
+ command install -Dm$(stat -c '%a' "$fil") "$fil" "$TMPDIR/root/$dest"
fi
else
err "file '${1}' does not exist"
diff --git a/mkinitcpio b/mkinitcpio
index 7c42e9f..853cf03 100755
--- a/mkinitcpio
+++ b/mkinitcpio
@@ -10,11 +10,11 @@
# in case of embedded spaces, quote all path names and string comparisons
#
+shopt -s extglob
# Settings
TMPDIR="$(mktemp -d /tmp/mkinitcpio.XXXXXX)"
BASEDIR=""
-FILELIST="${TMPDIR}/filelist"
MESSAGEFILE="${TMPDIR}/message"
KERNELVERSION="$(uname -r)"
FUNCTIONS="functions"
@@ -24,7 +24,6 @@ INSTDIR="install"
MODULE_FILE=""
SAVELIST=""
GENIMG=""
-APPEND=""
PRESET=""
MESSAGE=""
SKIPHOOKS=()
@@ -52,10 +51,9 @@ usage ()
echo "${APPNAME}: usage"
echo " -c CONFIG Use CONFIG file. default: /etc/mkinitcpio.conf"
echo " -k KERNELVERSION Use KERNELVERSION. default: $(uname -r)"
- echo " -s NAME Save filelist. default: no"
+ echo " -s Save build directory. default: no"
echo " -b BASEDIR Use BASEDIR. default: /"
echo " -g IMAGE Generate a cpio image as IMAGE. default: no"
- echo " -a NAME Append to an existing filelist. default: no"
echo " -p PRESET Build specified preset."
echo " -m MESSAGE Print MESSAGE before passing control to init."
echo " -S SKIPHOOKS Skip SKIPHOOKS (comma-separated) when building the image."
@@ -70,7 +68,11 @@ usage ()
cleanup ()
{
- [ -n "${TMPDIR}" -a -d "${TMPDIR}" ] && rm -rf ${TMPDIR}
+ if [[ $SAVELIST ]]; then
+ echo ":: build directory saved in $TMPDIR"
+ else
+ rm -rf ${TMPDIR}
+ fi
}
sighandler() {
@@ -80,7 +82,7 @@ sighandler() {
trap sighandler TERM INT
-while getopts ':c:k:s:b:g:a:p:m:vH:LMhS:' arg; do
+while getopts ':c:k:sb:g:p:m:vH:LMhS:' arg; do
if [ "${OPTARG#-}" != "${OPTARG}" ]; then
echo "error: optional argument to '-${arg}' begins with a '-'"
echo " you probably don't want this....aborting."
@@ -89,10 +91,9 @@ while getopts ':c:k:s:b:g:a:p:m:vH:LMhS:' arg; do
case "${arg}" in
c) CONFIG="${OPTARG}" ;;
k) KERNELVERSION="${OPTARG}" ;;
- s) SAVELIST="y"; FILELIST="${OPTARG}" ;;
+ s) SAVELIST="y"; ;;
b) BASEDIR="${OPTARG}" ;;
g) GENIMG="${OPTARG}" ;;
- a) APPEND="y"; SAVELIST="y"; FILELIST="${OPTARG}" ;;
p) PRESET="${OPTARG}" ;;
m) MESSAGE="${OPTARG}" ;;
v) QUIET="n" ;;
@@ -188,6 +189,15 @@ BASEDIR="${BASEDIR%/}"
MODULEDIR="${BASEDIR}/lib/modules/${KERNELVERSION}"
+if [[ $GENIMG ]]; then
+ IMGPATH=$(readlink -f "$GENIMG")
+ if [[ -z $IMGPATH || ! -w ${IMGPATH%/*} ]]; then
+ echo "error: unable to write to path: '$GENIMG'"
+ cleanup
+ exit 1
+ fi
+fi
+
if [ -n "${BASEDIR}" ]; then
if [ "${BASEDIR}" = "${BASEDIR#/}" ]; then
BASEDIR="$(pwd)/${BASEDIR}"
@@ -205,19 +215,6 @@ if [ ! -f "${CONFIG}" ]; then
fi
. "${CONFIG}"
-if [ -f "${FILELIST}" -a -z "${APPEND}" ]; then
- if [ -z "${SAVELIST}" ]; then
- rm ${FILELIST}
- touch "${FILELIST}"
- else
- echo "destination file list '${FILELIST}' exists - remove before running"
- cleanup
- exit 1
- fi
-else
- touch "${FILELIST}"
-fi
-
BASEDIR=$(echo ${BASEDIR} | tr -s /)
MODULEDIR=$(echo ${MODULEDIR} | tr -s /)
@@ -279,31 +276,36 @@ done
if (( ${#ADDED_MODULES[*]} )); then
echo ":: Generating module dependencies"
- for mod in $(grep "file /lib/modules/${KERNELVERSION}" ${FILELIST} | cut -d' ' -f2); do
- install -m 644 -D "${BASEDIR}${mod}" "${TMPDIR}${mod}"
- done
- /sbin/depmod -b ${TMPDIR} ${KERNELVERSION}
- for dmfile in modules.{dep,alias,symbols}.bin; do
- add_file "${TMPDIR}/lib/modules/${KERNELVERSION}/$dmfile" "/lib/modules/${KERNELVERSION}/$dmfile"
- done
+ /sbin/depmod -b "${TMPDIR}/root" "${KERNELVERSION}"
+ rm "$TMPDIR/root/lib/modules/$KERNELVERSION"/modules.!(dep.bin|alias.bin|symbols.bin)
fi
-status=0
+declare -i status=0
+declare -a pipesave
if [ -n "${GENIMG}" ]; then
echo ":: Generating image '${GENIMG}'"
- shopt -s -o pipefail
[ ${COMPRESSION} = "xz" ] && COMPRESSION_OPTIONS="${COMPRESSION_OPTIONS} --check=crc32"
- if ! /sbin/gen_init_cpio ${FILELIST} | ${COMPRESSION} ${COMPRESSION_OPTIONS} > "${GENIMG}"; then
- echo ":: Image generation FAILED"
+
+ pushd "$TMPDIR/root" >/dev/null
+ find . -print0 | bsdcpio -0oH newc | $COMPRESSION $COMPRESSION_OPTIONS > "$IMGPATH"
+ pipesave=("${PIPESTATUS[@]}") # save immediately
+ popd >/dev/null
+
+ if (( pipesave[0] )); then
+ errmsg="find reported an error"
+ elif (( pipesave[1] )); then
+ errmsg="bsdcpio reported an error"
+ elif (( pipesave[2] )); then
+ errmsg="$COMPRESSION reported an error"
+ fi
+
+ if [[ $errmsg ]]; then
+ echo ":: Image generation FAILED ($errmsg)"
status=1
else
echo ":: Image generation successful"
- status=0
fi
- if [ -z "${SAVELIST}" ]; then
- rm ${FILELIST}
- fi
else
echo ":: Dry run complete, use -g IMAGE to generate a real image"
fi
diff --git a/mkinitcpio.5.txt b/mkinitcpio.5.txt
index 1c095dc..3d0fdc9 100644
--- a/mkinitcpio.5.txt
+++ b/mkinitcpio.5.txt
@@ -21,8 +21,8 @@ Options
*-k* 'kernelversion'::
Use 'kernelversion'. Default is the current running kernel.
-*-s* 'filelist'::
- Saves a list of all the files in the initial ramdisk in 'filelist'. Default: no; This means the filelist will not be retained if this option isn't specified. Useful for debugging purposes.
+*-s*::
+ Saves the build directory for the initial ramdisk. Default: no; This means the directory will not be retained if this option isn't specified. Useful for debugging purposes.
*-b* 'basedir'::
Use 'basedir' as a starting point for gathering information about the currently running system. Default: /.
@@ -30,9 +30,6 @@ Options
*-g* 'filename'::
Generate a CPIO image as 'filename'. Default: no; this means nothing will be written to the filesystem unless this option is specified.
-*-a* 'filelist'::
- Append to an existing 'filelist'. Default no.
-
*-p* 'preset'::
Build initial ramdisk according to specified 'preset'. Presets are found in /etc/mkinitcpio.d