Re: 2.6.9-rc4-mm1: initramfs build fix [u]

From: Martin Schlemmer [c]
Date: Mon Oct 18 2004 - 14:40:14 EST


On Sun, 2004-10-17 at 22:12 +0200, Martin Schlemmer wrote:
> On Sun, 2004-10-17 at 23:33 +0200, Sam Ravnborg wrote:
>
> Hiya,
>
> >
> > Can you submit a new version based on Linus' tree with the following modifications:
>
> It depends on gen_init_cpio-uses-external-file-list.patch from -mm, so
> cannot until that is merged.
>
> > 1) Propoer changelog
>
> Should be with the other thread I guess.
>
> > 2) Document use of .shipped somewhere
> >
>
> If I remember correctly, Andrew asked Thayne Harbaugh to add docs for
> the list format, etc. I will thus have to wait for those to do changes
> brought by my patch.
>
> > And the following small comments.
> >
> >
> > > # or set INITRAMFS_LIST to another filename.
> > > -INITRAMFS_LIST ?= $(obj)/initramfs_list
> > > +INITRAMFS_LIST := $(obj)/initramfs_list
> >
> > Kbuild style is to reser all-uppercase to external visible variables.
> >
>
> Ok, so we need that in smaller caps.
>
> > > # initramfs_data.o contains the initramfs_data.cpio.gz image.
> > > # The image is included using .incbin, a dependency which is not
> > > @@ -23,6 +23,23 @@ $(obj)/initramfs_data.o: $(obj)/initramf
> > > # Commented out for now
> > > # initramfs-y := $(obj)/root/hello
> > >
> > > +quiet_cmd_gen_list = GEN_INITRAMFS_LIST $@
> > Please aling output properly with rest of kbuild output.
> > > +quiet_cmd_gen_list = GEN $@
> > Should be enough - the filename give some context as well
> >
>
> Right, thanks. I did change it at some time (second only being GEN),
> but I guess I missed the first.
>
> > > + cmd_gen_list = $(shell \
> > > + if test -f "$(CONFIG_INITRAMFS_SOURCE)"; then \
> > > + if [ "$(CONFIG_INITRAMFS_SOURCE)" != $@ ]; then \
> > > + echo 'cp -f "$(CONFIG_INITRAMFS_SOURCE)" $@'; \
> > > + else \
> > > + echo 'cp -f "$(srctree)/$(INITRAMFS_LIST).shipped" $@'; \
> > Test for .shipped to be present first?
> >
>
> This needed even though its supposed to be there? How should one handle
> the event that its not .. just 'exit 1' ?
>
> >
> > > + fi; \
> > > + elif test -d "$(CONFIG_INITRAMFS_SOURCE)"; then \
> > > + echo 'scripts/gen_initramfs_list.sh "$(CONFIG_INITRAMFS_SOURCE)" > $@'; \
> > > + else \
> > > + echo 'cp -f "$(srctree)/$(INITRAMFS_LIST).shipped" $@'; \
> > Same here.
> >
> > > + fi)
> > > +
> > > +$(INITRAMFS_LIST): FORCE
> > > + $(call cmd,gen_list)
> >
> > How do you secure that the list gets updated when some of the above logic changes?
>
> Currently it will error if one of the commands called fails - is there a
> more preferred error handling method?
>
> > Likewise avoid the list to be generated unles required.
> >
>
> Simply checking mtime should do?
>
>

How about this one:

diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/drivers/block/Kconfig linux-2.6.9-rc4-mm1/drivers/block/Kconfig
--- linux-2.6.9-rc4-mm1.orig/drivers/block/Kconfig 2004-10-18 21:20:06.885571688 +0200
+++ linux-2.6.9-rc4-mm1/drivers/block/Kconfig 2004-10-17 16:58:35.000000000 +0200
@@ -348,6 +348,32 @@ config BLK_DEV_INITRD
"real" root file system, etc. See <file:Documentation/initrd.txt>
for details.

