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
}