mirror of
https://github.com/kdave/btrfs-progs
synced 2025-04-25 20:47:58 +00:00
btrfs-progs: ignore devices representing paths in multipath
Currently btrfs-progs will happily enumerate any device which has a btrfs filesystem on it irrespective of its type. For the majority of use cases that's fine and there haven't been any problems with that. However, there was a recent report that in multipath scenario when running "btrfs fi show" after a path flap (path going down and then coming back up) instead of the multipath device being show the device which represents the flapped path is shown. So a multipath filesystem might look like: Label: none uuid: d3c1261f-18be-4015-9fef-6b35759dfdba Total devices 1 FS bytes used 192.00KiB devid 1 size 10.00GiB used 536.00MiB path /dev/mapper/3600140501cc1f49e5364f0093869c763 /dev/mapper/xxx is actually backed by an arbitrary number of paths, which in turn are presented to the system as ordinary SCSI devices i.e /dev/sdX. If a path flaps and a user re-runs 'btrfs fi show' the output would look like: Label: none uuid: d3c1261f-18be-4015-9fef-6b35759dfdba Total devices 1 FS bytes used 192.00KiB devid 1 size 10.00GiB used 536.00MiB path /dev/sdd This only occurs on unmounted filesystems as those are enumerated by btrfs-progs, for mounted filesystem the kernel properly deals only with the actual multipath device. Turns out the output of this command is consumed by libraries and the presence of a path device rather than the actual multipath causes issues. Fix this by checking for the presence of DM_MULTIPATH_DEVICE_PATH udev attribute as multipath path devices are tagged with this attribute by the multipath udev scripts. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f74ebeee5c
commit
681b4bd5e1
@ -14,6 +14,10 @@
|
|||||||
* Boston, MA 021110-1307, USA.
|
* Boston, MA 021110-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef STATIC_BUILD
|
||||||
|
#undef HAVE_LIBUDEV
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "kerncompat.h"
|
#include "kerncompat.h"
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -25,6 +29,10 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <blkid/blkid.h>
|
#include <blkid/blkid.h>
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
|
#ifdef HAVE_LIBUDEV
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <libudev.h>
|
||||||
|
#endif
|
||||||
#include "kernel-lib/overflow.h"
|
#include "kernel-lib/overflow.h"
|
||||||
#include "common/path-utils.h"
|
#include "common/path-utils.h"
|
||||||
#include "common/device-scan.h"
|
#include "common/device-scan.h"
|
||||||
@ -364,6 +372,42 @@ void free_seen_fsid(struct seen_fsid *seen_fsid_hash[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUDEV
|
||||||
|
static bool is_path_device(char *device_path)
|
||||||
|
{
|
||||||
|
struct udev *udev = NULL;
|
||||||
|
struct udev_device *dev = NULL;
|
||||||
|
struct stat dev_stat;
|
||||||
|
const char *val;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if (stat(device_path, &dev_stat) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
udev = udev_new();
|
||||||
|
if (!udev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dev = udev_device_new_from_devnum(udev, 'b', dev_stat.st_rdev);
|
||||||
|
if (!dev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
val = udev_device_get_property_value(dev, "DM_MULTIPATH_DEVICE_PATH");
|
||||||
|
if (val && atoi(val) > 0)
|
||||||
|
ret = true;
|
||||||
|
out:
|
||||||
|
udev_device_unref(dev);
|
||||||
|
udev_unref(udev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static bool is_path_device(char *device_path)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int btrfs_scan_devices(int verbose)
|
int btrfs_scan_devices(int verbose)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
@ -394,6 +438,9 @@ int btrfs_scan_devices(int verbose)
|
|||||||
/* if we are here its definitely a btrfs disk*/
|
/* if we are here its definitely a btrfs disk*/
|
||||||
strncpy_null(path, blkid_dev_devname(dev));
|
strncpy_null(path, blkid_dev_devname(dev));
|
||||||
|
|
||||||
|
if (is_path_device(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
error("cannot open %s: %m", path);
|
error("cannot open %s: %m", path);
|
||||||
|
Loading…
Reference in New Issue
Block a user