+config INITRAMFS_SOURCE
+ string "Source directory of cpio_list"
+ default ""
+ help
+ This can be set to either a directory containing files, etc to be
+ included in the initramfs archive, or a file containing newline
+ separated entries.
+
+ If it is a file, it should be in the following format:
+ # a comment
+ file <name> <location> <mode> <uid> <gid>
+ dir <name> <mode> <uid> <gid>
+ nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
+
+ Where:
+ <name> name of the file/dir/nod in the archive
+ <location> location of the file in the current filesystem
+ <mode> mode/permissions of the file
+ <uid> user id (0=root)
+ <gid> group id (0=root)
+ <dev_type> device type (b=block, c=character)
+ <maj> major number of nod
+ <min> minor number of nod
+
+ If you are not sure, leave it blank.
+
config LBD
bool "Support for Large Block Devices"
depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/scripts/gen_initramfs_list.sh linux-2.6.9-rc4-mm1/scripts/gen_initramfs_list.sh
--- linux-2.6.9-rc4-mm1.orig/scripts/gen_initramfs_list.sh 1970-01-01 02:00:00.000000000 +0200
+++ linux-2.6.9-rc4-mm1/scripts/gen_initramfs_list.sh 2004-10-18 20:02:09.000000000 +0200
@@ -0,0 +1,98 @@
+#!/bin/bash
+# Copyright (C) Martin Schlemmer <azarah@xxxxxxxxxxxxxxxx>
+# Released under the terms of the GNU GPL
+#
+# A script to generate newline separated entries (to stdout) from a directory's
+# contents suitable for use as a cpio_list for gen_init_cpio.
+#
+# Arguements: $1 -- the source directory
+#
+# TODO: Add support for symlinks, sockets and pipes when gen_init_cpio
+# supports them.
+
+usage() {
+ echo "Usage: $0 initramfs-source-dir"
+ exit 1
+}
+
+srcdir=$(echo "$1" | sed -e 's://*:/:g')
+
+if [ "$#" -gt 1 -o ! -d "${srcdir}" ]; then
+ usage
+fi
+
+filetype() {
+ local argv1="$1"
+
+ if [ -f "${argv1}" ]; then
+ echo "file"
+ elif [ -d "${argv1}" ]; then
+ echo "dir"
+ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
+ echo "nod"
+ else
+ echo "invalid"
+ fi
+ return 0
+}
+
+parse() {
+ local location="$1"
+ local name="${location/${srcdir}//}"
+ local mode="$2"
+ local uid="$3"
+ local gid="$4"
+ local ftype=$(filetype "${location}")
+ local str="${mode} ${uid} ${gid}"
+
+ [ "${ftype}" == "invalid" ] && return 0
+ [ "${location}" == "${srcdir}" ] && return 0
+
+ case "${ftype}" in
+ "file")
+ str="${ftype} ${name} ${location} ${str}"
+ ;;
+ "nod")
+ local dev_type=
+ local maj=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{sub(/,/, "", $5); print $5}')
+ local min=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{print $6}')
+
+ if [ -b "${location}" ]; then
+ dev_type="b"
+ else
+ dev_type="c"
+ fi
+ str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
+ ;;
+ *)
+ str="${ftype} ${name} ${str}"
+ ;;
+ esac
+
+ echo "${str}"
+
+ return 0
+}
+
+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
+ echo "${dirlist}" | \
+ while read x; do
+ parse ${x}
+ done
+else
+ # Failsafe in case directory is empty
+ cat <<-EOF
+ # This is a very simple initramfs
+
+ dir /dev 0755 0 0
+ nod /dev/console 0600 0 0 c 5 1
+ dir /root 0700 0 0
+ EOF
+fi
+
+exit 0
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/Makefile linux-2.6.9-rc4-mm1/usr/Makefile
--- linux-2.6.9-rc4-mm1.orig/usr/Makefile 2004-10-18 21:20:06.886571536 +0200
+++ linux-2.6.9-rc4-mm1/usr/Makefile 2004-10-18 21:02:35.722372784 +0200
@@ -6,9 +6,11 @@ hostprogs-y := gen_init_cpio
clean-files := initramfs_data.cpio.gz

# If you want a different list of files in the initramfs_data.cpio
-# then you can either overwrite the cpio_list in this directory
-# or set INITRAMFS_LIST to another filename.
-INITRAMFS_LIST ?= $(obj)/initramfs_list
+# then you can either overwrite initramfs_list.shipped in this directory
+# or set CONFIG_INITRAMFS_SOURCE to another filename or directory.
+initramfs_list := initramfs_list
+
+clean-files += $(initramfs_list)

