Skip to content

Commit

Permalink
Merge pull request #600 from vojtechtrefny/master_lvm-thinmetadata-ca…
Browse files Browse the repository at this point in the history
…lculation-fix

LVM thin metadata calculation fix
  • Loading branch information
vojtechtrefny authored Dec 7, 2020
2 parents 00a34d3 + a517389 commit 4b9ed6a
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 176 deletions.
4 changes: 0 additions & 4 deletions dist/libblockdev.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,6 @@ BuildRequires: device-mapper-devel
Summary: The LVM plugin for the libblockdev library
Requires: %{name}-utils%{?_isa} >= 0.11
Requires: lvm2
# for thin_metadata_size
Requires: device-mapper-persistent-data

%description lvm
The libblockdev library plugin (and in the same time a standalone library)
Expand All @@ -402,8 +400,6 @@ BuildRequires: device-mapper-devel
Summary: The LVM plugin for the libblockdev library
Requires: %{name}-utils%{?_isa} >= 1.4
Requires: lvm2-dbusd >= 2.02.156
# for thin_metadata_size
Requires: device-mapper-persistent-data

%description lvm-dbus
The libblockdev library plugin (and in the same time a standalone library)
Expand Down
12 changes: 7 additions & 5 deletions src/lib/plugin_apis/lvm.api
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
#define BD_LVM_DEFAULT_PE_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB
#define BD_LVM_MIN_PE_SIZE G_GUINT64_CONSTANT (1024ULL) // 1 KiB
#define BD_LVM_MAX_PE_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB
#define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (2097152ULL) // 2 MiB
#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (17179869184ULL) // 16 GiB
#define BD_LVM_MIN_THPOOL_MD_SIZE G_GUINT64_CONSTANT (4194304ULL) // 4 MiB
#define BD_LVM_MAX_THPOOL_MD_SIZE G_GUINT64_CONSTANT (33957085184ULL) // 31.62 GiB
#define BD_LVM_MIN_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB
#define BD_LVM_MAX_THPOOL_CHUNK_SIZE G_GUINT64_CONSTANT (1073741824ULL) // 1 GiB
#define BD_LVM_DEFAULT_CHUNK_SIZE G_GUINT64_CONSTANT (65536ULL) // 64 KiB
Expand Down Expand Up @@ -738,11 +738,13 @@ guint64 bd_lvm_get_thpool_padding (guint64 size, guint64 pe_size, gboolean inclu
* bd_lvm_get_thpool_meta_size:
* @size: size of the thin pool
* @chunk_size: chunk size of the thin pool or 0 to use the default (%BD_LVM_DEFAULT_CHUNK_SIZE)
* @n_snapshots: number of snapshots that will be created in the pool
* @n_snapshots: ignored
* @error: (out): place to store error (if any)
*
* Returns: recommended size of the metadata space for the specified pool or 0
* in case of error
* Note: This function will be changed in 3.0: the @n_snapshots parameter
* is currently not used and will be removed.
*
* Returns: recommended size of the metadata space for the specified pool
*
* Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored)
*/
Expand Down
102 changes: 27 additions & 75 deletions src/plugins/lvm-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <glib.h>
#include <math.h>
#include <string.h>
#include <libdevmapper.h>
#include <unistd.h>
#include <blockdev/utils.h>
#include <gio/gio.h>
Expand Down Expand Up @@ -256,14 +255,6 @@ static volatile guint avail_features = 0;
static volatile guint avail_module_deps = 0;
static GMutex deps_check_lock;

#define DEPS_THMS 0
#define DEPS_THMS_MASK (1 << DEPS_THMS)
#define DEPS_LAST 1

static const UtilDep deps[DEPS_LAST] = {
{"thin_metadata_size", NULL, NULL, NULL},
};

#define DBUS_DEPS_LVMDBUSD 0
#define DBUS_DEPS_LVMDBUSD_MASK (1 << DBUS_DEPS_LVMDBUSD)
#define DBUS_DEPS_LVMDBUSD_WRITECACHE 1
Expand Down Expand Up @@ -315,17 +306,6 @@ gboolean bd_lvm_check_deps (void) {
check_ret = check_ret && success;
}

for (i=0; i < DEPS_LAST; i++) {
success = bd_utils_check_util_version (deps[i].name, deps[i].version,
deps[i].ver_arg, deps[i].ver_regexp, &error);
if (!success)
bd_utils_log_format (BD_UTILS_LOG_WARNING, "%s", error->message);
else
g_atomic_int_or (&avail_deps, 1 << i);
g_clear_error (&error);
check_ret = check_ret && success;
}

