diff mbox series

gen_init_cpio: Apply mtime supplied by user to all file types

Message ID 20231220-gen_init_cpio-reproducible-v1-1-d40da0b2c15c@arista.com (mailing list archive)
State New, archived
Headers show
Series gen_init_cpio: Apply mtime supplied by user to all file types | expand

Commit Message

Dmitry Safonov Dec. 20, 2023, 12:33 a.m. UTC
Currently gen_init_cpio -d <timestamp> is applied to symlinks,
directories and special files. These files are created by
gen_init_cpio from their description. Without <timestamp> option
current time(NULL) is used. And regular files that go in initramfs
are created before cpio generation, so their mtime(s) are preserved.

This is usually not an issue as reproducible builds should rebuild
everything in the distribution, including binaries, configs and whatever
other regular files may find their way into kernel's initramfs.

On the other hand, gen_initramfs.sh usage claims:
>	-d <date>      Use date for all file mtime values

Ar Arista initramfs files are managed with version control system
that preserves mtime. Those are configs, boot parameters, init scripts,
version files, platform-specific files, probably some others, too.

While it's certainly possible to work this around by copying the file
into temp directory and adjusting mtime prior to gen_init_cpio call,
I don't see why it needs workarounds.

The intended user of -d <date> option is the one that needs to create
a reproducible build, see commit a8b8017c34fe ("initramfs: Use
KBUILD_BUILD_TIMESTAMP for generated entries"). If a user wants
the build reproduction, they use -d <date>, which can be set on all
types of files, without surprising exceptions and workarounds.
Let's KISS here and just apply the time that user specified
with -d option.

Based-on-a-patch-by: Baptiste Covolato <baptiste@arista.com>
Link: https://lore.kernel.org/lkml/20181025215133.20138-1-baptiste@arista.com/
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 usr/gen_init_cpio.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)


---
base-commit: 55cb5f43689d7a9ea5bf35ef050f12334f197347
change-id: 20231219-gen_init_cpio-reproducible-99c707d8e66c

Best regards,

Comments

