Skip to content

Commit

Permalink
Require libblkid
Browse files Browse the repository at this point in the history
Historically libblkid support was detected as part of configure
and optionally enabled.  This was done because at the time support
for detecting ZFS pool vdevs had just be added to libblkid and
those updated packages were not yet part of many distributions.
This is no longer the case and any reasonably current distribution
will ship a version of libblkid which can detect ZFS pool vdevs.

This patch makes libblkid mandatory at build time and libblkid
the preferred method of scanning for ZFS pools.  For distributions
which include a modern version of libblkid there is no change in
behavior.  Explicitly scanning the default search paths is still
supported and can be enabled with the '-s' command line option.

Additionally making libblkid mandatory means that the 'zpool create'
command can reliably detect if a specified device has an existing
non-ZFS filesystem (ext4, xfs) and print a warning.

Signed-off-by: Brian Behlendorf <[email protected]>
Issue openzfs#2448
  • Loading branch information
behlendorf committed Feb 25, 2016
1 parent d2f3e29 commit 9b37c5c
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 147 deletions.
10 changes: 9 additions & 1 deletion cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2080,6 +2080,9 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
*
* -o Set property=value and/or temporary mount options (without '=').
*
* -s Scan using the default search path, the libblkid cache will
* not be consulted.
*
* The import command scans for pools to import, and import pools based on pool
* name and GUID. The pool can also be renamed as part of the import process.
*/
Expand Down Expand Up @@ -2109,13 +2112,14 @@ zpool_do_import(int argc, char **argv)
boolean_t dryrun = B_FALSE;
boolean_t do_rewind = B_FALSE;
boolean_t xtreme_rewind = B_FALSE;
boolean_t do_scan = B_FALSE;
uint64_t pool_state, txg = -1ULL;
char *cachefile = NULL;
importargs_t idata = { 0 };
char *endptr;

