forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kbuild: rebuild initramfs if content of initramfs changes
initramfs.cpio.gz being build in usr/ and included in the kernel was not rebuild when the included files changed. To fix this the following was done: - let gen_initramfs.sh generate a list of files and directories included in the initramfs - gen_initramfs generate the gzipped cpio archive so we could simplify the kbuild file (Makefile) - utilising the kbuild infrastructure so when uid/gid root mapping changes the initramfs will be rebuild With this change we have a much more robust initramfs generation. Signed-off-by: Sam Ravnborg <[email protected]>
- Loading branch information
Sam Ravnborg
committed
Apr 11, 2006
1 parent
d9df92e
commit d39a206
Showing
2 changed files
with
189 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,55 @@ | ||
#!/bin/bash | ||
# Copyright (C) Martin Schlemmer <[email protected]> | ||
# Released under the terms of the GNU GPL | ||
# | ||
# Generate a newline separated list of entries from the file/directory | ||
# supplied as an argument. | ||
# | ||
# If a file/directory is not supplied then generate a small dummy file. | ||
# Copyright (c) 2006 Sam Ravnborg <[email protected]> | ||
# | ||
# The output is suitable for gen_init_cpio built from usr/gen_init_cpio.c. | ||
# Released under the terms of the GNU GPL | ||
# | ||
# Generate a cpio packed initramfs. It uses gen_init_cpio to generate | ||
# the cpio archive, and gzip to pack it. | ||
# The script may also be used to generate the inputfile used for gen_init_cpio | ||
# This script assumes that gen_init_cpio is located in usr/ directory | ||
|
||
# error out on errors | ||
set -e | ||
|
||
usage() { | ||
cat << EOF | ||
Usage: | ||
$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ... | ||
-o <file> Create gzipped initramfs file named <file> using | ||
gen_init_cpio and gzip | ||
-u <uid> User ID to map to user ID 0 (root). | ||
<uid> is only meaningful if <cpio_source> | ||
is a directory. | ||
-g <gid> Group ID to map to group ID 0 (root). | ||
<gid> is only meaningful if <cpio_source> | ||
is a directory. | ||
<cpio_source> File list or directory for cpio archive. | ||
If <cpio_source> is a .cpio file it will be used | ||
as direct input to initramfs. | ||
-d Output the default cpio list. | ||
All options except -o and -l may be repeated and are interpreted | ||
sequentially and immediately. -u and -g states are preserved across | ||
<cpio_source> options so an explicit "-u 0 -g 0" is required | ||
to reset the root/group mapping. | ||
EOF | ||
} | ||
|
||
list_default_initramfs() { | ||
# echo usr/kinit/kinit | ||
: | ||
} | ||
|
||
default_initramfs() { | ||
cat <<-EOF | ||
cat <<-EOF >> ${output} | ||
# This is a very simple, default initramfs | ||
dir /dev 0755 0 0 | ||
nod /dev/console 0600 0 0 c 5 1 | ||
dir /root 0700 0 0 | ||
# file /kinit usr/kinit/kinit 0755 0 0 | ||
# slink /init kinit 0755 0 0 | ||
EOF | ||
} | ||
|
||
|
@@ -42,18 +75,28 @@ filetype() { | |
return 0 | ||
} | ||
|
||
list_print_mtime() { | ||
: | ||
} | ||
|
||
print_mtime() { | ||
local argv1="$1" | ||
local my_mtime="0" | ||
|
||
if [ -e "${argv1}" ]; then | ||
my_mtime=$(find "${argv1}" -printf "%T@\n" | sort -r | head -n 1) | ||
if [ -e "$1" ]; then | ||
my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1) | ||
fi | ||
|
||
echo "# Last modified: ${my_mtime}" | ||
echo | ||
|
||
echo "# Last modified: ${my_mtime}" >> ${output} | ||
echo "" >> ${output} | ||
} | ||
|
||
list_parse() { | ||
echo "$1 \\" | ||
} | ||
|
||
# for each file print a line in following format | ||
# <filetype> <name> <path to file> <octal mode> <uid> <gid> | ||
# for links, devices etc the format differs. See gen_init_cpio for details | ||
parse() { | ||
local location="$1" | ||
local name="${location/${srcdir}//}" | ||
|
@@ -99,80 +142,112 @@ parse() { | |
;; | ||
esac | ||
|
||
echo "${str}" | ||
echo "${str}" >> ${output} | ||
|
||
return 0 | ||
} | ||
|
||
usage() { | ||
printf "Usage:\n" | ||
printf "$0 [ [-u <root_uid>] [-g <root_gid>] [-d | <cpio_source>] ] . . .\n" | ||
printf "\n" | ||
printf -- "-u <root_uid> User ID to map to user ID 0 (root).\n" | ||
printf " <root_uid> is only meaningful if <cpio_source>\n" | ||
printf " is a directory.\n" | ||
printf -- "-g <root_gid> Group ID to map to group ID 0 (root).\n" | ||
printf " <root_gid> is only meaningful if <cpio_source>\n" | ||
printf " is a directory.\n" | ||
printf "<cpio_source> File list or directory for cpio archive.\n" | ||
printf " If <cpio_source> is not provided then a\n" | ||
printf " a default list will be output.\n" | ||
printf -- "-d Output the default cpio list. If no <cpio_source>\n" | ||
printf " is given then the default cpio list will be output.\n" | ||
printf "\n" | ||
printf "All options may be repeated and are interpreted sequentially\n" | ||
printf "and immediately. -u and -g states are preserved across\n" | ||
printf "<cpio_source> options so an explicit \"-u 0 -g 0\" is required\n" | ||
printf "to reset the root/group mapping.\n" | ||
unknown_option() { | ||
printf "ERROR: unknown option \"$arg\"\n" >&2 | ||
printf "If the filename validly begins with '-', " >&2 | ||
printf "then it must be prefixed\n" >&2 | ||
printf "by './' so that it won't be interpreted as an option." >&2 | ||
printf "\n" >&2 | ||
usage >&2 | ||
exit 1 | ||
} | ||
|
||
list_header() { | ||
echo "deps_initramfs := \\" | ||
} | ||
|
||
header() { | ||
printf "\n#####################\n# $1\n" >> ${output} | ||
} | ||
|
||
# process one directory (incl sub-directories) | ||
dir_filelist() { | ||
${dep_list}header "$1" | ||
|
||
srcdir=$(echo "$1" | sed -e 's://*:/:g') | ||
dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) | ||
|
||
# If $dirlist is only one line, then the directory is empty | ||
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then | ||
${dep_list}print_mtime "$1" | ||
|
||
echo "${dirlist}" | \ | ||
while read x; do | ||
${dep_list}parse ${x} | ||
done | ||
fi | ||
} | ||
|
||
build_list() { | ||
printf "\n#####################\n# $cpio_source\n" | ||
|
||
if [ -f "$cpio_source" ]; then | ||
print_mtime "$cpio_source" | ||
cat "$cpio_source" | ||
elif [ -d "$cpio_source" ]; then | ||
srcdir=$(echo "$cpio_source" | sed -e 's://*:/:g') | ||
dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null) | ||
|
||
# If $dirlist is only one line, then the directory is empty | ||
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then | ||
print_mtime "$cpio_source" | ||
|
||
echo "${dirlist}" | \ | ||
while read x; do | ||
parse ${x} | ||
done | ||
# if only one file is specified and it is .cpio file then use it direct as fs | ||
# if a directory is specified then add all files in given direcotry to fs | ||
# if a regular file is specified assume it is in gen_initramfs format | ||
input_file() { | ||
source="$1" | ||
if [ -f "$1" ]; then | ||
${dep_list}header "$1" | ||
is_cpio="$(echo "$1" | sed 's/^.*\.cpio/cpio/')" | ||
if [ $2 -eq 0 -a ${is_cpio} == "cpio" ]; then | ||
cpio_file=$1 | ||
[ ! -z ${dep_list} ] && echo "$1" | ||
return 0 | ||
fi | ||
if [ -z ${dep_list} ]; then | ||
print_mtime "$1" >> ${output} | ||
cat "$1" >> ${output} | ||
else | ||
# Failsafe in case directory is empty | ||
default_initramfs | ||
grep ^file "$1" | cut -d ' ' -f 3 | ||
fi | ||
elif [ -d "$1" ]; then | ||
dir_filelist "$1" | ||
else | ||
echo " $0: Cannot open '$cpio_source'" >&2 | ||
echo " ${prog}: Cannot open '$1'" >&2 | ||
exit 1 | ||
fi | ||
} | ||
|
||
|
||
prog=$0 | ||
root_uid=0 | ||
root_gid=0 | ||
dep_list= | ||
cpio_file= | ||
cpio_list= | ||
output="/dev/stdout" | ||
output_file="" | ||
|
||
arg="$1" | ||
case "$arg" in | ||
"-l") # files included in initramfs - used by kbuild | ||
dep_list="list_" | ||
shift | ||
;; | ||
"-o") # generate gzipped cpio image named $1 | ||
shift | ||
output_file="$1" | ||
cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)" | ||
output=${cpio_list} | ||
shift | ||
;; | ||
esac | ||
while [ $# -gt 0 ]; do | ||
arg="$1" | ||
shift | ||
case "$arg" in | ||
"-u") | ||
"-u") # map $1 to uid=0 (root) | ||
root_uid="$1" | ||
shift | ||
;; | ||
"-g") | ||
"-g") # map $1 to gid=0 (root) | ||
root_gid="$1" | ||
shift | ||
;; | ||
"-d") | ||
"-d") # display default initramfs list | ||
default_list="$arg" | ||
default_initramfs | ||
${dep_list}default_initramfs | ||
;; | ||
"-h") | ||
usage | ||
|
@@ -181,23 +256,27 @@ while [ $# -gt 0 ]; do | |
*) | ||
case "$arg" in | ||
"-"*) | ||
printf "ERROR: unknown option \"$arg\"\n" >&2 | ||
printf "If the filename validly begins with '-', then it must be prefixed\n" >&2 | ||
printf "by './' so that it won't be interpreted as an option." >&2 | ||
printf "\n" >&2 | ||
usage >&2 | ||
exit 1 | ||
unknown_option | ||
;; | ||
*) | ||
cpio_source="$arg" | ||
build_list | ||
*) # input file/dir - process it | ||
input_file "$arg" "$#" | ||
;; | ||
esac | ||
;; | ||
esac | ||
done | ||
|
||
# spit out the default cpio list if a source hasn't been specified | ||
[ -z "$cpio_source" -a -z "$default_list" ] && default_initramfs | ||
|
||
# If output_file is set we will generate cpio archive and gzip it | ||
# we are carefull to delete tmp files | ||
if [ ! -z ${output_file} ]; then | ||
if [ -z ${cpio_file} ]; then | ||
cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)" | ||
usr/gen_init_cpio ${cpio_list} > ${cpio_tfile} | ||
else | ||
cpio_tfile=${cpio_file} | ||
fi | ||
rm ${cpio_list} | ||
cat ${cpio_tfile} | gzip -f -9 - > ${output_file} | ||
[ -z ${cpio_file} ] && rm ${cpio_tfile} | ||
fi | ||
exit 0 |
Oops, something went wrong.