svn commit: r301879 - in head/usr.sbin/makefs: . ffs

Ed Maste emaste at FreeBSD.org
Tue Jun 14 14:03:30 UTC 2016


Author: emaste
Date: Tue Jun 14 14:03:28 2016
New Revision: 301879
URL: https://svnweb.freebsd.org/changeset/base/301879

Log:
  makefs: Provide a -T option to set timestamps to a consistent value
  
  This is taken from the NetBSD versions listed below and adapted to the
  makefs version in FreeBSD, along with a bug fix from cem@ that will be
  sent to NetBSD.
  
  Reviewed by:	pfg
  Approved by:	re (gjb)
  Obtained from:	NetBSD
  MFC after:	1 month
  Differential Revision:	https://reviews.freebsd.org/D6835

Modified:
  head/usr.sbin/makefs/cd9660.c
  head/usr.sbin/makefs/ffs.c
  head/usr.sbin/makefs/ffs/mkfs.c
  head/usr.sbin/makefs/ffs/newfs_extern.h
  head/usr.sbin/makefs/makefs.8
  head/usr.sbin/makefs/makefs.c
  head/usr.sbin/makefs/makefs.h
  head/usr.sbin/makefs/walk.c

Modified: head/usr.sbin/makefs/cd9660.c
==============================================================================
--- head/usr.sbin/makefs/cd9660.c	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/cd9660.c	Tue Jun 14 14:03:28 2016	(r301879)
@@ -442,7 +442,7 @@ cd9660_parse_opts(const char *option, fs
  */
 void
 cd9660_makefs(const char *image, const char *dir, fsnode *root,
-	      fsinfo_t *fsopts)
+    fsinfo_t *fsopts)
 {
 	int64_t startoffset;
 	int numDirectories;
@@ -619,7 +619,7 @@ typedef int (*cd9660node_func)(cd9660nod
 static void
 cd9660_finalize_PVD(void)
 {
-	time_t tim;
+	time_t tstamp = stampst.st_ino ? stampst.st_mtime : time(NULL);
 
 	/* root should be a fixed size of 34 bytes since it has no name */
 	memcpy(diskStructure.primaryDescriptor.root_directory_record,
@@ -668,26 +668,26 @@ cd9660_finalize_PVD(void)
 		diskStructure.primaryDescriptor.bibliographic_file_id, 37);
 
 	/* Setup dates */
-	time(&tim);
 	cd9660_time_8426(
 	    (unsigned char *)diskStructure.primaryDescriptor.creation_date,
-	    tim);
+	    tstamp);
 	cd9660_time_8426(
 	    (unsigned char *)diskStructure.primaryDescriptor.modification_date,
-	    tim);
+	    tstamp);
 
-	/*
-	cd9660_set_date(diskStructure.primaryDescriptor.expiration_date, now);
-	*/
+#if 0
+	cd9660_set_date(diskStructure.primaryDescriptor.expiration_date,
+	    tstamp);
+#endif
 
 	memset(diskStructure.primaryDescriptor.expiration_date, '0', 16);
 	diskStructure.primaryDescriptor.expiration_date[16] = 0;
 	cd9660_time_8426(
 	    (unsigned char *)diskStructure.primaryDescriptor.effective_date,
-	    tim);
+	    tstamp);
 	/* make this sane */
 	cd9660_time_915(diskStructure.rootNode->dot_record->isoDirRecord->date,
-			tim);
+	    tstamp);
 }
 
 static void
