Commit c36c68d8 authored by intrigeri's avatar intrigeri
Browse files

Commit Debian 3.0 (quilt) metadata

[dgit (9.14) quilt-fixup]
parent 0877c027
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Mon, 1 Nov 2021 13:06:47 +0100
X-Dgit-Generated: 1.1.3-2.0tails1 da88b43187949e327b417db1bea98ebe03586aa5
Subject: Add a rudimentary unit test for sort files
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
--- squashfs-tools-ng-1.1.3.orig/include/fstree.h
+++ squashfs-tools-ng-1.1.3/include/fstree.h
@@ -195,6 +195,9 @@ tree_node_t *fstree_add_generic(fstree_t
int fstree_from_file(fstree_t *fs, const char *filename,
const char *basepath);
+int fstree_from_file_stream(fstree_t *fs, istream_t *file,
+ const char *basepath);
+
/*
This function performs all the necessary post processing steps on the file
system tree, i.e. recursively sorting all directory entries by name,
--- squashfs-tools-ng-1.1.3.orig/lib/fstree/fstree_from_file.c
+++ squashfs-tools-ng-1.1.3/lib/fstree/fstree_from_file.c
@@ -540,16 +540,14 @@ out_desc:
return -1;
}
-int fstree_from_file(fstree_t *fs, const char *filename, const char *basepath)
+int fstree_from_file_stream(fstree_t *fs, istream_t *fp, const char *basepath)
{
+ const char *filename;
size_t line_num = 1;
- istream_t *fp;
char *line;
int ret;
- fp = istream_open_file(filename);
- if (fp == NULL)
- return -1;
+ filename = istream_get_filename(fp);
for (;;) {
ret = istream_get_line(fp, &line, &line_num,
@@ -570,10 +568,23 @@ int fstree_from_file(fstree_t *fs, const
++line_num;
}
- sqfs_destroy(fp);
return 0;
fail_line:
free(line);
- sqfs_destroy(fp);
return -1;
}
+
+int fstree_from_file(fstree_t *fs, const char *filename, const char *basepath)
+{
+ istream_t *fp;
+ int ret;
+
+ fp = istream_open_file(filename);
+ if (fp == NULL)
+ return -1;
+
+ ret = fstree_from_file_stream(fs, fp, basepath);
+
+ sqfs_destroy(fp);
+ return ret;
+}
--- squashfs-tools-ng-1.1.3.orig/tests/libfstree/Makemodule.am
+++ squashfs-tools-ng-1.1.3/tests/libfstree/Makemodule.am
@@ -55,6 +55,9 @@ test_filename_sane_w32_SOURCES = tests/l
test_filename_sane_w32_SOURCES += lib/fstree/filename_sane.c
test_filename_sane_w32_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_WIN32=1
+test_sort_file_SOURCES = tests/libfstree/sort_file.c
+test_sort_file_LDADD = libfstree.a libfstream.a libcompat.a
+
fstree_fuzz_SOURCES = tests/libfstree/fstree_fuzz.c
fstree_fuzz_LDADD = libfstree.a libfstream.a libcompat.a
@@ -63,7 +66,7 @@ FSTREE_TESTS = \
test_mknode_reg test_mknode_dir test_gen_inode_numbers \
test_add_by_path test_get_path test_fstree_sort test_fstree_from_file \
test_fstree_init test_filename_sane test_filename_sane_w32 \
- test_fstree_from_dir test_fstree_glob1
+ test_fstree_from_dir test_fstree_glob1 test_sort_file
if BUILD_TOOLS
check_PROGRAMS += $(FSTREE_TESTS)
--- /dev/null
+++ squashfs-tools-ng-1.1.3/tests/libfstree/sort_file.c
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * sort_file.c
+ *
+ * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "sqfs/block.h"
+#include "fstree.h"
+#include "../test.h"
+
+static const char *listing =
+"dir /bin 0755 0 0\n"
+"dir /lib 0755 0 0\n"
+"dir /usr 0755 0 0\n"
+"dir /usr/share 0755 0 0\n"
+"\n"
+"file /bin/chown 0755 0 0\n"
+"file /bin/ls 0755 0 0\n"
+"file /bin/chmod 0755 0 0\n"
+"file /bin/dir 0755 0 0\n"
+"file /bin/cp 0755 0 0\n"
+"file /bin/dd 0755 0 0\n"
+"file /bin/ln 0755 0 0\n"
+"file /bin/mkdir 0755 0 0\n"
+"file /bin/mknod 0755 0 0\n"
+"\n"
+"file /lib/libssl.so 0755 0 0\n"
+"file /lib/libfoobar.so 0755 0 0\n"
+"file /lib/libwhatever.so 0755 0 0\n"
+"\n"
+"file /usr/share/bla.txt 0644 0 0\n";
+
+static const char *sort_file =
+"# Blockwise reverse the order of the /bin files\n"
+" 10 [glob] /bin/mk*\n"
+" 20 [glob] /bin/ch*\n"
+" 30 [glob] /bin/d*\n"
+" 40 /bin/cp\n"
+" 50 [glob] /bin/*\n"
+"\n"
+"# Make this file appear first\n"
+" -10000 [dont_compress,dont_fragment,align] /usr/share/bla.txt";
+
+static const char *initial_order[] = {
+ "bin/chmod",
+ "bin/chown",
+ "bin/cp",
+ "bin/dd",
+ "bin/dir",
+ "bin/ln",
+ "bin/ls",
+ "bin/mkdir",
+ "bin/mknod",
+ "lib/libfoobar.so",
+ "lib/libssl.so",
+ "lib/libwhatever.so",
+ "usr/share/bla.txt",
+};
+
+static const char *after_sort_order[] = {
+ "usr/share/bla.txt",
+ "lib/libfoobar.so",
+ "lib/libssl.so",
+ "lib/libwhatever.so",
+ "bin/mkdir",
+ "bin/mknod",
+ "bin/chmod",
+ "bin/chown",
+ "bin/dd",
+ "bin/dir",
+ "bin/cp",
+ "bin/ln",
+ "bin/ls",
+};
+
+static sqfs_s64 priorities[] = {
+ -10000,
+ 0,
+ 0,
+ 0,
+ 10,
+ 10,
+ 20,
+ 20,
+ 30,
+ 30,
+ 40,
+ 50,
+ 50,
+};
+
+static int flags[] = {
+ SQFS_BLK_DONT_COMPRESS | SQFS_BLK_ALIGN | SQFS_BLK_DONT_FRAGMENT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+/*****************************************************************************/
+
+static sqfs_u8 temp_buffer[2048];
+static const char *input_file = NULL;
+
+static void destroy_noop(sqfs_object_t *obj)
+{
+ (void)obj;
+}
+
+static int memfile_load(istream_t *strm)
+{
+ strcpy((char *)temp_buffer, input_file);
+ strm->eof = true;
+ strm->buffer_used = strlen(input_file);
+ return 0;
+}
+
+static const char *get_filename(istream_t *strm)
+{
+ (void)strm;
+ return "memstream";
+}
+
+static istream_t memstream = {
+ .base = {
+ .destroy = destroy_noop,
+ },
+
+ .buffer_used = 0,
+ .buffer_offset = 0,
+ .eof = false,
+ .buffer = temp_buffer,
+
+ .precache = memfile_load,
+ .get_filename = get_filename,
+};
+
+/*****************************************************************************/
+
+int main(void)
+{
+ file_info_t *fi;
+ fstree_t fs;
+ size_t i;
+
+ input_file = listing;
+ memstream.buffer_used = 0;
+ memstream.buffer_offset = 0;
+ memstream.eof = false;
+
+ TEST_ASSERT(fstree_init(&fs, NULL) == 0);
+ TEST_ASSERT(fstree_from_file_stream(&fs, &memstream, NULL) == 0);
+
+ fstree_post_process(&fs);
+
+ for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) {
+ tree_node_t *n = container_of(fi, tree_node_t, data.file);
+ char *path = fstree_get_path(n);
+ int ret;
+
+ TEST_NOT_NULL(path);
+
+ ret = canonicalize_name(path);
+ TEST_EQUAL_I(ret, 0);
+
+ TEST_STR_EQUAL(initial_order[i], path);
+ free(path);
+
+ TEST_EQUAL_I(fi->priority, 0);
+ TEST_EQUAL_I(fi->flags, 0);
+ }
+
+ TEST_EQUAL_UI(i, sizeof(initial_order) / sizeof(initial_order[0]));
+
+
+ input_file = sort_file;
+ memstream.buffer_used = 0;
+ memstream.buffer_offset = 0;
+ memstream.eof = false;
+
+ TEST_ASSERT(fstree_sort_files(&fs, &memstream) == 0);
+
+ for (i = 0, fi = fs.files; fi != NULL; fi = fi->next, ++i) {
+ tree_node_t *n = container_of(fi, tree_node_t, data.file);
+ char *path = fstree_get_path(n);
+ int ret;
+
+ TEST_NOT_NULL(path);
+
+ ret = canonicalize_name(path);
+ TEST_EQUAL_I(ret, 0);
+
+ TEST_STR_EQUAL(after_sort_order[i], path);
+ free(path);
+
+ TEST_EQUAL_I(fi->priority, priorities[i]);
+ TEST_EQUAL_I(fi->flags, flags[i]);
+ }
+
+ TEST_EQUAL_UI(i, sizeof(after_sort_order) /
+ sizeof(after_sort_order[0]));
+
+ fstree_cleanup(&fs);
+ return EXIT_SUCCESS;
+}
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Mon, 1 Nov 2021 12:02:02 +0100
X-Dgit-Generated: 1.1.3-2.0tails1 709273e99cc5fcfeb5a7165dd6192676bf823141
Subject: Add a sort-file option to gensquashfs
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
--- squashfs-tools-ng-1.1.3.orig/bin/gensquashfs/mkfs.c
+++ squashfs-tools-ng-1.1.3/bin/gensquashfs/mkfs.c
@@ -52,7 +52,7 @@ static int pack_files(sqfs_block_process
return -1;
}
- flags = 0;
+ flags = fi->flags;
filesize = file->get_size(file);
if (opt->no_tail_packing && filesize > opt->cfg.block_size)
@@ -141,6 +141,7 @@ static void override_owner_dfs(const opt
int main(int argc, char **argv)
{
int status = EXIT_FAILURE;
+ istream_t *sortfile = NULL;
void *sehnd = NULL;
sqfs_writer_t sqfs;
options_t opt;
@@ -156,6 +157,12 @@ int main(int argc, char **argv)
goto out;
}
+ if (opt.sortfile != NULL) {
+ sortfile = istream_open_file(opt.sortfile);
+ if (sortfile == NULL)
+ goto out;
+ }
+
if (opt.infile == NULL) {
if (fstree_from_dir(&sqfs.fs, sqfs.fs.root, opt.packdir,
NULL, NULL, opt.dirscan_flags)) {
@@ -179,6 +186,11 @@ int main(int argc, char **argv)
}
}
+ if (sortfile != NULL) {
+ if (fstree_sort_files(&sqfs.fs, sortfile))
+ goto out;
+ }
+
if (pack_files(sqfs.data, &sqfs.fs, &opt))
goto out;
@@ -190,6 +202,8 @@ out:
sqfs_writer_cleanup(&sqfs, status);
if (sehnd != NULL)
selinux_close_context_file(sehnd);
+ if (sortfile != NULL)
+ sqfs_destroy(sortfile);
free(opt.packdir);
return status;
}
--- squashfs-tools-ng-1.1.3.orig/bin/gensquashfs/mkfs.h
+++ squashfs-tools-ng-1.1.3/bin/gensquashfs/mkfs.h
@@ -43,6 +43,7 @@ typedef struct {
unsigned int dirscan_flags;
const char *infile;
const char *selinux;
+ const char *sortfile;
bool no_tail_packing;
/* copied from command line or constructed from infile argument
--- squashfs-tools-ng-1.1.3.orig/bin/gensquashfs/options.c
+++ squashfs-tools-ng-1.1.3/bin/gensquashfs/options.c
@@ -35,12 +35,13 @@ static struct option long_opts[] = {
#ifdef WITH_SELINUX
{ "selinux", required_argument, NULL, 's' },
#endif
+ { "sort-file", required_argument, NULL, 'S' },
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 },
};
-static const char *short_opts = "F:D:X:c:b:B:d:u:g:j:Q:kxoefqThV"
+static const char *short_opts = "F:D:X:c:b:B:d:u:g:j:Q:S:kxoefqThV"
#ifdef WITH_SELINUX
"s:"
#endif
@@ -98,6 +99,10 @@ static const char *help_string =
" directory entries actually specify.\n"
" --all-root A short hand for `--set-uid 0 --set-gid 0`.\n"
"\n"
+" --sort-file, -S <file> Specify a \"sort file\" that can be used to\n"
+" micro manage the order of files during packing\n"
+" and behaviour (compression, fragmentation, ..)\n"
+"\n"
#ifdef WITH_SELINUX
" --selinux, -s <file> Specify an SELinux label file to get context\n"
" attributes from.\n"
@@ -169,6 +174,39 @@ const char *help_details =
" glob /usr/lib 0777 0 0 -type l -name \"*.so.*\" ./lib\n"
"\n\n";
+const char *sort_details =
+"When using a sort file, the order in which regular files are packed can be\n"
+"changed, as well as packing behaviour. Each line in the sort file consists\n"
+"of a numeric priority (can be negative, lower priority is packed first),\n"
+"followed by optional packing flags, followed by the file path.\n"
+"\n"
+"The fields are white-space separated. The flags are comma seperated and\n"
+"contained within two square bracktes. Single line comments with `#` and\n"
+"empty lines are allowed.\n"
+"\n"
+"The default priority for un-listed files is 0. The filename specifies the\n"
+"path within the SquashFS image and is normalized. If e.g. spaces at the\n"
+"beginning or end are needed, it can be enclosed in double quotes `\"`\n"
+"and back-slash can be used for escaping.\n"
+"\n"
+"The sorting algorithm is stable, so files with the same priority do not\n"
+"change place relative to each other in their initial ordering.\n"
+"\n"
+"Example:\n"
+" # Specify a packing order with file globbing\n"
+" -8000 [glob] bin/*\n"
+" -5000 [glob] lib/*\n"
+"\n"
+" # glob_no_path means * is allowed to match /\n"
+" -1000 [glob_no_path] share/*\n"
+"\n"
+" # Our boot loader needs this\n"
+" -100000 [dont_compress,dont_fragment,nosparse] boot/vmlinuz\n"
+"\n"
+" # For demonstration, a quoted filename and no flags\n"
+" 1337 \"usr/share/my \\\"special\\\" file \"\n"
+"\n\n";
+
void process_command_line(options_t *opt, int argc, char **argv)
{
bool have_compressor;
@@ -285,10 +323,14 @@ void process_command_line(options_t *opt
opt->selinux = optarg;
break;
#endif
+ case 'S':
+ opt->sortfile = optarg;
+ break;
case 'h':
printf(help_string,
SQFS_DEFAULT_BLOCK_SIZE, SQFS_DEVBLK_SIZE);
fputs(help_details, stdout);
+ fputs(sort_details, stdout);
compressor_print_available();
exit(EXIT_SUCCESS);
case 'V':
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Mon, 1 Nov 2021 11:51:49 +0100
X-Dgit-Generated: 1.1.3-2.0tails1 83e5182722ec35d01bba6405e9c7f74310f49391
Subject: Add sort-file implementation
A `flags` field and `priority` are added to all file information
structs. A news fstree function is introduced for parsing a "sort-file".
Each line in the file is space separated, and has the following format:
priority [flags] filename
Priority is a 64 bit number, flags are optional and filename can be put
in quotes if it is supposed to start or end with spaces. Single line
comments can be used.
The flags can be used to set block-processor flags (e.g. don't fragment,
or don't compress), as well as instructing the parser to use file
globbing to match the filename.
After parsing the file, the list of file info structure is sorted
according to the priority (default is 0) using a stable sort algorithm.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
--- squashfs-tools-ng-1.1.3.orig/include/common.h
+++ squashfs-tools-ng-1.1.3/include/common.h
@@ -33,9 +33,6 @@ typedef struct sqfs_hard_link_t {
char *target;
} sqfs_hard_link_t;
-#define container_of(ptr, type, member) \
- ((type *)((char *)ptr - offsetof(type, member)))
-
int inode_stat(const sqfs_tree_node_t *node, struct stat *sb);
char *sqfs_tree_node_get_path(const sqfs_tree_node_t *node);
--- squashfs-tools-ng-1.1.3.orig/include/fstree.h
+++ squashfs-tools-ng-1.1.3/include/fstree.h
@@ -15,6 +15,7 @@
#include <stdio.h>
#include "sqfs/predef.h"
+#include "fstream.h"
#include "compat.h"
enum {
@@ -41,6 +42,9 @@ typedef struct file_info_t file_info_t;
typedef struct dir_info_t dir_info_t;
typedef struct fstree_t fstree_t;
+#define container_of(ptr, type, member) \
+ ((type *)((char *)ptr - offsetof(type, member)))
+
/*
Optionally used by fstree_from_dir and fstree_from_subdir to
execute custom actions for each discovered node.
@@ -59,6 +63,11 @@ struct file_info_t {
char *input_file;
sqfs_inode_generic_t *inode;
+
+ /* used by sort file processing */
+ sqfs_s64 priority;
+ int flags;
+ bool already_matched;
};
/* Additional meta data stored in a tree_node_t for directories */
@@ -274,4 +283,6 @@ int fstree_from_subdir(fstree_t *fs, tre
const char *path, const char *subdir,
scan_node_callback cb, void *user, unsigned int flags);
+int fstree_sort_files(fstree_t *fs, istream_t *sortfile);
+
#endif /* FSTREE_H */
--- squashfs-tools-ng-1.1.3.orig/lib/fstree/Makemodule.am
+++ squashfs-tools-ng-1.1.3/lib/fstree/Makemodule.am
@@ -7,6 +7,7 @@ libfstree_a_SOURCES += include/fstree.h
libfstree_a_SOURCES += lib/fstree/source_date_epoch.c
libfstree_a_SOURCES += lib/fstree/canonicalize_name.c
libfstree_a_SOURCES += lib/fstree/filename_sane.c
+libfstree_a_SOURCES += lib/fstree/sort_by_file.c
libfstree_a_CFLAGS = $(AM_CFLAGS)
libfstree_a_CPPFLAGS = $(AM_CPPFLAGS)
--- /dev/null
+++ squashfs-tools-ng-1.1.3/lib/fstree/sort_by_file.c
@@ -0,0 +1,366 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * sort_by_file.c
+ *
+ * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "fstree.h"
+#include "compat.h"
+
+#include "sqfs/block.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static int decode_priority(const char *filename, size_t line_no,
+ char *line, sqfs_s64 *priority)
+{
+ bool negative = false;
+ size_t i = 0;
+
+ if (line[0] == '-') {
+ negative = true;
+ i = 1;
+ }
+
+ if (!isdigit(line[i]))
+ goto fail_number;
+
+ *priority = 0;
+
+ for (; isdigit(line[i]); ++i) {
+ sqfs_s64 x = line[i] - '0';
+
+ if ((*priority) >= ((0x7FFFFFFFFFFFFFFFL - x) / 10L))
+ goto fail_ov;
+
+ (*priority) = (*priority) * 10 + x;
+ }
+
+ if (!isspace(line[i]))
+ goto fail_filename;
+
+ while (isspace(line[i]))
+ ++i;
+
+ if (line[i] == '\0')
+ goto fail_filename;
+
+ if (negative)
+ (*priority) = -(*priority);
+
+ memmove(line, line + i, strlen(line + i) + 1);
+ return 0;
+fail_number:
+ fprintf(stderr, "%s: " PRI_SZ ": Line must start with "
+ "numeric sort priority.\n",
+ filename, line_no);
+ return -1;
+fail_ov:
+ fprintf(stderr, "%s: " PRI_SZ ": Numeric overflow in sort priority.\n",
+ filename, line_no);
+ return -1;
+fail_filename:
+ fprintf(stderr, "%s: " PRI_SZ ": Expacted `<space> <filename>` "
+ "after sort priority.\n",
+ filename, line_no);
+ return -1;
+}
+