[lxc-devel] [lxc/master] bdev: be smarter about btrfs subvolume detection

brauner on Github lxc-bot at linuxcontainers.org
Fri Aug 12 19:22:21 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 370 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160812/6aa1c34f/attachment.bin>
-------------- next part --------------
From 313e48e86c07a8494c2a0ded137930f9a41d9a8e Mon Sep 17 00:00:00 2001
From: Christian Brauner <cbrauner at suse.de>
Date: Fri, 12 Aug 2016 21:07:34 +0200
Subject: [PATCH] bdev: be smarter about btrfs subvolume detection

Signed-off-by: Christian Brauner <cbrauner at suse.de>
---
 src/lxc/bdev/lxcbtrfs.c | 27 +++++++++++++++++++++++++++
 src/lxc/bdev/lxcbtrfs.h |  5 +++++
 src/lxc/lxccontainer.c  |  4 ++++
 3 files changed, 36 insertions(+)

diff --git a/src/lxc/bdev/lxcbtrfs.c b/src/lxc/bdev/lxcbtrfs.c
index 5ee6dd3..7879d71 100644
--- a/src/lxc/bdev/lxcbtrfs.c
+++ b/src/lxc/bdev/lxcbtrfs.c
@@ -33,6 +33,7 @@
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/vfs.h>
 
 #include "bdev.h"
 #include "log.h"
@@ -142,6 +143,32 @@ bool is_btrfs_fs(const char *path)
 	return true;
 }
 
+/*
+ * Taken from btrfs toolsuite. Test if path is a subvolume.
+ *	return 0;   path exists but it is not a subvolume
+ *	return 1;   path exists and it is  a subvolume
+ *	return < 0; error
+ */
+int is_btrfs_subvol(const char *path)
+{
+	struct stat st;
+	struct statfs stfs;
+	int ret;
+
+	ret = stat(path, &st);
+	if (ret < 0)
+		return -errno;
+
+	if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode))
+		return 0;
+
+	ret = statfs(path, &stfs);
+	if (ret < 0)
+		return -errno;
+
+	return stfs.f_type == BTRFS_SUPER_MAGIC;
+}
+
 int btrfs_detect(const char *path)
 {
 	struct stat st;
diff --git a/src/lxc/bdev/lxcbtrfs.h b/src/lxc/bdev/lxcbtrfs.h
index 3b2742f..ebd8421 100644
--- a/src/lxc/bdev/lxcbtrfs.h
+++ b/src/lxc/bdev/lxcbtrfs.h
@@ -30,6 +30,10 @@
 #include <stdint.h>
 #include <byteswap.h>
 
+#ifndef BTRFS_SUPER_MAGIC
+#  define BTRFS_SUPER_MAGIC       0x9123683E
+#endif
+
 typedef uint8_t u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
@@ -404,6 +408,7 @@ char *get_btrfs_subvol_path(int fd, u64 dir_id, u64 objid, char *name,
 			    int name_len);
 int btrfs_list_get_path_rootid(int fd, u64 *treeid);
 bool is_btrfs_fs(const char *path);
+int is_btrfs_subvol(const char *path);
 bool btrfs_try_remove_subvol(const char *path);
 int btrfs_same_fs(const char *orig, const char *new);
 int btrfs_snapshot(const char *orig, const char *new);
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index ae0286f..5721977 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -2826,6 +2826,7 @@ bool should_default_to_snapshot(struct lxc_container *c0,
 	size_t l1 = strlen(c1->config_path) + strlen(c1->name) + 2;
 	char *p0 = alloca(l0 + 1);
 	char *p1 = alloca(l1 + 1);
+	char *rootfs = c0->lxc_conf->rootfs.path;
 
 	snprintf(p0, l0, "%s/%s", c0->config_path, c0->name);
 	snprintf(p1, l1, "%s/%s", c1->config_path, c1->name);
@@ -2833,6 +2834,9 @@ bool should_default_to_snapshot(struct lxc_container *c0,
 	if (!is_btrfs_fs(p0) || !is_btrfs_fs(p1))
 		return false;
 
+	if (is_btrfs_subvol(rootfs) <= 0)
+		return false;
+
 	return btrfs_same_fs(p0, p1) == 0;
 }
 


More information about the lxc-devel mailing list