# initramfs_data.o contains the initramfs_data.cpio.gz image.
# The image is included using .incbin, a dependency which is not
@@ -23,10 +25,43 @@ $(obj)/initramfs_data.o: $(obj)/initramf
# Commented out for now
# initramfs-y := $(obj)/root/hello

+# This should only return a command if there was no error
+quiet_cmd_gen_list = GEN $@
+ cmd_gen_list = $(shell \
+ if [ -d $(CONFIG_INITRAMFS_SOURCE) ]; then \
+ tmplist="`find $(CONFIG_INITRAMFS_SOURCE) -newer $@ 2>/dev/null`"; \
+ if [ ! -f $@ -o "x${tmplist}" != x ]; then \
+ echo '$(CONFIG_SHELL) scripts/gen_initramfs_list.sh \
+ $(CONFIG_INITRAMFS_SOURCE) > $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ else \
+ if [ -f $(CONFIG_INITRAMFS_SOURCE) -a $(CONFIG_INITRAMFS_SOURCE) != $@ ]; then \
+ if [ ! -f $@ -o $(CONFIG_INITRAMFS_SOURCE) -nt $@ ]; then \
+ echo 'cp -f $(CONFIG_INITRAMFS_SOURCE) $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ else \
+ if [ -f $(srctree)/$(src)/$(initramfs_list).shipped ]; then \
+ if [ ! -f $@ -o $(srctree)/$(src)/$(initramfs_list).shipped -nt $@ ]; then \
+ echo 'cp -f $(srctree)/$(src)/$(initramfs_list).shipped $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ fi \
+ fi \
+ fi)
+
+$(obj)/$(initramfs_list): FORCE
+ $(if $(cmd_gen_list), $(call cmd,gen_list), \
+ error file "$(src)/$(initramfs_list).shipped" does not exist)
+
quiet_cmd_cpio = CPIO $@
- cmd_cpio = ./$< $(INITRAMFS_LIST) > $@
+ cmd_cpio = ./$< $(obj)/$(initramfs_list) > $@

-$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(INITRAMFS_LIST) FORCE
+$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(obj)/$(initramfs_list) FORCE
$(call if_changed,cpio)

targets += initramfs_data.cpio
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/initramfs_list linux-2.6.9-rc4-mm1/usr/initramfs_list
--- linux-2.6.9-rc4-mm1.orig/usr/initramfs_list 2004-10-18 21:20:06.974558160 +0200
+++ linux-2.6.9-rc4-mm1/usr/initramfs_list 1970-01-01 02:00:00.000000000 +0200
@@ -1,5 +0,0 @@
-# This is a very simple initramfs - mostly preliminary for future expansion
-
-dir /dev 0755 0 0
-nod /dev/console 0600 0 0 c 5 1
-dir /root 0700 0 0
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/initramfs_list.shipped linux-2.6.9-rc4-mm1/usr/initramfs_list.shipped
--- linux-2.6.9-rc4-mm1.orig/usr/initramfs_list.shipped 1970-01-01 02:00:00.000000000 +0200
+++ linux-2.6.9-rc4-mm1/usr/initramfs_list.shipped 2004-10-18 21:20:50.866885512 +0200
@@ -0,0 +1,5 @@
+# This is a very simple initramfs - mostly preliminary for future expansion
+
+dir /dev 0755 0 0
+nod /dev/console 0600 0 0 c 5 1
+dir /root 0700 0 0

--
Martin Schlemmer

diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/drivers/block/Kconfig linux-2.6.9-rc4-mm1/drivers/block/Kconfig
--- linux-2.6.9-rc4-mm1.orig/drivers/block/Kconfig 2004-10-18 21:20:06.885571688 +0200
+++ linux-2.6.9-rc4-mm1/drivers/block/Kconfig 2004-10-17 16:58:35.000000000 +0200
@@ -348,6 +348,32 @@ config BLK_DEV_INITRD
"real" root file system, etc. See <file:Documentation/initrd.txt>
for details.

+config INITRAMFS_SOURCE
+ string "Source directory of cpio_list"
+ default ""
+ help
+ This can be set to either a directory containing files, etc to be
+ included in the initramfs archive, or a file containing newline
+ separated entries.
+
+ If it is a file, it should be in the following format:
+ # a comment
+ file <name> <location> <mode> <uid> <gid>
+ dir <name> <mode> <uid> <gid>
+ nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
+
+ Where:
+ <name> name of the file/dir/nod in the archive
+ <location> location of the file in the current filesystem
+ <mode> mode/permissions of the file
+ <uid> user id (0=root)
+ <gid> group id (0=root)
+ <dev_type> device type (b=block, c=character)
+ <maj> major number of nod
+ <min> minor number of nod
+
+ If you are not sure, leave it blank.
+
config LBD
bool "Support for Large Block Devices"
depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/scripts/gen_initramfs_list.sh linux-2.6.9-rc4-mm1/scripts/gen_initramfs_list.sh
--- linux-2.6.9-rc4-mm1.orig/scripts/gen_initramfs_list.sh 1970-01-01 02:00:00.000000000 +0200
+++ linux-2.6.9-rc4-mm1/scripts/gen_initramfs_list.sh 2004-10-18 20:02:09.000000000 +0200
@@ -0,0 +1,98 @@
+#!/bin/bash
+# Copyright (C) Martin Schlemmer <azarah@xxxxxxxxxxxxxxxx>
+# Released under the terms of the GNU GPL
+#
+# A script to generate newline separated entries (to stdout) from a directory's
+# contents suitable for use as a cpio_list for gen_init_cpio.
+#
+# Arguements: $1 -- the source directory
+#
+# TODO: Add support for symlinks, sockets and pipes when gen_init_cpio
+# supports them.
+
+usage() {
+ echo "Usage: $0 initramfs-source-dir"
+ exit 1
+}
+
+srcdir=$(echo "$1" | sed -e 's://*:/:g')
+
+if [ "$#" -gt 1 -o ! -d "${srcdir}" ]; then
+ usage
+fi
+
+filetype() {
+ local argv1="$1"
+
+ if [ -f "${argv1}" ]; then
+ echo "file"
+ elif [ -d "${argv1}" ]; then
+ echo "dir"
+ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
+ echo "nod"
+ else
+ echo "invalid"
+ fi
+ return 0
+}
+
+parse() {
+ local location="$1"
+ local name="${location/${srcdir}//}"
+ local mode="$2"
+ local uid="$3"
+ local gid="$4"
+ local ftype=$(filetype "${location}")
+ local str="${mode} ${uid} ${gid}"
+
+ [ "${ftype}" == "invalid" ] && return 0
+ [ "${location}" == "${srcdir}" ] && return 0
+
+ case "${ftype}" in
+ "file")
+ str="${ftype} ${name} ${location} ${str}"
+ ;;
+ "nod")
+ local dev_type=
+ local maj=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{sub(/,/, "", $5); print $5}')
+ local min=$(LC_ALL=C ls -l "${location}" | \
+ gawk '{print $6}')
+
+ if [ -b "${location}" ]; then
+ dev_type="b"
+ else
+ dev_type="c"
+ fi
+ str="${ftype} ${name} ${str} ${dev_type} ${maj} ${min}"
+ ;;
+ *)
+ str="${ftype} ${name} ${str}"
+ ;;
+ esac
+
+ echo "${str}"
+
+ return 0
+}
+
+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
+ echo "${dirlist}" | \
+ while read x; do
+ parse ${x}
+ done
+else
+ # Failsafe in case directory is empty
+ cat <<-EOF
+ # This is a very simple initramfs
+
+ dir /dev 0755 0 0
+ nod /dev/console 0600 0 0 c 5 1
+ dir /root 0700 0 0
+ EOF
+fi
+
+exit 0
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/Makefile linux-2.6.9-rc4-mm1/usr/Makefile
--- linux-2.6.9-rc4-mm1.orig/usr/Makefile 2004-10-18 21:20:06.886571536 +0200
+++ linux-2.6.9-rc4-mm1/usr/Makefile 2004-10-18 21:02:35.722372784 +0200
@@ -6,9 +6,11 @@ hostprogs-y := gen_init_cpio
clean-files := initramfs_data.cpio.gz

