File kdump-Enumerate-all-BTRFS-devices-for-btrfs-mount-points.patch of Package kdump.21346
From: Petr Tesarik <ptesarik@suse.com>
Date: Mon, 1 Mar 2021 18:14:58 +0100
Subject: Enumerate all BTRFS devices for btrfs mount points
References: bsc#1180513
Upstream: merged
Git-commit: c45c51923cfba621af3fa90c3634f735bd8ae921
BTRFS may comprise several devices. It takes some special handling
to find them all.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
kdumptool/mounts.cc | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++-
kdumptool/mounts.h | 3 +
2 files changed, 111 insertions(+), 2 deletions(-)
--- a/kdumptool/mounts.cc
+++ b/kdumptool/mounts.cc
@@ -24,11 +24,22 @@
#include <sstream>
#include <string>
+#include <errno.h>
#include <unistd.h>
// for makedev() and friends:
#include <sys/sysmacros.h>
+// for open() and friends:
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+// for memset():
+#include <string.h>
+
+#include <linux/btrfs.h>
+
#include "global.h"
#include "debug.h"
#include "mounts.h"
@@ -353,6 +364,88 @@ FilePath PathResolver::resolve(string co
}
//}}}
+//{{{ Btrfs --------------------------------------------------------------------
+
+class Btrfs {
+protected:
+ int m_fd;
+
+public:
+ Btrfs(string const& path);
+ ~Btrfs()
+ { close(m_fd); }
+
+ int fd(void) const
+ { return m_fd; }
+
+ void getFsInfo(struct btrfs_ioctl_fs_info_args *info);
+ bool getDevInfo(struct btrfs_ioctl_dev_info_args *info,
+ unsigned long devid);
+ StringVector getDeviceList(void);
+};
+
+// -----------------------------------------------------------------------------
+Btrfs::Btrfs(string const& path)
+{
+ Debug::debug()->trace("Btrfs::Btrfs(%s)", path.c_str());
+
+ m_fd = open(path.c_str(), O_RDONLY);
+ if (m_fd < 0)
+ throw KSystemError("Cannot open " + path, errno);
+}
+
+// -----------------------------------------------------------------------------
+void Btrfs::getFsInfo(struct btrfs_ioctl_fs_info_args *info)
+{
+ if (ioctl(m_fd, BTRFS_IOC_FS_INFO, info) < 0)
+ throw KSystemError("Cannot get BTRFS filesystem info", errno);
+}
+
+// -----------------------------------------------------------------------------
+bool Btrfs::getDevInfo(struct btrfs_ioctl_dev_info_args *info,
+ unsigned long devid)
+{
+ info->devid = devid;
+ memset(&info->uuid, 0, sizeof(info->uuid));
+ int ret = ioctl(m_fd, BTRFS_IOC_DEV_INFO, info);
+ if (ret < 0) {
+ if (errno == ENODEV)
+ return false;
+ throw KSystemError("Cannot get BTRFS device info for devid=%d", devid);
+ }
+ return true;
+}
+
+//}}}
+
+// -----------------------------------------------------------------------------
+StringVector Btrfs::getDeviceList(void)
+{
+ Debug::debug()->trace("Btrfs::getDeviceList()");
+
+ struct btrfs_ioctl_fs_info_args fs_info;
+ unsigned long id;
+ StringVector ret;
+
+ getFsInfo(&fs_info);
+ for (id = 0; id <= fs_info.max_id; ++id) {
+ struct btrfs_ioctl_dev_info_args dev_info;
+ if (!getDevInfo(&dev_info, id)) {
+ Debug::debug()->dbg("Device id %d does not exist", id);
+ continue;
+ }
+ if (!dev_info.path[0]) {
+ Debug::debug()->dbg("Device id %d is missing", id);
+ continue;
+ }
+ Debug::debug()->dbg("Found device id %d: %s", id, dev_info.path);
+ ret.push_back((char*)dev_info.path);
+ }
+
+ return ret;
+}
+
+//}}}
//{{{ FilesystemTypeMap --------------------------------------------------------
// -----------------------------------------------------------------------------
@@ -361,8 +454,21 @@ void FilesystemTypeMap::addPath(FilePath
Debug::debug()->trace("FilesystemTypeMap::addPath(%s)", path.c_str());
PathMountPoint mnt(path);
- if (mnt)
- m_sources.insert(m_resolver.resolve(mnt.source()));
+ if (mnt) {
+ if (string(mnt.fstype()) == "btrfs") {
+ Debug::debug()->dbg("Enumerating %s btrfs devices", mnt.target());
+
+ Btrfs btrfs(mnt.target());
+ StringVector devices = btrfs.getDeviceList();
+ for (StringVector::iterator it = devices.begin();
+ it != devices.end();
+ ++it) {
+ m_sources.insert(m_resolver.resolve(*it));
+ }
+ } else {
+ m_sources.insert(m_resolver.resolve(mnt.source()));
+ }
+ }
}
// -----------------------------------------------------------------------------
--- a/kdumptool/mounts.h
+++ b/kdumptool/mounts.h
@@ -152,6 +152,9 @@ class MountPoint {
const char *target(void)
{ return mnt_fs_get_target(m_fs); }
+
+ const char *fstype(void)
+ { return mnt_fs_get_fstype(m_fs); }
};
//}}}