if (!check_ret)
bd_utils_log_format (BD_UTILS_LOG_WARNING, "Cannot load the LVM plugin");

Expand Down Expand Up @@ -396,10 +376,7 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_TECH_UNAVAIL,
"Only 'query' supported for thin calculations");
return FALSE;
} else if ((mode & BD_LVM_TECH_MODE_QUERY) &&
!check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
return FALSE;
else
} else
return TRUE;
case BD_LVM_TECH_CALCS:
if (mode & ~BD_LVM_TECH_MODE_QUERY) {
Expand Down Expand Up @@ -1010,7 +987,7 @@ static BDLVMPVdata* get_pv_data_from_props (GVariant *props, GError **error) {
return data;
}

static BDLVMVGdata* get_vg_data_from_props (GVariant *props, GError **error __attribute__((unused))) {
static BDLVMVGdata* get_vg_data_from_props (GVariant *props, GError **error UNUSED) {
BDLVMVGdata *data = g_new0 (BDLVMVGdata, 1);
GVariantDict dict;
GVariant *value = NULL;
Expand Down Expand Up @@ -1232,7 +1209,7 @@ static BDLVMLVdata* get_lv_data_from_props (GVariant *props, GError **error) {
return data;
}

static BDLVMVDOPooldata* get_vdo_data_from_props (GVariant *props, GError **error __attribute__((unused))) {
static BDLVMVDOPooldata* get_vdo_data_from_props (GVariant *props, GError **error UNUSED) {
BDLVMVDOPooldata *data = g_new0 (BDLVMVDOPooldata, 1);
GVariantDict dict;
gchar *value = NULL;
Expand Down Expand Up @@ -1336,7 +1313,7 @@ static GVariant* create_size_str_param (guint64 size, const gchar *unit) {
*
* Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored)
*/
gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__((unused))) {
gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error UNUSED) {
return (((size % 2) == 0) && (size >= (BD_LVM_MIN_PE_SIZE)) && (size <= (BD_LVM_MAX_PE_SIZE)));
}

Expand All @@ -1348,7 +1325,7 @@ gboolean bd_lvm_is_supported_pe_size (guint64 size, GError **error __attribute__
*
* Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored)
*/
guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused))) {
guint64 *bd_lvm_get_supported_pe_sizes (GError **error UNUSED) {
guint8 i;
guint64 val = BD_LVM_MIN_PE_SIZE;
guint8 num_items = ((guint8) round (log2 ((double) BD_LVM_MAX_PE_SIZE))) - ((guint8) round (log2 ((double) BD_LVM_MIN_PE_SIZE))) + 2;
Expand All @@ -1370,7 +1347,7 @@ guint64 *bd_lvm_get_supported_pe_sizes (GError **error __attribute__((unused)))
*
* Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored)
*/
guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) {
guint64 bd_lvm_get_max_lv_size (GError **error UNUSED) {
return BD_LVM_MAX_LV_SIZE;
}

Expand All @@ -1390,7 +1367,7 @@ guint64 bd_lvm_get_max_lv_size (GError **error __attribute__((unused))) {
*
* Tech category: %BD_LVM_TECH_CALCS no mode (it is ignored)
*/
guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error __attribute__((unused))) {
guint64 bd_lvm_round_size_to_pe (guint64 size, guint64 pe_size, gboolean roundup, GError **error UNUSED) {
pe_size = RESOLVE_PE_SIZE(pe_size);
guint64 delta = size % pe_size;
if (delta == 0)
Expand Down Expand Up @@ -1451,53 +1428,28 @@ guint64 bd_lvm_get_thpool_padding (guint64 size, guint64 pe_size, gboolean inclu
* bd_lvm_get_thpool_meta_size:
* @size: size of the thin pool
* @chunk_size: chunk size of the thin pool or 0 to use the default (%BD_LVM_DEFAULT_CHUNK_SIZE)
* @n_snapshots: number of snapshots that will be created in the pool
* @n_snapshots: ignored
* @error: (out): place to store error (if any)
*
* Returns: recommended size of the metadata space for the specified pool or 0
* in case of error
* Note: This function will be changed in 3.0: the @n_snapshots parameter
* is currently not used and will be removed.
*
* Returns: recommended size of the metadata space for the specified pool
*
* Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored)
*/
guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots, GError **error) {
/* ub - output in bytes, n - output just the number */
const gchar* args[7] = {"thin_metadata_size", "-ub", "-n", NULL, NULL, NULL, NULL};
gchar *output = NULL;
gboolean success = FALSE;
guint64 ret = 0;

if (!check_deps (&avail_deps, DEPS_THMS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
return 0;
guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n_snapshots UNUSED, GError **error UNUSED) {
guint64 md_size = 0;

/* s - total size, b - chunk size, m - number of snapshots */
args[3] = g_strdup_printf ("-s%"G_GUINT64_FORMAT, size);
args[4] = g_strdup_printf ("-b%"G_GUINT64_FORMAT,
chunk_size != 0 ? chunk_size : (guint64) BD_LVM_DEFAULT_CHUNK_SIZE);
args[5] = g_strdup_printf ("-m%"G_GUINT64_FORMAT, n_snapshots);

success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
g_free ((gchar*) args[3]);
g_free ((gchar*) args[4]);
g_free ((gchar*) args[5]);

if (!success) {
/* error is already set */
g_free (output);
return 0;
}

ret = g_ascii_strtoull (output, NULL, 0);
if (ret == 0) {
g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_PARSE,
"Failed to parse number from thin_metadata_size's output: '%s'",
output);
g_free (output);
return 0;
}
/* based on lvcreate metadata size calculation */
md_size = UINT64_C(64) * size / (chunk_size ? chunk_size : BD_LVM_DEFAULT_CHUNK_SIZE);

g_free (output);
if (md_size > BD_LVM_MAX_THPOOL_MD_SIZE)
md_size = BD_LVM_MAX_THPOOL_MD_SIZE;
else if (md_size < BD_LVM_MIN_THPOOL_MD_SIZE)
md_size = BD_LVM_MIN_THPOOL_MD_SIZE;

return MAX (ret, BD_LVM_MIN_THPOOL_MD_SIZE);
return md_size;
}

/**
Expand All @@ -1509,7 +1461,7 @@ guint64 bd_lvm_get_thpool_meta_size (guint64 size, guint64 chunk_size, guint64 n
*
* Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored)
*/
gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribute__((unused))) {
gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error UNUSED) {
return ((BD_LVM_MIN_THPOOL_MD_SIZE <= size) && (size <= BD_LVM_MAX_THPOOL_MD_SIZE));
}

Expand All @@ -1523,7 +1475,7 @@ gboolean bd_lvm_is_valid_thpool_md_size (guint64 size, GError **error __attribut
*
* Tech category: %BD_LVM_TECH_THIN_CALCS no mode (it is ignored)
*/
gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error __attribute__((unused))) {
gboolean bd_lvm_is_valid_thpool_chunk_size (guint64 size, gboolean discard, GError **error UNUSED) {
gdouble size_log2 = 0.0;

if ((size < BD_LVM_MIN_THPOOL_CHUNK_SIZE) || (size > BD_LVM_MAX_THPOOL_CHUNK_SIZE))
Expand Down Expand Up @@ -3001,7 +2953,7 @@ gboolean bd_lvm_thsnapshotcreate (const gchar *vg_name, const gchar *origin_name
*
* Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored)
*/
gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __attribute__((unused))) {
gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error UNUSED) {
/* XXX: the error attribute will likely be used in the future when
some validation comes into the game */

Expand All @@ -3026,7 +2978,7 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error __att
*
* Tech category: %BD_LVM_TECH_GLOB_CONF no mode (it is ignored)
*/
gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) {
gchar* bd_lvm_get_global_config (GError **error UNUSED) {
gchar *ret = NULL;

g_mutex_lock (&global_config_lock);
Expand All @@ -3045,7 +2997,7 @@ gchar* bd_lvm_get_global_config (GError **error __attribute__((unused))) {
*
* Tech category: %BD_LVM_TECH_CACHE_CALCS no mode (it is ignored)
*/
guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __attribute__((unused))) {
guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error UNUSED) {
return MAX ((guint64) cache_size / 1000, BD_LVM_MIN_CACHE_MD_SIZE);
}

Expand All @@ -3055,7 +3007,7 @@ guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error __a
*
* Get LV type string from flags.
*/
static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error __attribute__((unused))) {
static const gchar* get_lv_type_from_flags (BDLVMCachePoolFlags flags, gboolean meta, GError **error UNUSED) {
if (!meta) {
if (flags & BD_LVM_CACHE_POOL_STRIPED)
return "striped";
Expand Down
Loading

0 comments on commit 4b9ed6a

Please sign in to comment.