diff --git a/tools/Makefile.am b/tools/Makefile.am index 4f8d60cb..36cfde2a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,7 @@ COMPOSEFS_HASH_CFLAGS = -DUSE_OBSTACK=0 -DTESTING=0 -DUSE_DIFF_HASH=0 bin_PROGRAMS = mkcomposefs composefs-info sbin_PROGRAMS = mount.composefs -noinst_PROGRAMS = +noinst_PROGRAMS = composefs-dump if USE_YAJL noinst_PROGRAMS += composefs-from-json @@ -27,6 +27,9 @@ composefs_info_SOURCES = composefs-info.c ../libcomposefs/hash.c composefs_info_CFLAGS = $(AM_CFLAGS) $(COMPOSEFS_HASH_CFLAGS) composefs_info_LDADD = ../libcomposefs/libcomposefs.la +composefs_dump_SOURCES = composefs-dump.c +composefs_dump_LDADD = ../libcomposefs/libcomposefs.la + composefs_fuse_SOURCES = cfs-fuse.c composefs_fuse_LDADD = ../libcomposefs/libcomposefs.la $(FUSE3_LIBS) composefs_fuse_CFLAGS = $(AM_CFLAGS) $(FUSE3_CFLAGS) @@ -45,6 +48,6 @@ endif EXTRA_DIST = test-checksums.sh $(patsubst %,test-assets/%,${TEST_ASSETS_SMALL}) $(patsubst %,test-assets/%.sha256_erofs,${TEST_ASSETS_SMALL}) check-checksums: - $(srcdir)/test-checksums.sh "${WRITER_JSON_PREFIX} $(builddir)/composefs-from-json" "$(srcdir)/test-assets" "${TEST_ASSETS}" + $(srcdir)/test-checksums.sh "${WRITER_JSON_PREFIX} $(builddir)" "$(srcdir)/test-assets" "${TEST_ASSETS}" check: check-checksums diff --git a/tools/composefs-dump.c b/tools/composefs-dump.c new file mode 100644 index 00000000..980ec975 --- /dev/null +++ b/tools/composefs-dump.c @@ -0,0 +1,94 @@ +/* lcfs + Copyright (C) 2023 Alexander Larsson + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define _GNU_SOURCE + +#include "config.h" + +#include "libcomposefs/lcfs-writer.h" +#include "libcomposefs/lcfs-utils.h" + +#include +#include +#include +#include +#include +#include + +static void usage(const char *argv0) +{ + fprintf(stderr, "usage: %s SRC DEST\n", argv0); +} + +static ssize_t write_cb(void *_file, void *buf, size_t count) +{ + FILE *file = _file; + + return fwrite(buf, 1, count, file); +} + +int main(int argc, char **argv) +{ + const char *bin = argv[0]; + int fd; + struct lcfs_node_s *root; + const char *src_path = NULL; + const char *dst_path = NULL; + struct lcfs_write_options_s options = { 0 }; + + if (argc <= 1) { + fprintf(stderr, "No source path specified\n"); + usage(bin); + exit(1); + } + src_path = argv[1]; + + if (argc <= 2) { + fprintf(stderr, "No destination path specified\n"); + usage(bin); + exit(1); + } + dst_path = argv[2]; + + fd = open(src_path, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + err(EXIT_FAILURE, "Failed to open '%s'", src_path); + } + + root = lcfs_load_node_from_fd(fd); + if (root == NULL) { + err(EXIT_FAILURE, "Failed to load '%s'", src_path); + } + + close(fd); + + options.format = LCFS_FORMAT_EROFS; + + FILE *out_file = fopen(dst_path, "we"); + if (out_file == NULL) + error(EXIT_FAILURE, errno, "failed to open '%s'", dst_path); + + options.file = out_file; + options.file_write_cb = write_cb; + + if (lcfs_write_to(root, &options) < 0) + error(EXIT_FAILURE, errno, "cannot write file"); + + lcfs_node_unref(root); + + return 0; +} diff --git a/tools/test-checksums.sh b/tools/test-checksums.sh index 52d542ab..231f69a0 100755 --- a/tools/test-checksums.sh +++ b/tools/test-checksums.sh @@ -1,12 +1,13 @@ #!/usr/bin/bash -WRITER_JSON="$1" +BINDIR="$1" ASSET_DIR="$2" TEST_ASSETS="$3" set -e tmpfile=$(mktemp /tmp/lcfs-test.XXXXXX) -trap 'rm -rf -- "$tmpfile"' EXIT +tmpfile2=$(mktemp /tmp/lcfs-test.XXXXXX) +trap 'rm -rf -- "$tmpfile" "$tmpfile2"' EXIT for format in erofs ; do for file in ${TEST_ASSETS} ; do @@ -21,12 +22,19 @@ for format in erofs ; do CAT=cat fi - $CAT $ASSET_DIR/$file | $WRITER_JSON --format=$format --out=$tmpfile - + $CAT $ASSET_DIR/$file | ${BINDIR}/composefs-from-json --format=$format --out=$tmpfile - SHA=$(sha256sum $tmpfile | awk "{print \$1}") if [ $SHA != $EXPECTED_SHA ]; then echo Invalid $format checksum of file generated from $file: $SHA, expected $EXPECTED_SHA exit 1 fi + + # Ensure dump reproduces the same file + ${BINDIR}/composefs-dump $tmpfile $tmpfile2 + if ! cmp $tmpfile $tmpfile2; then + echo Dump is not reproducible + exit 1 + fi done done