# If you want a different list of files in the initramfs_data.cpio
-# then you can either overwrite the cpio_list in this directory
-# or set INITRAMFS_LIST to another filename.
-INITRAMFS_LIST ?= $(obj)/initramfs_list
+# then you can either overwrite initramfs_list.shipped in this directory
+# or set CONFIG_INITRAMFS_SOURCE to another filename or directory.
+initramfs_list := initramfs_list
+
+clean-files += $(initramfs_list)

# initramfs_data.o contains the initramfs_data.cpio.gz image.
# The image is included using .incbin, a dependency which is not
@@ -23,10 +25,43 @@ $(obj)/initramfs_data.o: $(obj)/initramf
# Commented out for now
# initramfs-y := $(obj)/root/hello

+# This should only return a command if there was no error
+quiet_cmd_gen_list = GEN $@
+ cmd_gen_list = $(shell \
+ if [ -d $(CONFIG_INITRAMFS_SOURCE) ]; then \
+ tmplist="`find $(CONFIG_INITRAMFS_SOURCE) -newer $@ 2>/dev/null`"; \
+ if [ ! -f $@ -o "x${tmplist}" != x ]; then \
+ echo '$(CONFIG_SHELL) scripts/gen_initramfs_list.sh \
+ $(CONFIG_INITRAMFS_SOURCE) > $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ else \
+ if [ -f $(CONFIG_INITRAMFS_SOURCE) -a $(CONFIG_INITRAMFS_SOURCE) != $@ ]; then \
+ if [ ! -f $@ -o $(CONFIG_INITRAMFS_SOURCE) -nt $@ ]; then \
+ echo 'cp -f $(CONFIG_INITRAMFS_SOURCE) $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ else \
+ if [ -f $(srctree)/$(src)/$(initramfs_list).shipped ]; then \
+ if [ ! -f $@ -o $(srctree)/$(src)/$(initramfs_list).shipped -nt $@ ]; then \
+ echo 'cp -f $(srctree)/$(src)/$(initramfs_list).shipped $@'; \
+ else \
+ echo '/bin/true'; \
+ fi \
+ fi \
+ fi \
+ fi)
+
+$(obj)/$(initramfs_list): FORCE
+ $(if $(cmd_gen_list), $(call cmd,gen_list), \
+ error file "$(src)/$(initramfs_list).shipped" does not exist)
+
quiet_cmd_cpio = CPIO $@
- cmd_cpio = ./$< $(INITRAMFS_LIST) > $@
+ cmd_cpio = ./$< $(obj)/$(initramfs_list) > $@

