From 4e0d2ba25e91ba248839006b948bd49151a63aac Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Fri, 28 Jul 2023 14:33:42 +0200 Subject: [PATCH] Support features sets --- CMakeLists.txt | 1 + include/dwarfs/features.h | 31 ++++++++++++++++++++ src/dwarfs/features.cpp | 59 ++++++++++++++++++++++++++++++++++++++ src/dwarfs/metadata_v2.cpp | 18 +++++++++++- thrift/metadata.thrift | 13 +++++++++ 5 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 include/dwarfs/features.h create mode 100644 src/dwarfs/features.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b400a26..dfab4426 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,7 @@ list( src/dwarfs/console_writer.cpp src/dwarfs/entry.cpp src/dwarfs/error.cpp + src/dwarfs/features.cpp src/dwarfs/file_scanner.cpp src/dwarfs/file_stat.cpp src/dwarfs/file_type.cpp diff --git a/include/dwarfs/features.h b/include/dwarfs/features.h new file mode 100644 index 00000000..83a787ee --- /dev/null +++ b/include/dwarfs/features.h @@ -0,0 +1,31 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/** + * \author Marcus Holland-Moritz (github@mhxnet.de) + * \copyright Copyright (c) Marcus Holland-Moritz + * + * This file is part of dwarfs. + * + * dwarfs 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. + * + * dwarfs 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 dwarfs. If not, see . + */ + +#pragma once + +#include +#include + +namespace dwarfs { + +std::set get_unsupported_features(std::set features); + +} // namespace dwarfs diff --git a/src/dwarfs/features.cpp b/src/dwarfs/features.cpp new file mode 100644 index 00000000..6a309171 --- /dev/null +++ b/src/dwarfs/features.cpp @@ -0,0 +1,59 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/** + * \author Marcus Holland-Moritz (github@mhxnet.de) + * \copyright Copyright (c) Marcus Holland-Moritz + * + * This file is part of dwarfs. + * + * dwarfs 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. + * + * dwarfs 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 dwarfs. If not, see . + */ + +#include +#include + +#include "dwarfs/features.h" + +namespace dwarfs { + +namespace { + +std::set supported_features{ +#ifdef DWARFS_HAVE_LIBZSTD + "zstd", +#endif +#ifdef DWARFS_HAVE_LIBLZ4 + "lz4", +#endif +#ifdef DWARFS_HAVE_LIBLZMA + "lzma", +#endif +#ifdef DWARFS_HAVE_LIBBROTLI + "brotli", +#endif +#ifdef DWARFS_HAVE_FLAC + "flac", +#endif +}; + +} // namespace + +std::set get_unsupported_features(std::set features) { + std::set rv; + std::set_difference(features.begin(), features.end(), + supported_features.begin(), supported_features.end(), + std::inserter(rv, rv.end())); + return rv; +} + +} // namespace dwarfs diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 052eb594..4faac1be 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -44,6 +44,7 @@ #include #include "dwarfs/error.h" +#include "dwarfs/features.h" #include "dwarfs/file_stat.h" #include "dwarfs/fstypes.h" #include "dwarfs/logger.h" @@ -136,6 +137,20 @@ map_frozen(std::span schema, std::span data) { return ret; } +MappedFrozen +check_frozen(MappedFrozen meta) { + if (meta.features()) { + auto unsupported = get_unsupported_features(meta.features()->thaw()); + if (!unsupported.empty()) { + DWARFS_THROW(runtime_error, + fmt::format("file system uses the following features " + "unsupported by this build: {}", + boost::join(unsupported, ", "))); + } + } + return meta; +} + void analyze_frozen(std::ostream& os, MappedFrozen const& meta, size_t total_size, int detail) { @@ -302,7 +317,8 @@ class metadata_ final : public metadata_v2::impl { std::span data, metadata_options const& options, int inode_offset, bool force_consistency_check) : data_(data) - , meta_(map_frozen(schema, data_)) + , meta_( + check_frozen(map_frozen(schema, data_))) , global_(lgr, &meta_, options.check_consistency || force_consistency_check) , root_(dir_entry_view::from_dir_entry_index(0, &global_)) diff --git a/thrift/metadata.thrift b/thrift/metadata.thrift index 0872bcbc..0ff3b2bb 100644 --- a/thrift/metadata.thrift +++ b/thrift/metadata.thrift @@ -350,6 +350,19 @@ struct metadata { 25: optional string_table compact_symlinks + //=========================================================// + // fields added with dwarfs-0.7.0, file system version 2.5 // + //=========================================================// + // preferred path separator of original file system 26: optional UInt32 preferred_path_separator + + //=========================================================// + // fields added with dwarfs-0.7.3, file system version 2.5 // + //=========================================================// + + // The set of features used in this file system image. As long + // as an older binary supports all features, it will be able + // to use images created with newer versions. + 27: optional set features }