/* check options */
while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:tT:VX")) != -1) {
while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:stT:VX")) != -1) {
switch (c) {
case 'a':
do_all = B_TRUE;
Expand Down Expand Up @@ -2173,6 +2177,9 @@ zpool_do_import(int argc, char **argv)
ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
goto error;
break;
case 's':
do_scan = B_TRUE;
break;
case 't':
flags |= ZFS_IMPORT_TEMP_NAME;
if (add_prop_list_default(zpool_prop_to_name(
Expand Down Expand Up @@ -2322,6 +2329,7 @@ zpool_do_import(int argc, char **argv)
idata.poolname = searchname;
idata.guid = searchguid;
idata.cachefile = cachefile;
idata.scan = do_scan;

pools = zpool_search_import(g_zfs, &idata);

Expand Down
11 changes: 0 additions & 11 deletions cmd/zpool/zpool_vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,7 @@
#include <sys/vtoc.h>
#include <sys/mntent.h>
#include <uuid/uuid.h>
#ifdef HAVE_LIBBLKID
#include <blkid/blkid.h>
#else
#define blkid_cache void *
#endif /* HAVE_LIBBLKID */

#include "zpool_util.h"
#include <sys/zfs_context.h>

Expand Down Expand Up @@ -374,7 +369,6 @@ static int
check_slice(const char *path, blkid_cache cache, int force, boolean_t isspare)
{
int err;
#ifdef HAVE_LIBBLKID
char *value;

/* No valid type detected device is safe to use */
Expand All @@ -400,9 +394,6 @@ check_slice(const char *path, blkid_cache cache, int force, boolean_t isspare)
}

free(value);
#else
err = check_file(path, force, isspare);
#endif /* HAVE_LIBBLKID */

return (err);
}
Expand Down Expand Up @@ -500,7 +491,6 @@ check_device(const char *path, boolean_t force,
{
static blkid_cache cache = NULL;

#ifdef HAVE_LIBBLKID
/*
* There is no easy way to add a correct blkid_put_cache() call,
* memory will be reclaimed when the command exits.
Expand All @@ -519,7 +509,6 @@ check_device(const char *path, boolean_t force,
return (-1);
}
}
#endif /* HAVE_LIBBLKID */

return (check_disk(path, cache, force, isspare, iswholedisk));
}
Expand Down
112 changes: 6 additions & 106 deletions config/user-libblkid.m4
Original file line number Diff line number Diff line change
@@ -1,113 +1,13 @@
dnl #
dnl # Check for ZFS support in libblkid. This test needs to check
dnl # more than if the library exists because we expect there are
dnl # at least 3 flavors of the library out in the wild:
dnl #
dnl # 1) blkid which has no ZFS support
dnl # 2) blkid with ZFS support and a flawed method of probing
dnl # 3) blkid with ZFS support and a working method of probing
dnl #
dnl # To handle this the check first validates that there is a version
dnl # of the library installed. If there is it creates a simulated
dnl # ZFS filesystem and then links a small test app which attempts
dnl # to detect the simualated filesystem type. If it correctly
dnl # identifies the filesystem as ZFS we can safely assume case 3).
dnl # Otherwise we disable blkid support and resort to manual probing.
dnl # Check for libblkid. Basic support for detecting ZFS pools
dnl # has existing in blkid since 2008.
dnl #
AC_DEFUN([ZFS_AC_CONFIG_USER_LIBBLKID], [
AC_ARG_WITH([blkid],
[AS_HELP_STRING([--with-blkid],
[support blkid caching @<:@default=check@:>@])],
[],
[with_blkid=check])
LIBBLKID=
AS_IF([test "x$with_blkid" = xyes],
[
AC_SUBST([LIBBLKID], ["-lblkid"])
AC_DEFINE([HAVE_LIBBLKID], 1,
[Define if you have libblkid])
])
AS_IF([test "x$with_blkid" = xcheck],
[
AC_CHECK_LIB([blkid], [blkid_get_cache],
[
AC_MSG_CHECKING([for blkid zfs support])
ZFS_DEV=`mktemp`
truncate -s 64M $ZFS_DEV
echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
dd of=$ZFS_DEV bs=1k count=8 \
seek=128 conv=notrunc &>/dev/null \
>/dev/null 2>/dev/null
echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
dd of=$ZFS_DEV bs=1k count=8 \
seek=132 conv=notrunc &>/dev/null \
>/dev/null 2>/dev/null
echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
dd of=$ZFS_DEV bs=1k count=8 \
seek=136 conv=notrunc &>/dev/null \
>/dev/null 2>/dev/null
echo -en "\x0c\xb1\xba\0\0\0\0\0" | \
dd of=$ZFS_DEV bs=1k count=8 \
seek=140 conv=notrunc &>/dev/null \
>/dev/null 2>/dev/null
saved_LIBS="$LIBS"
LIBS="-lblkid"
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[
#include <stdio.h>
#include <stdlib.h>
#include <blkid/blkid.h>
],
[
blkid_cache cache;
char *value;
if (blkid_get_cache(&cache, NULL) < 0)
return 1;
value = blkid_get_tag_value(cache, "TYPE",
"$ZFS_DEV");
if (!value) {
blkid_put_cache(cache);
return 2;
}
if (strcmp(value, "zfs_member")) {
free(value);
blkid_put_cache(cache);
return 0;
}
free(value);
blkid_put_cache(cache);
])],
[
rm -f $ZFS_DEV
AC_MSG_RESULT([yes])
AC_SUBST([LIBBLKID], ["-lblkid"])
AC_DEFINE([HAVE_LIBBLKID], 1,
[Define if you have libblkid])
],
[
rm -f $ZFS_DEV
AC_MSG_RESULT([no])
AS_IF([test "x$with_blkid" != xcheck],
[AC_MSG_FAILURE(
[--with-blkid given but unavailable])])
])
AC_CHECK_HEADER([blkid/blkid.h], [], [AC_MSG_FAILURE([
*** blkid.h missing, libblkid-devel package required])])
LIBS="$saved_LIBS"
],
[
AS_IF([test "x$with_blkid" != xcheck],
[AC_MSG_FAILURE(
[--with-blkid given but unavailable])])
]
[])
])
AC_SUBST([LIBBLKID], ["-lblkid"])
AC_DEFINE([HAVE_LIBBLKID], 1, [Define if you have libblkid])
])
1 change: 1 addition & 0 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ typedef struct importargs {
int can_be_active : 1; /* can the pool be active? */
int unique : 1; /* does 'poolname' already exist? */
int exists : 1; /* set on return if pool already exists */
int scan : 1; /* prefer scanning to libblkid cache */
} importargs_t;

extern nvlist_t *zpool_search_import(libzfs_handle_t *, importargs_t *);
Expand Down
22 changes: 6 additions & 16 deletions lib/libzfs/libzfs_import.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,8 @@
#include <sys/vtoc.h>
#include <sys/dktp/fdisk.h>
#include <sys/efi_partition.h>

#include <sys/vdev_impl.h>
#ifdef HAVE_LIBBLKID
#include <blkid/blkid.h>
#endif

#include "libzfs.h"
#include "libzfs_impl.h"

Expand Down Expand Up @@ -1203,7 +1199,6 @@ zpool_clear_label(int fd)
return (0);
}

#ifdef HAVE_LIBBLKID
/*
* Use libblkid to quickly search for zfs devices
*/
Expand Down Expand Up @@ -1273,7 +1268,6 @@ zpool_find_import_blkid(libzfs_handle_t *hdl, pool_list_t *pools)
err_blkid1:
return (err);
}
#endif /* HAVE_LIBBLKID */

char *
zpool_default_import_path[DEFAULT_IMPORT_PATH_SIZE] = {
Expand Down Expand Up @@ -1313,17 +1307,15 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)

verify(iarg->poolname == NULL || iarg->guid == 0);

