-fixed-time <timestamp> set mkfs-timestamp and file-mtime to this timestamp. Reproducible builds requires the removal of all timestamp or setting all to a specific one.
Signed-off-by: Alexander Couzens <lyn...@fe80.eu> --- .../patches/120-add-fixed-timestamp-support.patch | 130 +++++++++++++ .../patches/200-add-fixed-timestamp-option.patch | 210 +++++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 tools/squashfs/patches/120-add-fixed-timestamp-support.patch create mode 100644 tools/squashfs4/patches/200-add-fixed-timestamp-option.patch diff --git a/tools/squashfs/patches/120-add-fixed-timestamp-support.patch b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch new file mode 100644 index 0000000..a88623f --- /dev/null +++ b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch @@ -0,0 +1,130 @@ +Index: squashfs3.0/squashfs-tools/mksquashfs.c +=================================================================== +--- squashfs3.0.orig/squashfs-tools/mksquashfs.c ++++ squashfs3.0/squashfs-tools/mksquashfs.c +@@ -253,7 +253,7 @@ int get_sorted_inode(squashfs_inode *ino + int read_sort_file(char *filename, int source, char *source_path[]); + void sort_files_and_write(struct dir_info *dir); + struct file_info *duplicate(char *(get_next_file_block)(struct duplicate_buffer_handle *, unsigned int), struct duplicate_buffer_handle *file_start, long long bytes, unsigned int **block_list, long long *start, int blocks, struct fragment **fragment, char *frag_data, int frag_bytes); +-struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct dir_info *)); ++struct dir_info *dir_scan1(char *, int (_readdir)(char *, char *, struct dir_info *), time_t fixed_time); + + #define MKINODE(A) ((squashfs_inode)(((squashfs_inode) inode_bytes << 16) + (((char *)A) - data_cache))) + +@@ -1518,12 +1518,13 @@ void scan2_freedir(struct directory *dir + } + + +-void dir_scan(squashfs_inode *inode, char *pathname, int (_readdir)(char *, char *, struct dir_info *)) ++void dir_scan(squashfs_inode *inode, char *pathname, int (_readdir)(char *, char *, struct dir_info *), ++ time_t fixed_time) + { +- struct dir_info *dir_info = dir_scan1(pathname, _readdir); ++ struct dir_info *dir_info = dir_scan1(pathname, _readdir, fixed_time); + struct dir_ent *dir_ent; + struct inode_info *inode_info; + + if(dir_info == NULL) + return; + +@@ -1547,20 +1548,25 @@ void dir_scan(squashfs_inode *inode, cha + inode_info->buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO; + inode_info->buf.st_uid = getuid(); + inode_info->buf.st_gid = getgid(); +- inode_info->buf.st_mtime = time(NULL); ++ inode_info->buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL); + } else if(lstat(pathname, &inode_info->buf) == -1) { + char buffer[8192]; + sprintf(buffer, "Cannot stat dir/file %s, ignoring", pathname); + perror(buffer); + return; + } ++ ++ /* override timestamp of lstat if fixed_time is given */ ++ if(fixed_time != -1) ++ inode_info->buf.st_mtime= fixed_time; + if(sorted) + sort_files_and_write(dir_info); + dir_scan2(inode, dir_info); + } + + +-struct dir_info *dir_scan1(char *pathname, int (_readdir)(char *, char *, struct dir_info *)) ++struct dir_info *dir_scan1(char *pathname, int (_readdir)(char *, char *, struct dir_info *), ++ time_t fixed_time) + { + struct dir_info *dir, *sub_dir; + struct stat buf; +@@ -1582,11 +1590,14 @@ struct dir_info *dir_scan1(char *pathnam + perror(buffer); + continue; + } ++ ++ if(fixed_time != -1) ++ buf.st_mtime = fixed_time; + if(excluded(filename, &buf)) + continue; + + if((buf.st_mode & S_IFMT) == S_IFDIR) { +- if((sub_dir = dir_scan1(filename, scan1_readdir)) == NULL) ++ if((sub_dir = dir_scan1(filename, scan1_readdir, fixed_time)) == NULL) + continue; + dir->directory_count ++; + } else +@@ -1809,6 +1822,7 @@ int main(int argc, char *argv[]) + char *b, *root_name = NULL; + int be, nopad = FALSE, keep_as_directory = FALSE, orig_be; + squashfs_inode inode; ++ time_t fixed_time = -1; + + #if __BYTE_ORDER == __BIG_ENDIAN + be = TRUE; +@@ -1898,6 +1912,16 @@ int main(int argc, char *argv[]) + exit(1); + } + } ++ } else if(strcmp(argv[i], "-fixed-time") == 0) { ++ if(++i == argc) { ++ ERROR("%s: -fixed-time missing a timestamp\n", argv[0]); ++ exit(1); ++ } ++ fixed_time = strtoll(argv[i], &b, 10); ++ if(*b != '\0') { ++ ERROR("%s: -fixed-time has an invalid number\n", argv[0]); ++ exit(1); ++ } + } else if(strcmp(argv[i], "-noI") == 0 || + strcmp(argv[i], "-noInodeCompression") == 0) + noI = TRUE; +@@ -1967,6 +1991,7 @@ printOptions: + ERROR("-all-root\t\tmake all files owned by root\n"); + ERROR("-force-uid uid\t\tset all file uids to uid\n"); + ERROR("-force-gid gid\t\tset all file gids to gid\n"); ++ ERROR("-fixed-time timestamp\tSet all timestamps to timestamp\n"); + ERROR("-le\t\t\tcreate a little endian filesystem\n"); + ERROR("-be\t\t\tcreate a big endian filesystem\n"); + ERROR("-nopad\t\t\tdo not pad filesystem to a multiple of 4K\n"); +@@ -2177,11 +2202,11 @@ printOptions: + block_offset = check_data ? 3 : 2; + + if(delete && !keep_as_directory && source == 1 && S_ISDIR(source_buf.st_mode)) +- dir_scan(&inode, source_path[0], scan1_readdir); ++ dir_scan(&inode, source_path[0], scan1_readdir, fixed_time); + else if(!keep_as_directory && source == 1 && S_ISDIR(source_buf.st_mode)) +- dir_scan(&inode, source_path[0], scan1_single_readdir); ++ dir_scan(&inode, source_path[0], scan1_single_readdir, fixed_time); + else +- dir_scan(&inode, "", scan1_encomp_readdir); ++ dir_scan(&inode, "", scan1_encomp_readdir, fixed_time); + sBlk.root_inode = inode; + sBlk.inodes = inode_count; + sBlk.s_magic = SQUASHFS_MAGIC; +@@ -2190,7 +2215,7 @@ printOptions: + sBlk.block_size = block_size; + sBlk.block_log = block_log; + sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, check_data, noF, no_fragments, always_use_fragments, duplicate_checking); +- sBlk.mkfs_time = time(NULL); ++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL); + + restore_filesystem: + write_fragment(); diff --git a/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch new file mode 100644 index 0000000..5bc243f --- /dev/null +++ b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch @@ -0,0 +1,210 @@ +Index: squashfs4.2/squashfs-tools/mksquashfs.c +=================================================================== +--- squashfs4.2.orig/squashfs-tools/mksquashfs.c ++++ squashfs4.2/squashfs-tools/mksquashfs.c +@@ -429,9 +429,10 @@ struct file_info *duplicate(long long fi + struct file_buffer *file_buffer, int blocks, unsigned short checksum, + unsigned short fragment_checksum, int checksum_flag); + struct dir_info *dir_scan1(char *, struct pathnames *, int (_readdir)(char *, +- char *, struct dir_info *)); +-struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo); +-void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info); ++ char *, struct dir_info *), time_t fixed_time); ++struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo, ++ time_t timestamp); ++void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info, time_t fixed_time); + struct file_info *add_non_dup(long long file_size, long long bytes, + unsigned int *block_list, long long start, struct fragment *fragment, + unsigned short checksum, unsigned short fragment_checksum, +@@ -3588,16 +3589,17 @@ void scan3_freedir(struct directory *dir + + + void dir_scan(squashfs_inode *inode, char *pathname, +- int (_readdir)(char *, char *, struct dir_info *)) ++ int (_readdir)(char *, char *, struct dir_info *), ++ time_t fixed_time) + { + struct stat buf; +- struct dir_info *dir_info = dir_scan1(pathname, paths, _readdir); ++ struct dir_info *dir_info = dir_scan1(pathname, paths, _readdir, fixed_time); + struct dir_ent *dir_ent; + + if(dir_info == NULL) + return; + +- dir_scan2(dir_info, pseudo); ++ dir_scan2(dir_info, pseudo, fixed_time); + + dir_ent = malloc(sizeof(struct dir_ent)); + if(dir_ent == NULL) +@@ -3612,7 +3614,7 @@ void dir_scan(squashfs_inode *inode, cha + buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR; + buf.st_uid = getuid(); + buf.st_gid = getgid(); +- buf.st_mtime = time(NULL); ++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL); + buf.st_dev = 0; + buf.st_ino = 0; + dir_ent->inode = lookup_inode(&buf); +@@ -3623,6 +3625,9 @@ void dir_scan(squashfs_inode *inode, cha + pathname, strerror(errno)); + return; + } ++ if (fixed_time != -1) ++ buf.st_mtime = fixed_time; ++ + dir_ent->inode = lookup_inode(&buf); + } + +@@ -3647,14 +3652,15 @@ void dir_scan(squashfs_inode *inode, cha + sort_files_and_write(dir_info); + if(progress) + enable_progress_bar(); +- dir_scan3(inode, dir_info); ++ dir_scan3(inode, dir_info, fixed_time); + dir_ent->inode->inode = *inode; + dir_ent->inode->type = SQUASHFS_DIR_TYPE; + } + + + struct dir_info *dir_scan1(char *pathname, struct pathnames *paths, +- int (_readdir)(char *, char *, struct dir_info *)) ++ int (_readdir)(char *, char *, struct dir_info *), ++ time_t fixed_time) + { + char filename[8192], dir_name[8192]; + struct dir_info *dir = scan1_opendir(pathname); +@@ -3699,7 +3705,7 @@ struct dir_info *dir_scan1(char *pathnam + } + + if((buf.st_mode & S_IFMT) == S_IFDIR) { +- sub_dir = dir_scan1(filename, new, scan1_readdir); ++ sub_dir = dir_scan1(filename, new, scan1_readdir, fixed_time); + if(sub_dir == NULL) + continue; + dir->directory_count ++; +@@ -3717,7 +3723,8 @@ error: + } + + +-struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo) ++struct dir_info *dir_scan2(struct dir_info *dir, struct pseudo *pseudo, ++ time_t fixed_time) + { + struct dir_info *sub_dir; + struct dir_ent *dir_ent; +@@ -3734,7 +3741,8 @@ struct dir_info *dir_scan2(struct dir_in + char *name = dir_ent->name; + + if((buf->st_mode & S_IFMT) == S_IFDIR) +- dir_scan2(dir_ent->dir, pseudo_subdir(name, pseudo)); ++ dir_scan2(dir_ent->dir, pseudo_subdir(name, pseudo), ++ fixed_time); + } + + while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) { +@@ -3778,7 +3786,7 @@ struct dir_info *dir_scan2(struct dir_in + } + + if(pseudo_ent->dev->type == 'd') { +- sub_dir = dir_scan2(NULL, pseudo_ent->pseudo); ++ sub_dir = dir_scan2(NULL, pseudo_ent->pseudo, fixed_time); + if(sub_dir == NULL) { + ERROR("Could not create pseudo directory \"%s\"" + ", skipping...\n", +@@ -3795,7 +3803,7 @@ struct dir_info *dir_scan2(struct dir_in + buf.st_gid = pseudo_ent->dev->gid; + buf.st_rdev = makedev(pseudo_ent->dev->major, + pseudo_ent->dev->minor); +- buf.st_mtime = time(NULL); ++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL); + buf.st_ino = pseudo_ino ++; + + if(pseudo_ent->dev->type == 'f') { +@@ -3836,7 +3844,7 @@ struct dir_info *dir_scan2(struct dir_in + } + + +-void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info) ++void dir_scan3(squashfs_inode *inode, struct dir_info *dir_info, time_t fixed_time) + { + int squashfs_type; + int duplicate_file; +@@ -3855,6 +3863,9 @@ void dir_scan3(squashfs_inode *inode, st + ? dir_ent->inode->inode_number : + dir_ent->inode->inode_number + dir_inode_no; + ++ if(fixed_time != -1) ++ buf->st_mtime = fixed_time; ++ + if(dir_ent->inode->inode == SQUASHFS_INVALID_BLK) { + switch(buf->st_mode & S_IFMT) { + case S_IFREG: +@@ -3870,7 +3881,7 @@ void dir_scan3(squashfs_inode *inode, st + + case S_IFDIR: + squashfs_type = SQUASHFS_DIR_TYPE; +- dir_scan3(inode, dir_ent->dir); ++ dir_scan3(inode, dir_ent->dir, fixed_time); + break; + + case S_IFLNK: +@@ -4578,6 +4589,7 @@ int main(int argc, char *argv[]) + struct squashfs_super_block sBlk; + char *b, *root_name = NULL; + int nopad = FALSE, keep_as_directory = FALSE; ++ time_t fixed_time = -1; + squashfs_inode inode; + int readb_mbytes = READER_BUFFER_DEFAULT, + writeb_mbytes = WRITER_BUFFER_DEFAULT, +@@ -4674,6 +4686,15 @@ int main(int argc, char *argv[]) + progress = FALSE; + else if(strcmp(argv[i], "-no-exports") == 0) + exportable = FALSE; ++ else if(strcmp(argv[i], "-fixed-time") == 0) { ++ if((++i == argc) || (fixed_time = ++ strtoll(argv[i], &b, 10), *b != '\0')) { ++ ERROR("%s: -fixed-time missing or invalid " ++ "timestamp\n", argv[0]); ++ ++ exit(1); ++ } ++ } + else if(strcmp(argv[i], "-processors") == 0) { + if((++i == argc) || (processors = + strtol(argv[i], &b, 10), *b != '\0')) { +@@ -4936,8 +4957,9 @@ printOptions: + ERROR("-info\t\t\tprint files written to filesystem\n"); + ERROR("-no-progress\t\tdon't display the progress " + "bar\n"); ++ ERROR("-fixed-time <timestamp>\tSet all timestamps to <timestamp>\n"); + ERROR("-processors <number>\tUse <number> processors." + " By default will use number of\n"); + ERROR("\t\t\tprocessors available\n"); + ERROR("-read-queue <size>\tSet input queue to <size> " + "Mbytes. Default %d Mbytes\n", +@@ -5298,12 +5318,12 @@ printOptions: + + if(delete && !keep_as_directory && source == 1 && + S_ISDIR(source_buf.st_mode)) +- dir_scan(&inode, source_path[0], scan1_readdir); ++ dir_scan(&inode, source_path[0], scan1_readdir, fixed_time); + else if(!keep_as_directory && source == 1 && + S_ISDIR(source_buf.st_mode)) +- dir_scan(&inode, source_path[0], scan1_single_readdir); ++ dir_scan(&inode, source_path[0], scan1_single_readdir, fixed_time); + else +- dir_scan(&inode, "", scan1_encomp_readdir); ++ dir_scan(&inode, "", scan1_encomp_readdir, fixed_time); + sBlk.root_inode = inode; + sBlk.inodes = inode_count; + sBlk.s_magic = SQUASHFS_MAGIC; +@@ -5314,7 +5334,7 @@ printOptions: + sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, no_fragments, + always_use_fragments, duplicate_checking, exportable, + no_xattrs, comp_opts); +- sBlk.mkfs_time = time(NULL); ++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL); + + restore_filesystem: + if(progress && estimated_uncompressed) { -- 2.6.3 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel