mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-26 16:23:58 +03:00
Compare commits
17 Commits
dev-dct-de
...
dev-dct-in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b9f78332b | ||
|
|
07576f7e51 | ||
|
|
ae8d5113f4 | ||
|
|
7fdba39b3f | ||
|
|
0e8c429e30 | ||
|
|
14dbf6ca7b | ||
|
|
3eecdcbd64 | ||
|
|
8281f7c111 | ||
|
|
be229b0cd1 | ||
|
|
557b2850ce | ||
|
|
c288ddd6c8 | ||
|
|
60fbbd5f5f | ||
|
|
0eef5ab6e1 | ||
|
|
f8aa073a8d | ||
|
|
39e65c8f59 | ||
|
|
5bf4efbab5 | ||
|
|
77be3250d9 |
@@ -1 +1 @@
|
||||
1.02.199-git (2024-05-16)
|
||||
1.02.200-git (2024-07-12)
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
Version 2.03.25 -
|
||||
Version 2.03.26 -
|
||||
==================
|
||||
Use log/report_command_log=1 config setting by default for JSON output format.
|
||||
lvextend fix unreleased memory pools on RAID
|
||||
|
||||
Version 2.03.25 - 12nd July 2024
|
||||
================================
|
||||
Utilize more radix_tree instead of dm_hash and btree.
|
||||
Refactor DM uuid caching from device_mapper directory.
|
||||
Enhance checking for DM uuid device.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Version 1.02.199 -
|
||||
Version 1.02.200 -
|
||||
===================
|
||||
|
||||
Version 1.02.199 - 12nd July 2024
|
||||
=================================
|
||||
|
||||
Version 1.02.198 - 16th May 2024
|
||||
================================
|
||||
Fix static only compilation of libdevmapper.a and dmsetup tool.
|
||||
|
||||
@@ -801,6 +801,9 @@ log {
|
||||
# to define fields to display and sort fields for the log report.
|
||||
# You can also use log/command_log_selection to define selection
|
||||
# criteria used each time the log is reported.
|
||||
# Note that if report/output_format (or --reporformat command line
|
||||
# option) is set to json or json_std, then log/report_command_log=1
|
||||
# is default.
|
||||
# This configuration option has an automatic default value.
|
||||
# report_command_log = 0
|
||||
|
||||
@@ -1989,7 +1992,7 @@ report {
|
||||
# If there is more than one report per command, then the format
|
||||
# is applied for all reports. You can also change output format
|
||||
# directly on command line using --reportformat option which
|
||||
# has precedence over log/output_format setting.
|
||||
# has precedence over report/output_format setting.
|
||||
# Accepted values:
|
||||
# basic
|
||||
# Original format with columns and rows. If there is more than
|
||||
@@ -2003,6 +2006,7 @@ report {
|
||||
# - it does not use double quotes around numeric values,
|
||||
# - it uses 'null' for undefined numeric values,
|
||||
# - it prints string list as proper JSON array of strings instead of a single string.
|
||||
# Note that if json or json_std output format is used, then log/command_log_report=1 is default.
|
||||
# This configuration option has an automatic default value.
|
||||
# output_format = "basic"
|
||||
|
||||
|
||||
@@ -1023,6 +1023,7 @@ struct integrity_settings {
|
||||
uint32_t commit_time;
|
||||
uint32_t bitmap_flush_interval;
|
||||
uint64_t sectors_per_bit;
|
||||
uint32_t allow_discards;
|
||||
|
||||
unsigned journal_sectors_set:1;
|
||||
unsigned interleave_sectors_set:1;
|
||||
@@ -1031,6 +1032,7 @@ struct integrity_settings {
|
||||
unsigned commit_time_set:1;
|
||||
unsigned bitmap_flush_interval_set:1;
|
||||
unsigned sectors_per_bit_set:1;
|
||||
unsigned allow_discards_set:1;
|
||||
};
|
||||
|
||||
int dm_tree_node_add_integrity_target(struct dm_tree_node *node,
|
||||
|
||||
@@ -2868,6 +2868,8 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
|
||||
count++;
|
||||
if (set->sectors_per_bit_set)
|
||||
count++;
|
||||
if (set->allow_discards_set && set->allow_discards)
|
||||
count++;
|
||||
|
||||
EMIT_PARAMS(pos, "%s 0 %u %s %d fix_padding block_size:%u internal_hash:%s",
|
||||
origin_dev,
|
||||
@@ -2904,6 +2906,9 @@ static int _integrity_emit_segment_line(struct dm_task *dmt,
|
||||
if (set->sectors_per_bit_set)
|
||||
EMIT_PARAMS(pos, " sectors_per_bit:%llu", (unsigned long long)set->sectors_per_bit);
|
||||
|
||||
if (set->allow_discards_set && set->allow_discards)
|
||||
EMIT_PARAMS(pos, " allow_discards");
|
||||
|
||||
if (!dm_task_secure_data(dmt))
|
||||
stack;
|
||||
|
||||
|
||||
@@ -14,9 +14,6 @@ Version 2.03.25
|
||||
* And as usually some clean up, static analysis fixes, etc.
|
||||
|
||||
<!-- remove the pending tag on release, remove draft tag once editing is complete -->
|
||||
[[!tag draft pending]]
|
||||
<!--
|
||||
For old releases add Release Timestamp like this, date from git show $COMMIT is fine.
|
||||
\[[!meta date="Tue Nov 21 14:26:07 2023 +0100"]]
|
||||
-->
|
||||
[[!tag]]
|
||||
[[!meta date="Fri Jul 12 12:49:07 2024 +0200"]]
|
||||
|
||||
|
||||
@@ -771,7 +771,7 @@ int dm_device_is_usable(struct cmd_context *cmd, struct device *dev, struct dev_
|
||||
int only_error_or_zero_target = 1;
|
||||
int r = 0;
|
||||
|
||||
if (dm_devs_cache_use(cmd) &&
|
||||
if (dm_devs_cache_use() &&
|
||||
/* With cache we can avoid status calls for unusable UUIDs */
|
||||
(dm_dev = dm_devs_cache_get_by_devno(cmd, dev->dev)) &&
|
||||
!_is_usable_uuid(dev, dm_dev->name, dm_dev->uuid, check.check_reserved, check.check_lv, is_lv))
|
||||
@@ -902,7 +902,10 @@ int devno_dm_uuid(struct cmd_context *cmd, int major, int minor,
|
||||
const char *uuid;
|
||||
int r = 0;
|
||||
|
||||
if (dm_devs_cache_use(cmd)) {
|
||||
if (major != cmd->dev_types->device_mapper_major)
|
||||
return 0;
|
||||
|
||||
if (dm_devs_cache_use()) {
|
||||
if ((dm_dev = dm_devs_cache_get_by_devno(cmd, MKDEV(major, minor)))) {
|
||||
dm_strncpy(uuid_buf, dm_dev->uuid, uuid_buf_size);
|
||||
return 1;
|
||||
@@ -1090,7 +1093,7 @@ int dev_manager_info(struct cmd_context *cmd,
|
||||
|
||||
dm_strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
|
||||
|
||||
if (dm_devs_cache_use(cmd) &&
|
||||
if (dm_devs_cache_use() &&
|
||||
!dm_devs_cache_get_by_uuid(cmd, dlid) &&
|
||||
!dm_devs_cache_get_by_uuid(cmd, old_style_dlid)) {
|
||||
log_debug("Cached as inactive %s.", name);
|
||||
@@ -2464,7 +2467,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!(dlid = build_dm_uuid(dm->track_pending_delete ? dm->cmd->pending_delete_mem : dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
if (dm_devs_cache_use(dm->cmd)) {
|
||||
if (dm_devs_cache_use()) {
|
||||
if (!(dm_dev = dm_devs_cache_get_by_uuid(dm->cmd, dlid))) {
|
||||
log_debug("Cached as not present %s.", name);
|
||||
return 1;
|
||||
@@ -2619,7 +2622,7 @@ static int _pool_callback(struct dm_tree_node *node,
|
||||
}
|
||||
}
|
||||
|
||||
dm_devs_cache_destroy(cmd);
|
||||
dm_devs_cache_destroy();
|
||||
|
||||
log_debug("Running check command on %s", mpath);
|
||||
|
||||
@@ -4003,7 +4006,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
|
||||
/* Drop any cache before DM table manipulation within locked section
|
||||
* TODO: check if it makes sense to manage cache within lock */
|
||||
dm_devs_cache_destroy(dm->cmd);
|
||||
dm_devs_cache_destroy();
|
||||
|
||||
dtree = _create_partial_dtree(dm, lv, laopts->origin_only);
|
||||
|
||||
|
||||
4
lib/cache/lvmcache.c
vendored
4
lib/cache/lvmcache.c
vendored
@@ -3237,11 +3237,11 @@ const char *dev_filtered_reason(struct device *dev)
|
||||
return "device cannot be used";
|
||||
}
|
||||
|
||||
const char *devname_error_reason(struct cmd_context *cmd, const char *devname)
|
||||
const char *devname_error_reason(const char *devname)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
if ((dev = dev_cache_get_by_name(cmd, devname))) {
|
||||
if ((dev = dev_cache_get_dev_by_name(devname))) {
|
||||
if (dev->filtered_flags)
|
||||
return dev_filtered_reason(dev);
|
||||
if (lvmcache_dev_is_unused_duplicate(dev))
|
||||
|
||||
2
lib/cache/lvmcache.h
vendored
2
lib/cache/lvmcache.h
vendored
@@ -218,7 +218,7 @@ void lvmcache_get_mdas(struct cmd_context *cmd,
|
||||
struct dm_list *mda_list);
|
||||
|
||||
const char *dev_filtered_reason(struct device *dev);
|
||||
const char *devname_error_reason(struct cmd_context *cmd, const char *devname);
|
||||
const char *devname_error_reason(const char *devname);
|
||||
|
||||
struct metadata_area *lvmcache_get_dev_mda(struct device *dev, int mda_num);
|
||||
|
||||
|
||||
@@ -1167,7 +1167,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_cache_add_dir(cmd, cv->v.str)) {
|
||||
if (!dev_cache_add_dir(cv->v.str)) {
|
||||
log_error("Failed to add %s to internal device cache",
|
||||
cv->v.str);
|
||||
return 0;
|
||||
@@ -1899,7 +1899,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(cmd, &cmd->formats);
|
||||
|
||||
if (!dev_cache_exit(cmd))
|
||||
if (!dev_cache_exit())
|
||||
stack;
|
||||
_destroy_dev_types(cmd);
|
||||
_destroy_tags(cmd);
|
||||
@@ -2028,7 +2028,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
||||
_destroy_segtypes(&cmd->segtypes);
|
||||
_destroy_formats(cmd, &cmd->formats);
|
||||
_destroy_filters(cmd);
|
||||
dev_cache_exit(cmd);
|
||||
dev_cache_exit();
|
||||
_destroy_dev_types(cmd);
|
||||
_destroy_tags(cmd);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "lib/device/dev-cache.h"
|
||||
#include "lib/device/dev-type.h"
|
||||
#include "lib/commands/cmd_enum.h"
|
||||
#include "base/data-struct/radix-tree.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
@@ -223,11 +222,6 @@ struct cmd_context {
|
||||
/*
|
||||
* Devices and filtering.
|
||||
*/
|
||||
struct dm_list dev_dirs; /* paths, like /dev, to look for devnames */
|
||||
struct radix_tree *devnames; /* path names in dev_dirs, get struct device from path name */
|
||||
struct radix_tree *devnos; /* devnos found in dev_dirs, get struct device from devno */
|
||||
struct dm_regex *preferred_names_matcher; /* preferred dev names to display from lvm.conf */
|
||||
|
||||
struct dev_filter *filter;
|
||||
struct dm_list use_devices; /* struct dev_use for each entry in devices file */
|
||||
const char *md_component_checks;
|
||||
@@ -236,22 +230,6 @@ struct cmd_context {
|
||||
const char *devicesfile; /* from --devicesfile option */
|
||||
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
|
||||
|
||||
/*
|
||||
* LV dev index.
|
||||
*/
|
||||
struct dm_hash_table *vgid_index;
|
||||
struct dm_hash_table *lvid_index;
|
||||
struct radix_tree *sysfs_only_devices;
|
||||
|
||||
/*
|
||||
* Cache of DM devices.
|
||||
* Look up struct dm_active_device from devno or dm uuid.
|
||||
*/
|
||||
int use_dm_devs_cache; /* use this cache or not */
|
||||
struct dm_list *dm_devs; /* list of dm_active_device */
|
||||
struct radix_tree *dm_uuids; /* dm uuids of dm devices, get entry from dm_devs */
|
||||
struct radix_tree *dm_devnos; /* devnos of dm devices, get entry from dm_devs */
|
||||
|
||||
/*
|
||||
* Configuration.
|
||||
*/
|
||||
|
||||
@@ -859,7 +859,10 @@ cfg(log_report_command_log_CFG, "report_command_log", log_CFG_SECTION, CFG_PROFI
|
||||
"option. Use log/command_log_cols and log/command_log_sort settings\n"
|
||||
"to define fields to display and sort fields for the log report.\n"
|
||||
"You can also use log/command_log_selection to define selection\n"
|
||||
"criteria used each time the log is reported.\n")
|
||||
"criteria used each time the log is reported.\n"
|
||||
"Note that if report/output_format (or --reporformat command line\n"
|
||||
"option) is set to json or json_std, then log/report_command_log=1\n"
|
||||
"is default.\n")
|
||||
|
||||
cfg(log_command_log_sort_CFG, "command_log_sort", log_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED | CFG_DISALLOW_INTERACTIVE, CFG_TYPE_STRING, DEFAULT_COMMAND_LOG_SORT, vsn(2, 2, 158), NULL, 0, NULL,
|
||||
"List of columns to sort by when reporting command log.\n"
|
||||
@@ -1840,7 +1843,7 @@ cfg(report_output_format_CFG, "output_format", report_CFG_SECTION, CFG_PROFILABL
|
||||
"If there is more than one report per command, then the format\n"
|
||||
"is applied for all reports. You can also change output format\n"
|
||||
"directly on command line using --reportformat option which\n"
|
||||
"has precedence over log/output_format setting.\n"
|
||||
"has precedence over report/output_format setting.\n"
|
||||
"Accepted values:\n"
|
||||
" basic\n"
|
||||
" Original format with columns and rows. If there is more than\n"
|
||||
@@ -1853,8 +1856,8 @@ cfg(report_output_format_CFG, "output_format", report_CFG_SECTION, CFG_PROFILABL
|
||||
" Compared to original \"json\" format:\n"
|
||||
" - it does not use double quotes around numeric values,\n"
|
||||
" - it uses 'null' for undefined numeric values,\n"
|
||||
" - it prints string list as proper JSON array of strings instead of a single string."
|
||||
"\n")
|
||||
" - it prints string list as proper JSON array of strings instead of a single string.\n"
|
||||
"Note that if json or json_std output format is used, then log/command_log_report=1 is default.\n")
|
||||
|
||||
cfg(report_compact_output_CFG, "compact_output", report_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_REP_COMPACT_OUTPUT, vsn(2, 2, 115), NULL, 0, NULL,
|
||||
"Do not print empty values for all report fields.\n"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,8 +36,8 @@ struct dev_filter {
|
||||
|
||||
void dev_init(struct device *dev);
|
||||
|
||||
struct dm_list *dev_cache_get_dev_list_for_vgid(struct cmd_context *cmd, const char *vgid);
|
||||
struct dm_list *dev_cache_get_dev_list_for_lvid(struct cmd_context *cmd, const char *lvid);
|
||||
struct dm_list *dev_cache_get_dev_list_for_vgid(const char *vgid);
|
||||
struct dm_list *dev_cache_get_dev_list_for_lvid(const char *lvid);
|
||||
|
||||
/*
|
||||
* The cache of dm devices is enabled when the kernel
|
||||
@@ -49,9 +49,9 @@ struct dm_list *dev_cache_get_dev_list_for_lvid(struct cmd_context *cmd, const c
|
||||
* have an alternative for when dm_devs_cache_use()
|
||||
* returns 0.
|
||||
*/
|
||||
int dm_devs_cache_use(struct cmd_context *cmd);
|
||||
int dm_devs_cache_update(struct cmd_context *cmd);
|
||||
void dm_devs_cache_destroy(struct cmd_context *cmd);
|
||||
int dm_devs_cache_use(void);
|
||||
int dm_devs_cache_update(void);
|
||||
void dm_devs_cache_destroy(void);
|
||||
void dm_devs_cache_label_invalidate(struct cmd_context *cmd);
|
||||
const struct dm_active_device *
|
||||
dm_devs_cache_get_by_devno(struct cmd_context *cmd, dev_t devno);
|
||||
@@ -62,32 +62,38 @@ dm_devs_cache_get_by_uuid(struct cmd_context *cmd, const char *dm_uuid);
|
||||
* The global device cache.
|
||||
*/
|
||||
int dev_cache_init(struct cmd_context *cmd);
|
||||
int dev_cache_exit(struct cmd_context *cmd);
|
||||
int dev_cache_exit(void);
|
||||
|
||||
/*
|
||||
* Returns number of open devices.
|
||||
*/
|
||||
int dev_cache_check_for_open_devices(void);
|
||||
|
||||
void dev_cache_scan(struct cmd_context *cmd);
|
||||
int dev_cache_has_scanned(void);
|
||||
|
||||
int dev_cache_add_dir(struct cmd_context *cmd, const char *path);
|
||||
int dev_cache_add_dir(const char *path);
|
||||
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
|
||||
void dev_cache_verify_aliases(struct cmd_context *cmd, struct device *dev);
|
||||
|
||||
struct device *dev_cache_get_by_devno(struct cmd_context *cmd, dev_t devno);
|
||||
struct device *dev_cache_get_by_name(struct cmd_context *cmd, const char *name);
|
||||
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
|
||||
struct device *dev_cache_get_by_pvid(struct cmd_context *cmd, const char *pvid);
|
||||
void dev_cache_verify_aliases(struct device *dev);
|
||||
|
||||
void dev_set_preferred_name(struct cmd_context *cmd, struct dm_str_list *sl, struct device *dev);
|
||||
struct device *dev_cache_get_dev_by_name(const char *name);
|
||||
|
||||
void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
|
||||
|
||||
/*
|
||||
* Object for iterating through the cache.
|
||||
*/
|
||||
struct dev_iter;
|
||||
struct dev_iter *dev_iter_create(struct cmd_context *cmd, struct dev_filter *f, int unused);
|
||||
struct dev_iter *dev_iter_create(struct dev_filter *f, int unused);
|
||||
void dev_iter_destroy(struct dev_iter *iter);
|
||||
struct device *dev_iter_get(struct cmd_context *cmd, struct dev_iter *iter);
|
||||
|
||||
void dev_cache_failed_path(struct cmd_context *cmd, struct device *dev, const char *path);
|
||||
void dev_cache_failed_path(struct device *dev, const char *path);
|
||||
|
||||
bool dev_cache_has_md_with_end_superblock(struct cmd_context *cmd, struct dev_types *dt);
|
||||
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
|
||||
|
||||
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
|
||||
int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen);
|
||||
|
||||
@@ -576,7 +576,7 @@ static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
|
||||
* Check the primary device, not the partition.
|
||||
*/
|
||||
if (primary_result == 2) {
|
||||
if (!(dev = dev_cache_get_by_devno(cmd, primary_dev))) {
|
||||
if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) {
|
||||
log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,6 @@ struct device {
|
||||
uint64_t end;
|
||||
struct dev_ext ext;
|
||||
const char *duplicate_prefer_reason;
|
||||
struct cmd_context *cmd;
|
||||
|
||||
const char *vgid; /* if device is an LV */
|
||||
const char *lvid; /* if device is an LV */
|
||||
|
||||
@@ -2738,7 +2738,7 @@ void device_ids_match(struct cmd_context *cmd)
|
||||
*/
|
||||
found = 0;
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
continue;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
/* skip a dev that's already matched to another entry */
|
||||
@@ -2855,7 +2855,7 @@ static void _get_devs_with_serial_numbers(struct cmd_context *cmd, struct dm_lis
|
||||
struct dev_id *id;
|
||||
const char *idname;
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
/* if serial has already been read for this dev then use it */
|
||||
@@ -3794,7 +3794,7 @@ void device_ids_search(struct cmd_context *cmd, struct dm_list *new_devs,
|
||||
* filter), in the process of doing this search outside the deviceid
|
||||
* filter.
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
if (dev->flags & DEV_MATCHED_USE_ID)
|
||||
|
||||
@@ -39,7 +39,7 @@ static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f
|
||||
*/
|
||||
if ((dev->flags & DEV_MATCHED_USE_ID) && mpath_devno) {
|
||||
if (!get_du_for_devno(cmd, mpath_devno)) {
|
||||
struct device *mpath_dev = dev_cache_get_by_devno(cmd, mpath_devno);
|
||||
struct device *mpath_dev = dev_cache_get_by_devt(cmd, mpath_devno);
|
||||
log_warn("WARNING: devices file is missing %s (%u:%u) using multipath component %s.",
|
||||
mpath_dev ? dev_name(mpath_dev) : "unknown",
|
||||
MAJOR(mpath_devno), MINOR(mpath_devno), dev_name(dev));
|
||||
|
||||
@@ -183,7 +183,7 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
|
||||
if (m >= 0) {
|
||||
if (dm_bit(rf->accept, m)) {
|
||||
if (!first && !cmd->filter_regex_set_preferred_name_disable)
|
||||
dev_set_preferred_name(cmd, sl, dev);
|
||||
dev_set_preferred_name(sl, dev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,12 @@ static int _integrity_text_import(struct lv_segment *seg,
|
||||
set->sectors_per_bit_set = 1;
|
||||
}
|
||||
|
||||
if (dm_config_has_node(sn, "allow_discards")) {
|
||||
if (!dm_config_get_uint32(sn, "allow_discards", &set->allow_discards))
|
||||
return SEG_LOG_ERROR("Unknown integrity_setting in");
|
||||
set->allow_discards_set = 1;
|
||||
}
|
||||
|
||||
seg->origin = origin_lv;
|
||||
seg->integrity_meta_dev = meta_lv;
|
||||
seg->lv->status |= INTEGRITY;
|
||||
@@ -217,6 +223,9 @@ static int _integrity_text_export(const struct lv_segment *seg,
|
||||
if (set->sectors_per_bit)
|
||||
outf(f, "sectors_per_bit = %llu", (unsigned long long)set->sectors_per_bit);
|
||||
|
||||
if (set->allow_discards_set)
|
||||
outf(f, "allow_discards = %u", set->allow_discards);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -499,7 +499,7 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
|
||||
* became stale somehow (e.g. manually copying devices with dd) and
|
||||
* need to be refreshed.
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return 0;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
if (dm_list_empty(&dev->aliases))
|
||||
@@ -877,7 +877,7 @@ static int _read_hint_file(struct cmd_context *cmd, struct dm_list *hints, int *
|
||||
/*
|
||||
* Calculate and compare hash of devices that may be scanned.
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return 0;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
if (cmd->enable_devices_file && !get_du_for_dev(cmd, dev))
|
||||
@@ -1049,7 +1049,7 @@ int write_hint_file(struct cmd_context *cmd, int newhints)
|
||||
* dev flagged DEV_SCAN_FOUND_LABEL
|
||||
*/
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0))) {
|
||||
if (!(iter = dev_iter_create(NULL, 0))) {
|
||||
ret = 0;
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
@@ -537,8 +537,8 @@ static int _scan_dev_open(struct device *dev)
|
||||
*/
|
||||
log_debug("Drop alias for %u:%u failed open %s (%d).",
|
||||
MAJOR(dev->dev), MINOR(dev->dev), name, errno);
|
||||
dev_cache_failed_path(dev->cmd, dev, name);
|
||||
dev_cache_verify_aliases(dev->cmd, dev);
|
||||
dev_cache_failed_path(dev, name);
|
||||
dev_cache_verify_aliases(dev);
|
||||
goto next_name;
|
||||
}
|
||||
}
|
||||
@@ -548,8 +548,8 @@ static int _scan_dev_open(struct device *dev)
|
||||
log_warn("Invalid path %s for device %u:%u, trying different path.",
|
||||
name, MAJOR(dev->dev), MINOR(dev->dev));
|
||||
(void)close(fd);
|
||||
dev_cache_failed_path(dev->cmd, dev, name);
|
||||
dev_cache_verify_aliases(dev->cmd, dev);
|
||||
dev_cache_failed_path(dev, name);
|
||||
dev_cache_verify_aliases(dev);
|
||||
goto next_name;
|
||||
}
|
||||
|
||||
@@ -899,7 +899,7 @@ int label_scan_for_pvid(struct cmd_context *cmd, char *pvid, struct device **dev
|
||||
* pass filters, and are those we can use.
|
||||
*/
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, cmd->filter, 0))) {
|
||||
if (!(iter = dev_iter_create(cmd->filter, 0))) {
|
||||
log_error("Scanning failed to get devices.");
|
||||
return 0;
|
||||
}
|
||||
@@ -1046,7 +1046,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
|
||||
dm_list_iterate_items(po, &pvs_online) {
|
||||
if (po->dev)
|
||||
continue;
|
||||
if (!(po->dev = dev_cache_get_by_devno(cmd, po->devno))) {
|
||||
if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) {
|
||||
log_error("No device found for %u:%u PVID %s.",
|
||||
MAJOR(po->devno), MINOR(po->devno), po->pvid);
|
||||
goto bad;
|
||||
@@ -1263,7 +1263,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
* here, before processing the hints file, so that the dm uuid checks
|
||||
* in hint processing can benefit from the dm uuid cache.)
|
||||
*/
|
||||
if (!dm_devs_cache_update(cmd))
|
||||
if (!dm_devs_cache_update())
|
||||
return_0;
|
||||
|
||||
/*
|
||||
@@ -1288,7 +1288,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
*/
|
||||
if (cmd->md_component_detection && !cmd->use_full_md_check &&
|
||||
!strcmp(cmd->md_component_checks, "auto") &&
|
||||
dev_cache_has_md_with_end_superblock(cmd, cmd->dev_types)) {
|
||||
dev_cache_has_md_with_end_superblock(cmd->dev_types)) {
|
||||
log_debug("Enable full md component check.");
|
||||
cmd->use_full_md_check = 1;
|
||||
}
|
||||
@@ -1299,7 +1299,7 @@ int label_scan(struct cmd_context *cmd)
|
||||
* Invalidate bcache data for all devs (there will usually be no bcache
|
||||
* data to invalidate.)
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0))) {
|
||||
if (!(iter = dev_iter_create(NULL, 0))) {
|
||||
log_error("Failed to get device list.");
|
||||
return 0;
|
||||
}
|
||||
@@ -1652,7 +1652,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
|
||||
if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) {
|
||||
/* FIXME: Still unclear what is it supposed to find */
|
||||
devt = MKDEV(lvinfo.major, lvinfo.minor);
|
||||
if ((dev = dev_cache_get_by_devno(cmd, devt)))
|
||||
if ((dev = dev_cache_get_by_devt(cmd, devt)))
|
||||
label_scan_invalidate(dev);
|
||||
}
|
||||
}
|
||||
@@ -1670,7 +1670,7 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
|
||||
|
||||
log_debug("Invalidating devs for any PVs on LVs.");
|
||||
|
||||
if (dm_devs_cache_use(cmd))
|
||||
if (dm_devs_cache_use())
|
||||
dm_devs_cache_label_invalidate(cmd);
|
||||
else {
|
||||
dm_list_iterate_items(lvl, lvs)
|
||||
@@ -1688,7 +1688,7 @@ void label_scan_drop(struct cmd_context *cmd)
|
||||
struct dev_iter *iter;
|
||||
struct device *dev;
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return;
|
||||
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
|
||||
@@ -330,7 +330,7 @@ int vg_write_lock_held(void)
|
||||
|
||||
int sync_local_dev_names(struct cmd_context* cmd)
|
||||
{
|
||||
dm_devs_cache_destroy(cmd);
|
||||
dm_devs_cache_destroy();
|
||||
memlock_unlock(cmd);
|
||||
fs_unlock();
|
||||
return 1;
|
||||
|
||||
@@ -50,7 +50,8 @@ int lv_is_integrity_origin(const struct logical_volume *lv)
|
||||
* plus some initial space for journals.
|
||||
* (again from trial and error testing.)
|
||||
*/
|
||||
static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
|
||||
static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes, uint32_t journal_sectors,
|
||||
uint32_t extent_size)
|
||||
{
|
||||
uint64_t meta_bytes;
|
||||
uint64_t initial_bytes;
|
||||
@@ -58,8 +59,16 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
|
||||
/* Every 500M of data needs 4M of metadata. */
|
||||
meta_bytes = ((lv_size_bytes / (500 * ONE_MB_IN_BYTES)) + 1) * (4 * ONE_MB_IN_BYTES);
|
||||
|
||||
if (journal_sectors) {
|
||||
/* for calculating the metadata LV size for the specified
|
||||
journal size, round the specified journal size up to the
|
||||
nearest extent. extent_size is in sectors. */
|
||||
initial_bytes = dm_round_up(journal_sectors, extent_size) * 512;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* initial space used for journals
|
||||
* initial space used for journals (when journal size is not specified):
|
||||
* lv_size <= 512M -> 4M
|
||||
* lv_size <= 1G -> 8M
|
||||
* lv_size <= 4G -> 32M
|
||||
@@ -73,7 +82,10 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
|
||||
initial_bytes = 32 * ONE_MB_IN_BYTES;
|
||||
else if (lv_size_bytes > (4ULL * ONE_GB_IN_BYTES))
|
||||
initial_bytes = 64 * ONE_MB_IN_BYTES;
|
||||
|
||||
out:
|
||||
log_debug("integrity_meta_bytes %llu from lv_size_bytes %llu meta_bytes %llu initial_bytes %llu journal_sectors %u",
|
||||
(unsigned long long)(meta_bytes+initial_bytes), (unsigned long long)lv_size_bytes,
|
||||
(unsigned long long)meta_bytes, (unsigned long long)initial_bytes, journal_sectors);
|
||||
return meta_bytes + initial_bytes;
|
||||
}
|
||||
|
||||
@@ -84,6 +96,7 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
|
||||
static int _lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
struct volume_group *vg,
|
||||
struct lvcreate_params *lp,
|
||||
struct integrity_settings *settings,
|
||||
struct logical_volume **meta_lv)
|
||||
{
|
||||
char metaname[NAME_LEN] = { 0 };
|
||||
@@ -115,7 +128,7 @@ static int _lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
lp_meta.pvh = lp->pvh;
|
||||
|
||||
lv_size_bytes = (uint64_t)lp->extents * (uint64_t)vg->extent_size * 512;
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes);
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes, settings->journal_sectors, vg->extent_size);
|
||||
meta_sectors = meta_bytes / 512;
|
||||
lp_meta.extents = meta_sectors / vg->extent_size;
|
||||
|
||||
@@ -181,13 +194,20 @@ int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh)
|
||||
}
|
||||
|
||||
lv_size_bytes = lv_iorig->size * 512;
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes);
|
||||
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes, 0, 0);
|
||||
meta_sectors = meta_bytes / 512;
|
||||
meta_extents = meta_sectors / vg->extent_size;
|
||||
|
||||
prev_meta_sectors = lv_imeta->size;
|
||||
prev_meta_extents = prev_meta_sectors / vg->extent_size;
|
||||
|
||||
/*
|
||||
* FIXME: allow --integritysettings journal_sectors to be used
|
||||
* with lvextend to override the default journal_sectors
|
||||
* calculation, but only if the LV is inactive (the journal
|
||||
* sectors cannot be updated in reload.)
|
||||
*/
|
||||
|
||||
if (meta_extents <= prev_meta_extents) {
|
||||
log_debug("extend not needed for imeta LV %s", lv_imeta->name);
|
||||
continue;
|
||||
@@ -597,7 +617,7 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting
|
||||
lp.pvh = use_pvh;
|
||||
lp.extents = lv_image->size / vg->extent_size;
|
||||
|
||||
if (!_lv_create_integrity_metadata(cmd, vg, &lp, &meta_lv))
|
||||
if (!_lv_create_integrity_metadata(cmd, vg, &lp, settings, &meta_lv))
|
||||
goto_bad;
|
||||
|
||||
revert_meta_lvs++;
|
||||
|
||||
@@ -4415,6 +4415,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
|
||||
log_error("Failed to remove LV");
|
||||
else if (!vg_write(vg) || !vg_commit(vg))
|
||||
log_error("Failed to commit VG %s", vg->name);
|
||||
dm_pool_free(vg->vgmem, lvl);
|
||||
return_0;
|
||||
}
|
||||
|
||||
@@ -4571,7 +4572,7 @@ int lv_extend(struct logical_volume *lv,
|
||||
alloc != ALLOC_ANYWHERE &&
|
||||
!(r = _lv_raid_redundant_allocation(lv, allocatable_pvs))) {
|
||||
log_error("Insufficient suitable allocatable extents for logical volume %s", display_lvname(lv));
|
||||
if (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg))
|
||||
if (!old_extents && (!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)))
|
||||
return_0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3353,7 +3353,7 @@ int vg_missing_pv_count(const struct volume_group *vg)
|
||||
|
||||
#define DEV_LIST_DELIM ", "
|
||||
|
||||
static int _check_devs_used_correspond_with_lv(struct cmd_context *cmd, struct dm_pool *mem, struct dm_list *list, struct logical_volume *lv)
|
||||
static int _check_devs_used_correspond_with_lv(struct dm_pool *mem, struct dm_list *list, struct logical_volume *lv)
|
||||
{
|
||||
struct device_list *dl;
|
||||
int found_inconsistent = 0;
|
||||
@@ -3363,7 +3363,7 @@ static int _check_devs_used_correspond_with_lv(struct cmd_context *cmd, struct d
|
||||
int warned_about_no_dev = 0;
|
||||
char *used_devnames = NULL, *assumed_devnames = NULL;
|
||||
|
||||
if (!(list = dev_cache_get_dev_list_for_lvid(cmd, lv->lvid.s + ID_LEN)))
|
||||
if (!(list = dev_cache_get_dev_list_for_lvid(lv->lvid.s + ID_LEN)))
|
||||
return 1;
|
||||
|
||||
dm_list_iterate_items(dl, list) {
|
||||
@@ -3429,7 +3429,7 @@ static int _check_devs_used_correspond_with_lv(struct cmd_context *cmd, struct d
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _check_devs_used_correspond_with_vg(struct cmd_context *cmd, struct volume_group *vg)
|
||||
static int _check_devs_used_correspond_with_vg(struct volume_group *vg)
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
char vgid[ID_LEN + 1] __attribute__((aligned(8)));
|
||||
@@ -3458,7 +3458,7 @@ static int _check_devs_used_correspond_with_vg(struct cmd_context *cmd, struct v
|
||||
pvl->pv->dev->flags |= DEV_ASSUMED_FOR_LV;
|
||||
}
|
||||
|
||||
if (!(list = dev_cache_get_dev_list_for_vgid(cmd, vgid)))
|
||||
if (!(list = dev_cache_get_dev_list_for_vgid(vgid)))
|
||||
return 1;
|
||||
|
||||
dm_list_iterate_items(dl, list) {
|
||||
@@ -3474,7 +3474,7 @@ static int _check_devs_used_correspond_with_vg(struct cmd_context *cmd, struct v
|
||||
return_0;
|
||||
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!_check_devs_used_correspond_with_lv(cmd, mem, list, lvl->lv)) {
|
||||
if (!_check_devs_used_correspond_with_lv(mem, list, lvl->lv)) {
|
||||
dm_pool_destroy(mem);
|
||||
return_0;
|
||||
}
|
||||
@@ -5092,7 +5092,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const
|
||||
log_warn("WARNING: One or more devices used as PVs in VG %s have changed sizes.", vg->name);
|
||||
|
||||
if (cmd->check_devs_used)
|
||||
_check_devs_used_correspond_with_vg(cmd, vg);
|
||||
_check_devs_used_correspond_with_vg(vg);
|
||||
|
||||
if (!_access_vg_lock_type(cmd, vg, lockd_state, &failure)) {
|
||||
/* Either FAILED_LOCK_TYPE or FAILED_LOCK_MODE were set. */
|
||||
|
||||
@@ -26,6 +26,39 @@ lvcreate -l1 -T $vg/$lv1
|
||||
lvcreate -l1 -n $lv2 --addtag lv_tag1 -an $vg
|
||||
lvcreate -l1 -n $lv3 --addtag lv_tag3 --addtag lv_tag1 --addtag lv_tag2 $vg
|
||||
|
||||
check_json_vs_log() {
|
||||
local format_param
|
||||
local log_output=$2
|
||||
local extra_cmd_line=$3
|
||||
|
||||
if [ -z $1 ]; then
|
||||
format_param=""
|
||||
else
|
||||
format_param="--reportformat $1"
|
||||
fi
|
||||
|
||||
not lvs $format_param $extra_cmd_line -o name $vg/lvolX 2>&1 | tee "$OUT_LOG_FILE"
|
||||
|
||||
if [ "$log_output" = "log_in_report" ]; then
|
||||
# {
|
||||
# "report": [
|
||||
# ...
|
||||
# ]
|
||||
# "log": [
|
||||
# { ... "log_message": "Failed to find logical volume" ...},
|
||||
# ...
|
||||
# }
|
||||
grep -E "^[[:space:]]*\"log\": \[" out
|
||||
grep -E "^[[:space:]]*\{.*\"log_message\":\"Failed to find logical volume.*\}" out
|
||||
elif [ "$log_output" = "direct_log" ]; then
|
||||
# Failed to find logical volume ...
|
||||
not grep -E "^[[:space:]]*\"log\": \[" out
|
||||
grep -E "[[:space:]]*Failed to find logical volume" out
|
||||
else
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
aux lvmconf "report/output_format = basic"
|
||||
lvs -o name,kernel_major,data_percent,tags | tee "$OUT_LOG_FILE"
|
||||
|
||||
@@ -39,6 +72,14 @@ grep -E "^[[:space:]]*${lv1}[[:space:]]*[[:digit:]]+[[:space:]]*[[:digit:]]+.[[:
|
||||
grep -E "^[[:space:]]*${lv2}[[:space:]]*-1[[:space:]]*lv_tag1[[:space:]]*\$" out
|
||||
grep -E "^[[:space:]]*${lv3}[[:space:]]*[[:digit:]]+[[:space:]]*lv_tag1,lv_tag2,lv_tag3\$" out
|
||||
|
||||
check_json_vs_log "" direct_log ""
|
||||
check_json_vs_log "" direct_log "--config log/report_command_log=1"
|
||||
|
||||
check_json_vs_log json log_in_report ""
|
||||
check_json_vs_log json_std log_in_report ""
|
||||
|
||||
check_json_vs_log json direct_log "--config log/report_command_log=0"
|
||||
check_json_vs_log json_std direct_log "--config log/report_command_log=0"
|
||||
|
||||
aux lvmconf "report/output_format = json"
|
||||
lvs -o name,kernel_major,data_percent,tags | tee "$OUT_LOG_FILE"
|
||||
@@ -57,6 +98,9 @@ grep -E "^[[:space:]]*{\"lv_name\":\"$lv1\", \"lv_kernel_major\":\"[[:digit:]]+\
|
||||
grep -E "^[[:space:]]*{\"lv_name\":\"$lv2\", \"lv_kernel_major\":\"-1\", \"data_percent\":\"\", \"lv_tags\":\"lv_tag1\"},\$" out
|
||||
grep -E "^[[:space:]]*{\"lv_name\":\"$lv3\", \"lv_kernel_major\":\"[[:digit:]]+\", \"data_percent\":\"\", \"lv_tags\":\"lv_tag1,lv_tag2,lv_tag3\"}\$" out
|
||||
|
||||
check_json_vs_log "" log_in_report ""
|
||||
check_json_vs_log "" direct_log "--config log/report_command_log=0"
|
||||
|
||||
aux lvmconf "report/output_format = json_std"
|
||||
lvs -o name,kernel_major,data_percent,tags | tee "$OUT_LOG_FILE"
|
||||
# {
|
||||
@@ -74,4 +118,15 @@ grep -E "^[[:space:]]*{\"lv_name\":\"$lv1\", \"lv_kernel_major\":[[:digit:]]+, \
|
||||
grep -E "^[[:space:]]*{\"lv_name\":\"$lv2\", \"lv_kernel_major\":-1, \"data_percent\":null, \"lv_tags\":\[\"lv_tag1\"\]},\$" out
|
||||
grep -E "^[[:space:]]*{\"lv_name\":\"$lv3\", \"lv_kernel_major\":[[:digit:]]+, \"data_percent\":null, \"lv_tags\":\[\"lv_tag1\",\"lv_tag2\",\"lv_tag3\"\]}\$" out
|
||||
|
||||
check_json_vs_log "" log_in_report ""
|
||||
check_json_vs_log "" direct_log "--config log/report_command_log=0"
|
||||
|
||||
aux lvmconf "log/report_command_log = 0"
|
||||
check_json_vs_log "" direct_log ""
|
||||
check_json_vs_log "" log_in_report "--config log/report_command_log=1"
|
||||
|
||||
aux lvmconf "log/report_command_log = 1"
|
||||
check_json_vs_log "" log_in_report ""
|
||||
check_json_vs_log "" direct_log "--config log/report_command_log=0"
|
||||
|
||||
vgremove -ff $vg
|
||||
|
||||
@@ -1392,6 +1392,10 @@ arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", 0, 0, 0,
|
||||
"Ignore the \"activation skip\" LV flag during activation\n"
|
||||
"to allow LVs with the flag set to be activated.\n")
|
||||
|
||||
arg(integritysettings_ARG, '\0', "integritysettings", string_VAL, ARG_GROUPABLE, 0,
|
||||
"Specifies tunable kernel options for dm-integrity.\n"
|
||||
"See \\fBlvmraid\\fP(7) for more information.\n")
|
||||
|
||||
arg(maps_ARG, 'm', "maps", 0, 0, 0,
|
||||
"#lvdisplay\n"
|
||||
"Display the mapping of logical extents to PVs and physical extents.\n"
|
||||
|
||||
@@ -843,7 +843,7 @@ FLAGS: SECONDARY_SYNTAX
|
||||
---
|
||||
|
||||
lvconvert --raidintegrity Bool LV_raid
|
||||
OO: --raidintegritymode String, --raidintegrityblocksize Number, OO_LVCONVERT
|
||||
OO: --raidintegritymode String, --raidintegrityblocksize Number, --integritysettings String, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_integrity
|
||||
DESC: Add or remove data integrity checksums to raid images.
|
||||
@@ -869,7 +869,7 @@ OO_LVCREATE_VDO: --compression Bool, --deduplication Bool, --vdosettings String
|
||||
OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool, --pooldatavdo Bool, OO_LVCREATE_VDO, OO_LVCREATE_POOL
|
||||
|
||||
OO_LVCREATE_RAID: --regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
|
||||
--raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number
|
||||
--raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number, --integritysettings String
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -6519,6 +6519,11 @@ static int _lvconvert_integrity_single(struct cmd_context *cmd,
|
||||
struct integrity_settings settings = { .tag_size = 0 };
|
||||
int ret;
|
||||
|
||||
if (arg_is_set(cmd, integritysettings_ARG)) {
|
||||
if (!get_integrity_settings(cmd, &settings))
|
||||
return_ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &settings))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
|
||||
@@ -615,6 +615,10 @@ static int _read_raid_params(struct cmd_context *cmd,
|
||||
if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &lp->integrity_settings))
|
||||
return_0;
|
||||
}
|
||||
if (arg_is_set(cmd, integritysettings_ARG)) {
|
||||
if (!get_integrity_settings(cmd, &lp->integrity_settings))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -936,7 +940,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||
raidminrecoveryrate_ARG, \
|
||||
raidintegrity_ARG, \
|
||||
raidintegritymode_ARG, \
|
||||
raidintegrityblocksize_ARG
|
||||
raidintegrityblocksize_ARG, \
|
||||
integritysettings_ARG
|
||||
|
||||
#define SIZE_ARGS \
|
||||
extents_ARG,\
|
||||
|
||||
@@ -40,7 +40,7 @@ static void _search_devs_for_pvids(struct cmd_context *cmd, struct dm_list *sear
|
||||
* any filters, since we do not want filters to read any of the
|
||||
* devices yet.
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return;
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
/* Skip devs with a valid match to a du. */
|
||||
@@ -697,7 +697,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
if (update_set)
|
||||
dm_list_del(&du->list);
|
||||
|
||||
if (!(mpath_dev = dev_cache_get_by_devno(cmd, mpath_devno)))
|
||||
if (!(mpath_dev = dev_cache_get_by_devt(cmd, mpath_devno)))
|
||||
continue;
|
||||
|
||||
if (!get_du_for_dev(cmd, mpath_dev)) {
|
||||
|
||||
@@ -34,7 +34,7 @@ static int _get_max_dev_name_len(struct cmd_context *cmd, struct dev_filter *fil
|
||||
struct dev_iter *iter;
|
||||
struct device *dev;
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, filter, 1))) {
|
||||
if (!(iter = dev_iter_create(filter, 1))) {
|
||||
log_error("dev_iter_create failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ int lvmdiskscan(struct cmd_context *cmd, int argc __attribute__((unused)),
|
||||
|
||||
_max_len = _get_max_dev_name_len(cmd, cmd->filter);
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, cmd->filter, 0))) {
|
||||
if (!(iter = dev_iter_create(cmd->filter, 0))) {
|
||||
log_error("dev_iter_create failed");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
@@ -3033,7 +3033,7 @@ static int _pvck_mf(struct metadata_file *mf, struct cmd_context *cmd, int argc,
|
||||
}
|
||||
|
||||
if (!(dev = dev_cache_get(cmd, pv_name, NULL))) {
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(cmd, pv_name));
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -3057,7 +3057,7 @@ static int _pvck_mf(struct metadata_file *mf, struct cmd_context *cmd, int argc,
|
||||
dev = dev_cache_get(cmd, pv_name, NULL);
|
||||
}
|
||||
if (!dev && !def) {
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(cmd, pv_name));
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -3183,7 +3183,7 @@ static int _pvck_mf(struct metadata_file *mf, struct cmd_context *cmd, int argc,
|
||||
pv_name = argv[i];
|
||||
|
||||
if (!(dev = dev_cache_get(cmd, argv[i], cmd->filter))) {
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(cmd, pv_name));
|
||||
log_error("Cannot use %s: %s.", pv_name, devname_error_reason(pv_name));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1385,7 +1385,7 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv,
|
||||
* The use of filter here will just reuse the existing
|
||||
* (persistent) filter info label_scan has already set up.
|
||||
*/
|
||||
if (!(iter = dev_iter_create(cmd, cmd->filter, 1)))
|
||||
if (!(iter = dev_iter_create(cmd->filter, 1)))
|
||||
return_0;
|
||||
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
@@ -1461,7 +1461,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
|
||||
|
||||
if (cmd->md_component_detection && !cmd->use_full_md_check &&
|
||||
!strcmp(cmd->md_component_checks, "auto") &&
|
||||
dev_cache_has_md_with_end_superblock(cmd, cmd->dev_types)) {
|
||||
dev_cache_has_md_with_end_superblock(cmd->dev_types)) {
|
||||
log_debug("Enable full md component check.");
|
||||
cmd->use_full_md_check = 1;
|
||||
}
|
||||
|
||||
@@ -1487,9 +1487,9 @@ int devtypes(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
int report_format_init(struct cmd_context *cmd)
|
||||
{
|
||||
int config_set = find_config_tree_node(cmd, report_output_format_CFG, NULL) != NULL;
|
||||
const char *config_format_str = find_config_tree_str(cmd, report_output_format_CFG, NULL);
|
||||
const char *format_str = arg_str_value(cmd, reportformat_ARG, config_set ? config_format_str : NULL);
|
||||
const char *format_str = arg_str_value(cmd, reportformat_ARG, config_format_str);
|
||||
int report_command_log_config_set = find_config_tree_node(cmd, log_report_command_log_CFG, NULL) != NULL;
|
||||
int report_command_log;
|
||||
struct report_args args = {0};
|
||||
struct single_report_args *single_args;
|
||||
@@ -1504,8 +1504,12 @@ int report_format_init(struct cmd_context *cmd)
|
||||
: DM_REPORT_GROUP_SINGLE;
|
||||
} else if (!strcmp(format_str, REPORT_FORMAT_NAME_JSON)) {
|
||||
args.report_group_type = DM_REPORT_GROUP_JSON;
|
||||
if (!report_command_log_config_set)
|
||||
report_command_log = 1;
|
||||
} else if (!strcmp(format_str, REPORT_FORMAT_NAME_JSON_STD)) {
|
||||
args.report_group_type = DM_REPORT_GROUP_JSON_STD;
|
||||
if (!report_command_log_config_set)
|
||||
report_command_log = 1;
|
||||
} else {
|
||||
log_error("%s: unknown report format.", format_str);
|
||||
log_error("Supported report formats: %s, %s, %s.",
|
||||
|
||||
122
tools/toollib.c
122
tools/toollib.c
@@ -1627,6 +1627,118 @@ int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _get_one_integrity_setting(struct cmd_context *cmd, struct integrity_settings *settings,
|
||||
char *key, char *val)
|
||||
{
|
||||
/*
|
||||
* Some settings handled by other options:
|
||||
* settings->mode from --raidintegritymode
|
||||
* settings->block_size from --raidintegrityblocksize
|
||||
*/
|
||||
|
||||
/* always set in metadata and on table line */
|
||||
|
||||
if (!strncmp(key, "journal_sectors", sizeof("journal_sectors") - 1)) {
|
||||
uint32_t size_mb;
|
||||
|
||||
if (sscanf(val, "%u", &settings->journal_sectors) != 1)
|
||||
goto_bad;
|
||||
|
||||
size_mb = settings->journal_sectors / 2048;
|
||||
if (size_mb < 4 || size_mb > 1024) {
|
||||
log_error("Invalid raid integrity journal size %d MiB (use 4-1024 MiB).", size_mb);
|
||||
goto_bad;
|
||||
}
|
||||
settings->journal_sectors_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* optional, not included in metadata or table line unless set */
|
||||
|
||||
if (!strncmp(key, "journal_watermark", sizeof("journal_watermark") - 1)) {
|
||||
if (sscanf(val, "%u", &settings->journal_watermark) != 1)
|
||||
goto_bad;
|
||||
if (settings->journal_watermark > 100)
|
||||
goto_bad;
|
||||
settings->journal_watermark_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(key, "commit_time", sizeof("commit_time") - 1)) {
|
||||
if (sscanf(val, "%u", &settings->commit_time) != 1)
|
||||
goto_bad;
|
||||
settings->commit_time_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(key, "bitmap_flush_interval", sizeof("bitmap_flush_interval") - 1)) {
|
||||
if (sscanf(val, "%u", &settings->bitmap_flush_interval) != 1)
|
||||
goto_bad;
|
||||
settings->bitmap_flush_interval_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(key, "allow_discards", sizeof("allow_discards") - 1)) {
|
||||
if (sscanf(val, "%u", &settings->allow_discards) != 1)
|
||||
goto_bad;
|
||||
if (settings->allow_discards != 0 && settings->allow_discards != 1)
|
||||
goto_bad;
|
||||
settings->allow_discards_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
bad:
|
||||
log_error("Invalid setting: %s", key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_integrity_settings(struct cmd_context *cmd, struct integrity_settings *settings)
|
||||
{
|
||||
struct arg_value_group_list *group;
|
||||
const char *str;
|
||||
char key[64];
|
||||
char val[64];
|
||||
int num;
|
||||
unsigned pos;
|
||||
|
||||
/*
|
||||
* "grouped" means that multiple --integritysettings options can be used.
|
||||
* Each option is also allowed to contain multiple key = val pairs.
|
||||
*/
|
||||
|
||||
dm_list_iterate_items(group, &cmd->arg_value_groups) {
|
||||
if (!grouped_arg_is_set(group->arg_values, integritysettings_ARG))
|
||||
continue;
|
||||
|
||||
if (!(str = grouped_arg_str_value(group->arg_values, integritysettings_ARG, NULL)))
|
||||
break;
|
||||
|
||||
pos = 0;
|
||||
|
||||
while (pos < strlen(str)) {
|
||||
/* scan for "key1=val1 key2 = val2 key3= val3" */
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
memset(val, 0, sizeof(val));
|
||||
|
||||
if (sscanf(str + pos, " %63[^=]=%63s %n", key, val, &num) != 2) {
|
||||
log_error("Invalid setting at: %s", str+pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos += num;
|
||||
|
||||
if (!_get_one_integrity_setting(cmd, settings, key, val))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FIXME move to lib */
|
||||
static int _pv_change_tag(struct physical_volume *pv, const char *tag, int addtag)
|
||||
{
|
||||
@@ -1777,7 +1889,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, cmd->filter, 1))) {
|
||||
if (!(iter = dev_iter_create(cmd->filter, 1))) {
|
||||
log_error("dev_iter creation failed.");
|
||||
ret_max = ECMD_FAILED;
|
||||
goto out;
|
||||
@@ -4201,7 +4313,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
|
||||
log_error("Cannot use %s: %s", sl->str, devname_error_reason(cmd, sl->str));
|
||||
log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
|
||||
ret_max = EINIT_FAILED;
|
||||
} else {
|
||||
memcpy(dil->pvid, dil->dev->pvid, ID_LEN);
|
||||
@@ -4235,7 +4347,7 @@ static int _process_other_devices(struct cmd_context *cmd,
|
||||
* was set by label_scan which did filtering.
|
||||
*/
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, NULL, 0)))
|
||||
if (!(iter = dev_iter_create(NULL, 0)))
|
||||
return_0;
|
||||
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
@@ -5578,7 +5690,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
|
||||
*/
|
||||
dm_list_iterate_items_safe(pd, pd2, &pp->arg_devices) {
|
||||
if (!cmd->filter->passes_filter(cmd, cmd->filter, pd->dev, NULL)) {
|
||||
log_error("Cannot use %s: %s", pd->name, devname_error_reason(cmd, pd->name));
|
||||
log_error("Cannot use %s: %s", pd->name, devname_error_reason(pd->name));
|
||||
dm_list_del(&pd->list);
|
||||
dm_list_add(&pp->arg_fail, &pd->list);
|
||||
}
|
||||
@@ -5804,7 +5916,7 @@ do_command:
|
||||
|
||||
dm_list_iterate_items_safe(pd, pd2, &pp->arg_process) {
|
||||
if (!cmd->filter->passes_filter(cmd, cmd->filter, pd->dev, NULL)) {
|
||||
log_error("Cannot use %s: %s", pd->name, devname_error_reason(cmd, pd->name));
|
||||
log_error("Cannot use %s: %s", pd->name, devname_error_reason(pd->name));
|
||||
dm_list_del(&pd->list);
|
||||
dm_list_add(&pp->arg_fail, &pd->list);
|
||||
}
|
||||
|
||||
@@ -227,6 +227,8 @@ int get_vdo_settings(struct cmd_context *cmd,
|
||||
int get_writecache_settings(struct cmd_context *cmd, struct writecache_settings *settings,
|
||||
uint32_t *block_size_sectors);
|
||||
|
||||
int get_integrity_settings(struct cmd_context *cmd, struct integrity_settings *settings);
|
||||
|
||||
int change_tag(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct logical_volume *lv, struct physical_volume *pv, int arg);
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ static int _get_other_devs(struct cmd_context *cmd, struct dm_list *new_devs, st
|
||||
struct device_list *devl;
|
||||
int r = 1;
|
||||
|
||||
if (!(iter = dev_iter_create(cmd, cmd->filter, 0)))
|
||||
if (!(iter = dev_iter_create(cmd->filter, 0)))
|
||||
return_0;
|
||||
|
||||
while ((dev = dev_iter_get(cmd, iter))) {
|
||||
|
||||
Reference in New Issue
Block a user