2011-04-05 15:06:16

by Michal Marek

[permalink] [raw]
Subject: [PATCH 08/34] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries

gen_init_cpio uses the current time for symlinks, special files and
directories. Make it possible to override this with the
KBUILD_BUILD_TIMESTAMP variable for reproducible builds.

Signed-off-by: Michal Marek <[email protected]>
---
scripts/gen_initramfs_list.sh | 4 ++++
usr/gen_init_cpio.c | 17 +++++++++++------
2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 4a43fe1..18cde32 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -283,6 +283,10 @@ while [ $# -gt 0 ]; do
esac
done

+if test -n "$KBUILD_BUILD_TIMESTAMP"; then
+ export CPIO_TIMESTAMP=$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s)
+fi
+
# If output_file is set we will generate cpio archive and compress it
# we are carefull to delete tmp files
if [ ! -z ${output_file} ]; then
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 7f06884..11f604d 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -22,6 +22,7 @@

static unsigned int offset;
static unsigned int ino = 721;
+static time_t default_mtime;

struct file_handler {
const char *type;
@@ -102,7 +103,6 @@ static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);

if (name[0] == '/')
name++;
@@ -114,7 +114,7 @@ static int cpio_mkslink(const char *name, const char *target,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
(unsigned)strlen(target)+1, /* filesize */
3, /* major */
1, /* minor */
@@ -152,7 +152,6 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);