@@ -808,7 +808,7 @@ cd9660_fill_extended_attribute_record(cd
 static int
 cd9660_translate_node_common(cd9660node *newnode)
 {
-	time_t tim;
+	time_t tstamp = stampst.st_ino ? stampst.st_mtime : time(NULL);
 	int test;
 	u_char flag;
 	char temp[ISO_FILENAME_MAXLENGTH_WITH_PADDING];
@@ -829,9 +829,8 @@ cd9660_translate_node_common(cd9660node 
 	/* Set the various dates */
 
 	/* If we want to use the current date and time */
-	time(&tim);
 
-	cd9660_time_915(newnode->isoDirRecord->date, tim);
+	cd9660_time_915(newnode->isoDirRecord->date, tstamp);
 
 	cd9660_bothendian_dword(newnode->fileDataLength,
 	    newnode->isoDirRecord->size);
@@ -876,7 +875,8 @@ cd9660_translate_node(fsnode *node, cd96
 		return 0;
 
 	/* Finally, overwrite some of the values that are set by default */
-	cd9660_time_915(newnode->isoDirRecord->date, node->inode->st.st_mtime);
+	cd9660_time_915(newnode->isoDirRecord->date,
+	    stampst.st_ino ? stampst.st_mtime : node->inode->st.st_mtime);
 
 	return 1;
 }
@@ -1261,6 +1261,8 @@ cd9660_rrip_move_directory(cd9660node *d
 				diskStructure.rootNode, dir);
 		if (diskStructure.rr_moved_dir == NULL)
 			return 0;
+		cd9660_time_915(diskStructure.rr_moved_dir->isoDirRecord->date,
+		    stampst.st_ino ? stampst.st_mtime : start_time.tv_sec);
 	}
 
 	/* Create a file with the same ORIGINAL name */

Modified: head/usr.sbin/makefs/ffs.c
==============================================================================
--- head/usr.sbin/makefs/ffs.c	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/ffs.c	Tue Jun 14 14:03:28 2016	(r301879)
@@ -482,6 +482,7 @@ ffs_create_image(const char *image, fsin
 	char	*buf;
 	int	i, bufsize;
 	off_t	bufrem;
+	time_t	tstamp;
 
 	assert (image != NULL);
 	assert (fsopts != NULL);
@@ -541,7 +542,15 @@ ffs_create_image(const char *image, fsin
 		/* make the file system */
 	if (debug & DEBUG_FS_CREATE_IMAGE)
 		printf("calling mkfs(\"%s\", ...)\n", image);
-	fs = ffs_mkfs(image, fsopts);
+
+	if (stampst.st_ino != 0)
+		tstamp = stampst.st_ctime;
+	else
+		tstamp = start_time.tv_sec;
+
+	srandom(tstamp);
+
+	fs = ffs_mkfs(image, fsopts, tstamp);
 	fsopts->superblock = (void *)fs;
 	if (debug & DEBUG_FS_CREATE_IMAGE) {
 		time_t t;
@@ -648,19 +657,12 @@ ffs_build_dinode1(struct ufs1_dinode *di
 {
 	int slen;
 	void *membuf;
+	struct stat *st = stampst.st_ino != 0 ? &stampst : &cur->inode->st;
 
 	memset(dinp, 0, sizeof(*dinp));
 	dinp->di_mode = cur->inode->st.st_mode;
 	dinp->di_nlink = cur->inode->nlink;
 	dinp->di_size = cur->inode->st.st_size;
-	dinp->di_atime = cur->inode->st.st_atime;
-	dinp->di_mtime = cur->inode->st.st_mtime;
-	dinp->di_ctime = cur->inode->st.st_ctime;
-#if HAVE_STRUCT_STAT_ST_MTIMENSEC
-	dinp->di_atimensec = cur->inode->st.st_atimensec;
-	dinp->di_mtimensec = cur->inode->st.st_mtimensec;
-	dinp->di_ctimensec = cur->inode->st.st_ctimensec;
-#endif
 #if HAVE_STRUCT_STAT_ST_FLAGS
 	dinp->di_flags = cur->inode->st.st_flags;
 #endif
@@ -669,6 +671,15 @@ ffs_build_dinode1(struct ufs1_dinode *di
 #endif
 	dinp->di_uid = cur->inode->st.st_uid;
 	dinp->di_gid = cur->inode->st.st_gid;
+
+	dinp->di_atime = st->st_atime;
+	dinp->di_mtime = st->st_mtime;
+	dinp->di_ctime = st->st_ctime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+	dinp->di_atimensec = st->st_atimensec;
+	dinp->di_mtimensec = st->st_mtimensec;
+	dinp->di_ctimensec = st->st_ctimensec;
+#endif
 		/* not set: di_db, di_ib, di_blocks, di_spare */
 
 	membuf = NULL;
@@ -696,31 +707,33 @@ ffs_build_dinode2(struct ufs2_dinode *di
 {
 	int slen;
 	void *membuf;
+	struct stat *st = stampst.st_ino != 0 ? &stampst : &cur->inode->st;
 
 	memset(dinp, 0, sizeof(*dinp));
 	dinp->di_mode = cur->inode->st.st_mode;
 	dinp->di_nlink = cur->inode->nlink;
 	dinp->di_size = cur->inode->st.st_size;
-	dinp->di_atime = cur->inode->st.st_atime;
-	dinp->di_mtime = cur->inode->st.st_mtime;
-	dinp->di_ctime = cur->inode->st.st_ctime;
-#if HAVE_STRUCT_STAT_ST_MTIMENSEC
-	dinp->di_atimensec = cur->inode->st.st_atimensec;
-	dinp->di_mtimensec = cur->inode->st.st_mtimensec;
-	dinp->di_ctimensec = cur->inode->st.st_ctimensec;
-#endif
 #if HAVE_STRUCT_STAT_ST_FLAGS
 	dinp->di_flags = cur->inode->st.st_flags;
 #endif
 #if HAVE_STRUCT_STAT_ST_GEN
 	dinp->di_gen = cur->inode->st.st_gen;
 #endif
-#if HAVE_STRUCT_STAT_BIRTHTIME
-	dinp->di_birthtime = cur->inode->st.st_birthtime;
-	dinp->di_birthnsec = cur->inode->st.st_birthtimensec;
-#endif
 	dinp->di_uid = cur->inode->st.st_uid;
 	dinp->di_gid = cur->inode->st.st_gid;
+
+	dinp->di_atime = st->st_atime;
+	dinp->di_mtime = st->st_mtime;
+	dinp->di_ctime = st->st_ctime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+	dinp->di_atimensec = st->st_atimensec;
+	dinp->di_mtimensec = st->st_mtimensec;
+	dinp->di_ctimensec = st->st_ctimensec;
+#endif
+#if HAVE_STRUCT_STAT_BIRTHTIME
+	dinp->di_birthtime = st->st_birthtime;
+	dinp->di_birthnsec = st->st_birthtimensec;
+#endif
 		/* not set: di_db, di_ib, di_blocks, di_spare */
 
 	membuf = NULL;
@@ -1125,11 +1138,6 @@ ffs_write_inode(union dinode *dp, uint32
 	    initediblk < ufs_rw32(cgp->cg_niblk, fsopts->needswap)) {
 		memset(buf, 0, fs->fs_bsize);
 		dip = (struct ufs2_dinode *)buf;
-		/*
-		 * XXX: Time-based seeds should be avoided for
-		 * reproduceable builds.
-		 */
-		srandom(time(NULL));
 		for (i = 0; i < INOPB(fs); i++) {
 			dip->di_gen = random();
 			dip++;

Modified: head/usr.sbin/makefs/ffs/mkfs.c
==============================================================================
--- head/usr.sbin/makefs/ffs/mkfs.c	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/ffs/mkfs.c	Tue Jun 14 14:03:28 2016	(r301879)
@@ -113,7 +113,7 @@ static int     avgfilesize;	   /* expect
 static int     avgfpdir;	   /* expected number of files per directory */
 
 struct fs *
-ffs_mkfs(const char *fsys, const fsinfo_t *fsopts)
+ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
 {
 	int fragsperinode, optimalfpg, origdensity, minfpg, lastminfpg;
 	int32_t cylno, i, csfrags;
@@ -434,7 +434,7 @@ ffs_mkfs(const char *fsys, const fsinfo_
 	sblock.fs_state = 0;
 	sblock.fs_clean = FS_ISCLEAN;
 	sblock.fs_ronly = 0;
-	sblock.fs_id[0] = start_time.tv_sec;
+	sblock.fs_id[0] = tstamp;
 	sblock.fs_id[1] = random();
 	sblock.fs_fsmnt[0] = '\0';
 	csfrags = howmany(sblock.fs_cssize, sblock.fs_fsize);
@@ -450,9 +450,9 @@ ffs_mkfs(const char *fsys, const fsinfo_
 	sblock.fs_cstotal.cs_nifree = sblock.fs_ncg * sblock.fs_ipg - ROOTINO;
 	sblock.fs_cstotal.cs_ndir = 0;
 	sblock.fs_dsize -= csfrags;
-	sblock.fs_time = start_time.tv_sec;
+	sblock.fs_time = tstamp;
 	if (Oflag <= 1) {
-		sblock.fs_old_time = start_time.tv_sec;
+		sblock.fs_old_time = tstamp;
 		sblock.fs_old_dsize = sblock.fs_dsize;
 		sblock.fs_old_csaddr = sblock.fs_csaddr;
 		sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
@@ -508,7 +508,7 @@ ffs_mkfs(const char *fsys, const fsinfo_
 
 	printf("super-block backups (for fsck -b #) at:");
 	for (cylno = 0; cylno < sblock.fs_ncg; cylno++) {
-		initcg(cylno, start_time.tv_sec, fsopts);
+		initcg(cylno, tstamp, fsopts);
 		if (cylno % nprintcols == 0)
 			printf("\n");
 		printf(" %*lld,", printcolwidth,
@@ -521,7 +521,7 @@ ffs_mkfs(const char *fsys, const fsinfo_
 	 * Now construct the initial file system,
 	 * then write out the super-block.
 	 */
-	sblock.fs_time = start_time.tv_sec;
+	sblock.fs_time = tstamp;
 	if (Oflag <= 1) {
 		sblock.fs_old_cstotal.cs_ndir = sblock.fs_cstotal.cs_ndir;
 		sblock.fs_old_cstotal.cs_nbfree = sblock.fs_cstotal.cs_nbfree;

Modified: head/usr.sbin/makefs/ffs/newfs_extern.h
==============================================================================
--- head/usr.sbin/makefs/ffs/newfs_extern.h	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/ffs/newfs_extern.h	Tue Jun 14 14:03:28 2016	(r301879)
@@ -1,4 +1,4 @@
-/*	$NetBSD: newfs_extern.h,v 1.3 2009/10/21 01:07:47 snj Exp $	*/
+/*	$NetBSD: newfs_extern.h,v 1.4 2015/12/21 00:58:08 christos Exp $	*/
 /* From: NetBSD: extern.h,v 1.3 2000/12/01 12:03:27 simonb Exp $ */
 
 /*
@@ -28,7 +28,7 @@
  */
 
 /* prototypes */
-struct fs	*ffs_mkfs(const char *, const fsinfo_t *);
+struct fs	*ffs_mkfs(const char *, const fsinfo_t *, time_t);
 void		ffs_write_superblock(struct fs *, const fsinfo_t *);
 void		ffs_rdfs(daddr_t, int, void *, const fsinfo_t *);
 void		ffs_wtfs(daddr_t, int, void *, const fsinfo_t *);

Modified: head/usr.sbin/makefs/makefs.8
==============================================================================
--- head/usr.sbin/makefs/makefs.8	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/makefs.8	Tue Jun 14 14:03:28 2016	(r301879)
@@ -35,7 +35,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 9, 2015
+.Dd June 14, 2016
 .Dt MAKEFS 8
 .Os
 .Sh NAME
@@ -56,6 +56,7 @@
 .Op Fl R Ar roundup-size
 .Op Fl S Ar sector-size
 .Op Fl s Ar image-size
+.Op Fl T Ar timestamp
 .Op Fl t Ar fs-type
 .Ar image-file
 .Ar directory | manifest
@@ -212,6 +213,18 @@ Defaults to 512.
 .It Fl s Ar image-size
 Set the size of the file system image to
 .Ar image-size .
+.It Fl T Ar timestamp
+Specify a timestamp to be set for all filesystem files and directories
+created so that repeatable builds are possible.
+The
+.Ar timestamp
+can be a
+.Pa pathname ,
+where the timestamps are derived from that file, or an integer
+value interpreted as the number of seconds from the Epoch.
+Note that timestamps specified in an
+.Xr mtree 5
+spec file, override the default timestamp.
 .It Fl t Ar fs-type
 Create an
 .Ar fs-type

Modified: head/usr.sbin/makefs/makefs.c
==============================================================================
--- head/usr.sbin/makefs/makefs.c	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/makefs.c	Tue Jun 14 14:03:28 2016	(r301879)
@@ -78,8 +78,10 @@ static fstype_t fstypes[] = {
 u_int		debug;
 int		dupsok;
 struct timespec	start_time;
+struct stat stampst;
 
 static	fstype_t *get_fstype(const char *);
+static int get_tstamp(const char *, struct stat *);
 static	void	usage(void);
 int		main(int, char *[]);
 
@@ -110,13 +112,15 @@ main(int argc, char *argv[])
 		fstype->prepare_options(&fsoptions);
 
 	specfile = NULL;
-	if (gettimeofday(&start, NULL) == -1)
-		err(1, "Unable to get system time");
-
+	ch = gettimeofday(&start, NULL);
 	start_time.tv_sec = start.tv_sec;
 	start_time.tv_nsec = start.tv_usec * 1000;
 
-	while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:pR:s:S:t:xZ")) != -1) {
+	if (ch == -1)
+		err(1, "Unable to get system time");
+
+
+	while ((ch = getopt(argc, argv, "B:b:Dd:f:F:M:m:N:o:pR:s:S:t:T:xZ")) != -1) {
 		switch (ch) {
 
 		case 'B':
@@ -239,6 +243,12 @@ main(int argc, char *argv[])
 			fstype->prepare_options(&fsoptions);
 			break;
 
+		case 'T':
+			if (get_tstamp(optarg, &stampst) == -1)
+				errx(1, "Cannot get timestamp from `%s'",
+				    optarg);
+			break;
+
 		case 'x':
 			fsoptions.onlyspec = 1;
 			break;
@@ -360,6 +370,32 @@ get_fstype(const char *type)
 	return (NULL);
 }
 
+static int
+get_tstamp(const char *b, struct stat *st)
+{
+	time_t when;
+	char *eb;
+	long long l;
+
+	if (stat(b, st) != -1)
+		return 0;
+
+	{
+		errno = 0;
+		l = strtoll(b, &eb, 0);
+		if (b == eb || *eb || errno)
+			return -1;
+		when = (time_t)l;
+	}
+
+	st->st_ino = 1;
+#ifdef HAVE_STRUCT_STAT_BIRTHTIME
+	st->st_birthtime =
+#endif
+	st->st_mtime = st->st_ctime = st->st_atime = when;
+	return 0;
+}
+
 static void
 usage(void)
 {
@@ -370,7 +406,8 @@ usage(void)
 "usage: %s [-t fs-type] [-o fs-options] [-d debug-mask] [-B endian]\n"
 "\t[-S sector-size] [-M minimum-size] [-m maximum-size] [-R roundup-size]\n"
 "\t[-s image-size] [-b free-blocks] [-f free-files] [-F mtree-specfile]\n"
-"\t[-xZ] [-N userdb-dir] image-file directory | manifest [extra-directory ...]\n",
+"\t[-xZ] [-N userdb-dir] [-T <timestamp/file>]\n"
+"\timage-file directory | manifest [extra-directory ...]\n",
 	    prog);
 	exit(1);
 }

Modified: head/usr.sbin/makefs/makefs.h
==============================================================================
--- head/usr.sbin/makefs/makefs.h	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/makefs.h	Tue Jun 14 14:03:28 2016	(r301879)
@@ -172,6 +172,7 @@ void		cd9660_makefs(const char *, const 
 extern	u_int		debug;
 extern	int		dupsok;
 extern	struct timespec	start_time;
+extern struct stat stampst;
 
 /*
  * If -x is specified, we want to exclude nodes which do not appear

Modified: head/usr.sbin/makefs/walk.c
==============================================================================
--- head/usr.sbin/makefs/walk.c	Tue Jun 14 06:21:51 2016	(r301878)
+++ head/usr.sbin/makefs/walk.c	Tue Jun 14 14:03:28 2016	(r301879)
@@ -229,6 +229,20 @@ create_fsnode(const char *root, const ch
 	cur->type = stbuf->st_mode & S_IFMT;
 	cur->inode->nlink = 1;
 	cur->inode->st = *stbuf;
+	if (stampst.st_ino) {
+		cur->inode->st.st_atime = stampst.st_atime;
+		cur->inode->st.st_mtime = stampst.st_mtime;
+		cur->inode->st.st_ctime = stampst.st_ctime;
+#if HAVE_STRUCT_STAT_ST_MTIMENSEC
+		cur->inode->st.st_atimensec = stampst.st_atimensec;
+		cur->inode->st.st_mtimensec = stampst.st_mtimensec;
+		cur->inode->st.st_ctimensec = stampst.st_ctimensec;
+#endif
+#if HAVE_STRUCT_STAT_BIRTHTIME
+		cur->inode->st.st_birthtime = stampst.st_birthtime;
+		cur->inode->st.st_birthtimensec = stampst.st_birthtimensec;
+#endif
+	}
 	return (cur);
 }
 


More information about the svn-src-all mailing list