mirror of https://github.com/vitalif/e2fsprogs
Add device-mapper support to the blkid library
On systems where is multi-path storage device is problem with duplicated filesystems. The solution is select "the best" device. This is possible by device-mapper library. Short quotation from RH bugzilla: With my patch, all dm devices remains in libblkid cache. Only the top level dm devices are given high priority and more appropriate node names (i.e. /dev/mapper/*) are used. For example, if we have linear mapped dm device "ov1" over dm device "disk1p3" which is multipath mapped to /dev/sdd3 and /dev/sdh3: # dmsetup.static ls --tree ov1 (253:5) <-- /dev/mapper/ov1 or /dev/dm-5 `-disk1p3 (253:4) <-- /dev/mapper/disk1p3 or /dev/dm-4 `-disk1 (253:0) |- (8:112) <-- /dev/sdh `- (8:48) <-- /dev/sdd Original version of blkid will show: # ./orig/blkid -t LABEL=mpdisk1p3 -l /dev/sdd3: LABEL="mpdisk1p3" ... TYPE="ext3" With my patch, blkid will show: # ./deptree/blkid -t LABEL=mpdisk1p3 -l /dev/mapper/ov1: LABEL="mpdisk1p3" ... TYPE="ext3" In blkid cache, all devices are listed: # ./orig/blkid -t LABEL=mpdisk1p3 /dev/sdd3: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/sdh3: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/dm-4: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/dm-5: LABEL="mpdisk1p3" ... TYPE="ext3" # ./deptree/blkid -t LABEL=mpdisk1p3 /dev/mapper/ov1: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/sdd3: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/sdh3: LABEL="mpdisk1p3" ... TYPE="ext3" /dev/dm-4: LABEL="mpdisk1p3" ... TYPE="ext3" For more details see discussion on: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=156324 Addresses Red Hat Bug: #156324 Signed-off-by: Karel Zak <kzak@redhat.com> Signed-off-by: Peter Jones <pjones@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>bitmap-optimize
parent
d2955d2216
commit
4db2f59a71
|
@ -66,13 +66,16 @@ MKINSTALLDIRS = @MKINSTALLDIRS@
|
|||
#
|
||||
# Library definitions
|
||||
#
|
||||
DEVMAPPER_LIBS = @DEVMAPPER_LIBS@
|
||||
STATIC_DEVMAPPER_LIBS = @STATIC_DEVMAPPER_LIBS@
|
||||
|
||||
LIB = $(top_builddir)/lib
|
||||
LIBSS = $(LIB)/libss@LIB_EXT@
|
||||
LIBCOM_ERR = $(LIB)/libcom_err@LIB_EXT@
|
||||
LIBE2P = $(LIB)/libe2p@LIB_EXT@
|
||||
LIBEXT2FS = $(LIB)/libext2fs@LIB_EXT@
|
||||
LIBUUID = $(LIB)/libuuid@LIB_EXT@ @SOCKET_LIB@
|
||||
LIBBLKID = $(LIB)/libblkid@LIB_EXT@
|
||||
LIBBLKID = $(LIB)/libblkid@LIB_EXT@ $(DEVMAPPER_LIBS)
|
||||
LIBINTL = @LIBINTL@
|
||||
DEPLIBUUID = $(LIB)/libuuid@LIB_EXT@
|
||||
|
||||
|
@ -81,7 +84,7 @@ STATIC_LIBCOM_ERR = $(LIB)/libcom_err@STATIC_LIB_EXT@
|
|||
STATIC_LIBE2P = $(LIB)/libe2p@STATIC_LIB_EXT@
|
||||
STATIC_LIBEXT2FS = $(LIB)/libext2fs@STATIC_LIB_EXT@
|
||||
STATIC_LIBUUID = $(LIB)/libuuid@STATIC_LIB_EXT@ @SOCKET_LIB@
|
||||
STATIC_LIBBLKID = $(LIB)/libblkid@STATIC_LIB_EXT@
|
||||
STATIC_LIBBLKID = $(LIB)/libblkid@STATIC_LIB_EXT@ $(STATIC_DEVMAPPER_LIBS)
|
||||
DEPSTATIC_LIBUUID = $(LIB)/libuuid@STATIC_LIB_EXT@
|
||||
|
||||
PROFILED_LIBSS = $(LIB)/libss@PROFILED_LIB_EXT@
|
||||
|
|
|
@ -309,7 +309,7 @@ ac_includes_default="\
|
|||
# include <unistd.h>
|
||||
#endif"
|
||||
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS E2FSPROGS_YEAR E2FSPROGS_MONTH E2FSPROGS_DAY E2FSPROGS_VERSION build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LD CPP EGREP LINUX_INCLUDE MAINTAINER_CMT HTREE_CMT ELF_CMT BSDLIB_CMT PROFILE_CMT CHECKER_CMT LIB_EXT STATIC_LIB_EXT PROFILED_LIB_EXT SWAPFS_CMT DEBUGFS_CMT IMAGER_CMT RESIZER_CMT E2FSCK_TYPE FSCK_PROG FSCK_MAN E2INITRD_PROG E2INITRD_MAN GETTEXT_PACKAGE PACKAGE VERSION SET_MAKE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE RANLIB ac_ct_RANLIB ALLOCA GLIBC21 HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB BINARY_TYPE LN LN_S MV CP RM CHMOD AWK SED PERL LDCONFIG AR ac_ct_AR STRIP ac_ct_STRIP BUILD_CC SIZEOF_SHORT SIZEOF_INT SIZEOF_LONG SIZEOF_LONG_LONG SOCKET_LIB DLOPEN_LIB LINUX_CMT CYGWIN_CMT UNIX_CMT root_prefix root_bindir root_sbindir root_libdir root_sysconfdir LDFLAG_STATIC SS_DIR ET_DIR DO_TEST_SUITE INTL_FLAGS BUILD_CFLAGS BUILD_LDFLAGS LIBOBJS LTLIBOBJS'
|
||||
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS E2FSPROGS_YEAR E2FSPROGS_MONTH E2FSPROGS_DAY E2FSPROGS_VERSION build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT LD CPP EGREP LINUX_INCLUDE MAINTAINER_CMT HTREE_CMT ELF_CMT BSDLIB_CMT PROFILE_CMT CHECKER_CMT LIB_EXT STATIC_LIB_EXT PROFILED_LIB_EXT SWAPFS_CMT DEBUGFS_CMT IMAGER_CMT RESIZER_CMT E2FSCK_TYPE FSCK_PROG FSCK_MAN E2INITRD_PROG E2INITRD_MAN DEVMAPPER_REQ DEVMAPPER_PC_LIBS DEVMAPPER_LIBS STATIC_DEVMAPPER_LIBS GETTEXT_PACKAGE PACKAGE VERSION SET_MAKE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE RANLIB ac_ct_RANLIB ALLOCA GLIBC21 HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB BINARY_TYPE LN LN_S MV CP RM CHMOD AWK SED PERL LDCONFIG AR ac_ct_AR STRIP ac_ct_STRIP BUILD_CC SIZEOF_SHORT SIZEOF_INT SIZEOF_LONG SIZEOF_LONG_LONG SOCKET_LIB DLOPEN_LIB LINUX_CMT CYGWIN_CMT UNIX_CMT root_prefix root_bindir root_sbindir root_libdir root_sysconfdir LDFLAG_STATIC SS_DIR ET_DIR DO_TEST_SUITE INTL_FLAGS BUILD_CFLAGS BUILD_LDFLAGS LIBOBJS LTLIBOBJS'
|
||||
ac_subst_files='MCONFIG MAKEFILE_ELF MAKEFILE_BSDLIB MAKEFILE_PROFILE MAKEFILE_CHECKER MAKEFILE_LIBRARY'
|
||||
|
||||
# Initialize some variables set by options.
|
||||
|
@ -861,6 +861,7 @@ Optional Features:
|
|||
--enable-dynamic-e2fsck build e2fsck dynamically
|
||||
--enable-fsck build fsck wrapper program
|
||||
--enable-e2initrd-helper build e2initrd-helper program
|
||||
--enable-blkid-devmapper build with device-mapper support
|
||||
--disable-nls do not use Native Language Support
|
||||
--disable-rpath do not hardcode runtime library paths
|
||||
|
||||
|
@ -3450,6 +3451,37 @@ echo "Building e2initrd helper by default"
|
|||
fi;
|
||||
|
||||
|
||||
# Check whether --enable-blkid-devmapper or --disable-blkid-devmapper was given.
|
||||
if test "${enable_blkid_devmapper+set}" = set; then
|
||||
enableval="$enable_blkid_devmapper"
|
||||
if test "$enableval" = "no"
|
||||
then
|
||||
echo "Disabling device-mapper support"
|
||||
DEVMAPPER_REQ=''
|
||||
DEVMAPPER_LIBS=''
|
||||
STATIC_DEVMAPPER_LIBS=''
|
||||
else
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_DEVMAPPER 1
|
||||
_ACEOF
|
||||
|
||||
echo "Enabling device-mapper support"
|
||||
|
||||
DEVMAPPER_REQ='libselinux libsepol'
|
||||
DEVMAPPER_PC_LIBS='-ldevmapper'
|
||||
DEVMAPPER_LIBS='-ldevmapper -lselinux -lsepol'
|
||||
STATIC_DEVMAPPER_LIBS='/usr/lib/libdevmapper.a /usr/lib/libselinux.a /usr/lib/libsepol.a'
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
echo "Disabling device-mapper support by default"
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
|
||||
|
||||
MAKEFILE_LIBRARY=$srcdir/lib/Makefile.library
|
||||
|
||||
GETTEXT_PACKAGE=e2fsprogs
|
||||
|
@ -14969,6 +15001,10 @@ s,@FSCK_PROG@,$FSCK_PROG,;t t
|
|||
s,@FSCK_MAN@,$FSCK_MAN,;t t
|
||||
s,@E2INITRD_PROG@,$E2INITRD_PROG,;t t
|
||||
s,@E2INITRD_MAN@,$E2INITRD_MAN,;t t
|
||||
s,@DEVMAPPER_REQ@,$DEVMAPPER_REQ,;t t
|
||||
s,@DEVMAPPER_PC_LIBS@,$DEVMAPPER_PC_LIBS,;t t
|
||||
s,@DEVMAPPER_LIBS@,$DEVMAPPER_LIBS,;t t
|
||||
s,@STATIC_DEVMAPPER_LIBS@,$STATIC_DEVMAPPER_LIBS,;t t
|
||||
s,@GETTEXT_PACKAGE@,$GETTEXT_PACKAGE,;t t
|
||||
s,@PACKAGE@,$PACKAGE,;t t
|
||||
s,@VERSION@,$VERSION,;t t
|
||||
|
|
28
configure.in
28
configure.in
|
@ -480,6 +480,34 @@ echo "Building e2initrd helper by default"
|
|||
)
|
||||
AC_SUBST(E2INITRD_PROG)
|
||||
AC_SUBST(E2INITRD_MAN)
|
||||
dnl handle --enable-blkid-devmapper
|
||||
dnl
|
||||
AC_ARG_ENABLE([blkid-devmapper],
|
||||
[ --enable-blkid-devmapper build with device-mapper support],
|
||||
[if test "$enableval" = "no"
|
||||
then
|
||||
echo "Disabling device-mapper support"
|
||||
DEVMAPPER_REQ=''
|
||||
DEVMAPPER_LIBS=''
|
||||
STATIC_DEVMAPPER_LIBS=''
|
||||
else
|
||||
AC_DEFINE(HAVE_DEVMAPPER)
|
||||
echo "Enabling device-mapper support"
|
||||
|
||||
DEVMAPPER_REQ='libselinux libsepol'
|
||||
DEVMAPPER_PC_LIBS='-ldevmapper'
|
||||
DEVMAPPER_LIBS='-ldevmapper -lselinux -lsepol'
|
||||
STATIC_DEVMAPPER_LIBS='/usr/lib/libdevmapper.a /usr/lib/libselinux.a /usr/lib/libsepol.a'
|
||||
|
||||
fi]
|
||||
,
|
||||
echo "Disabling device-mapper support by default"
|
||||
)
|
||||
AC_SUBST(DEVMAPPER_REQ)
|
||||
AC_SUBST(DEVMAPPER_PC_LIBS)
|
||||
AC_SUBST(DEVMAPPER_LIBS)
|
||||
AC_SUBST(STATIC_DEVMAPPER_LIBS)
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
MAKEFILE_LIBRARY=$srcdir/lib/Makefile.library
|
||||
|
|
|
@ -37,7 +37,7 @@ ELF_SO_VERSION = 1
|
|||
ELF_IMAGE = libblkid
|
||||
ELF_MYDIR = blkid
|
||||
ELF_INSTALL_DIR = $(root_libdir)
|
||||
ELF_OTHER_LIBS = -L../.. -luuid
|
||||
ELF_OTHER_LIBS = -L../.. -luuid $(DEVMAPPER_LIBS)
|
||||
|
||||
BSDLIB_VERSION = 2.0
|
||||
BSDLIB_IMAGE = libblkid
|
||||
|
|
|
@ -6,6 +6,6 @@ includedir=@includedir@
|
|||
Name: blkid
|
||||
Description: Block device id library
|
||||
Version: @E2FSPROGS_VERSION@
|
||||
Requires: uuid
|
||||
Requires: uuid @DEVMAPPER_REQ@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lblkid
|
||||
Libs: -L${libdir} -lblkid @DEVMAPPER_PC_LIBS@
|
||||
|
|
|
@ -118,6 +118,7 @@ extern const char *blkid_devdirs[];
|
|||
/*
|
||||
* Priority settings for different types of devices
|
||||
*/
|
||||
#define BLKID_PRI_DM 40
|
||||
#define BLKID_PRI_EVMS 30
|
||||
#define BLKID_PRI_LVM 20
|
||||
#define BLKID_PRI_MD 10
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
* %End-Header%
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#if HAVE_UNISTD_H
|
||||
|
@ -35,6 +37,10 @@
|
|||
|
||||
#include "blkidP.h"
|
||||
|
||||
#ifdef HAVE_DEVMAPPER
|
||||
#include <libdevmapper.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find a dev struct in the cache by device name, if available.
|
||||
*
|
||||
|
@ -75,6 +81,10 @@ blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
|
|||
return dev;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEVMAPPER
|
||||
static int dm_device_is_leaf(const dev_t dev);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Probe a single block device to add to the device cache.
|
||||
*/
|
||||
|
@ -90,6 +100,10 @@ static void probe_one(blkid_cache cache, const char *ptname,
|
|||
list_for_each(p, &cache->bic_devs) {
|
||||
blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
|
||||
bid_devs);
|
||||
#ifdef HAVE_DEVMAPPER
|
||||
if (!dm_device_is_leaf(devno))
|
||||
continue;
|
||||
#endif
|
||||
if (tmp->bid_devno == devno) {
|
||||
if (only_if_new)
|
||||
return;
|
||||
|
@ -137,6 +151,155 @@ set_pri:
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEVMAPPER
|
||||
/*
|
||||
* device-mapper support
|
||||
*/
|
||||
static int dm_device_has_dep(const dev_t dev, const char *name)
|
||||
{
|
||||
struct dm_task *task;
|
||||
struct dm_deps *deps;
|
||||
struct dm_info info;
|
||||
int i;
|
||||
|
||||
task = dm_task_create(DM_DEVICE_DEPS);
|
||||
if (!task)
|
||||
return 0;
|
||||
|
||||
dm_task_set_name(task, name);
|
||||
dm_task_run(task);
|
||||
dm_task_get_info(task, &info);
|
||||
|
||||
if (!info.exists) {
|
||||
dm_task_destroy(task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
deps = dm_task_get_deps(task);
|
||||
if (!deps || deps->count == 0) {
|
||||
dm_task_destroy(task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < deps->count; i++) {
|
||||
dev_t dep_dev = deps->device[i];
|
||||
|
||||
if (dev == dep_dev) {
|
||||
dm_task_destroy(task);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
dm_task_destroy(task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dm_device_is_leaf(const dev_t dev)
|
||||
{
|
||||
struct dm_task *task;
|
||||
struct dm_names *names;
|
||||
unsigned int next = 0;
|
||||
int n, ret = 1;
|
||||
|
||||
task = dm_task_create(DM_DEVICE_LIST);
|
||||
if (!task)
|
||||
return 1;
|
||||
|
||||
dm_task_run(task);
|
||||
names = dm_task_get_names(task);
|
||||
if (!names || !names->dev) {
|
||||
dm_task_destroy(task);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
do {
|
||||
names = (void *)names + next;
|
||||
|
||||
if (dm_device_has_dep(dev, names->name))
|
||||
ret = 0;
|
||||
|
||||
next = names->next;
|
||||
} while (next);
|
||||
|
||||
dm_task_destroy(task);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static dev_t dm_get_devno(const char *name)
|
||||
{
|
||||
struct dm_task *task;
|
||||
struct dm_info info;
|
||||
dev_t ret = 0;
|
||||
|
||||
task = dm_task_create(DM_DEVICE_INFO);
|
||||
if (!task)
|
||||
return ret;
|
||||
|
||||
dm_task_set_name(task, name);
|
||||
dm_task_run(task);
|
||||
dm_task_get_info(task, &info);
|
||||
|
||||
if (!info.exists) {
|
||||
dm_task_destroy(task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = makedev(info.major, info.minor);
|
||||
|
||||
dm_task_destroy(task);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dm_probe_all(blkid_cache cache, int only_if_new)
|
||||
{
|
||||
struct dm_task *task;
|
||||
struct dm_names *names;
|
||||
unsigned int next = 0;
|
||||
int n;
|
||||
|
||||
task = dm_task_create(DM_DEVICE_LIST);
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
dm_task_run(task);
|
||||
names = dm_task_get_names(task);
|
||||
if (!names || !names->dev) {
|
||||
dm_task_destroy(task);
|
||||
return;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
do {
|
||||
int rc;
|
||||
char *device = NULL;
|
||||
dev_t dev = 0;
|
||||
|
||||
names = (void *)names + next;
|
||||
|
||||
rc = asprintf(&device, "/dev/mapper/%s", names->name);
|
||||
if (rc < 0)
|
||||
goto try_next;
|
||||
|
||||
dev = dm_get_devno(names->name);
|
||||
if (dev == 0)
|
||||
goto try_next;
|
||||
|
||||
if (!dm_device_is_leaf(dev))
|
||||
goto try_next;
|
||||
|
||||
probe_one(cache, device, dev, BLKID_PRI_DM, only_if_new);
|
||||
|
||||
try_next:
|
||||
next = names->next;
|
||||
} while (next);
|
||||
|
||||
dm_task_destroy(task);
|
||||
}
|
||||
#endif /* HAVE_DEVMAPPER */
|
||||
|
||||
#define PROC_PARTITIONS "/proc/partitions"
|
||||
#define VG_DIR "/proc/lvm/VGs"
|
||||
|
||||
|
@ -290,6 +453,9 @@ static int probe_all(blkid_cache cache, int only_if_new)
|
|||
return 0;
|
||||
|
||||
blkid_read_cache(cache);
|
||||
#ifdef HAVE_DEVMAPPER
|
||||
dm_probe_all(cache, only_if_new);
|
||||
#endif
|
||||
evms_probe_all(cache, only_if_new);
|
||||
#ifdef VG_DIR
|
||||
lvm_probe_all(cache, only_if_new);
|
||||
|
|
Loading…
Reference in New Issue