if (name[0] == '/')
name++;
@@ -164,7 +163,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
2, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -242,7 +241,6 @@ static int cpio_mknod(const char *name, unsigned int mode,
unsigned int maj, unsigned int min)
{
char s[256];
- time_t mtime = time(NULL);

if (dev_type == 'b')
mode |= S_IFBLK;
@@ -259,7 +257,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -529,6 +527,7 @@ int main (int argc, char *argv[])
char *args, *type;
int ec = 0;
int line_nr = 0;
+ const char *env;

if (2 != argc) {
usage(argv[0]);
@@ -544,6 +543,12 @@ int main (int argc, char *argv[])
exit(1);
}

+ env = getenv("CPIO_TIMESTAMP");
+ if (env)
+ default_mtime = atol(env);
+ if (!default_mtime)
+ default_mtime = time(NULL);
+
while (fgets(line, LINE_SIZE, cpio_list)) {
int type_idx;
size_t slen = strlen(line);
--
1.7.4.1


2011-04-05 17:32:00

by Milton Miller

[permalink] [raw]
Subject: Re: [08/34] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries

On Tue, 05 Apr 2011 about 14:58:55 -0000, Michal Marek wrote:
>
> gen_init_cpio uses the current time for symlinks, special files and
> directories.

gen_init_cpio gets the current time and uses it for each symlink,
special file, and directory.

Grab the current time once, and ...

> Make it possible to override this with the
(s/this/it/)
> KBUILD_BUILD_TIMESTAMP variable for reproducible builds.
>
> Signed-off-by: Michal Marek <[email protected]>
>
> ---
> scripts/gen_initramfs_list.sh | 4 ++++
> usr/gen_init_cpio.c | 17 +++++++++++------
> 2 files changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
snip
> diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
> index 7f06884..11f604d 100644
> --- a/usr/gen_init_cpio.c
> +++ b/usr/gen_init_cpio.c
snip
> @@ -529,6 +527,7 @@ int main (int argc, char *argv[])
> char *args, *type;
> int ec = 0;
> int line_nr = 0;
> + const char *env;
>
> if (2 != argc) {
> usage(argv[0]);
> @@ -544,6 +543,12 @@ int main (int argc, char *argv[])
> exit(1);
> }
>
> + env = getenv("CPIO_TIMESTAMP");
> + if (env)
> + default_mtime = atol(env);
> + if (!default_mtime)
> + default_mtime = time(NULL);
> +

Please pass it via an explicit flag in argv instead of magic env variables.

The other current use of the environment (the expansion of variables
in the location name) is via explicit reference in the input file.

Also, please use strol and check that the whole string is consumed.

milton

2011-04-05 18:12:20

by Michal Marek

[permalink] [raw]
Subject: Re: [08/34] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries

Dne 5.4.2011 19:31, Milton Miller napsal(a):
> On Tue, 05 Apr 2011 about 14:58:55 -0000, Michal Marek wrote:
>>
>> gen_init_cpio uses the current time for symlinks, special files and
>> directories.
>
> gen_init_cpio gets the current time and uses it for each symlink,
> special file, and directory.
>
> Grab the current time once, and ...
>
>> Make it possible to override this with the
> (s/this/it/)
>> KBUILD_BUILD_TIMESTAMP variable for reproducible builds.
>>
...
>> + env = getenv("CPIO_TIMESTAMP");
>> + if (env)
>> + default_mtime = atol(env);
>> + if (!default_mtime)
>> + default_mtime = time(NULL);
>> +
>
> Please pass it via an explicit flag in argv instead of magic env variables.
>
> The other current use of the environment (the expansion of variables
> in the location name) is via explicit reference in the input file.
>
> Also, please use strol and check that the whole string is consumed.

Yeah, I was too lazy. I'll do it properly in v2.

Thanks for the review.

Michal

2011-04-11 15:06:47

by Michal Marek

[permalink] [raw]
Subject: [PATCH v2] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries

gen_init_cpio gets the current time and uses it for each symlink,
special file, and directory. Grab the current time once and make it
possible to override it with the KBUILD_BUILD_TIMESTAMP variable for
reproducible builds.

Signed-off-by: Michal Marek <[email protected]>
---
Documentation/kbuild/kbuild.txt | 3 +-
scripts/gen_initramfs_list.sh | 9 ++++++-
usr/gen_init_cpio.c | 53 +++++++++++++++++++++++++++++---------
3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt
index 27d7928..46e6cb8 100644
--- a/Documentation/kbuild/kbuild.txt
+++ b/Documentation/kbuild/kbuild.txt
@@ -200,7 +200,8 @@ To get all available archs you can also specify all. E.g.:
KBUILD_BUILD_TIMESTAMP
--------------------------------------------------
Setting this to a date string overrides the timestamp used in the
-UTS_VERSION definition (uname -v in the running kernel). The default value
+UTS_VERSION definition (uname -v in the running kernel). The value has to
+be a string that can be passed to date -d. The default value
is the output of the date command at one point during build.

KBUILD_BUILD_USER, KBUILD_BUILD_HOST
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 4a43fe1..d44cf67 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -287,8 +287,15 @@ done
# we are carefull to delete tmp files
if [ ! -z ${output_file} ]; then
if [ -z ${cpio_file} ]; then
+ timestamp=
+ if test -n "$KBUILD_BUILD_TIMESTAMP"; then
+ timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
+ if test -n "$timestamp"; then
+ timestamp="-t $timestamp"
+ fi
+ fi
cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
- usr/gen_init_cpio ${cpio_list} > ${cpio_tfile}
+ usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
else
cpio_tfile=${cpio_file}
fi
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 7f06884..af0f22f 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -22,6 +22,7 @@

static unsigned int offset;
static unsigned int ino = 721;
+static time_t default_mtime;

struct file_handler {
const char *type;
@@ -102,7 +103,6 @@ static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);

if (name[0] == '/')
name++;
@@ -114,7 +114,7 @@ static int cpio_mkslink(const char *name, const char *target,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
(unsigned)strlen(target)+1, /* filesize */
3, /* major */
1, /* minor */
@@ -152,7 +152,6 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
char s[256];
- time_t mtime = time(NULL);

if (name[0] == '/')
name++;
@@ -164,7 +163,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
2, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -242,7 +241,6 @@ static int cpio_mknod(const char *name, unsigned int mode,
unsigned int maj, unsigned int min)
{
char s[256];
- time_t mtime = time(NULL);

if (dev_type == 'b')
mode |= S_IFBLK;
@@ -259,7 +257,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
(long) uid, /* uid */
(long) gid, /* gid */
1, /* nlink */
- (long) mtime, /* mtime */
+ (long) default_mtime, /* mtime */
0, /* filesize */
3, /* major */
1, /* minor */
@@ -460,7 +458,7 @@ static int cpio_mkfile_line(const char *line)
static void usage(const char *prog)
{
fprintf(stderr, "Usage:\n"
- "\t%s <cpio_list>\n"
+ "\t%s [-t <timestamp>] <cpio_list>\n"
"\n"
"<cpio_list> is a file containing newline separated entries that\n"
"describe the files to be included in the initramfs archive:\n"
@@ -491,7 +489,11 @@ static void usage(const char *prog)
"nod /dev/console 0600 0 0 c 5 1\n"
"dir /root 0700 0 0\n"
"dir /sbin 0755 0 0\n"
- "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
+ "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n"
+ "\n"
+ "<timestamp> is time in seconds since Epoch that will be used\n"
+ "as mtime for symlinks, special files and directories. The default\n"
+ "is to use the current time for these entries.\n",
prog);
}

@@ -529,17 +531,42 @@ int main (int argc, char *argv[])
char *args, *type;
int ec = 0;
int line_nr = 0;
+ const char *filename;
+
+ default_mtime = time(NULL);
+ while (1) {
+ int opt = getopt(argc, argv, "t:h");
+ char *invalid;

- if (2 != argc) {
+ if (opt == -1)
+ break;
+ switch (opt) {
+ case 't':
+ default_mtime = strtol(optarg, &invalid, 10);
+ if (!*optarg || *invalid) {
+ fprintf(stderr, "Invalid timestamp: %s\n",
+ optarg);
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ exit(opt == 'h' ? 0 : 1);
+ }
+ }
+
+ if (argc - optind != 1) {
usage(argv[0]);
exit(1);
}
-
- if (!strcmp(argv[1], "-"))
+ filename = argv[optind];
+ if (!strcmp(filename, "-"))
cpio_list = stdin;
- else if (! (cpio_list = fopen(argv[1], "r"))) {
+ else if (!(cpio_list = fopen(filename, "r"))) {
fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
- argv[1], strerror(errno));
+ filename, strerror(errno));
usage(argv[0]);
exit(1);
}
--
1.7.4.1

2011-04-18 13:06:24

by Michal Marek

[permalink] [raw]
Subject: Re: [PATCH v2] initramfs: Use KBUILD_BUILD_TIMESTAMP for generated entries

On Mon, Apr 11, 2011 at 05:06:22PM +0200, Michal Marek wrote:
> gen_init_cpio gets the current time and uses it for each symlink,
> special file, and directory. Grab the current time once and make it
> possible to override it with the KBUILD_BUILD_TIMESTAMP variable for
> reproducible builds.
>
> Signed-off-by: Michal Marek <[email protected]>
> ---
> Documentation/kbuild/kbuild.txt | 3 +-
> scripts/gen_initramfs_list.sh | 9 ++++++-
> usr/gen_init_cpio.c | 53 +++++++++++++++++++++++++++++---------
> 3 files changed, 50 insertions(+), 15 deletions(-)

Pushed to kbuild-2.6.git#kbuild.

Michal