/*
* Prefer to locate pool member vdevs using libblkid. Only fall
* back to legacy directory scanning when explicitly requested or
* if an error is encountered when consulted the libblkid cache.
*/
if (dirs == 0) {
#ifdef HAVE_LIBBLKID
/* Use libblkid to scan all device for their type */
if (zpool_find_import_blkid(hdl, &pools) == 0)
if (!iarg->scan && (zpool_find_import_blkid(hdl, &pools) == 0))
goto skip_scanning;

(void) zfs_error_fmt(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN, "blkid failure falling back "
"to manual probing"));
#endif /* HAVE_LIBBLKID */

dir = zpool_default_import_path;
dirs = DEFAULT_IMPORT_PATH_SIZE;
}
Expand Down Expand Up @@ -1465,9 +1457,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
goto error;
}

#ifdef HAVE_LIBBLKID
skip_scanning:
#endif
ret = get_configs(hdl, &pools, iarg->can_be_active);

error:
Expand Down
31 changes: 27 additions & 4 deletions man/man8/zpool.8
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ zpool \- configures ZFS storage pools
.LP
.nf
\fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
[\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-N\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR] [\fB-X\fR\] [\fB-T\fR\]] \fB-a\fR
[\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-N\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR] [\fB-X\fR\] [\fB-T\fR\]] [\fB-s\fR] \fB-a\fR
.fi

.LP
.nf
\fBzpool import\fR [\fB-o \fImntopts\fR\fR] [\fB-o\fR \fIproperty=value\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR]
[\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR] [\fB-X\fR] [\fB-T\fR\]] [\fB-t\fR]] \fIpool\fR |\fIid\fR [\fInewpool\fR]
[\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR] [\fB-X\fR] [\fB-T\fR\]] [\fB-t\fR]] [\fB-s\fR]
\fIpool\fR | \fIid\fR [\fInewpool\fR]
.fi

.LP
Expand Down Expand Up @@ -1322,7 +1323,7 @@ Lists destroyed pools only.
.ne 2
.mk
.na
\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-N\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR]] \fB-a\fR\fR
\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-N\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR]] [\fB-s\fR] \fB-a\fR\fR
.ad
.sp .6
.RS 4n
Expand Down Expand Up @@ -1477,13 +1478,24 @@ Specify the txg to use for rollback. Implies \fB-FX\fR. For more details about
\fBWARNING\fR: This option can be extremely hazardous to the health of your pool and should only be used as a last resort.
.RE

.sp
.ne 2
.mk
.na
\fB\fB-s\fR
.ad
.RS 21n
.rt
Scan using the default search path, the libblkid cache will not be consulted. A custom search path may be specified by setting the \fBZPOOL_IMPORT_PATH\fR environment variable.
.RE

.RE

.sp
.ne 2
.mk
.na
\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR]] [\fB-t\fR]] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
\fB\fBzpool import\fR [\fB-o\fR \fImntopts\fR] [ \fB-o\fR \fIproperty\fR=\fIvalue\fR] ... [\fB-d\fR \fIdir\fR | \fB-c\fR \fIcachefile\fR] [\fB-D\fR] [\fB-f\fR] [\fB-m\fR] [\fB-R\fR \fIroot\fR] [\fB-F\fR [\fB-n\fR]] [\fB-t\fR]] [\fB-s\fR] \fIpool\fR | \fIid\fR [\fInewpool\fR]\fR
.ad
.sp .6
.RS 4n
Expand Down Expand Up @@ -1635,6 +1647,17 @@ Used with "\fBnewpool\fR". Specifies that "\fBnewpool\fR" is temporary. Temporar
Allows a pool to import when there is a missing log device.
.RE

.sp
.ne 2
.mk
.na
\fB\fB-s\fR
.ad
.sp .6
.RS 4n
Scan using the default search path, the libblkid cache will not be consulted. A custom search path may be specified by setting the \fBZPOOL_IMPORT_PATH\fR environment variable.
.RE

.RE

.sp
Expand Down
9 changes: 0 additions & 9 deletions rpm/generic/zfs.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
%endif

%bcond_with debug
%bcond_with blkid
%bcond_with systemd

# Generic enable switch for systemd
Expand Down Expand Up @@ -89,10 +88,8 @@ Conflicts: zfs-fuse
%if 0%{?rhel}%{?fedora}%{?suse_version}
BuildRequires: zlib-devel
BuildRequires: libuuid-devel
%if %{with blkid}
BuildRequires: libblkid-devel
%endif
%endif
%if 0%{?_systemd}
Requires(post): systemd
Requires(preun): systemd
Expand Down Expand Up @@ -213,11 +210,6 @@ image which is ZFS aware.
%else
%define debug --disable-debug
%endif
%if %{with blkid}
%define blkid --with-blkid
%else
%define blkid --without-blkid
%endif
%if 0%{?_systemd}
%define systemd --enable-systemd --with-systemdunitdir=%{_unitdir} --with-systemdpresetdir=%{_presetdir} --disable-sysvinit
%else
Expand All @@ -234,7 +226,6 @@ image which is ZFS aware.
--with-dracutdir=%{_dracutdir} \
--disable-static \
%{debug} \
%{blkid} \
%{systemd}
make %{?_smp_mflags}

Expand Down

0 comments on commit 9b37c5c

Please sign in to comment.