From: David Sterba Date: Wed, 4 Jan 2023 17:18:26 +0000 (+0100) Subject: Add build support for libbtrfsutil and implement some Btrfs methods X-Git-Tag: v0.10.5~68^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6bcaec5b863a3fe9c76407aec38feb3b316e43ff;p=thirdparty%2Fsnapper.git Add build support for libbtrfsutil and implement some Btrfs methods - Use libbtrfsutil implementation for the following methods: - check if a subvolume exists - create subvolume, snapshot - subvolume read-only check - delete subvolume - set/get default subvolume - filesystem sync --- diff --git a/configure.ac b/configure.ac index ff43b730..38ed17d0 100644 --- a/configure.ac +++ b/configure.ac @@ -179,6 +179,14 @@ PKG_CHECK_MODULES(XML2, libxml-2.0) PKG_CHECK_MODULES(JSONC, json-c, [], [AC_MSG_WARN([Cannot find json-c. Please install libjson-c-devel])]) PKG_CHECK_MODULES(ZLIB, zlib) +AC_CHECK_LIB(btrfsutil, btrfs_util_strerror) +AC_CHECK_HEADERS([btrfsutil.h]) + +# Conditional support for libbtrfsutil +if test "x$ac_cv_lib_btrfsutil_btrfs_util_strerror" = "xyes"; then + PKG_CHECK_MODULES(LIBBTRFSUTIL, libbtrfsutil) +fi + AC_CHECK_HEADER(acl/libacl.h,[],[AC_MSG_ERROR([Cannout find libacl headers. Please install libacl-devel])]) AC_SUBST(VERSION) diff --git a/package/snapper.changes b/package/snapper.changes index 5a72d9d6..c05ec8dc 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Thu Jan 12 12:00:00 PM CET 2023 - David Sterba + +- Add build support for libbtrfsutil +- Use libbtrfsutil implementation for the following methods: + - check if a subvolume exists + - create subvolume, snapshot + - subvolume read-only check + - delete subvolume + - set/get default subvolume + - filesystem sync + ------------------------------------------------------------------- Tue Dec 27 13:20:38 UTC 2022 - Ludwig Nussel diff --git a/snapper/BtrfsUtils.cc b/snapper/BtrfsUtils.cc index b1ef17ba..5bcd940a 100644 --- a/snapper/BtrfsUtils.cc +++ b/snapper/BtrfsUtils.cc @@ -44,6 +44,9 @@ #include "snapper/AppUtil.h" #include "snapper/BtrfsUtils.h" +#ifdef HAVE_LIBBTRFSUTIL +#include +#endif namespace snapper { @@ -67,17 +70,35 @@ namespace snapper bool is_subvolume_read_only(int fd) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + bool readonly; + + err = btrfs_util_get_subvolume_read_only_fd(fd, &readonly); + if (err) + throw runtime_error_with_errno("btrfs_util_get_subvolume_read_only_fd() failed", errno); + + return readonly; +#else __u64 flags; if (ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_SUBVOL_GETFLAGS) failed", errno); return flags & BTRFS_SUBVOL_RDONLY; +#endif } void create_subvolume(int fddst, const string& name) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + + err = btrfs_util_create_subvolume_fd(fddst, name.c_str(), 0, NULL, NULL); + if (err) + throw runtime_error_with_errno("btrfs_util_create_subvolume_fd() failed", errno); +#else struct btrfs_ioctl_vol_args args; memset(&args, 0, sizeof(args)); @@ -85,12 +106,43 @@ namespace snapper if (ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE, &args) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_SUBVOL_CREATE) failed", errno); +#endif } void create_snapshot(int fd, int fddst, const string& name, bool read_only, qgroup_t qgroup) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + struct btrfs_util_qgroup_inherit *util_inherit = NULL; + int flags = 0; + + if (read_only) + flags |= BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY; + +#ifdef ENABLE_BTRFS_QUOTA + size_t size = sizeof(btrfs_qgroup_inherit) + sizeof(((btrfs_qgroup_inherit*) 0)->qgroups[0]); + vector buffer(size, 0); + + if (qgroup != no_qgroup) + { + struct btrfs_qgroup_inherit *inherit; + + inherit = (btrfs_qgroup_inherit*) &buffer[0]; + inherit->num_qgroups = 1; + inherit->num_ref_copies = 0; + inherit->num_excl_copies = 0; + inherit->qgroups[0] = qgroup; + util_inherit = (struct btrfs_util_qgroup_inherit *)inherit; + } +#endif + err = btrfs_util_create_snapshot_fd2(fd, fddst, name.c_str(), flags, NULL, util_inherit); + if (err && errno != ENOTTY && errno != EINVAL) + throw runtime_error_with_errno("btrfs_util_create_snapshot_fd2() failed", errno); + + /* No BTRFS_IOC_SNAP_CREATE fallback */ +#else struct btrfs_ioctl_vol_args_v2 args_v2; memset(&args_v2, 0, sizeof(args_v2)); @@ -132,12 +184,20 @@ namespace snapper if (ioctl(fddst, BTRFS_IOC_SNAP_CREATE, &args) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_SNAP_CREATE) failed", errno); +#endif } void delete_subvolume(int fd, const string& name) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + + err = btrfs_util_delete_subvolume_fd(fd, name.c_str(), 0); + if (err) + throw runtime_error_with_errno("btrfs_util_delete_subvolume_fd() failed", errno); +#else struct btrfs_ioctl_vol_args args; memset(&args, 0, sizeof(args)); @@ -145,6 +205,7 @@ namespace snapper if (ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_SNAP_DESTROY) failed", errno); +#endif } @@ -153,14 +214,32 @@ namespace snapper void set_default_id(int fd, subvolid_t id) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + + err = btrfs_util_set_default_subvolume_fd(fd, id); + if (err) + throw runtime_error_with_errno("btrfs_util_set_default_subvolume_fd() failed", errno); +#else if (ioctl(fd, BTRFS_IOC_DEFAULT_SUBVOL, &id) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_DEFAULT_SUBVOL) failed", errno); +#endif } subvolid_t get_default_id(int fd) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + uint64_t id; + + err = btrfs_util_get_default_subvolume_fd(fd, &id); + if (err) + throw runtime_error_with_errno("btrfs_util_get_default_subvolume_fd() failed", errno); + + return id; +#else struct btrfs_ioctl_search_args args; memset(&args, 0, sizeof(args)); @@ -191,6 +270,7 @@ namespace snapper throw std::runtime_error("name != default"); return btrfs_disk_key_objectid(&di->location); +#endif } @@ -229,6 +309,18 @@ namespace snapper bool does_subvolume_exist(int fd, subvolid_t subvolid) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + struct btrfs_util_subvolume_info subvol_info; + + err = btrfs_util_subvolume_info_fd(fd, subvolid, &subvol_info); + if (err == BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND) + return false; + else if (err) + throw runtime_error_with_errno("btrfs_util_subvolume_info_fd() failed", errno); + + return true; +#else struct btrfs_ioctl_search_args args; struct btrfs_ioctl_search_key* sk = &args.key; @@ -247,6 +339,7 @@ namespace snapper throw runtime_error_with_errno("ioctl(BTRFS_IOC_TREE_SEARCH) failed", errno); return sk->nr_items == 0; +#endif } #endif @@ -567,8 +660,16 @@ namespace snapper void sync(int fd) { +#ifdef HAVE_LIBBTRFSUTIL + enum btrfs_util_error err; + + err = btrfs_util_sync_fd(fd); + if (err) + throw runtime_error_with_errno("(btrfs_util_sync_fd() failed", errno); +#else if (ioctl(fd, BTRFS_IOC_SYNC) < 0) throw runtime_error_with_errno("ioctl(BTRFS_IOC_SYNC) failed", errno); +#endif } diff --git a/snapper/Makefile.am b/snapper/Makefile.am index fe7ab6d0..efc5d65f 100644 --- a/snapper/Makefile.am +++ b/snapper/Makefile.am @@ -67,6 +67,10 @@ libsnapper_la_LIBADD = -lboost_thread -lboost_system $(XML2_LIBS) -lacl $(ZLIB_L if ENABLE_ROLLBACK libsnapper_la_LIBADD += -lmount endif +if ENABLE_BTRFS +libsnapper_la_CPPFLAGS += $(LIBBTRFSUTIL_CFLAGS) +libsnapper_la_LIBADD += $(LIBBTRFSUTIL_LIBS) +endif pkgincludedir = $(includedir)/snapper