-$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(INITRAMFS_LIST) FORCE
+$(obj)/initramfs_data.cpio: $(obj)/gen_init_cpio $(initramfs-y) $(obj)/$(initramfs_list) FORCE
$(call if_changed,cpio)

targets += initramfs_data.cpio
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/initramfs_list linux-2.6.9-rc4-mm1/usr/initramfs_list
--- linux-2.6.9-rc4-mm1.orig/usr/initramfs_list 2004-10-18 21:20:06.974558160 +0200
+++ linux-2.6.9-rc4-mm1/usr/initramfs_list 1970-01-01 02:00:00.000000000 +0200
@@ -1,5 +0,0 @@
-# This is a very simple initramfs - mostly preliminary for future expansion
-
-dir /dev 0755 0 0
-nod /dev/console 0600 0 0 c 5 1
-dir /root 0700 0 0
diff -uprN -X dontdiff linux-2.6.9-rc4-mm1.orig/usr/initramfs_list.shipped linux-2.6.9-rc4-mm1/usr/initramfs_list.shipped
--- linux-2.6.9-rc4-mm1.orig/usr/initramfs_list.shipped 1970-01-01 02:00:00.000000000 +0200
+++ linux-2.6.9-rc4-mm1/usr/initramfs_list.shipped 2004-10-18 21:20:50.866885512 +0200
@@ -0,0 +1,5 @@
+# This is a very simple initramfs - mostly preliminary for future expansion
+
+dir /dev 0755 0 0
+nod /dev/console 0600 0 0 c 5 1
+dir /root 0700 0 0

Attachment: signature.asc
Description: This is a digitally signed message part