[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