Skip to content

Commit a8b8017

Browse files
committed
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]>
1 parent 53e6892 commit a8b8017

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

Documentation/kbuild/kbuild.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ gcc -W... options for more extensive build-time checking.
205205
KBUILD_BUILD_TIMESTAMP
206206
--------------------------------------------------
207207
Setting this to a date string overrides the timestamp used in the
208-
UTS_VERSION definition (uname -v in the running kernel). The default value
208+
UTS_VERSION definition (uname -v in the running kernel). The value has to
209+
be a string that can be passed to date -d. The default value
209210
is the output of the date command at one point during build.
210211

211212
KBUILD_BUILD_USER, KBUILD_BUILD_HOST

scripts/gen_initramfs_list.sh

+8-1
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,15 @@ done
287287
# we are carefull to delete tmp files
288288
if [ ! -z ${output_file} ]; then
289289
if [ -z ${cpio_file} ]; then
290+
timestamp=
291+
if test -n "$KBUILD_BUILD_TIMESTAMP"; then
292+
timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
293+
if test -n "$timestamp"; then
294+
timestamp="-t $timestamp"
295+
fi
296+
fi
290297
cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
291-
usr/gen_init_cpio ${cpio_list} > ${cpio_tfile}
298+
usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
292299
else
293300
cpio_tfile=${cpio_file}
294301
fi

usr/gen_init_cpio.c

+40-13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
static unsigned int offset;
2424
static unsigned int ino = 721;
25+
static time_t default_mtime;
2526

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

107107
if (name[0] == '/')
108108
name++;
@@ -114,7 +114,7 @@ static int cpio_mkslink(const char *name, const char *target,
114114
(long) uid, /* uid */
115115
(long) gid, /* gid */
116116
1, /* nlink */
117-
(long) mtime, /* mtime */
117+
(long) default_mtime, /* mtime */
118118
(unsigned)strlen(target)+1, /* filesize */
119119
3, /* major */
120120
1, /* minor */
@@ -152,7 +152,6 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
152152
uid_t uid, gid_t gid)
153153
{
154154
char s[256];
155-
time_t mtime = time(NULL);
156155

157156
if (name[0] == '/')
158157
name++;
@@ -164,7 +163,7 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
164163
(long) uid, /* uid */
165164
(long) gid, /* gid */
166165
2, /* nlink */
167-
(long) mtime, /* mtime */
166+
(long) default_mtime, /* mtime */
168167
0, /* filesize */
169168
3, /* major */
170169
1, /* minor */
@@ -242,7 +241,6 @@ static int cpio_mknod(const char *name, unsigned int mode,
242241
unsigned int maj, unsigned int min)
243242
{
244243
char s[256];
245-
time_t mtime = time(NULL);
246244

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

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

533-
if (2 != argc) {
541+
if (opt == -1)
542+
break;
543+
switch (opt) {
544+
case 't':
545+
default_mtime = strtol(optarg, &invalid, 10);
546+
if (!*optarg || *invalid) {
547+
fprintf(stderr, "Invalid timestamp: %s\n",
548+
optarg);
549+
usage(argv[0]);
550+
exit(1);
551+
}
552+
break;
553+
case 'h':
554+
case '?':
555+
usage(argv[0]);
556+
exit(opt == 'h' ? 0 : 1);
557+
}
558+
}
559+
560+
if (argc - optind != 1) {
534561
usage(argv[0]);
535562
exit(1);
536563
}
537-
538-
if (!strcmp(argv[1], "-"))
564+
filename = argv[optind];
565+
if (!strcmp(filename, "-"))
539566
cpio_list = stdin;
540-
else if (! (cpio_list = fopen(argv[1], "r"))) {
567+
else if (!(cpio_list = fopen(filename, "r"))) {
541568
fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
542-
argv[1], strerror(errno));
569+
filename, strerror(errno));
543570
usage(argv[0]);
544571
exit(1);
545572
}

0 commit comments

Comments
 (0)