1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-26 16:23:58 +03:00

Compare commits

..

17 Commits

Author SHA1 Message Date
David Teigland
3b9f78332b integrity: add --integritysettings for kernel tuning
The option can be used in multiple ways (like --cachesettings):

--integritysettings key=val
--integritysettings 'key1=val1 key2=val2'
--integritysettings key1=val1 --integritysettings key2=val2

Can be used to tune kernel settings:
journal_sectors
journal_watermark
commit_time
bitmap_flush_interval
allow_discards

Described in the kernel documentation
Documentation/admin-guide/device-mapper/dm-integrity.rst

Not yet supported:
lvs -o integritysettings
lvchange --integritysettings
lvextend --integritysettings journal_sectors
2024-08-05 16:53:25 -05:00
David Teigland
07576f7e51 devices: fix dev_dm_uuid
If a non-dm device is passed, the dm code doesn't fail and returns
some dm uuid.
2024-08-01 11:32:56 -05:00
Peter Rajnoha
ae8d5113f4 WHATS_NEW: update 2024-07-30 10:32:25 +02:00
Peter Rajnoha
7fdba39b3f tests: add tests for autoswitching to JSON format for log messages 2024-07-24 09:50:26 +00:00
Peter Rajnoha
0e8c429e30 make: generate 2024-07-24 09:50:26 +00:00
Peter Rajnoha
14dbf6ca7b reporter: simplify checking output format setting in report_format_init 2024-07-24 09:50:26 +00:00
Peter Rajnoha
3eecdcbd64 config_settings: fix typo 2024-07-24 09:50:26 +00:00
Peter Rajnoha
8281f7c111 config: use default log/command_log_report=1 for json/json_std output format
log/command_log_report config setting defaults to 1 now if json or json_std
output format is used (either by setting report/output_format config
setting or using --reportformat cmd line arg).

This means that if we use json/json_std output format, the command log
messages are then part of the json output too, not interleaved as
unstructured text mixed with the json output.

If log/command_log_report is set explicitly in the config, then we still
respect that, no matter what output format is used currently. In this
case, users can still separate and redirect the output by using
LVM_OUT_FD, LVM_ERR_FD and LVM_REPORT_FD so that the different types
do not interleave with the json/json_std output.
2024-07-24 09:50:26 +00:00
Heinz Mauelshagen
be229b0cd1 WHATS_NEW 2024-07-19 13:28:30 +02:00
Heinz Mauelshagen
557b2850ce lv_manip: avoid unreleased memory pool(s) message on RAID extend
In case of different PV sizes in a VG, the lvm2 allocator falls short
to define extended segments resiliently asked for 100%FREE RaidLV extension
and a RAID distinct allocation check fails.  Fix is to release a memory pool
on the resulting error path.

Until the lvm2 allocator gets enhanced (WIP) to do such complex (and other)
allocations proper, a workaround is to extend a RaidLV to any free space on
its already allocated PVs by defining those PVs on the lvextend command line
then iteratively run further such lvextend commands to extend it to its
final intended size.  Mind, this may be a non-trivial extension interation.
2024-07-18 14:36:47 +02:00
Marian Csontos
c288ddd6c8 pages: Update release note tag and timestamp 2024-07-12 12:50:20 +02:00
Marian Csontos
60fbbd5f5f post-release 2024-07-12 12:42:39 +02:00
Marian Csontos
0eef5ab6e1 pre-release 2024-07-12 12:42:39 +02:00
David Teigland
f8aa073a8d Revert "dev-cache: move global variables into cmd struct"
This reverts commit 77be3250d9.
2024-07-08 15:32:41 -05:00
David Teigland
39e65c8f59 Revert "bcache: move from global variable to cmd struct"
This reverts commit 5bf4efbab5.
2024-07-08 15:32:35 -05:00
David Teigland
5bf4efbab5 bcache: move from global variable to cmd struct 2024-07-03 12:58:18 -05:00
David Teigland
77be3250d9 dev-cache: move global variables into cmd struct
The cmd struct is now required in many more functions, and
it's added as a function arg for most direct dev-cache function
calls.  The cmd struct is added to struct device (dev->cmd) so
that it can be accessed in many other cases where dev-cache
functions are being called from places where getting the cmd
struct is too difficult.
2024-07-03 11:52:32 -05:00
41 changed files with 607 additions and 318 deletions

View File

@@ -1 +1 @@
2.03.25(2)-git (2024-05-16)
2.03.26(2)-git (2024-07-12)

View File

@@ -1 +1 @@
1.02.199-git (2024-05-16)
1.02.200-git (2024-07-12)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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"

View File

@@ -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,

View File

@@ -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;

View File

@@ -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"]]

View File

@@ -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);

View File

@@ -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))

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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))) {

View File

@@ -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;

View File

@@ -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++;

View File

@@ -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;
}

View File

@@ -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. */

View File

@@ -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

View File

@@ -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"

View File

@@ -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
---

View File

@@ -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;

View File

@@ -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,\

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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.",

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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))) {