]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
Add build support for libbtrfsutil and implement some Btrfs methods 767/head
authorDavid Sterba <dsterba@suse.com>
Wed, 4 Jan 2023 17:18:26 +0000 (18:18 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 12 Jan 2023 14:52:37 +0000 (15:52 +0100)
- 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

configure.ac
package/snapper.changes
snapper/BtrfsUtils.cc
snapper/Makefile.am

index ff43b730e9e32ae751d8b7e0fddbd994e29ebbfb..38ed17d08e83051c1148fc08af79889d773ed8c8 100644 (file)
@@ -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)
index 5a72d9d68b68f88d7f6db72cc41faaf2605eae0d..c05ec8dc09bc50f7f6c40c3b93fb5284b908af34 100644 (file)
@@ -1,3 +1,15 @@
+-------------------------------------------------------------------
+Thu Jan 12 12:00:00 PM CET 2023 - David Sterba <dsterba@suse.cz>
+
+- 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 <lnussel@suse.com>
 
index b1ef17baff4bfd487156ec21247413b2ca56acb2..5bcd940aa133466e0f4264d6e5994040163b2648 100644 (file)
@@ -44,6 +44,9 @@
 #include "snapper/AppUtil.h"
 #include "snapper/BtrfsUtils.h"
 
+#ifdef HAVE_LIBBTRFSUTIL
+#include <btrfsutil.h>
+#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<char> 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
        }
 
 
index fe7ab6d03a893e60c2a9bd0fc2fe52db591218e9..efc5d65fc73b2007a7a021dd4f9b9bc3c6dbc919 100644 (file)
@@ -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