diff --git a/0001-nvdim-plugin.patch b/0001-nvdim-plugin.patch new file mode 100644 index 0000000..0cb7d5b --- /dev/null +++ b/0001-nvdim-plugin.patch @@ -0,0 +1,1685 @@ +From b0b6f77b3c75ca881bf21771f629c0716378ece2 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Mon, 29 Jan 2018 13:56:17 +0100 +Subject: [PATCH 1/4] Add the NVDIMM plugin + +Add a new plugin for working with the NVDIMM devices. Currently +only namespace management is supported. +--- + Makefile.am | 1 + + configure.ac | 6 + + dist/libblockdev.spec.in | 48 +++- + docs/libblockdev-docs.xml.in | 1 + + docs/libblockdev-sections.txt | 22 ++ + src/lib/Makefile.am | 3 +- + src/lib/blockdev.c.in | 14 +- + src/lib/plugin_apis/nvdimm.api | 206 ++++++++++++++ + src/lib/plugins.h | 1 + + src/plugins/Makefile.am | 16 ++ + src/plugins/nvdimm.c | 544 ++++++++++++++++++++++++++++++++++++ + src/plugins/nvdimm.h | 76 +++++ + src/python/gi/overrides/BlockDev.py | 43 +++ + 13 files changed, 977 insertions(+), 4 deletions(-) + create mode 100644 src/lib/plugin_apis/nvdimm.api + create mode 100644 src/plugins/nvdimm.c + create mode 100644 src/plugins/nvdimm.h + +diff --git a/Makefile.am b/Makefile.am +index ad41c1b..d30acd1 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -41,6 +41,7 @@ PLUGINS = btrfs \ + lvm \ + mdraid \ + mpath \ ++ nvdimm \ + part \ + s390 \ + swap +diff --git a/configure.ac b/configure.ac +index d41a307..4206afa 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -141,6 +141,7 @@ LIBBLOCKDEV_PLUGIN([SWAP], [swap]) + LIBBLOCKDEV_PLUGIN([KBD], [kbd]) + LIBBLOCKDEV_PLUGIN([PART], [part]) + LIBBLOCKDEV_PLUGIN([FS], [fs]) ++LIBBLOCKDEV_PLUGIN([NVDIMM], [nvdimm]) + + AM_CONDITIONAL(WITH_PART_O_WITH_FS, test "x$with_part" != "xno" -o "x$with_fs" != "xno") + +@@ -194,6 +195,11 @@ AS_IF([test "x$with_btrfs" != "xno" -o "x$with_mdraid" != "xno" -o "x$with_kbd" + [LIBBLOCKDEV_PKG_CHECK_MODULES([BYTESIZE], [bytesize >= 0.1])], + []) + ++AS_IF([test "x$with_nvdimm" != "xno"], ++ [LIBBLOCKDEV_PKG_CHECK_MODULES([UUID], [uuid]) ++ LIBBLOCKDEV_PKG_CHECK_MODULES([NDCTL], [libndctl])] ++ []) ++ + AC_SUBST([skip_patterns], [$skip_patterns]) + AC_SUBST([MAJOR_VER], [\"2\"]) + +diff --git a/dist/libblockdev.spec.in b/dist/libblockdev.spec.in +index b23bb5b..5e2f52b 100644 +--- a/dist/libblockdev.spec.in ++++ b/dist/libblockdev.spec.in +@@ -13,6 +13,7 @@ + %define with_kbd @WITH_KBD@ + %define with_part @WITH_PART@ + %define with_fs @WITH_FS@ ++%define with_nvdimm @WITH_NVDIMM@ + %define with_gi @WITH_GI@ + + # python3 is not available on older RHEL +@@ -59,11 +60,14 @@ + %if %{with_fs} != 1 + %define fs_copts --without-fs + %endif ++%if %{with_nvdimm} != 1 ++%define nvdimm_copts --without-nvdimm ++%endif + %if %{with_gi} != 1 + %define gi_copts --disable-introspection + %endif + +-%define configure_opts %{?distro_copts} %{?btrfs_copts} %{?crypto_copts} %{?dm_copts} %{?loop_copts} %{?lvm_copts} %{?lvm_dbus_copts} %{?mdraid_copts} %{?mpath_copts} %{?swap_copts} %{?kbd_copts} %{?part_copts} %{?fs_copts} %{?gi_copts} ++%define configure_opts %{?distro_copts} %{?btrfs_copts} %{?crypto_copts} %{?dm_copts} %{?loop_copts} %{?lvm_copts} %{?lvm_dbus_copts} %{?mdraid_copts} %{?mpath_copts} %{?swap_copts} %{?kbd_copts} %{?part_copts} %{?fs_copts} %{?nvdimm_copts} %{?gi_copts} + + Name: libblockdev + Version: 2.16 +@@ -394,6 +398,29 @@ This package contains header files and pkg-config files needed for development + with the libblockdev-mpath plugin/library. + %endif + ++%if %{with_nvdimm} ++%package nvdimm ++BuildRequires: ndctl-devel ++BuildRequires: libuuid-devel ++Summary: The NVDIMM plugin for the libblockdev library ++Requires: %{name}-utils%{?_isa} >= 0.11 ++Requires: ndctl ++ ++%description nvdimm ++The libblockdev library plugin (and in the same time a standalone library) ++providing the functionality related to operations with NVDIMM devices. ++ ++%package nvdimm-devel ++Summary: Development files for the libblockdev-nvdimm plugin/library ++Requires: %{name}-nvdimm%{?_isa} = %{version}-%{release} ++Requires: %{name}-utils-devel%{?_isa} ++Requires: glib2-devel ++ ++%description nvdimm-devel ++This package contains header files and pkg-config files needed for development ++with the libblockdev-nvdimm plugin/library. ++%endif ++ + + %if %{with_part} + %package part +@@ -502,6 +529,10 @@ Requires: %{name}-mdraid%{?_isa} = %{version}-%{release} + Requires: %{name}-mpath%{?_isa} = %{version}-%{release} + %endif + ++%if %{with_nvdimm} ++Requires: %{name}-nvdimm%{?_isa} = %{version}-%{release} ++%endif ++ + %if %{with_part} + Requires: %{name}-part%{?_isa} = %{version}-%{release} + %endif +@@ -580,6 +611,10 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} + %postun mpath -p /sbin/ldconfig + %endif + ++%if %{with_nvdimm} ++%ldconfig_scriptlets nvdimm ++%endif ++ + %if %{with_part} + %post part -p /sbin/ldconfig + %postun part -p /sbin/ldconfig +@@ -765,6 +800,17 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} + %endif + + ++%if %{with_nvdimm} ++%files nvdimm ++%{_libdir}/libbd_nvdimm.so.* ++ ++%files nvdimm-devel ++%{_libdir}/libbd_nvdimm.so ++%dir %{_includedir}/blockdev ++%{_includedir}/blockdev/nvdimm.h ++%endif ++ ++ + %if %{with_part} + %files part + %{_libdir}/libbd_part.so.* +diff --git a/docs/libblockdev-docs.xml.in b/docs/libblockdev-docs.xml.in +index a758657..98aa0bf 100644 +--- a/docs/libblockdev-docs.xml.in ++++ b/docs/libblockdev-docs.xml.in +@@ -29,6 +29,7 @@ + + + ++ + + + +diff --git a/docs/libblockdev-sections.txt b/docs/libblockdev-sections.txt +index cc0ae7a..756b5b5 100644 +--- a/docs/libblockdev-sections.txt ++++ b/docs/libblockdev-sections.txt +@@ -565,3 +565,25 @@ BDS390Tech + BDS390TechMode + bd_s390_is_tech_avail + ++ ++
++nvdimm ++bd_nvdimm_check_deps ++bd_nvdimm_close ++bd_nvdimm_init ++bd_nvdimm_error_quark ++BD_NVDIMM_ERROR ++BDNVDIMMError ++BDNVDIMMNamespaceMode ++BDNVDIMMNamespaceInfo ++bd_nvdimm_namespace_get_mode_from_str ++bd_nvdimm_namespace_get_mode_str ++bd_nvdimm_namespace_enable ++bd_nvdimm_namespace_disable ++bd_nvdimm_namespace_info ++bd_nvdimm_list_namespaces ++bd_nvdimm_namespace_reconfigure ++BDNVDIMMTech ++BDNVDIMMTechMode ++bd_nvdimm_is_tech_avail ++
+diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am +index e020703..d9a91ca 100644 +--- a/src/lib/Makefile.am ++++ b/src/lib/Makefile.am +@@ -30,7 +30,8 @@ GIHEADERS = ${builddir}/plugin_apis/kbd.h \ + ${builddir}/plugin_apis/loop.h \ + ${builddir}/plugin_apis/mpath.h \ + ${builddir}/plugin_apis/part.h \ +- ${builddir}/plugin_apis/fs.h ++ ${builddir}/plugin_apis/fs.h \ ++ ${builddir}/plugin_apis/nvdimm.h + + GIHEADERS += $(wildcard ${srcdir}/../utils/*.[ch]) + GIHEADERS += blockdev.c blockdev.h plugins.c plugins.h +diff --git a/src/lib/blockdev.c.in b/src/lib/blockdev.c.in +index 2aeeac2..fd36fee 100644 +--- a/src/lib/blockdev.c.in ++++ b/src/lib/blockdev.c.in +@@ -25,6 +25,8 @@ + #include "plugin_apis/part.c" + #include "plugin_apis/fs.h" + #include "plugin_apis/fs.c" ++#include "plugin_apis/nvdimm.h" ++#include "plugin_apis/nvdimm.c" + + #if defined(__s390__) || defined(__s390x__) + #include "plugin_apis/s390.h" +@@ -59,7 +61,8 @@ static gchar * default_plugin_so[BD_PLUGIN_UNDEF] = { + "libbd_crypto.so."@MAJOR_VER@, "libbd_mpath.so."@MAJOR_VER@, + "libbd_dm.so."@MAJOR_VER@, "libbd_mdraid.so."@MAJOR_VER@, + "libbd_kbd.so."@MAJOR_VER@,"libbd_s390.so."@MAJOR_VER@, +- "libbd_part.so."@MAJOR_VER@, "libbd_fs.so."@MAJOR_VER@ ++ "libbd_part.so."@MAJOR_VER@, "libbd_fs.so."@MAJOR_VER@, ++ "libbd_nvdimm.so."@MAJOR_VER@ + }; + static BDPluginStatus plugins[BD_PLUGIN_UNDEF] = { + {{BD_PLUGIN_LVM, NULL}, NULL}, +@@ -74,9 +77,10 @@ static BDPluginStatus plugins[BD_PLUGIN_UNDEF] = { + {{BD_PLUGIN_S390, NULL}, NULL}, + {{BD_PLUGIN_PART, NULL}, NULL}, + {{BD_PLUGIN_FS, NULL}, NULL}, ++ {{BD_PLUGIN_NVDIMM, NULL}, NULL}, + }; + static gchar* plugin_names[BD_PLUGIN_UNDEF] = { +- "lvm", "btrfs", "swap", "loop", "crypto", "mpath", "dm", "mdraid", "kbd", "s390", "part", "fs" ++ "lvm", "btrfs", "swap", "loop", "crypto", "mpath", "dm", "mdraid", "kbd", "s390", "part", "fs", "nvdimm" + }; + + static void set_plugin_so_name (BDPlugin name, const gchar *so_name) { +@@ -226,6 +230,10 @@ static void unload_plugins () { + if (plugins[BD_PLUGIN_FS].handle && !unload_fs (plugins[BD_PLUGIN_FS].handle)) + g_warning ("Failed to close the fs plugin"); + plugins[BD_PLUGIN_FS].handle = NULL; ++ ++ if (plugins[BD_PLUGIN_NVDIMM].handle && !unload_nvdimm (plugins[BD_PLUGIN_NVDIMM].handle)) ++ g_warning ("Failed to close the nvdimm plugin"); ++ plugins[BD_PLUGIN_NVDIMM].handle = NULL; + } + + static void load_plugin_from_sonames (BDPlugin plugin, LoadFunc load_fn, void **handle, GSList *sonames) { +@@ -264,6 +272,8 @@ static void do_load (GSList **plugins_sonames) { + load_plugin_from_sonames (BD_PLUGIN_PART, load_part_from_plugin, &(plugins[BD_PLUGIN_PART].handle), plugins_sonames[BD_PLUGIN_PART]); + if (!plugins[BD_PLUGIN_FS].handle && plugins_sonames[BD_PLUGIN_FS]) + load_plugin_from_sonames (BD_PLUGIN_FS, load_fs_from_plugin, &(plugins[BD_PLUGIN_FS].handle), plugins_sonames[BD_PLUGIN_FS]); ++ if (!plugins[BD_PLUGIN_NVDIMM].handle && plugins_sonames[BD_PLUGIN_NVDIMM]) ++ load_plugin_from_sonames (BD_PLUGIN_NVDIMM, load_nvdimm_from_plugin, &(plugins[BD_PLUGIN_NVDIMM].handle), plugins_sonames[BD_PLUGIN_NVDIMM]); + } + + static gboolean load_plugins (BDPluginSpec **require_plugins, gboolean reload, guint64 *num_loaded) { +diff --git a/src/lib/plugin_apis/nvdimm.api b/src/lib/plugin_apis/nvdimm.api +new file mode 100644 +index 0000000..3d74f62 +--- /dev/null ++++ b/src/lib/plugin_apis/nvdimm.api +@@ -0,0 +1,206 @@ ++#include ++#include ++#include ++ ++#ifndef BD_NVDIMM_API ++#define BD_NVDIMM_API ++ ++GQuark bd_nvdimm_error_quark (void) { ++ return g_quark_from_static_string ("g-bd-nvdimm-error-quark"); ++} ++ ++#define BD_NVDIMM_ERROR bd_nvdimm_error_quark () ++typedef enum { ++ BD_NVDIMM_ERROR_NAMESPACE_PARSE, ++ BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, ++ BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL ++} BDNVDIMMError; ++ ++typedef enum { ++ BD_NVDIMM_NAMESPACE_MODE_RAW, ++ BD_NVDIMM_NAMESPACE_MODE_SECTOR, ++ BD_NVDIMM_NAMESPACE_MODE_MEMORY, ++ BD_NVDIMM_NAMESPACE_MODE_DAX, ++ BD_NVDIMM_NAMESPACE_MODE_UNKNOWN ++} BDNVDIMMNamespaceMode; ++ ++#define BD_NVDIMM_TYPE_NAMESPACE_INFO (bd_nvdimm_namespace_info_get_type ()) ++GType bd_nvdimm_namespace_info_get_type(); ++ ++/** ++ * BDNVDIMMNamespaceInfo: ++ * @dev: namespace device name ("namespaceX.Y") ++ * @mode: mode of the namespace (BDNVDIMMNamespaceMode) ++ * @size: size of the namespace ++ * @uuid: UUID of the namespace ++ * @sector_size: sector size of the namespace (0 for non-sector namespaces) ++ * @blockdev: name of the block device for the namespace ++ * @enabled: whether the namespace is enabled or not ++ */ ++typedef struct BDNVDIMMNamespaceInfo { ++ gchar *dev; ++ guint64 mode; ++ guint64 size; ++ gchar *uuid; ++ guint64 sector_size; ++ gchar *blockdev; ++ gboolean enabled; ++} BDNVDIMMNamespaceInfo; ++ ++/** ++ * bd_nvdimm_namespace_info_free: (skip) ++ * ++ * Frees @info. ++ */ ++void bd_nvdimm_namespace_info_free (BDNVDIMMNamespaceInfo *info) { ++ g_free (info->dev); ++ g_free (info->uuid); ++ g_free (info->blockdev); ++ g_free (info); ++} ++ ++/** ++ * bd_nvdimm_namespace_info_copy: (skip) ++ * ++ * Creates a new copy of @info. ++ */ ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *info) { ++ BDNVDIMMNamespaceInfo *new_info = g_new0 (BDNVDIMMNamespaceInfo, 1); ++ ++ new_info->dev = info->dev; ++ new_info->mode = info->mode; ++ new_info->size = info->size; ++ new_info->uuid = g_strdup (info->uuid); ++ new_info->sector_size = info->sector_size; ++ new_info->blockdev = g_strdup (info->blockdev); ++ new_info->enabled = info->enabled; ++ ++ return new_info; ++} ++ ++GType bd_nvdimm_namespace_info_get_type () { ++ static GType type = 0; ++ ++ if (G_UNLIKELY(type == 0)) { ++ type = g_boxed_type_register_static("BDNVDIMMNamespaceInfo", ++ (GBoxedCopyFunc) bd_nvdimm_namespace_info_copy, ++ (GBoxedFreeFunc) bd_nvdimm_namespace_info_free); ++ } ++ ++ return type; ++} ++ ++typedef enum { ++ BD_NVDIMM_TECH_NAMESPACE = 0, ++} BDNVDIMMTech; ++ ++typedef enum { ++ BD_NVDIMM_TECH_MODE_CREATE = 1 << 0, ++ BD_NVDIMM_TECH_MODE_REMOVE = 1 << 1, ++ BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE = 1 << 2, ++ BD_NVDIMM_TECH_MODE_QUERY = 1 << 3, ++ BD_NVDIMM_TECH_MODE_RECONFIGURE = 1 << 4, ++} BDNVDIMMTechMode; ++ ++/** ++ * bd_nvdimm_is_tech_avail: ++ * @tech: the queried tech ++ * @mode: a bit mask of queried modes of operation (#BDNVDIMMTechMode) for @tech ++ * @error: (out): place to store error (details about why the @tech-@mode combination is not available) ++ * ++ * Returns: whether the @tech-@mode combination is available -- supported by the ++ * plugin implementation and having all the runtime dependencies available ++ */ ++gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_get_mode_from_str: ++ * @mode_str: string representation of mode ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: mode matching the @mode_str given or %BD_NVDIMM_NAMESPACE_MODE_UNKNOWN in case of no match ++ * ++ * Tech category: always available ++ */ ++BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_get_mode_str: ++ * @mode: mode to get string representation of ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer none): string representation of @mode or %NULL in case of error ++ * ++ * Tech category: always available ++ */ ++const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_enable: ++ * @namespace: name of the namespace to enable ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @namespace was successfully enabled or not ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE ++ */ ++gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_disable: ++ * @namespace: name of the namespace to disable ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @namespace was successfully disabled or not ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE ++ */ ++gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_info: ++ * @namespace: namespace to get information about ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer full): information about given namespace or %NULL if no such ++ * namespace was found (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info (const gchar *namespace, const BDExtraArg **extra, GError **error); ++ ++/** ++ * bd_nvdimm_list_namespaces: ++ * @bus: (allow-none): return only namespaces on given bus (specified by name), ++ * %NULL may be specified to return namespaces from all buses ++ * @region: (allow-none): return only namespaces on given region (specified by regionX name or region id), ++ * %NULL may be specified to return namespaces from all regions ++ * @idle: whether to list idle (not enabled) namespaces too ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the creation (right now ++ * passed to the 'ndctl' utility) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (array zero-terminated=1): information about the namespaces on @bus and @region or ++ * %NULL if no namespaces were found (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus, const gchar *region, gboolean idle, const BDExtraArg **extra, GError **error); ++ ++/** ++ * bd_nvdimm_namespace_reconfigure: ++ * @namespace: name of the namespace to recofigure ++ * @mode: mode type to set (memory/sector/raw/dax) ++ * @error: (out): place to store error if any ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the creation (right now ++ * passed to the 'ndctl' utility) ++ * ++ * Returns: whether @namespace was successfully reconfigured or not ++ */ ++gboolean bd_nvdimm_namespace_reconfigure (const gchar* namespace, BDNVDIMMNamespaceMode mode, gboolean force, const BDExtraArg **extra, GError** error); ++ ++#endif /* BD_NVDIMM_API */ +diff --git a/src/lib/plugins.h b/src/lib/plugins.h +index 48d2217..9bc9799 100644 +--- a/src/lib/plugins.h ++++ b/src/lib/plugins.h +@@ -17,6 +17,7 @@ typedef enum { + BD_PLUGIN_S390, + BD_PLUGIN_PART, + BD_PLUGIN_FS, ++ BD_PLUGIN_NVDIMM, + BD_PLUGIN_UNDEF + } BDPlugin; + +diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am +index b69c8f7..d11bdca 100644 +--- a/src/plugins/Makefile.am ++++ b/src/plugins/Makefile.am +@@ -36,6 +36,10 @@ if WITH_MPATH + lib_LTLIBRARIES += libbd_mpath.la + endif + ++if WITH_NVDIMM ++lib_LTLIBRARIES += libbd_nvdimm.la ++endif ++ + if WITH_SWAP + lib_LTLIBRARIES += libbd_swap.la + endif +@@ -122,6 +126,14 @@ libbd_mpath_la_CPPFLAGS = -I${builddir}/../../include/ + libbd_mpath_la_SOURCES = mpath.c mpath.h check_deps.c check_deps.h + endif + ++if WITH_NVDIMM ++libbd_nvdimm_la_CFLAGS = $(GLIB_CFLAGS) $(UUID_CFLAGS) $(NDCTL_CFLAGS) -Wall -Wextra -Werror ++libbd_nvdimm_la_LIBADD = $(GLIB_LIBS) $(UUID_LIBS) $(NDCTL_LIBS) ${builddir}/../utils/libbd_utils.la ++libbd_nvdimm_la_LDFLAGS = -L${srcdir}/../utils/ -version-info 2:0:0 -Wl,--no-undefined ++libbd_nvdimm_la_CPPFLAGS = -I${builddir}/../../include/ ++libbd_nvdimm_la_SOURCES = nvdimm.c nvdimm.h check_deps.c check_deps.h ++endif ++ + if WITH_SWAP + libbd_swap_la_CFLAGS = $(GLIB_CFLAGS) -Wall -Wextra -Werror + libbd_swap_la_LIBADD = $(GLIB_LIBS) ${builddir}/../utils/libbd_utils.la +@@ -194,6 +206,10 @@ if WITH_MPATH + libinclude_HEADERS += mpath.h + endif + ++if WITH_NVDIMM ++libinclude_HEADERS += nvdimm.h ++endif ++ + if WITH_SWAP + libinclude_HEADERS += swap.h + endif +diff --git a/src/plugins/nvdimm.c b/src/plugins/nvdimm.c +new file mode 100644 +index 0000000..7a6802a +--- /dev/null ++++ b/src/plugins/nvdimm.c +@@ -0,0 +1,544 @@ ++/* ++ * Copyright (C) 2018 Red Hat, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * ++ * Author: Vojtech Trefny ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "nvdimm.h" ++#include "check_deps.h" ++ ++/** ++ * SECTION: nvdimm ++ * @short_description: plugin for operations with nvdimm space ++ * @title: NVDIMM ++ * @include: nvdimm.h ++ * ++ * A plugin for operations with NVDIMM devices. ++ */ ++ ++/** ++ * bd_nvdimm_error_quark: (skip) ++ */ ++GQuark bd_nvdimm_error_quark (void) { ++ return g_quark_from_static_string ("g-bd-nvdimm-error-quark"); ++} ++ ++void bd_nvdimm_namespace_info_free (BDNVDIMMNamespaceInfo *info) { ++ g_free (info->dev); ++ g_free (info->uuid); ++ g_free (info->blockdev); ++ g_free (info); ++} ++ ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *info) { ++ BDNVDIMMNamespaceInfo *new_info = g_new0 (BDNVDIMMNamespaceInfo, 1); ++ ++ new_info->dev = g_strdup (info->dev); ++ new_info->mode = info->mode; ++ new_info->size = info->size; ++ new_info->uuid = g_strdup (info->uuid); ++ new_info->sector_size = info->sector_size; ++ new_info->blockdev = g_strdup (info->blockdev); ++ new_info->enabled = info->enabled; ++ ++ return new_info; ++} ++ ++ ++static const gchar * const mode_str[BD_NVDIMM_NAMESPACE_MODE_UNKNOWN+1] = {"raw", "sector", "memory", "dax", "unknown"}; ++ ++static volatile guint avail_deps = 0; ++static GMutex deps_check_lock; ++ ++#define DEPS_NDCTL 0 ++#define DEPS_NDCTL_MASK (1 << DEPS_NDCTL) ++#define DEPS_LAST 1 ++ ++static UtilDep deps[DEPS_LAST] = { ++ {"ndctl", NULL, NULL, NULL}, ++}; ++ ++/** ++ * bd_nvdimm_check_deps: ++ * ++ * Returns: whether the plugin's runtime dependencies are satisfied or not ++ * ++ * Function checking plugin's runtime dependencies. ++ * ++ */ ++gboolean bd_nvdimm_check_deps () { ++ GError *error = NULL; ++ guint i = 0; ++ gboolean status = FALSE; ++ gboolean ret = TRUE; ++ ++ for (i=0; i < DEPS_LAST; i++) { ++ status = bd_utils_check_util_version (deps[i].name, deps[i].version, ++ deps[i].ver_arg, deps[i].ver_regexp, &error); ++ if (!status) ++ g_warning ("%s", error->message); ++ else ++ g_atomic_int_or (&avail_deps, 1 << i); ++ g_clear_error (&error); ++ ret = ret && status; ++ } ++ ++ if (!ret) ++ g_warning("Cannot load the NVDIMM plugin"); ++ ++ return ret; ++} ++ ++/** ++ * bd_nvdimm_init: ++ * ++ * Initializes the plugin. **This function is called automatically by the ++ * library's initialization functions.** ++ * ++ */ ++gboolean bd_nvdimm_init () { ++ /* nothing to do here */ ++ return TRUE; ++} ++ ++/** ++ * bd_nvdimm_close: ++ * ++ * Cleans up after the plugin. **This function is called automatically by the ++ * library's functions that unload it.** ++ * ++ */ ++void bd_nvdimm_close () { ++ /* nothing to do here */ ++ return; ++} ++ ++#define UNUSED __attribute__((unused)) ++ ++/** ++ * bd_nvdimm_is_tech_avail: ++ * @tech: the queried tech ++ * @mode: a bit mask of queried modes of operation (#BDNVDIMMTechMode) for @tech ++ * @error: (out): place to store error (details about why the @tech-@mode combination is not available) ++ * ++ * Returns: whether the @tech-@mode combination is available -- supported by the ++ * plugin implementation and having all the runtime dependencies available ++ */ ++gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **error) { ++ /* all tech-mode combinations are supported by this implementation of the ++ plugin, namespace reconfigure requires the 'ndctl' utility */ ++ ++ if (tech == BD_NVDIMM_TECH_NAMESPACE) { ++ if (mode & BD_NVDIMM_TECH_MODE_RECONFIGURE) ++ return check_deps (&avail_deps, DEPS_NDCTL_MASK, deps, DEPS_LAST, &deps_check_lock, error); ++ else ++ return TRUE; ++ } else { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_TECH_UNAVAIL, "Unknown technology"); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/** ++ * bd_nvdimm_namespace_get_mode_from_str: ++ * @mode_str: string representation of mode ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: mode matching the @mode_str given or %BD_NVDIMM_NAMESPACE_MODE_UNKNOWN in case of no match ++ * ++ * Tech category: always available ++ */ ++BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error) { ++ if (g_strcmp0 (mode_str, "raw") == 0) ++ return BD_NVDIMM_NAMESPACE_MODE_RAW; ++ else if (g_strcmp0 (mode_str, "sector") == 0) ++ return BD_NVDIMM_NAMESPACE_MODE_SECTOR; ++ else if (g_strcmp0 (mode_str, "memory") == 0) ++ return BD_NVDIMM_NAMESPACE_MODE_MEMORY; ++ else if (g_strcmp0 (mode_str, "dax") == 0) ++ return BD_NVDIMM_NAMESPACE_MODE_DAX; ++ else { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL, ++ "Invalid mode given: '%s'", mode_str); ++ return BD_NVDIMM_NAMESPACE_MODE_UNKNOWN; ++ } ++} ++ ++/** ++ * bd_nvdimm_namespace_get_mode_str: ++ * @mode: mode to get string representation of ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer none): string representation of @mode or %NULL in case of error ++ * ++ * Tech category: always available ++ */ ++const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error) { ++ if (mode <= BD_NVDIMM_NAMESPACE_MODE_UNKNOWN) ++ return mode_str[mode]; ++ else { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL, ++ "Invalid mode given: %d", mode); ++ return NULL; ++ } ++} ++ ++static struct ndctl_namespace* get_namespace_by_name (const gchar *namespace, struct ndctl_ctx *ctx) { ++ struct ndctl_namespace *ndns = NULL; ++ struct ndctl_region *region = NULL; ++ struct ndctl_bus *bus = NULL; ++ ++ ndctl_bus_foreach (ctx, bus) { ++ ndctl_region_foreach (bus, region) { ++ ndctl_namespace_foreach (region, ndns) { ++ if (g_strcmp0 (namespace, ndctl_namespace_get_devname (ndns)) == 0) ++ return ndns; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++/** ++ * bd_nvdimm_namespace_enable: ++ * @namespace: name of the namespace to enable ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @namespace was successfully enabled or not ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE ++ */ ++gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) { ++ struct ndctl_ctx *ctx = NULL; ++ struct ndctl_namespace *ndns = NULL; ++ gint ret = 0; ++ ++ ret = ndctl_new (&ctx); ++ if (ret != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to create ndctl context"); ++ return FALSE; ++ } ++ ++ ndns = get_namespace_by_name (namespace, ctx); ++ if (!ndns) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, ++ "Failed to enable namespace: namespace '%s' not found.", namespace); ++ return FALSE; ++ } ++ ++ ret = ndctl_namespace_enable (ndns); ++ if (ret < 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to enable namespace: %s", strerror (-ret)); ++ ndctl_unref (ctx); ++ return FALSE; ++ } ++ ++ ndctl_unref (ctx); ++ return TRUE; ++} ++ ++/** ++ * bd_nvdimm_namespace_disable: ++ * @namespace: name of the namespace to disable ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @namespace was successfully disabled or not ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE ++ */ ++gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) { ++ struct ndctl_ctx *ctx = NULL; ++ struct ndctl_namespace *ndns = NULL; ++ gint ret = 0; ++ ++ ret = ndctl_new (&ctx); ++ if (ret != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to create ndctl context"); ++ return FALSE; ++ } ++ ++ ndns = get_namespace_by_name (namespace, ctx); ++ if (!ndns) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, ++ "Failed to disable namespace: namespace '%s' not found.", namespace); ++ return FALSE; ++ } ++ ++ ret = ndctl_namespace_disable_safe (ndns); ++ if (ret != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to disable namespace: %s", strerror (-ret)); ++ ndctl_unref (ctx); ++ return FALSE; ++ } ++ ++ ndctl_unref (ctx); ++ return TRUE; ++} ++ ++static BDNVDIMMNamespaceInfo* get_nvdimm_namespace_info (struct ndctl_namespace *ndns, GError **error) { ++ struct ndctl_btt *btt; ++ struct ndctl_pfn *pfn; ++ struct ndctl_dax *dax; ++ enum ndctl_namespace_mode mode; ++ gchar uuid_buf[37] = {0}; ++ uuid_t uuid; ++ ++ btt = ndctl_namespace_get_btt (ndns); ++ dax = ndctl_namespace_get_dax (ndns); ++ pfn = ndctl_namespace_get_pfn (ndns); ++ mode = ndctl_namespace_get_mode (ndns); ++ ++ BDNVDIMMNamespaceInfo *info = g_new0 (BDNVDIMMNamespaceInfo, 1); ++ ++ info->dev = g_strdup (ndctl_namespace_get_devname (ndns)); ++ ++ switch (mode) { ++ case NDCTL_NS_MODE_MEMORY: ++ if (pfn) ++ info->size = ndctl_pfn_get_size (pfn); ++ else ++ info->size = ndctl_namespace_get_size (ndns); ++ info->mode = BD_NVDIMM_NAMESPACE_MODE_MEMORY; ++ break; ++ case NDCTL_NS_MODE_DAX: ++ if (!dax) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to get information about namespaces: DAX mode " ++ "detected but no DAX device found."); ++ bd_nvdimm_namespace_info_free (info); ++ return NULL; ++ } ++ info->size = ndctl_dax_get_size (dax); ++ info->mode = BD_NVDIMM_NAMESPACE_MODE_DAX; ++ break; ++ case NDCTL_NS_MODE_SAFE: ++ if (!btt) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to get information about namespaces: Sector mode " ++ "detected but no BTT device found."); ++ bd_nvdimm_namespace_info_free (info); ++ return NULL; ++ } ++ info->size = ndctl_btt_get_size (btt); ++ info->mode = BD_NVDIMM_NAMESPACE_MODE_SECTOR; ++ break; ++ case NDCTL_NS_MODE_RAW: ++ info->size = ndctl_namespace_get_size (ndns); ++ info->mode = BD_NVDIMM_NAMESPACE_MODE_RAW; ++ break; ++ default: ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to get information about namespaces: Unknow mode."); ++ bd_nvdimm_namespace_info_free (info); ++ return NULL; ++ } ++ ++ if (btt) { ++ ndctl_btt_get_uuid (btt, uuid); ++ uuid_unparse (uuid, uuid_buf); ++ info->uuid = g_strdup (uuid_buf); ++ ++ info->sector_size = ndctl_btt_get_sector_size (btt); ++ info->blockdev = g_strdup (ndctl_btt_get_block_device (btt)); ++ } else if (pfn) { ++ ndctl_pfn_get_uuid (pfn, uuid); ++ uuid_unparse (uuid, uuid_buf); ++ info->uuid = g_strdup (uuid_buf); ++ ++ info->sector_size = 0; // no sector size for memory mode ++ info->blockdev = g_strdup (ndctl_pfn_get_block_device (pfn)); ++ } else if (dax) { ++ ndctl_dax_get_uuid (dax, uuid); ++ uuid_unparse (uuid, uuid_buf); ++ info->uuid = g_strdup (uuid_buf); ++ ++ /* no sector size or blockdev for dax mode */ ++ info->sector_size = 0; ++ info->blockdev = NULL; ++ } else { ++ ndctl_namespace_get_uuid (ndns, uuid); ++ ++ if (uuid_is_null (uuid)) ++ info->uuid = NULL; ++ else { ++ uuid_unparse (uuid, uuid_buf); ++ info->uuid = g_strdup (uuid_buf); ++ } ++ ++ info->sector_size = 0; // no sector size for raw mode ++ info->blockdev = g_strdup (ndctl_namespace_get_block_device (ndns)); ++ } ++ ++ info->enabled = ndctl_namespace_is_active (ndns); ++ ++ return info; ++} ++ ++/** ++ * bd_nvdimm_namespace_info: ++ * @namespace: namespace to get information about ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer full): information about given namespace or %NULL if no such ++ * namespace was found (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info (const gchar *namespace, const BDExtraArg **extra UNUSED, GError **error) { ++ struct ndctl_ctx *ctx = NULL; ++ struct ndctl_namespace *ndns = NULL; ++ BDNVDIMMNamespaceInfo *info = NULL; ++ gint ret = 0; ++ ++ ret = ndctl_new (&ctx); ++ if (ret != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to create ndctl context"); ++ return NULL; ++ } ++ ++ ndns = get_namespace_by_name (namespace, ctx); ++ if (ndns) { ++ info = get_nvdimm_namespace_info (ndns, error); ++ ndctl_unref (ctx); ++ return info; ++ } ++ ++ ndctl_unref (ctx); ++ return NULL; ++} ++ ++/** ++ * bd_nvdimm_list_namespaces: ++ * @bus_name: (allow-none): return only namespaces on given bus (specified by name), ++ * %NULL may be specified to return namespaces from all buses ++ * @region_name: (allow-none): return only namespaces on given region (specified by 'regionX' name), ++ * %NULL may be specified to return namespaces from all regions ++ * @idle: whether to list idle (not enabled) namespaces too ++ * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (array zero-terminated=1): information about the namespaces on @bus and @region or ++ * %NULL if no namespaces were found (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus_name, const gchar *region_name, gboolean idle, const BDExtraArg **extra UNUSED, GError **error) { ++ struct ndctl_ctx *ctx = NULL; ++ struct ndctl_namespace *ndns = NULL; ++ struct ndctl_region *region = NULL; ++ struct ndctl_bus *bus = NULL; ++ gint ret = 0; ++ BDNVDIMMNamespaceInfo **info = NULL; ++ ++ GPtrArray *namespaces = g_ptr_array_new (); ++ ++ ret = ndctl_new (&ctx); ++ if (ret != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to create ndctl context"); ++ return NULL; ++ } ++ ++ ndctl_bus_foreach (ctx, bus) { ++ if (bus_name && g_strcmp0 (bus_name, ndctl_bus_get_devname (bus)) != 0) ++ continue; ++ ++ ndctl_region_foreach (bus, region) { ++ if (region_name && g_strcmp0 (bus_name, ndctl_region_get_devname (region)) != 0) ++ continue; ++ ++ ndctl_namespace_foreach (region, ndns) { ++ if (!idle && !ndctl_namespace_is_active (ndns)) ++ continue; ++ ++ BDNVDIMMNamespaceInfo *info = get_nvdimm_namespace_info (ndns, error); ++ if (!info) { ++ g_ptr_array_foreach (namespaces, (GFunc) (void *) bd_nvdimm_namespace_info_free, NULL); ++ g_ptr_array_free (namespaces, FALSE); ++ ndctl_unref (ctx); ++ return NULL; ++ } ++ ++ g_ptr_array_add (namespaces, info); ++ } ++ } ++ } ++ ++ if (namespaces->len == 0) { ++ ndctl_unref (ctx); ++ return NULL; ++ } ++ ++ g_ptr_array_add (namespaces, NULL); ++ ++ info = (BDNVDIMMNamespaceInfo **) g_ptr_array_free (namespaces, FALSE); ++ ndctl_unref (ctx); ++ ++ return info; ++} ++ ++/** ++ * bd_nvdimm_namespace_reconfigure: ++ * @namespace: name of the namespace to recofigure ++ * @mode: mode type to set ++ * @error: (out): place to store error if any ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the creation (right now ++ * passed to the 'ndctl' utility) ++ * ++ * Returns: whether @namespace was successfully reconfigured or not ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_RECONFIGURE ++ */ ++gboolean bd_nvdimm_namespace_reconfigure (const gchar* namespace, BDNVDIMMNamespaceMode mode, gboolean force, const BDExtraArg **extra, GError** error) { ++ const gchar *args[8] = {"ndctl", "create-namespace", "-e", namespace, "-m", NULL, NULL, NULL}; ++ gboolean ret = FALSE; ++ const gchar *mode_str = NULL; ++ ++ if (!check_deps (&avail_deps, DEPS_NDCTL_MASK, deps, DEPS_LAST, &deps_check_lock, error)) ++ return FALSE; ++ ++ mode_str = bd_nvdimm_namespace_get_mode_str (mode, error); ++ if (!mode_str) ++ /* error is already populated */ ++ return FALSE; ++ ++ args[5] = g_strdup (mode_str); ++ ++ if (force) ++ args[6] = "-f"; ++ ++ ret = bd_utils_exec_and_report_error (args, extra, error); ++ ++ g_free ((gchar *) args[5]); ++ return ret; ++} +diff --git a/src/plugins/nvdimm.h b/src/plugins/nvdimm.h +new file mode 100644 +index 0000000..5a1642f +--- /dev/null ++++ b/src/plugins/nvdimm.h +@@ -0,0 +1,76 @@ ++#include ++#include ++ ++#ifndef BD_NVDIMM ++#define BD_NVDIMM ++ ++GQuark bd_nvdimm_error_quark (void); ++#define BD_NVDIMM_ERROR bd_nvdimm_error_quark () ++typedef enum { ++ BD_NVDIMM_ERROR_NAMESPACE_PARSE, ++ BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ BD_NVDIMM_ERROR_NAMESPACE_NOEXIST, ++ BD_NVDIMM_ERROR_NAMESPACE_MODE_INVAL, ++ BD_NVDIMM_ERROR_TECH_UNAVAIL, ++} BDNVDIMMError; ++ ++typedef enum { ++ BD_NVDIMM_NAMESPACE_MODE_RAW, ++ BD_NVDIMM_NAMESPACE_MODE_SECTOR, ++ BD_NVDIMM_NAMESPACE_MODE_MEMORY, ++ BD_NVDIMM_NAMESPACE_MODE_DAX, ++ BD_NVDIMM_NAMESPACE_MODE_UNKNOWN ++} BDNVDIMMNamespaceMode; ++ ++typedef struct BDNVDIMMNamespaceInfo { ++ gchar *dev; ++ guint64 mode; ++ guint64 size; ++ gchar *uuid; ++ guint64 sector_size; ++ gchar *blockdev; ++ gboolean enabled; ++} BDNVDIMMNamespaceInfo; ++ ++void bd_nvdimm_namespace_info_free (BDNVDIMMNamespaceInfo *info); ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info_copy (BDNVDIMMNamespaceInfo *info); ++ ++typedef enum { ++ BD_NVDIMM_TECH_NAMESPACE = 0, ++} BDNVDIMMTech; ++ ++typedef enum { ++ BD_NVDIMM_TECH_MODE_CREATE = 1 << 0, ++ BD_NVDIMM_TECH_MODE_REMOVE = 1 << 1, ++ BD_NVDIMM_TECH_MODE_ACTIVATE_DEACTIVATE = 1 << 2, ++ BD_NVDIMM_TECH_MODE_QUERY = 1 << 3, ++ BD_NVDIMM_TECH_MODE_RECONFIGURE = 1 << 4, ++} BDNVDIMMTechMode; ++ ++/* ++ * If using the plugin as a standalone library, the following functions should ++ * be called to: ++ * ++ * check_deps() - check plugin's dependencies, returning TRUE if satisfied ++ * init() - initialize the plugin, returning TRUE on success ++ * close() - clean after the plugin at the end or if no longer used ++ * ++ */ ++gboolean bd_nvdimm_check_deps (); ++gboolean bd_nvdimm_init (); ++void bd_nvdimm_close (); ++ ++gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **error); ++ ++BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error); ++const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error); ++ ++gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra, GError **error); ++gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra, GError **error); ++ ++BDNVDIMMNamespaceInfo* bd_nvdimm_namespace_info (const gchar *namespace, const BDExtraArg **extra, GError **error); ++BDNVDIMMNamespaceInfo** bd_nvdimm_list_namespaces (const gchar *bus, const gchar *region, gboolean idle, const BDExtraArg **extra, GError **error); ++ ++gboolean bd_nvdimm_namespace_reconfigure (const gchar* namespace, BDNVDIMMNamespaceMode mode, gboolean force, const BDExtraArg **extra, GError** error); ++ ++#endif /* BD_CRYPTO */ +diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py +index fb3ffb4..dc634ab 100644 +--- a/src/python/gi/overrides/BlockDev.py ++++ b/src/python/gi/overrides/BlockDev.py +@@ -50,6 +50,7 @@ bd_plugins = { "lvm": BlockDev.Plugin.LVM, + "part": BlockDev.Plugin.PART, + "fs": BlockDev.Plugin.FS, + "s390": BlockDev.Plugin.S390, ++ "nvdimm": BlockDev.Plugin.NVDIMM, + } + + +@@ -692,6 +693,41 @@ def part_create_table(disk, type, ignore_existing=True): + __all__.append("part_create_table") + + ++_nvdimm_namespace_reconfigure = BlockDev.nvdimm_namespace_reconfigure ++@override(BlockDev.nvdimm_namespace_reconfigure) ++def nvdimm_namespace_reconfigure(namespace, mode, force=False, extra=None, **kwargs): ++ extra = _get_extra(extra, kwargs) ++ return _nvdimm_namespace_reconfigure(namespace, mode, force, extra) ++__all__.append("nvdimm_namespace_reconfigure") ++ ++_nvdimm_namespace_info = BlockDev.nvdimm_namespace_info ++@override(BlockDev.nvdimm_namespace_info) ++def nvdimm_namespace_info(namespace, extra=None, **kwargs): ++ extra = _get_extra(extra, kwargs) ++ return _nvdimm_namespace_info(namespace, extra) ++__all__.append("nvdimm_namespace_info") ++ ++_nvdimm_list_namespaces = BlockDev.nvdimm_list_namespaces ++@override(BlockDev.nvdimm_list_namespaces) ++def nvdimm_list_namespaces(bus=None, region=None, idle=False, extra=None, **kwargs): ++ extra = _get_extra(extra, kwargs) ++ return _nvdimm_list_namespaces(bus, region, idle, extra) ++__all__.append("nvdimm_list_namespaces") ++ ++_nvdimm_namespace_enable = BlockDev.nvdimm_namespace_enable ++@override(BlockDev.nvdimm_namespace_enable) ++def nvdimm_namespace_enable(namespace, extra=None, **kwargs): ++ extra = _get_extra(extra, kwargs) ++ return _nvdimm_namespace_enable(namespace, extra) ++__all__.append("nvdimm_namespace_enable") ++ ++_nvdimm_namespace_disable = BlockDev.nvdimm_namespace_disable ++@override(BlockDev.nvdimm_namespace_disable) ++def nvdimm_namespace_disable(namespace, extra=None, **kwargs): ++ extra = _get_extra(extra, kwargs) ++ return _nvdimm_namespace_disable(namespace, extra) ++__all__.append("nvdimm_namespace_disable") ++ + ## defined in this overrides only! + def plugin_specs_from_names(plugin_names): + ret = [] +@@ -886,6 +922,10 @@ class UtilsError(BlockDevError): + pass + __all__.append("UtilsError") + ++class NVDIMMError(BlockDevError): ++ pass ++__all__.append("NVDIMMError") ++ + class BlockDevNotImplementedError(NotImplementedError, BlockDevError): + pass + __all__.append("BlockDevNotImplementedError") +@@ -927,6 +967,9 @@ __all__.append("part") + fs = ErrorProxy("fs", BlockDev, [(GLib.Error, FSError)], [not_implemented_rule, fs_nofs_rule]) + __all__.append("fs") + ++nvdimm = ErrorProxy("nvdimm", BlockDev, [(GLib.Error, NVDIMMError)], [not_implemented_rule]) ++__all__.append("nvdimm") ++ + s390 = ErrorProxy("s390", BlockDev, [(GLib.Error, S390Error)], [not_implemented_rule]) + __all__.append("s390") + +-- +1.8.3.1 + + +From 2fda30f62f962eb9e10894b4d919acd013c9c93b Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Wed, 31 Jan 2018 16:27:59 +0100 +Subject: [PATCH 2/4] Add tests for the NVDIMM plugin + +--- + tests/nvdimm_test.py | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 178 insertions(+) + create mode 100644 tests/nvdimm_test.py + +diff --git a/tests/nvdimm_test.py b/tests/nvdimm_test.py +new file mode 100644 +index 0000000..b4eb43d +--- /dev/null ++++ b/tests/nvdimm_test.py +@@ -0,0 +1,178 @@ ++import json ++import os ++import unittest ++import overrides_hack ++ ++from utils import run_command, read_file, skip_on, fake_path ++from gi.repository import BlockDev, GLib ++ ++ ++@skip_on("debian", reason="NVDIMM plugin doesn't work on Debian (missing ndctl)") ++class NVDIMMTestCase(unittest.TestCase): ++ ++ requested_plugins = BlockDev.plugin_specs_from_names(("nvdimm",)) ++ ++ @classmethod ++ def setUpClass(cls): ++ if not BlockDev.is_initialized(): ++ BlockDev.init(cls.requested_plugins, None) ++ else: ++ BlockDev.reinit(cls.requested_plugins, True, None) ++ ++class NVDIMMNamespaceTestCase(NVDIMMTestCase): ++ ++ sys_info = None ++ ++ def _get_nvdimm_info(self): ++ ret, out, _err = run_command("ndctl list") ++ if ret != 0 or not out: ++ return None ++ ++ decoder = json.JSONDecoder() ++ decoded = decoder.decode(out) ++ return decoded ++ ++ def setUp(self): ++ self.sys_info = self._get_nvdimm_info() ++ if not self.sys_info: ++ self.skipTest("No NVDIMM devices available.") ++ ++ # skip the test if there is more than one device ++ # these tests change nvdimm mode a we need to be sure that we are really ++ # working with the 'fake' device created by the memmap kernel cmdline option ++ if type(self.sys_info) is not dict: ++ self.skipTest("Multiple NVDIMM devices found.") ++ ++ # skip the tests if the nvdimm is a 'fake' one ++ cmdline = read_file("/proc/cmdline") ++ if "memmap=" not in cmdline: ++ self.skipTest("NVDIMM device found, but not created by the 'memmap' kernel command-line option.") ++ ++ def _check_namespace_info(self, bd_info): ++ self.assertEqual(bd_info.dev, self.sys_info["dev"]) ++ self.assertEqual(bd_info.mode, BlockDev.nvdimm_namespace_get_mode_from_str(self.sys_info["mode"])) ++ self.assertEqual(bd_info.size, self.sys_info["size"]) ++ ++ if "uuid" in self.sys_info.keys(): ++ self.assertEqual(bd_info.uuid, self.sys_info["uuid"]) ++ else: ++ self.assertIsNone(bd_info.uuid) ++ ++ if "blockdev" in self.sys_info.keys(): ++ self.assertEqual(bd_info.blockdev, self.sys_info["blockdev"]) ++ else: ++ self.assertIsNone(bd_info.blockdev) ++ ++ if "sector_size" in self.sys_info.keys(): ++ self.assertEqual(bd_info.sector_size, self.sys_info["sector_size"]) ++ else: ++ self.assertEqual(bd_info.sector_size, 0) ++ ++ def test_namespace_info(self): ++ # get info about our 'testing' namespace ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self._check_namespace_info(info) ++ ++ info = BlockDev.nvdimm_namespace_info("definitely-not-a-namespace") ++ self.assertIsNone(info) ++ ++ def test_list_namespaces(self): ++ bd_namespaces = BlockDev.nvdimm_list_namespaces() ++ self.assertEqual(len(bd_namespaces), 1) ++ ++ self._check_namespace_info(bd_namespaces[0]) ++ ++ @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") ++ def test_enable_disable(self): ++ # non-existing/unknow namespace ++ with self.assertRaises(GLib.GError): ++ BlockDev.nvdimm_namespace_enable("definitely-not-a-namespace") ++ ++ # enable the namespace ++ ret = BlockDev.nvdimm_namespace_enable(self.sys_info["dev"]) ++ self.assertTrue(ret) ++ ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertTrue(info.enabled) ++ ++ # disable the namespace ++ ret = BlockDev.nvdimm_namespace_disable(self.sys_info["dev"]) ++ self.assertTrue(ret) ++ ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertFalse(info.enabled) ++ ++ # and enable it again ++ ret = BlockDev.nvdimm_namespace_enable(self.sys_info["dev"]) ++ self.assertTrue(ret) ++ ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertTrue(info.enabled) ++ ++ @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") ++ def test_namespace_reconfigure(self): ++ # active namespace -- reconfigure doesn't work without force ++ with self.assertRaises(GLib.GError): ++ BlockDev.nvdimm_namespace_reconfigure(self.sys_info["dev"], ++ BlockDev.NVDIMMNamespaceMode.SECTOR, ++ False) ++ ++ # non-existing/unknow mode ++ with self.assertRaises(GLib.GError): ++ BlockDev.nvdimm_namespace_reconfigure(self.sys_info["dev"], ++ BlockDev.NVDIMMNamespaceMode.UNKNOWN, ++ True) ++ ++ # non-existing/unknow namespace ++ with self.assertRaises(GLib.GError): ++ BlockDev.nvdimm_namespace_reconfigure("definitely-not-a-namespace", ++ BlockDev.NVDIMMNamespaceMode.SECTOR, ++ True) ++ ++ # switch to sector mode ++ ret = BlockDev.nvdimm_namespace_reconfigure(self.sys_info["dev"], ++ BlockDev.NVDIMMNamespaceMode.SECTOR, ++ True, extra={"-l": "512"}) ++ self.assertTrue(ret) ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertEqual(info.mode, BlockDev.NVDIMMNamespaceMode.SECTOR) ++ ++ # and now to memory mode ++ ret = BlockDev.nvdimm_namespace_reconfigure(self.sys_info["dev"], ++ BlockDev.NVDIMMNamespaceMode.MEMORY, ++ True) ++ self.assertTrue(ret) ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertEqual(info.mode, BlockDev.NVDIMMNamespaceMode.MEMORY) ++ ++ # and back to sector ++ ret = BlockDev.nvdimm_namespace_reconfigure(self.sys_info["dev"], ++ BlockDev.NVDIMMNamespaceMode.SECTOR, ++ True, extra={"-l": "512"}) ++ self.assertTrue(ret) ++ info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) ++ self.assertEqual(info.mode, BlockDev.NVDIMMNamespaceMode.SECTOR) ++ ++ ++class NVDIMMUnloadTest(NVDIMMTestCase): ++ def setUp(self): ++ # make sure the library is initialized with all plugins loaded for other ++ # tests ++ self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) ++ ++ def test_check_no_ndctl(self): ++ """Verify that checking ndctl tool availability works as expected""" ++ ++ # unload all plugins first ++ self.assertTrue(BlockDev.reinit([], True, None)) ++ ++ with fake_path(all_but="ndctl"): ++ # no ndctl tool available, the NVDIMM plugin should fail to load ++ with self.assertRaises(GLib.GError): ++ BlockDev.reinit(self.requested_plugins, True, None) ++ ++ self.assertNotIn("nvdimm", BlockDev.get_available_plugin_names()) ++ ++ # load the plugins back ++ self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) ++ self.assertIn("nvdimm", BlockDev.get_available_plugin_names()) +-- +1.8.3.1 + + +From 333bad8ceafc229b9a8c97df23715a02361aee01 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 1 Feb 2018 14:46:51 +0100 +Subject: [PATCH 3/4] Add --without-xyz to DISTCHECK_CONFIGURE_FLAGS for + disabled plugins + +We need to disable these plugins for distcheck because of missing +build dependecies etc. +--- + Makefile.am | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index d30acd1..54b89e1 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -4,6 +4,59 @@ SHELL = /bin/bash + ACLOCAL_AMFLAGS = -I m4 + DISTCHECK_CONFIGURE_FLAGS = --enable-introspection + ++if !WITH_BTRFS ++DISTCHECK_CONFIGURE_FLAGS += --without-btrfs ++endif ++ ++if !WITH_CRYPTO ++DISTCHECK_CONFIGURE_FLAGS += --without-crypto ++endif ++ ++if !WITH_DM ++DISTCHECK_CONFIGURE_FLAGS += --without-dm ++endif ++ ++if !WITH_LOOP ++DISTCHECK_CONFIGURE_FLAGS += --without-loop ++endif ++ ++if !WITH_LVM ++DISTCHECK_CONFIGURE_FLAGS += --without-lvm ++endif ++ ++if !WITH_LVM_DBUS ++DISTCHECK_CONFIGURE_FLAGS += --without-lvm-dbus ++endif ++ ++if !WITH_MDRAID ++DISTCHECK_CONFIGURE_FLAGS += --without-mdraid ++endif ++ ++if !WITH_MPATH ++DISTCHECK_CONFIGURE_FLAGS += --without-mpath ++endif ++ ++if !WITH_NVDIMM ++DISTCHECK_CONFIGURE_FLAGS += --without-nvdimm ++endif ++ ++if !WITH_SWAP ++DISTCHECK_CONFIGURE_FLAGS += --without-swap ++endif ++ ++if !WITH_KBD ++DISTCHECK_CONFIGURE_FLAGS += --without-kbd ++endif ++ ++if !WITH_PART ++DISTCHECK_CONFIGURE_FLAGS += --without-part ++endif ++ ++if !WITH_S390 ++DISTCHECK_CONFIGURE_FLAGS += --without-s390 ++endif ++ ++ + SUBDIRS = include src dist scripts data + if WITH_GTK_DOC + SUBDIRS += docs +-- +1.8.3.1 + + +From 7ebc9d20fa8b97482a109121dd016e01c4d032e4 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 6 Feb 2018 14:56:10 +0100 +Subject: [PATCH 4/4] Add function for getting NVDIMM namespace name from + devname or path + +For example getting "namespace0.0" from "pmem0" or "/dev/pmem0". +--- + docs/libblockdev-sections.txt | 1 + + src/lib/plugin_apis/nvdimm.api | 13 +++++++++ + src/plugins/nvdimm.c | 63 ++++++++++++++++++++++++++++++++++++++++++ + src/plugins/nvdimm.h | 2 ++ + tests/nvdimm_test.py | 8 ++++++ + 5 files changed, 87 insertions(+) + +diff --git a/docs/libblockdev-sections.txt b/docs/libblockdev-sections.txt +index 756b5b5..8aaa290 100644 +--- a/docs/libblockdev-sections.txt ++++ b/docs/libblockdev-sections.txt +@@ -578,6 +578,7 @@ BDNVDIMMNamespaceMode + BDNVDIMMNamespaceInfo + bd_nvdimm_namespace_get_mode_from_str + bd_nvdimm_namespace_get_mode_str ++bd_nvdimm_namespace_get_devname + bd_nvdimm_namespace_enable + bd_nvdimm_namespace_disable + bd_nvdimm_namespace_info +diff --git a/src/lib/plugin_apis/nvdimm.api b/src/lib/plugin_apis/nvdimm.api +index 3d74f62..9d5260c 100644 +--- a/src/lib/plugin_apis/nvdimm.api ++++ b/src/lib/plugin_apis/nvdimm.api +@@ -137,6 +137,19 @@ BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_s + const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error); + + /** ++ * bd_nvdimm_namespace_get_devname: ++ * @device: name or path of a block device (e.g. "/dev/pmem0") ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer full): namespace device name (e.g. "namespaceX.Y") for @device ++ * or %NULL if @device is not a NVDIMM namespace ++ * (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++gchar* bd_nvdimm_namespace_get_devname (const gchar *device, GError **error); ++ ++/** + * bd_nvdimm_namespace_enable: + * @namespace: name of the namespace to enable + * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) +diff --git a/src/plugins/nvdimm.c b/src/plugins/nvdimm.c +index 7a6802a..40ade05 100644 +--- a/src/plugins/nvdimm.c ++++ b/src/plugins/nvdimm.c +@@ -222,6 +222,69 @@ static struct ndctl_namespace* get_namespace_by_name (const gchar *namespace, st + } + + /** ++ * bd_nvdimm_namespace_get_devname: ++ * @device: name or path of a block device (e.g. "/dev/pmem0") ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: (transfer full): namespace device name (e.g. "namespaceX.Y") for @device ++ * or %NULL if @device is not a NVDIMM namespace ++ * (@error may be set to indicate error) ++ * ++ * Tech category: %BD_NVDIMM_TECH_NAMESPACE-%BD_NVDIMM_TECH_MODE_QUERY ++ */ ++gchar* bd_nvdimm_namespace_get_devname (const gchar *device, GError **error) { ++ struct ndctl_ctx *ctx = NULL; ++ struct ndctl_namespace *ndns = NULL; ++ struct ndctl_region *region = NULL; ++ struct ndctl_bus *bus = NULL; ++ gint success = 0; ++ gchar *ret = NULL; ++ ++ /* get rid of the "/dev/" prefix (if any) */ ++ if (g_str_has_prefix (device, "/dev/")) ++ device = device + 5; ++ ++ success = ndctl_new (&ctx); ++ if (success != 0) { ++ g_set_error (error, BD_NVDIMM_ERROR, BD_NVDIMM_ERROR_NAMESPACE_FAIL, ++ "Failed to create ndctl context"); ++ return FALSE; ++ } ++ ++ ndctl_bus_foreach (ctx, bus) { ++ ndctl_region_foreach (bus, region) { ++ ndctl_namespace_foreach (region, ndns) { ++ if (!ndctl_namespace_is_active (ndns)) ++ continue; ++ ++ struct ndctl_btt *btt = ndctl_namespace_get_btt (ndns); ++ struct ndctl_dax *dax = ndctl_namespace_get_dax (ndns); ++ struct ndctl_pfn *pfn = ndctl_namespace_get_pfn (ndns); ++ const gchar *blockdev = NULL; ++ ++ if (dax) ++ continue; ++ else if (btt) ++ blockdev = ndctl_btt_get_block_device (btt); ++ else if (pfn) ++ blockdev = ndctl_pfn_get_block_device (pfn); ++ else ++ blockdev = ndctl_namespace_get_block_device (ndns); ++ ++ if (g_strcmp0 (blockdev, device) == 0) { ++ ret = g_strdup (ndctl_namespace_get_devname (ndns)); ++ ndctl_unref (ctx); ++ return ret; ++ } ++ } ++ } ++ } ++ ++ ndctl_unref (ctx); ++ return NULL; ++} ++ ++/** + * bd_nvdimm_namespace_enable: + * @namespace: name of the namespace to enable + * @extra: (allow-none) (array zero-terminated=1): extra options (currently unused) +diff --git a/src/plugins/nvdimm.h b/src/plugins/nvdimm.h +index 5a1642f..fcc1038 100644 +--- a/src/plugins/nvdimm.h ++++ b/src/plugins/nvdimm.h +@@ -65,6 +65,8 @@ gboolean bd_nvdimm_is_tech_avail (BDNVDIMMTech tech, guint64 mode, GError **erro + BDNVDIMMNamespaceMode bd_nvdimm_namespace_get_mode_from_str (const gchar *mode_str, GError **error); + const gchar* bd_nvdimm_namespace_get_mode_str (BDNVDIMMNamespaceMode mode, GError **error); + ++gchar* bd_nvdimm_namespace_get_devname (const gchar *device, GError **error); ++ + gboolean bd_nvdimm_namespace_enable (const gchar *namespace, const BDExtraArg **extra, GError **error); + gboolean bd_nvdimm_namespace_disable (const gchar *namespace, const BDExtraArg **extra, GError **error); + +diff --git a/tests/nvdimm_test.py b/tests/nvdimm_test.py +index b4eb43d..92a6653 100644 +--- a/tests/nvdimm_test.py ++++ b/tests/nvdimm_test.py +@@ -73,6 +73,14 @@ class NVDIMMNamespaceTestCase(NVDIMMTestCase): + info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) + self._check_namespace_info(info) + ++ # test also that getting namespace devname from blockdev name works ++ namespace = BlockDev.nvdimm_namespace_get_devname(info.blockdev) ++ self.assertEqual(namespace, self.sys_info["dev"]) ++ ++ # should work even with path, e.g. /dev/pmem0 ++ namespace = BlockDev.nvdimm_namespace_get_devname("/dev/" + info.blockdev) ++ self.assertEqual(namespace, self.sys_info["dev"]) ++ + info = BlockDev.nvdimm_namespace_info("definitely-not-a-namespace") + self.assertIsNone(info) + +-- +1.8.3.1 + diff --git a/0002-nvdimm-nonblock-sector-size.patch b/0002-nvdimm-nonblock-sector-size.patch new file mode 100644 index 0000000..963fa0a --- /dev/null +++ b/0002-nvdimm-nonblock-sector-size.patch @@ -0,0 +1,68 @@ +From 625dc74ed3d5a2c7d1ee8dc82cecd572b8e31a35 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 20 Mar 2018 09:42:57 +0100 +Subject: [PATCH] Get sector size for non-block NVDIMM namespaces too + +ndctl utility now prints sector size for all namespaces that are +not in DAX mode, not only for namespaces in sector/block mode, so +we should do that too. +--- + src/plugins/nvdimm.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/src/plugins/nvdimm.c b/src/plugins/nvdimm.c +index 40ade055..abec7adf 100644 +--- a/src/plugins/nvdimm.c ++++ b/src/plugins/nvdimm.c +@@ -429,22 +429,19 @@ static BDNVDIMMNamespaceInfo* get_nvdimm_namespace_info (struct ndctl_namespace + uuid_unparse (uuid, uuid_buf); + info->uuid = g_strdup (uuid_buf); + +- info->sector_size = ndctl_btt_get_sector_size (btt); + info->blockdev = g_strdup (ndctl_btt_get_block_device (btt)); + } else if (pfn) { + ndctl_pfn_get_uuid (pfn, uuid); + uuid_unparse (uuid, uuid_buf); + info->uuid = g_strdup (uuid_buf); + +- info->sector_size = 0; // no sector size for memory mode + info->blockdev = g_strdup (ndctl_pfn_get_block_device (pfn)); + } else if (dax) { + ndctl_dax_get_uuid (dax, uuid); + uuid_unparse (uuid, uuid_buf); + info->uuid = g_strdup (uuid_buf); + +- /* no sector size or blockdev for dax mode */ +- info->sector_size = 0; ++ /* no blockdev for dax mode */ + info->blockdev = NULL; + } else { + ndctl_namespace_get_uuid (ndns, uuid); +@@ -456,10 +453,26 @@ static BDNVDIMMNamespaceInfo* get_nvdimm_namespace_info (struct ndctl_namespace + info->uuid = g_strdup (uuid_buf); + } + +- info->sector_size = 0; // no sector size for raw mode + info->blockdev = g_strdup (ndctl_namespace_get_block_device (ndns)); + } + ++ if (btt) ++ info->sector_size = ndctl_btt_get_sector_size (btt); ++ else if (dax) ++ /* no sector size for dax mode */ ++ info->sector_size = 0; ++ else { ++ info->sector_size = ndctl_namespace_get_sector_size (ndns); ++ ++ /* apparently the default value for sector size is 512 ++ on non DAX namespaces even if libndctl says it's 0 ++ https://github.com/pmem/ndctl/commit/a7320456f1bca5edf15352ce977e757fdf78ed58 ++ */ ++ ++ if (info->sector_size == 0) ++ info->sector_size = 512; ++ } ++ + info->enabled = ndctl_namespace_is_active (ndns); + + return info; diff --git a/0003-aclocal.patch b/0003-aclocal.patch new file mode 100644 index 0000000..55dcacb --- /dev/null +++ b/0003-aclocal.patch @@ -0,0 +1,1016 @@ +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1,6 +1,6 @@ +-# generated automatically by aclocal 1.15.1 -*- Autoconf -*- ++# generated automatically by aclocal 1.16.1 -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2018 Free Software Foundation, Inc. + + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -20,7 +20,7 @@ + If you have problems, you may need to regenerate the build system entirely. + To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +-# Copyright (C) 2002-2017 Free Software Foundation, Inc. ++# Copyright (C) 2002-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -32,10 +32,10 @@ + # generated from the m4 files accompanying Automake X.Y. + # (This private macro should not be called outside this file.) + AC_DEFUN([AM_AUTOMAKE_VERSION], +-[am__api_version='1.15' ++[am__api_version='1.16' + dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to + dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.15.1], [], ++m4_if([$1], [1.16.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl + ]) + +@@ -51,12 +51,12 @@ + # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. + # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. + AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.15.1])dnl ++[AM_AUTOMAKE_VERSION([1.16.1])dnl + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl + _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +-# Copyright (C) 2011-2017 Free Software Foundation, Inc. ++# Copyright (C) 2011-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -118,7 +118,7 @@ + + # AM_AUX_DIR_EXPAND -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -170,7 +170,7 @@ + + # AM_CONDITIONAL -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -201,7 +201,7 @@ + Usually this means the macro was only invoked conditionally.]]) + fi])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -392,13 +392,12 @@ + + # Generate code to set up dependency tracking. -*- Autoconf -*- + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. + +- + # _AM_OUTPUT_DEPENDENCY_COMMANDS + # ------------------------------ + AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +@@ -406,49 +405,41 @@ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac ++ # TODO: see whether this extra hack can be removed once we start ++ # requiring Autoconf 2.70 or later. ++ AS_CASE([$CONFIG_FILES], ++ [*\'*], [eval set x "$CONFIG_FILES"], ++ [*], [set x $CONFIG_FILES]) + shift +- for mf ++ # Used to flag and report bootstrapping failures. ++ am_rc=0 ++ for am_mf + do + # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line ++ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile which includes ++ # dependency-tracking related rules and includes. ++ # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`AS_DIRNAME("$mf")` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`AS_DIRNAME(["$file"])` +- AS_MKDIR_P([$dirpart/$fdir]) +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done ++ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ ++ || continue ++ am_dirpart=`AS_DIRNAME(["$am_mf"])` ++ am_filepart=`AS_BASENAME(["$am_mf"])` ++ AM_RUN_LOG([cd "$am_dirpart" \ ++ && sed -e '/# am--include-marker/d' "$am_filepart" \ ++ | $MAKE -f - am--depfiles]) || am_rc=$? + done ++ if test $am_rc -ne 0; then ++ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments ++ for automatic dependency tracking. Try re-running configure with the ++ '--disable-dependency-tracking' option to at least be able to build ++ the package (albeit without support for automatic dependency tracking).]) ++ fi ++ AS_UNSET([am_dirpart]) ++ AS_UNSET([am_filepart]) ++ AS_UNSET([am_mf]) ++ AS_UNSET([am_rc]) ++ rm -f conftest-deps.mk + } + ])# _AM_OUTPUT_DEPENDENCY_COMMANDS + +@@ -457,18 +448,17 @@ + # ----------------------------- + # This macro should only be invoked once -- use via AC_REQUIRE. + # +-# This code is only required when automatic dependency tracking +-# is enabled. FIXME. This creates each '.P' file that we will +-# need in order to bootstrap the dependency handling code. ++# This code is only required when automatic dependency tracking is enabled. ++# This creates each '.Po' and '.Plo' makefile fragment that we'll need in ++# order to bootstrap the dependency handling code. + AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], + [AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], +- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +-]) ++ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + + # Do all the work for Automake. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -555,8 +545,8 @@ + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + # For better backward compatibility. To be removed once Automake 1.9.x + # dies out for good. For more background, see: +-# +-# ++# ++# + AC_SUBST([mkdir_p], ['$(MKDIR_P)']) + # We need awk for the "check" target (and possibly the TAP driver). The + # system "awk" is bad on some platforms. +@@ -623,7 +613,7 @@ + Aborting the configuration process, to ensure you take notice of the issue. + + You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: . ++that behaves properly: . + + If you want to complete the configuration process using your problematic + 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +@@ -665,7 +655,7 @@ + done + echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -686,7 +676,7 @@ + fi + AC_SUBST([install_sh])]) + +-# Copyright (C) 2003-2017 Free Software Foundation, Inc. ++# Copyright (C) 2003-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -707,7 +697,7 @@ + + # Check to see how 'make' treats includes. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -715,49 +705,42 @@ + + # AM_MAKE_INCLUDE() + # ----------------- +-# Check to see how make treats includes. ++# Check whether make has an 'include' directive that can support all ++# the idioms we need for our automatic dependency tracking code. + AC_DEFUN([AM_MAKE_INCLUDE], +-[am_make=${MAKE-make} +-cat > confinc << 'END' ++[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) ++cat > confinc.mk << 'END' + am__doit: +- @echo this is the am__doit target ++ @echo this is the am__doit target >confinc.out + .PHONY: am__doit + END +-# If we don't find an include directive, just comment out the code. +-AC_MSG_CHECKING([for style of include used by $am_make]) + am__include="#" + am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD +- ;; +- esac +-fi +-AC_SUBST([am__include]) +-AC_SUBST([am__quote]) +-AC_MSG_RESULT([$_am_result]) +-rm -f confinc confmf +-]) ++# BSD make does it like this. ++echo '.include "confinc.mk" # ignored' > confmf.BSD ++# Other make implementations (GNU, Solaris 10, AIX) do it like this. ++echo 'include confinc.mk # ignored' > confmf.GNU ++_am_result=no ++for s in GNU BSD; do ++ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) ++ AS_CASE([$?:`cat confinc.out 2>/dev/null`], ++ ['0:this is the am__doit target'], ++ [AS_CASE([$s], ++ [BSD], [am__include='.include' am__quote='"'], ++ [am__include='include' am__quote=''])]) ++ if test "$am__include" != "#"; then ++ _am_result="yes ($s style)" ++ break ++ fi ++done ++rm -f confinc.* confmf.* ++AC_MSG_RESULT([${_am_result}]) ++AC_SUBST([am__include])]) ++AC_SUBST([am__quote])]) + + # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -796,7 +779,7 @@ + + # Helper functions for option handling. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -825,7 +808,7 @@ + AC_DEFUN([_AM_IF_OPTION], + [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -872,7 +855,7 @@ + # For backward compatibility. + AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -905,10 +888,12 @@ + [ + dnl Find a Python interpreter. Python versions prior to 2.0 are not + dnl supported. (2.0 was released on October 16, 2000). +- dnl FIXME: Remove the need to hard-code Python versions here. + m4_define_default([_AM_PYTHON_INTERPRETER_LIST], +-[python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl +- python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) ++[python python2 python3 dnl ++ python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl ++ python3.2 python3.1 python3.0 dnl ++ python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl ++ python2.0]) + + AC_ARG_VAR([PYTHON], [the Python interpreter]) + +@@ -1108,7 +1093,7 @@ + sys.exit(sys.hexversion < minverhex)" + AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1127,7 +1112,7 @@ + + # Check to make sure that the build environment is sane. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1208,7 +1193,7 @@ + rm -f conftest.file + ]) + +-# Copyright (C) 2009-2017 Free Software Foundation, Inc. ++# Copyright (C) 2009-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1268,7 +1253,7 @@ + _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl + ]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1296,7 +1281,7 @@ + INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +-# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++# Copyright (C) 2006-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1315,7 +1300,7 @@ + + # Check how to create a tarball. -*- Autoconf -*- + +-# Copyright (C) 2004-2017 Free Software Foundation, Inc. ++# Copyright (C) 2004-2018 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + +--- a/configure ++++ b/configure +@@ -637,6 +637,10 @@ + LIBOBJS + MAJOR_VER + skip_patterns ++NDCTL_LIBS ++NDCTL_CFLAGS ++UUID_LIBS ++UUID_CFLAGS + BYTESIZE_LIBS + BYTESIZE_CFLAGS + PARTED_FS_LIBS +@@ -665,6 +669,9 @@ + GLIB_CFLAGS + WITH_PART_O_WITH_FS_FALSE + WITH_PART_O_WITH_FS_TRUE ++WITH_NVDIMM_FALSE ++WITH_NVDIMM_TRUE ++WITH_NVDIMM + WITH_FS_FALSE + WITH_FS_TRUE + WITH_FS +@@ -767,7 +774,6 @@ + AMDEPBACKSLASH + AMDEP_FALSE + AMDEP_TRUE +-am__quote + am__include + DEPDIR + OBJEXT +@@ -852,7 +858,8 @@ + PACKAGE_TARNAME + PACKAGE_NAME + PATH_SEPARATOR +-SHELL' ++SHELL ++am__quote' + ac_subst_files='' + ac_user_opts=' + enable_option_checking +@@ -884,6 +891,7 @@ + with_kbd + with_part + with_fs ++with_nvdimm + ' + ac_precious_vars='build_alias + host_alias +@@ -924,7 +932,11 @@ + PARTED_FS_CFLAGS + PARTED_FS_LIBS + BYTESIZE_CFLAGS +-BYTESIZE_LIBS' ++BYTESIZE_LIBS ++UUID_CFLAGS ++UUID_LIBS ++NDCTL_CFLAGS ++NDCTL_LIBS' + + + # Initialize some variables set by options. +@@ -1585,6 +1597,7 @@ + --with-kbd support kbd [default=yes] + --with-part support part [default=yes] + --with-fs support fs [default=yes] ++ --with-nvdimm support nvdimm [default=yes] + + Some influential environment variables: + PYTHON the Python interpreter +@@ -1642,6 +1655,11 @@ + C compiler flags for BYTESIZE, overriding pkg-config + BYTESIZE_LIBS + linker flags for BYTESIZE, overriding pkg-config ++ UUID_CFLAGS C compiler flags for UUID, overriding pkg-config ++ UUID_LIBS linker flags for UUID, overriding pkg-config ++ NDCTL_CFLAGS ++ C compiler flags for NDCTL, overriding pkg-config ++ NDCTL_LIBS linker flags for NDCTL, overriding pkg-config + + Use these variables to override the choices made by `configure' or to help + it to find libraries and programs with nonstandard names/locations. +@@ -2461,7 +2479,7 @@ + + + +-am__api_version='1.15' ++am__api_version='1.16' + + ac_aux_dir= + for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do +@@ -3006,8 +3024,8 @@ + + # For better backward compatibility. To be removed once Automake 1.9.x + # dies out for good. For more background, see: +-# +-# ++# ++# + mkdir_p='$(MKDIR_P)' + + # We need awk for the "check" target (and possibly the TAP driver). The +@@ -3058,7 +3076,7 @@ + Aborting the configuration process, to ensure you take notice of the issue. + + You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: . ++that behaves properly: . + + If you want to complete the configuration process using your problematic + 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +@@ -3079,7 +3097,7 @@ + + # Find any Python interpreter. + if test -z "$PYTHON"; then +- for ac_prog in python python2 python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 ++ for ac_prog in python python2 python3 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 + do + # Extract the first word of "$ac_prog", so it can be a program name with args. + set dummy $ac_prog; ac_word=$2 +@@ -3283,45 +3301,45 @@ + + ac_config_commands="$ac_config_commands depfiles" + +- +-am_make=${MAKE-make} +-cat > confinc << 'END' ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 ++$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } ++cat > confinc.mk << 'END' + am__doit: +- @echo this is the am__doit target ++ @echo this is the am__doit target >confinc.out + .PHONY: am__doit + END +-# If we don't find an include directive, just comment out the code. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +-$as_echo_n "checking for style of include used by $am_make... " >&6; } + am__include="#" + am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD ++# BSD make does it like this. ++echo '.include "confinc.mk" # ignored' > confmf.BSD ++# Other make implementations (GNU, Solaris 10, AIX) do it like this. ++echo 'include confinc.mk # ignored' > confmf.GNU ++_am_result=no ++for s in GNU BSD; do ++ { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 ++ (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } ++ case $?:`cat confinc.out 2>/dev/null` in #( ++ '0:this is the am__doit target') : ++ case $s in #( ++ BSD) : ++ am__include='.include' am__quote='"' ;; #( ++ *) : ++ am__include='include' am__quote='' ;; ++esac ;; #( ++ *) : + ;; +- esac +-fi +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +-$as_echo "$_am_result" >&6; } +-rm -f confinc confmf ++esac ++ if test "$am__include" != "#"; then ++ _am_result="yes ($s style)" ++ break ++ fi ++done ++rm -f confinc.* confmf.* ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 ++$as_echo "${_am_result}" >&6; } + + # Check whether --enable-dependency-tracking was given. + if test "${enable_dependency_tracking+set}" = set; then : +@@ -14088,6 +14106,32 @@ + fi + + ++# Check whether --with-nvdimm was given. ++if test "${with_nvdimm+set}" = set; then : ++ withval=$with_nvdimm; ++else ++ with_nvdimm=yes ++fi ++ ++ ++WITH_NVDIMM=0 ++ ++ if test "x$with_nvdimm" != "xno"; then ++ WITH_NVDIMM_TRUE= ++ WITH_NVDIMM_FALSE='#' ++else ++ WITH_NVDIMM_TRUE='#' ++ WITH_NVDIMM_FALSE= ++fi ++ ++if test "x$with_nvdimm" != "xno"; then : ++ ++$as_echo "#define WITH_BD_NVDIMM /**/" >>confdefs.h ++ WITH_NVDIMM=1 ++ ++fi ++ ++ + if test "x$with_part" != "xno" -o "x$with_fs" != "xno"; then + WITH_PART_O_WITH_FS_TRUE= + WITH_PART_O_WITH_FS_FALSE='#' +@@ -14603,6 +14647,10 @@ + + fi + ++ if $PKG_CONFIG --atleast-version=2.0 libcryptsetup; then : ++ $as_echo "#define LIBCRYPTSETUP_PIM_SUPPORT 1" >>confdefs.h ++ ++fi + + pkg_failed=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NSS" >&5 +@@ -14694,7 +14742,7 @@ + status=$? + rm -f $temp_file + rm -f $(basename ${temp_file%%.c}.o) +-if test $status == 0; then ++if test $status = 0; then + echo yes + else + echo no +@@ -14800,7 +14848,7 @@ + status=$? + rm -f $temp_file + rm -f $(basename ${temp_file%%.c}.o) +-if test $status == 0; then ++if test $status = 0; then + echo yes + else + echo no +@@ -15263,6 +15311,178 @@ + + fi + ++if test "x$with_nvdimm" != "xno"; then : ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UUID" >&5 ++$as_echo_n "checking for UUID... " >&6; } ++ ++if test -n "$UUID_CFLAGS"; then ++ pkg_cv_UUID_CFLAGS="$UUID_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "uuid") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_UUID_CFLAGS=`$PKG_CONFIG --cflags "uuid" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$UUID_LIBS"; then ++ pkg_cv_UUID_LIBS="$UUID_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "uuid") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_UUID_LIBS=`$PKG_CONFIG --libs "uuid" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ UUID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid" 2>&1` ++ else ++ UUID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$UUID_PKG_ERRORS" >&5 ++ ++ if test x"$libblockdev_failure_messages" = x; then : ++ libblockdev_failure_messages="$UUID_PKG_ERRORS" ++else ++ libblockdev_failure_messages="$libblockdev_failure_messages ++$UUID_PKG_ERRORS" ++ ++fi ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ if test x"$libblockdev_failure_messages" = x; then : ++ libblockdev_failure_messages="$UUID_PKG_ERRORS" ++else ++ libblockdev_failure_messages="$libblockdev_failure_messages ++$UUID_PKG_ERRORS" ++ ++fi ++else ++ UUID_CFLAGS=$pkg_cv_UUID_CFLAGS ++ UUID_LIBS=$pkg_cv_UUID_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++fi ++ ++ ++pkg_failed=no ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for NDCTL" >&5 ++$as_echo_n "checking for NDCTL... " >&6; } ++ ++if test -n "$NDCTL_CFLAGS"; then ++ pkg_cv_NDCTL_CFLAGS="$NDCTL_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libndctl\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libndctl") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_NDCTL_CFLAGS=`$PKG_CONFIG --cflags "libndctl" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$NDCTL_LIBS"; then ++ pkg_cv_NDCTL_LIBS="$NDCTL_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libndctl\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libndctl") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_NDCTL_LIBS=`$PKG_CONFIG --libs "libndctl" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ NDCTL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libndctl" 2>&1` ++ else ++ NDCTL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libndctl" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$NDCTL_PKG_ERRORS" >&5 ++ ++ if test x"$libblockdev_failure_messages" = x; then : ++ libblockdev_failure_messages="$NDCTL_PKG_ERRORS" ++else ++ libblockdev_failure_messages="$libblockdev_failure_messages ++$NDCTL_PKG_ERRORS" ++ ++fi ++elif test $pkg_failed = untried; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ if test x"$libblockdev_failure_messages" = x; then : ++ libblockdev_failure_messages="$NDCTL_PKG_ERRORS" ++else ++ libblockdev_failure_messages="$libblockdev_failure_messages ++$NDCTL_PKG_ERRORS" ++ ++fi ++else ++ NDCTL_CFLAGS=$pkg_cv_NDCTL_CFLAGS ++ NDCTL_LIBS=$pkg_cv_NDCTL_LIBS ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ ++fi ++ ++ ++fi ++ + skip_patterns=$skip_patterns + + MAJOR_VER=\"2\" +@@ -15527,6 +15747,10 @@ + as_fn_error $? "conditional \"WITH_FS\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${WITH_NVDIMM_TRUE}" && test -z "${WITH_NVDIMM_FALSE}"; then ++ as_fn_error $? "conditional \"WITH_NVDIMM\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${WITH_PART_O_WITH_FS_TRUE}" && test -z "${WITH_PART_O_WITH_FS_FALSE}"; then + as_fn_error $? "conditional \"WITH_PART_O_WITH_FS\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +@@ -16093,7 +16317,7 @@ + # + # INIT-COMMANDS + # +-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" ++AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + + # The HP-UX ksh and POSIX shell print the target directory to stdout +@@ -16843,29 +17067,35 @@ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac ++ # TODO: see whether this extra hack can be removed once we start ++ # requiring Autoconf 2.70 or later. ++ case $CONFIG_FILES in #( ++ *\'*) : ++ eval set x "$CONFIG_FILES" ;; #( ++ *) : ++ set x $CONFIG_FILES ;; #( ++ *) : ++ ;; ++esac + shift +- for mf ++ # Used to flag and report bootstrapping failures. ++ am_rc=0 ++ for am_mf + do + # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line ++ am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile which includes ++ # dependency-tracking related rules and includes. ++ # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`$as_dirname -- "$mf" || +-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$mf" : 'X\(//\)[^/]' \| \ +- X"$mf" : 'X\(//\)$' \| \ +- X"$mf" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$mf" | ++ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ ++ || continue ++ am_dirpart=`$as_dirname -- "$am_mf" || ++$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$am_mf" : 'X\(//\)[^/]' \| \ ++ X"$am_mf" : 'X\(//\)$' \| \ ++ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q +@@ -16883,53 +17113,48 @@ + q + } + s/.*/./; q'` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`$as_dirname -- "$file" || +-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$file" : 'X\(//\)[^/]' \| \ +- X"$file" : 'X\(//\)$' \| \ +- X"$file" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$file" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ ++ am_filepart=`$as_basename -- "$am_mf" || ++$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ ++ X"$am_mf" : 'X\(//\)$' \| \ ++ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || ++$as_echo X/"$am_mf" | ++ sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } +- /^X\(\/\/\)$/{ ++ /^X\/\(\/\/\)$/{ + s//\1/ + q + } +- /^X\(\/\).*/{ ++ /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` +- as_dir=$dirpart/$fdir; as_fn_mkdir_p +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done ++ { echo "$as_me:$LINENO: cd "$am_dirpart" \ ++ && sed -e '/# am--include-marker/d' "$am_filepart" \ ++ | $MAKE -f - am--depfiles" >&5 ++ (cd "$am_dirpart" \ ++ && sed -e '/# am--include-marker/d' "$am_filepart" \ ++ | $MAKE -f - am--depfiles) >&5 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } || am_rc=$? + done ++ if test $am_rc -ne 0; then ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 ++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} ++as_fn_error $? "Something went wrong bootstrapping makefile fragments ++ for automatic dependency tracking. Try re-running configure with the ++ '--disable-dependency-tracking' option to at least be able to build ++ the package (albeit without support for automatic dependency tracking). ++See \`config.log' for more details" "$LINENO" 5; } ++ fi ++ { am_dirpart=; unset am_dirpart;} ++ { am_filepart=; unset am_filepart;} ++ { am_mf=; unset am_mf;} ++ { am_rc=; unset am_rc;} ++ rm -f conftest-deps.mk + } + ;; + "libtool":C) diff --git a/libblockdev.spec b/libblockdev.spec index 10eaefb..40131a6 100644 --- a/libblockdev.spec +++ b/libblockdev.spec @@ -13,6 +13,7 @@ %define with_kbd 1 %define with_part 1 %define with_fs 1 +%define with_nvdimm 1 %define with_gi 1 # python3 is not available on older RHEL @@ -59,19 +60,25 @@ %if %{with_fs} != 1 %define fs_copts --without-fs %endif +%if %{with_nvdimm} != 1 +%define nvdimm_copts --without-nvdimm +%endif %if %{with_gi} != 1 %define gi_copts --disable-introspection %endif -%define configure_opts %{?distro_copts} %{?btrfs_copts} %{?crypto_copts} %{?dm_copts} %{?loop_copts} %{?lvm_copts} %{?lvm_dbus_copts} %{?mdraid_copts} %{?mpath_copts} %{?swap_copts} %{?kbd_copts} %{?part_copts} %{?fs_copts} %{?gi_copts} +%define configure_opts %{?distro_copts} %{?btrfs_copts} %{?crypto_copts} %{?dm_copts} %{?loop_copts} %{?lvm_copts} %{?lvm_dbus_copts} %{?mdraid_copts} %{?mpath_copts} %{?swap_copts} %{?kbd_copts} %{?part_copts} %{?fs_copts} %{?nvdimm_copts} %{?gi_copts} Name: libblockdev Version: 2.16 -Release: 2%{?dist} +Release: 3%{?dist} Summary: A library for low-level manipulation with block devices License: LGPLv2+ URL: https://github.com/storaged-project/libblockdev Source0: https://github.com/storaged-project/libblockdev/releases/download/%{version}-%{release}/%{name}-%{version}.tar.gz +Patch0: 0001-nvdim-plugin.patch +Patch1: 0002-nvdimm-nonblock-sector-size.patch +Patch2: 0003-aclocal.patch BuildRequires: glib2-devel %if %{with_gi} @@ -394,6 +401,29 @@ This package contains header files and pkg-config files needed for development with the libblockdev-mpath plugin/library. %endif +%if %{with_nvdimm} +%package nvdimm +BuildRequires: ndctl-devel +BuildRequires: libuuid-devel +Summary: The NVDIMM plugin for the libblockdev library +Requires: %{name}-utils%{?_isa} >= 0.11 +Requires: ndctl + +%description nvdimm +The libblockdev library plugin (and in the same time a standalone library) +providing the functionality related to operations with NVDIMM devices. + +%package nvdimm-devel +Summary: Development files for the libblockdev-nvdimm plugin/library +Requires: %{name}-nvdimm%{?_isa} = %{version}-%{release} +Requires: %{name}-utils-devel%{?_isa} +Requires: glib2-devel + +%description nvdimm-devel +This package contains header files and pkg-config files needed for development +with the libblockdev-nvdimm plugin/library. +%endif + %if %{with_part} %package part @@ -502,6 +532,10 @@ Requires: %{name}-mdraid%{?_isa} = %{version}-%{release} Requires: %{name}-mpath%{?_isa} = %{version}-%{release} %endif +%if %{with_nvdimm} +Requires: %{name}-nvdimm%{?_isa} = %{version}-%{release} +%endif + %if %{with_part} Requires: %{name}-part%{?_isa} = %{version}-%{release} %endif @@ -520,6 +554,9 @@ A meta-package that pulls all the libblockdev plugins as dependencies. %prep %setup -q -n %{name}-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 %build %configure %{?configure_opts} @@ -569,6 +606,10 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %ldconfig_scriptlets mpath %endif +%if %{with_nvdimm} +%ldconfig_scriptlets nvdimm +%endif + %if %{with_part} %ldconfig_scriptlets part %endif @@ -749,6 +790,15 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %{_includedir}/blockdev/mpath.h %endif +%if %{with_nvdimm} +%files nvdimm +%{_libdir}/libbd_nvdimm.so.* + +%files nvdimm-devel +%{_libdir}/libbd_nvdimm.so +%dir %{_includedir}/blockdev +%{_includedir}/blockdev/nvdimm.h +%endif %if %{with_part} %files part @@ -785,6 +835,13 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Wed Apr 11 2018 Vojtech Trefny - 2.16-3 +- Add the NVDIMM plugin (vtrefny) +- Add tests for the NVDIMM plugin (vtrefny) +- Add --without-xyz to DISTCHECK_CONFIGURE_FLAGS for disabled plugins (vtrefny) +- Add function for getting NVDIMM namespace name from devname or path (vtrefny) +- Get sector size for non-block NVDIMM namespaces too (vtrefny) + * Fri Feb 09 2018 Igor Gnatenko - 2.16-2 - Escape macros in %%changelog