Masahiro Yamada Dec. 23, 2023, 10:49 a.m. UTC | #1
On Wed, Dec 20, 2023 at 9:33 AM Dmitry Safonov <dima@arista.com> wrote:
>
> Currently gen_init_cpio -d <timestamp> is applied to symlinks,
> directories and special files. These files are created by
> gen_init_cpio from their description. Without <timestamp> option
> current time(NULL) is used. And regular files that go in initramfs
> are created before cpio generation, so their mtime(s) are preserved.
>
> This is usually not an issue as reproducible builds should rebuild
> everything in the distribution, including binaries, configs and whatever
> other regular files may find their way into kernel's initramfs.
>
> On the other hand, gen_initramfs.sh usage claims:
> >       -d <date>      Use date for all file mtime values
>
> Ar Arista initramfs files are managed with version control system
> that preserves mtime. Those are configs, boot parameters, init scripts,
> version files, platform-specific files, probably some others, too.
>
> While it's certainly possible to work this around by copying the file
> into temp directory and adjusting mtime prior to gen_init_cpio call,
> I don't see why it needs workarounds.
>
> The intended user of -d <date> option is the one that needs to create
> a reproducible build, see commit a8b8017c34fe ("initramfs: Use
> KBUILD_BUILD_TIMESTAMP for generated entries"). If a user wants
> the build reproduction, they use -d <date>, which can be set on all
> types of files, without surprising exceptions and workarounds.
> Let's KISS here and just apply the time that user specified
> with -d option.
>
> Based-on-a-patch-by: Baptiste Covolato <baptiste@arista.com>
> Link: https://lore.kernel.org/lkml/20181025215133.20138-1-baptiste@arista.com/
> Signed-off-by: Dmitry Safonov <dima@arista.com>



Applied to linux-kbuild.
Thanks.


> ---
>  usr/gen_init_cpio.c | 33 +++++++++++++++++++++------------
>  1 file changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
> index 61230532fef1..edcdb8abfa31 100644
> --- a/usr/gen_init_cpio.c
> +++ b/usr/gen_init_cpio.c
> @@ -27,6 +27,7 @@
>  static unsigned int offset;
>  static unsigned int ino = 721;
>  static time_t default_mtime;
> +static bool do_file_mtime;
>  static bool do_csum = false;
>
>  struct file_handler {
> @@ -329,6 +330,7 @@ static int cpio_mkfile(const char *name, const char *location,
>         int file;
>         int retval;
>         int rc = -1;
> +       time_t mtime;
>         int namesize;
>         unsigned int i;
>         uint32_t csum = 0;
> @@ -347,16 +349,21 @@ static int cpio_mkfile(const char *name, const char *location,
>                 goto error;
>         }
>
> -       if (buf.st_mtime > 0xffffffff) {
> -               fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
> -                       location);
> -               buf.st_mtime = 0xffffffff;
> -       }
> +       if (do_file_mtime) {
> +               mtime = default_mtime;
> +       } else {
> +               mtime = buf.st_mtime;
> +               if (mtime > 0xffffffff) {
> +                       fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
> +                                       location);
> +                       mtime = 0xffffffff;
> +               }
>
> -       if (buf.st_mtime < 0) {
> -               fprintf(stderr, "%s: Timestamp negative, clipping.\n",
> -                       location);
> -               buf.st_mtime = 0;
> +               if (mtime < 0) {
> +                       fprintf(stderr, "%s: Timestamp negative, clipping.\n",
> +                                       location);
> +                       mtime = 0;
> +               }
>         }
>
>         if (buf.st_size > 0xffffffff) {
> @@ -387,7 +394,7 @@ static int cpio_mkfile(const char *name, const char *location,
>                         (long) uid,             /* uid */
>                         (long) gid,             /* gid */
>                         nlinks,                 /* nlink */
> -                       (long) buf.st_mtime,    /* mtime */
> +                       (long) mtime,           /* mtime */
>                         size,                   /* filesize */
>                         3,                      /* major */
>                         1,                      /* minor */
> @@ -536,8 +543,9 @@ static void usage(const char *prog)
>                 "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"
> +               "as mtime for symlinks, directories, regular and special files.\n"
> +               "The default is to use the current time for all files, but\n"
> +               "preserve modification time for regular files.\n"
>                 "-c: calculate and store 32-bit checksums for file data.\n",
>                 prog);
>  }
> @@ -594,6 +602,7 @@ int main (int argc, char *argv[])
>                                 usage(argv[0]);
>                                 exit(1);
>                         }
> +                       do_file_mtime = true;
>                         break;
>                 case 'c':
>                         do_csum = true;
>
> ---
> base-commit: 55cb5f43689d7a9ea5bf35ef050f12334f197347
> change-id: 20231219-gen_init_cpio-reproducible-99c707d8e66c
>
> Best regards,
> --
> Dmitry Safonov <dima@arista.com>
>
diff mbox series

Patch

diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index 61230532fef1..edcdb8abfa31 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -27,6 +27,7 @@ 
 static unsigned int offset;
 static unsigned int ino = 721;
 static time_t default_mtime;
+static bool do_file_mtime;
 static bool do_csum = false;
 
 struct file_handler {
@@ -329,6 +330,7 @@  static int cpio_mkfile(const char *name, const char *location,
 	int file;
 	int retval;
 	int rc = -1;
+	time_t mtime;
 	int namesize;
 	unsigned int i;
 	uint32_t csum = 0;
@@ -347,16 +349,21 @@  static int cpio_mkfile(const char *name, const char *location,
 		goto error;
 	}
 
-	if (buf.st_mtime > 0xffffffff) {
-		fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
-			location);
-		buf.st_mtime = 0xffffffff;
-	}
+	if (do_file_mtime) {
+		mtime = default_mtime;
+	} else {
+		mtime = buf.st_mtime;
+		if (mtime > 0xffffffff) {
+			fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
+					location);
+			mtime = 0xffffffff;
+		}
 
-	if (buf.st_mtime < 0) {
-		fprintf(stderr, "%s: Timestamp negative, clipping.\n",
-			location);
-		buf.st_mtime = 0;
+		if (mtime < 0) {
+			fprintf(stderr, "%s: Timestamp negative, clipping.\n",
+					location);
+			mtime = 0;
+		}
 	}
 
 	if (buf.st_size > 0xffffffff) {
@@ -387,7 +394,7 @@  static int cpio_mkfile(const char *name, const char *location,
 			(long) uid,		/* uid */
 			(long) gid,		/* gid */
 			nlinks,			/* nlink */
-			(long) buf.st_mtime,	/* mtime */
+			(long) mtime,		/* mtime */
 			size,			/* filesize */
 			3,			/* major */
 			1,			/* minor */
@@ -536,8 +543,9 @@  static void usage(const char *prog)
 		"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"
+		"as mtime for symlinks, directories, regular and special files.\n"
+		"The default is to use the current time for all files, but\n"
+		"preserve modification time for regular files.\n"
 		"-c: calculate and store 32-bit checksums for file data.\n",
 		prog);
 }
@@ -594,6 +602,7 @@  int main (int argc, char *argv[])
 				usage(argv[0]);
 				exit(1);
 			}
+			do_file_mtime = true;
 			break;
 		case 'c':
 			do_csum = true;