mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-03 01:44:19 +03:00
Compare commits
33 Commits
dev-bmr-dm
...
v2_02_128
Author | SHA1 | Date | |
---|---|---|---|
|
be1db6b6c1 | ||
|
4227b2ebb4 | ||
|
15e20bb5c0 | ||
|
80bc87e377 | ||
|
77357081c8 | ||
|
4b28383b1c | ||
|
94c56559ca | ||
|
427d0a5e92 | ||
|
623b46a17d | ||
|
a606966029 | ||
|
79ea81b8a8 | ||
|
d4c024c836 | ||
|
b297d78367 | ||
|
4a6d5e2012 | ||
|
9d5cd4ca14 | ||
|
0b487802a0 | ||
|
f3891e90e3 | ||
|
0f3b81bb2e | ||
|
00ed523659 | ||
|
77fae3d852 | ||
|
16ff2d927f | ||
|
fc7a27bc3d | ||
|
666722324f | ||
|
bfb58b7e1c | ||
|
8852b25fc7 | ||
|
4d5b618d52 | ||
|
e6724f0303 | ||
|
37dd26e322 | ||
|
f10ad95c36 | ||
|
9b3dc72506 | ||
|
4534f0fbcf | ||
|
6a93206882 | ||
|
043fb32c4b |
@@ -1 +1 @@
|
||||
1.02.105-git (2015-08-10)
|
||||
1.02.105-git (2015-08-17)
|
||||
|
11
WHATS_NEW
11
WHATS_NEW
@@ -1,10 +1,11 @@
|
||||
Version 2.02.128 -
|
||||
Version 2.02.128 - 17th August 2015
|
||||
===================================
|
||||
Allocation setting cache_pool_cachemode is replaced by cache_mode.
|
||||
Don't attempt to close config file that couldn't be opened.
|
||||
Check for valid cache mode in validation of cache segment.
|
||||
Enhance internal API cache_set_mode() and cache_set_policy().
|
||||
Enhance toollib's get_cache_params().
|
||||
Runtime detect presence of cache smq policy.
|
||||
Add demo cache-mq and cache-smq profiles.
|
||||
Change internal interface handling cache mode and policy.
|
||||
When no cache policy specified, prefer smq (if available) over mq.
|
||||
Add demo cache-mq and cache-smq profiles.
|
||||
Add cmd profilable allocation/cache_policy,cache_settings,cache_mode.
|
||||
Require cache_check 0.5.4 for use of --clear-needs-check-flag.
|
||||
Fix lvmetad udev rules to not override SYSTEMD_WANTS, add the service instead.
|
||||
|
12
WHATS_NEW_DM
12
WHATS_NEW_DM
@@ -1,5 +1,15 @@
|
||||
Version 1.02.105 -
|
||||
Version 1.02.105 - 17th August 2015
|
||||
===================================
|
||||
Fix 'dmstats list -o all' segfault.
|
||||
Separate dmstats statistics fields from region information fields.
|
||||
Add interval and interval_ns fields to dmstats reports.
|
||||
Do not include internal glibc headers in libdm-timestamp.c (1.02.104)
|
||||
Exit immediately if no device is supplied to dmsetup wipe_table.
|
||||
Suppress dmsetup report headings when no data is output. (1.02.104)
|
||||
Adjust dmsetup usage/help output selection to match command invoked.
|
||||
Fix dmsetup -o all to select correct fields in splitname report.
|
||||
Restructure internal dmsetup argument handling across all commands.
|
||||
Add dm_report_is_empty() to indicate there is no data awaiting output.
|
||||
Add more arg validation for dm_tree_node_add_cache_target().
|
||||
Add --alldevices switch to replace use of --force for stats create / delete.
|
||||
|
||||
|
@@ -204,7 +204,7 @@ devices {
|
||||
|
||||
# Configuration option devices/default_data_alignment.
|
||||
# Default alignment of the start of a PV data area in MB.
|
||||
# If set to 0, a value of 64KB will be used.
|
||||
# If set to 0, a value of 64KiB will be used.
|
||||
# Set to 1 for 1MiB, 2 for 2MiB, etc.
|
||||
# default_data_alignment = 1
|
||||
|
||||
@@ -222,7 +222,7 @@ devices {
|
||||
data_alignment_detection = 1
|
||||
|
||||
# Configuration option devices/data_alignment.
|
||||
# Alignment of the start of a PV data area in KB.
|
||||
# Alignment of the start of a PV data area in KiB.
|
||||
# If a PV is placed directly on an md device and
|
||||
# md_chunk_alignment or data_alignment_detection are enabled,
|
||||
# then this setting is ignored. Otherwise, md_chunk_alignment
|
||||
@@ -234,10 +234,10 @@ devices {
|
||||
# Detect PV data alignment offset based on sysfs device information.
|
||||
# The start of a PV aligned data area will be shifted by the
|
||||
# alignment_offset exposed in sysfs. This offset is often 0, but
|
||||
# may be non-zero. Certain 4KB sector drives that compensate for
|
||||
# may be non-zero. Certain 4KiB sector drives that compensate for
|
||||
# windows partitioning will have an alignment_offset of 3584 bytes
|
||||
# (sector 7 is the lowest aligned logical block, the 4KB sectors start
|
||||
# at LBA -1, and consequently sector 63 is aligned on a 4KB boundary).
|
||||
# (sector 7 is the lowest aligned logical block, the 4KiB sectors start
|
||||
# at LBA -1, and consequently sector 63 is aligned on a 4KiB boundary).
|
||||
# pvcreate --dataalignmentoffset will skip this detection.
|
||||
data_alignment_offset_detection = 1
|
||||
|
||||
@@ -282,9 +282,9 @@ devices {
|
||||
require_restorefile_with_uuid = 1
|
||||
|
||||
# Configuration option devices/pv_min_size.
|
||||
# Minimum size (in KB) of block devices which can be used as PVs.
|
||||
# Minimum size in KiB of block devices which can be used as PVs.
|
||||
# In a clustered environment all nodes must use the same value.
|
||||
# Any value smaller than 512KB is ignored. The previous built-in
|
||||
# Any value smaller than 512KiB is ignored. The previous built-in
|
||||
# value was 512.
|
||||
pv_min_size = 2048
|
||||
|
||||
@@ -303,7 +303,7 @@ devices {
|
||||
}
|
||||
|
||||
# Configuration section allocation.
|
||||
# How LVM selects free space for Logical Volumes.
|
||||
# How LVM selects space and applies properties to LVs.
|
||||
allocation {
|
||||
|
||||
# Configuration option allocation/cling_tag_list.
|
||||
@@ -348,7 +348,7 @@ allocation {
|
||||
# Look for and erase any signatures while zeroing a new LV.
|
||||
# Zeroing is controlled by the -Z/--zero option, and if not
|
||||
# specified, zeroing is used by default if possible.
|
||||
# Zeroing simply overwrites the first 4 KiB of a new LV
|
||||
# Zeroing simply overwrites the first 4KiB of a new LV
|
||||
# with zeroes and does no signature detection or wiping.
|
||||
# Signature wiping goes beyond zeroing and detects exact
|
||||
# types and positions of signatures within the whole LV.
|
||||
@@ -374,17 +374,31 @@ allocation {
|
||||
# Cache pool metadata and data will always use different PVs.
|
||||
cache_pool_metadata_require_separate_pvs = 0
|
||||
|
||||
# Configuration option allocation/cache_pool_cachemode.
|
||||
# The default cache mode used for new cache pools.
|
||||
# Configuration option allocation/cache_mode.
|
||||
# The default cache mode used for new cache.
|
||||
# Possible options are: writethrough, writeback.
|
||||
# writethrough - Data blocks are immediately written from
|
||||
# the cache to disk.
|
||||
# writeback - Data blocks are written from the cache back
|
||||
# to disk after some delay to improve performance.
|
||||
# cache_pool_cachemode = "writethrough"
|
||||
# This setting replaces allocation/cache_pool_cachemode.
|
||||
# cache_mode = "writethrough"
|
||||
|
||||
# Configuration option allocation/cache_policy.
|
||||
# The default cache policy used for new cache volume.
|
||||
# For the kernel 4.2 and newer the default policy is smq
|
||||
# (Stochastic multique), otherwise the older mq (Multiqueue),
|
||||
# policy is selected.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration section allocation/cache_settings.
|
||||
# Individual settings for policies.
|
||||
# See the help for individual policies for more info.
|
||||
# cache_settings {
|
||||
# }
|
||||
|
||||
# Configuration option allocation/cache_pool_chunk_size.
|
||||
# The minimal chunk size (in kiB) for cache pool volumes.
|
||||
# The minimal chunk size in KiB for cache pool volumes.
|
||||
# Using a chunk_size that is too large can result in wasteful
|
||||
# use of the cache, where small reads and writes can cause
|
||||
# large sections of an LV to be mapped into the cache. However,
|
||||
@@ -392,8 +406,8 @@ allocation {
|
||||
# overhead trying to manage the numerous chunks that become mapped
|
||||
# into the cache. The former is more of a problem than the latter
|
||||
# in most cases, so we default to a value that is on the smaller
|
||||
# end of the spectrum. Supported values range from 32(kiB) to
|
||||
# 1048576 in multiples of 32.
|
||||
# end of the spectrum. Supported values range from 32KiB to
|
||||
# 1GiB in multiples of 32.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option allocation/thin_pool_metadata_require_separate_pvs.
|
||||
@@ -424,17 +438,17 @@ allocation {
|
||||
# thin_pool_chunk_size_policy = "generic"
|
||||
|
||||
# Configuration option allocation/thin_pool_chunk_size.
|
||||
# The minimal chunk size (in KB) for thin pool volumes.
|
||||
# The minimal chunk size in KiB for thin pool volumes.
|
||||
# Larger chunk sizes may improve performance for plain
|
||||
# thin volumes, however using them for snapshot volumes
|
||||
# is less efficient, as it consumes more space and takes
|
||||
# extra time for copying. When unset, lvm tries to estimate
|
||||
# chunk size starting from 64KB. Supported values are in
|
||||
# the range 64 to 1048576.
|
||||
# chunk size starting from 64KiB. Supported values are in
|
||||
# the range 64KiB to 1GiB.
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option allocation/physical_extent_size.
|
||||
# Default physical extent size to use for new VGs (in KB).
|
||||
# Default physical extent size in KiB to use for new VGs.
|
||||
# physical_extent_size = 4096
|
||||
}
|
||||
|
||||
@@ -779,11 +793,11 @@ global {
|
||||
sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@"
|
||||
|
||||
# Configuration option global/lvdisplay_shows_full_device_path.
|
||||
# Enable this to reinstate the previous lvdisplay name format.
|
||||
# The default format for displaying LV names in lvdisplay was changed
|
||||
# in version 2.02.89 to show the LV name and path separately.
|
||||
# Previously this was always shown as /dev/vgname/lvname even when that
|
||||
# was never a valid path in the /dev filesystem.
|
||||
# Enable this option to reinstate the previous format.
|
||||
# lvdisplay_shows_full_device_path = 0
|
||||
|
||||
# Configuration option global/use_lvmetad.
|
||||
@@ -889,6 +903,15 @@ global {
|
||||
# thin_disabled_features = [ "discards", "block_size" ]
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/cache_disabled_features.
|
||||
# Features to not use in the cache driver.
|
||||
# This can be helpful for testing, or to avoid
|
||||
# using a feature that is causing problems.
|
||||
# Features: policy_mq, policy_smq.
|
||||
# Example:
|
||||
# cache_disabled_features = [ "policy_smq" ]
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
# Configuration option global/cache_check_executable.
|
||||
# The full path to the cache_check command.
|
||||
# LVM uses this command to check that a cache metadata
|
||||
@@ -1031,12 +1054,12 @@ activation {
|
||||
use_linear_target = 1
|
||||
|
||||
# Configuration option activation/reserved_stack.
|
||||
# Stack size in KB to reserve for use while devices are suspended.
|
||||
# Stack size in KiB to reserve for use while devices are suspended.
|
||||
# Insufficent reserve risks I/O deadlock during device suspension.
|
||||
reserved_stack = 64
|
||||
|
||||
# Configuration option activation/reserved_memory.
|
||||
# Memory size in KB to reserve for use while devices are suspended.
|
||||
# Memory size in KiB to reserve for use while devices are suspended.
|
||||
# Insufficent reserve risks I/O deadlock during device suspension.
|
||||
reserved_memory = 8192
|
||||
|
||||
@@ -1267,7 +1290,7 @@ activation {
|
||||
monitoring = 1
|
||||
|
||||
# Configuration option activation/polling_interval.
|
||||
# Check pvmove or lvconvert progress at this interval (seconds)
|
||||
# Check pvmove or lvconvert progress at this interval (seconds).
|
||||
# When pvmove or lvconvert must wait for the kernel to finish
|
||||
# synchronising or merging data, they check and report progress
|
||||
# at intervals of this number of seconds.
|
||||
|
@@ -582,8 +582,11 @@ int config_file_read(struct dm_config_tree *cft)
|
||||
if (!(cf->dev = dev_create_file(filename, NULL, NULL, 1)))
|
||||
return_0;
|
||||
|
||||
if (!dev_open_readonly_buffered(cf->dev))
|
||||
if (!dev_open_readonly_buffered(cf->dev)) {
|
||||
dev_destroy_file(cf->dev);
|
||||
cf->dev = NULL;
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
|
||||
r = config_file_read_fd(cft, cf->dev, 0, (size_t) info.st_size, 0, 0,
|
||||
@@ -2416,27 +2419,3 @@ int get_default_allocation_cache_pool_chunk_size_CFG(struct cmd_context *cmd, st
|
||||
{
|
||||
return DEFAULT_CACHE_POOL_CHUNK_SIZE * 2;
|
||||
}
|
||||
|
||||
const char *get_default_allocation_cache_policy_CFG(struct cmd_context *cmd, struct profile *profile)
|
||||
{
|
||||
const struct segment_type *segtype = get_segtype_from_string(cmd, "cache");
|
||||
unsigned attr = ~0;
|
||||
|
||||
if (!segtype ||
|
||||
!segtype->ops->target_present ||
|
||||
!segtype->ops->target_present(cmd, NULL, &attr)) {
|
||||
log_warn("WARNING: Cannot detect default cache policy, using \""
|
||||
DEFAULT_CACHE_POLICY "\".");
|
||||
return DEFAULT_CACHE_POLICY;
|
||||
}
|
||||
|
||||
if (attr & CACHE_FEATURE_POLICY_SMQ)
|
||||
return "smq";
|
||||
|
||||
if (attr & CACHE_FEATURE_POLICY_MQ)
|
||||
return "mq";
|
||||
|
||||
log_warn("WARNING: Default cache policy not available.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -466,25 +466,26 @@ cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_
|
||||
"This has been replaced by the allocation/cache_mode setting.\n",
|
||||
"Cache mode.\n")
|
||||
|
||||
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
|
||||
cfg(allocation_cache_mode_CFG, "cache_mode", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_CACHE_MODE, vsn(2, 2, 128), NULL, 0, NULL,
|
||||
"The default cache mode used for new cache.\n"
|
||||
"Possible options are: writethrough, writeback.\n"
|
||||
"writethrough - Data blocks are immediately written from\n"
|
||||
"the cache to disk.\n"
|
||||
"writeback - Data blocks are written from the cache back\n"
|
||||
"to disk after some delay to improve performance.\n")
|
||||
"to disk after some delay to improve performance.\n"
|
||||
"This setting replaces allocation/cache_pool_cachemode.\n")
|
||||
|
||||
cfg_runtime(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, vsn(2, 2, 127), 0, NULL,
|
||||
cfg(allocation_cache_policy_CFG, "cache_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, 0, vsn(2, 2, 128), NULL, 0, NULL,
|
||||
"The default cache policy used for new cache volume.\n"
|
||||
"Generally available policies are: mq, smq.\n"
|
||||
"mq - Multiqueue policy with 88 bytes per block\n"
|
||||
"smq - Stochastic multique with 25 bytes per block (kernel >= 4.2).\n")
|
||||
"For the kernel 4.2 and newer the default policy is smq\n"
|
||||
"(Stochastic multique), otherwise the older mq (Multiqueue),\n"
|
||||
"policy is selected.\n")
|
||||
|
||||
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 127), 0, NULL,
|
||||
cfg_section(allocation_cache_settings_CFG_SECTION, "cache_settings", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
|
||||
"Individual settings for policies.\n"
|
||||
"See the help for individual policies for more info.\n")
|
||||
|
||||
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 127), 0, NULL,
|
||||
cfg_section(policy_settings_CFG_SUBSECTION, "policy_settings", allocation_cache_settings_CFG_SECTION, CFG_NAME_VARIABLE | CFG_SECTION_NO_CHECK | CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, vsn(2, 2, 128), 0, NULL,
|
||||
"Replace this subsection name with a policy name.\n"
|
||||
"Multiple subsections for different policies can be created.\n")
|
||||
|
||||
@@ -909,7 +910,7 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
|
||||
"Example:\n"
|
||||
"thin_disabled_features = [ \"discards\", \"block_size\" ]\n")
|
||||
|
||||
cfg_array(global_cache_disabled_features_CFG, "cache_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 126), NULL, 0, NULL,
|
||||
cfg_array(global_cache_disabled_features_CFG, "cache_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 128), NULL, 0, NULL,
|
||||
"Features to not use in the cache driver.\n"
|
||||
"This can be helpful for testing, or to avoid\n"
|
||||
"using a feature that is causing problems.\n"
|
||||
|
@@ -71,6 +71,16 @@ static void _dev_init(struct device *dev, int max_error_count)
|
||||
dm_list_init(&dev->open_list);
|
||||
}
|
||||
|
||||
void dev_destroy_file(struct device *dev)
|
||||
{
|
||||
if (!(dev->flags & DEV_ALLOCED))
|
||||
return;
|
||||
|
||||
dm_free((void *) dm_list_item(dev->aliases.n, struct dm_str_list)->str);
|
||||
dm_free(dev->aliases.n);
|
||||
dm_free(dev);
|
||||
}
|
||||
|
||||
struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
struct dm_str_list *alias, int use_malloc)
|
||||
{
|
||||
|
@@ -586,12 +586,8 @@ static void _close(struct device *dev)
|
||||
|
||||
log_debug_devs("Closed %s", dev_name(dev));
|
||||
|
||||
if (dev->flags & DEV_ALLOCED) {
|
||||
dm_free((void *) dm_list_item(dev->aliases.n, struct dm_str_list)->
|
||||
str);
|
||||
dm_free(dev->aliases.n);
|
||||
dm_free(dev);
|
||||
}
|
||||
if (dev->flags & DEV_ALLOCED)
|
||||
dev_destroy_file(dev);
|
||||
}
|
||||
|
||||
static int _dev_close(struct device *dev, int immediate)
|
||||
|
@@ -123,6 +123,7 @@ void dev_flush(struct device *dev);
|
||||
|
||||
struct device *dev_create_file(const char *filename, struct device *dev,
|
||||
struct dm_str_list *alias, int use_malloc);
|
||||
void dev_destroy_file(struct device *dev);
|
||||
|
||||
/* Return a valid device name from the alias list; NULL otherwise */
|
||||
const char *dev_name_confirmed(struct device *dev, int quiet);
|
||||
|
@@ -434,6 +434,34 @@ int lv_is_cache_origin(const struct logical_volume *lv)
|
||||
return seg && lv_is_cache(seg->lv) && !lv_is_pending_delete(seg->lv) && (seg_lv(seg, 0) == lv);
|
||||
}
|
||||
|
||||
static const char *_get_default_cache_policy(struct cmd_context *cmd)
|
||||
{
|
||||
const struct segment_type *segtype = get_segtype_from_string(cmd, "cache");
|
||||
unsigned attr = ~0;
|
||||
const char *def = NULL;
|
||||
|
||||
if (!segtype ||
|
||||
!segtype->ops->target_present ||
|
||||
!segtype->ops->target_present(cmd, NULL, &attr)) {
|
||||
log_warn("WARNING: Cannot detect default cache policy, using \""
|
||||
DEFAULT_CACHE_POLICY "\".");
|
||||
return DEFAULT_CACHE_POLICY;
|
||||
}
|
||||
|
||||
if (attr & CACHE_FEATURE_POLICY_SMQ)
|
||||
def = "smq";
|
||||
else if (attr & CACHE_FEATURE_POLICY_MQ)
|
||||
def = "mq";
|
||||
else {
|
||||
log_error("Default cache policy is not available.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log_debug_metadata("Detected default cache_policy \"%s\".", def);
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
int cache_set_policy(struct lv_segment *seg, const char *name,
|
||||
const struct dm_config_tree *settings)
|
||||
{
|
||||
@@ -451,8 +479,11 @@ int cache_set_policy(struct lv_segment *seg, const char *name,
|
||||
log_error("Failed to duplicate policy name.");
|
||||
return 0;
|
||||
}
|
||||
} else if (!seg->policy_name && passed_seg_is_cache)
|
||||
seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG, NULL);
|
||||
} else if (!seg->policy_name && passed_seg_is_cache) {
|
||||
if (!(seg->policy_name = find_config_tree_str(seg->lv->vg->cmd, allocation_cache_policy_CFG, NULL)) &&
|
||||
!(seg->policy_name = _get_default_cache_policy(seg->lv->vg->cmd)))
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (settings) {
|
||||
if (!seg->policy_name) {
|
||||
|
@@ -63,6 +63,10 @@ int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
|
||||
|
||||
tmsg->type = type;
|
||||
|
||||
/* If the 1st message is add in non-read-only mode, modify transaction_id */
|
||||
if (!no_update && dm_list_empty(&pool_seg->thin_messages))
|
||||
pool_seg->transaction_id++;
|
||||
|
||||
dm_list_add(&pool_seg->thin_messages, &tmsg->list);
|
||||
|
||||
log_debug_metadata("Added %s message.",
|
||||
@@ -476,9 +480,6 @@ int update_pool_lv(struct logical_volume *lv, int activate)
|
||||
|
||||
dm_list_init(&(first_seg(lv)->thin_messages));
|
||||
|
||||
/* thin-pool target transaction is finished, increase lvm2 TID */
|
||||
first_seg(lv)->transaction_id++;
|
||||
|
||||
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
|
||||
return_0;
|
||||
|
||||
|
@@ -295,7 +295,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
|
||||
}
|
||||
|
||||
if (!dm_tree_node_add_thin_pool_target(node, len,
|
||||
seg->transaction_id + (laopts->send_messages ? 1 : 0),
|
||||
seg->transaction_id,
|
||||
metadata_dlid, pool_dlid,
|
||||
seg->chunk_size, seg->low_water_mark,
|
||||
seg->zero_new_blocks ? 0 : 1))
|
||||
@@ -345,7 +345,7 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
|
||||
*/
|
||||
if (!lv_thin_pool_transaction_id(seg->lv, &transaction_id))
|
||||
return_0; /* Thin pool should exist and work */
|
||||
if (transaction_id != seg->transaction_id) {
|
||||
if ((transaction_id + 1) != seg->transaction_id) {
|
||||
log_error("Can't create snapshot %s as origin %s is not suspended.",
|
||||
lmsg->u.lv->name, origin->name);
|
||||
return 0;
|
||||
@@ -373,11 +373,11 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
|
||||
|
||||
if (!dm_list_empty(&seg->thin_messages)) {
|
||||
/* Messages were passed, modify transaction_id as the last one */
|
||||
log_debug_activation("Thin pool set transaction id %" PRIu64 ".", seg->transaction_id + 1);
|
||||
log_debug_activation("Thin pool set transaction id %" PRIu64 ".", seg->transaction_id);
|
||||
if (!dm_tree_node_add_thin_pool_message(node,
|
||||
DM_THIN_MESSAGE_SET_TRANSACTION_ID,
|
||||
seg->transaction_id,
|
||||
seg->transaction_id + 1))
|
||||
seg->transaction_id - 1,
|
||||
seg->transaction_id))
|
||||
return_0;
|
||||
}
|
||||
|
||||
|
@@ -72,7 +72,6 @@ dm_task_get_ioctl_timestamp
|
||||
dm_task_set_record_timestamp
|
||||
dm_timestamp_alloc
|
||||
dm_timestamp_compare
|
||||
dm_timestamp_copy
|
||||
dm_timestamp_delta
|
||||
dm_timestamp_destroy
|
||||
dm_timestamp_get
|
||||
|
4
libdm/.exported_symbols.DM_1_02_105
Normal file
4
libdm/.exported_symbols.DM_1_02_105
Normal file
@@ -0,0 +1,4 @@
|
||||
dm_report_is_empty
|
||||
dm_stats_get_area_offset
|
||||
dm_stats_get_current_area_offset
|
||||
dm_timestamp_copy
|
@@ -697,26 +697,36 @@ int dm_stats_set_program_id(struct dm_stats *dms, int allow_empty,
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id);
|
||||
uint64_t dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id);
|
||||
uint64_t dm_stats_get_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *area_len, uint64_t region_id);
|
||||
int dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id);
|
||||
|
||||
int dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id);
|
||||
|
||||
int dm_stats_get_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *len, uint64_t region_id);
|
||||
|
||||
/*
|
||||
* Area properties: start and length.
|
||||
* Area properties: start, offset and length.
|
||||
*
|
||||
* The area length is always equal to the area length of the region
|
||||
* that contains it and is obtained from dm_stats_get_region_area_len().
|
||||
*
|
||||
* The start offset of an area is a function of the area_id and the
|
||||
* containing region's start and area length.
|
||||
* The start of an area is a function of the area_id and the containing
|
||||
* region's start and area length: it gives the absolute offset into the
|
||||
* containing device of the beginning of the area.
|
||||
*
|
||||
* The offset expresses the area's relative offset into the current
|
||||
* region. I.e. the area start minus the start offset of the containing
|
||||
* region.
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_area_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
int dm_stats_get_area_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
int dm_stats_get_area_offset(const struct dm_stats *dms, uint64_t *offset,
|
||||
uint64_t region_id, uint64_t area_id);
|
||||
|
||||
/*
|
||||
* Retrieve program_id and aux_data for a specific region. Only valid
|
||||
@@ -856,14 +866,14 @@ uint64_t dm_stats_get_current_area(const struct dm_stats *dms);
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_region_start(const struct dm_stats *dms,
|
||||
uint64_t *start);
|
||||
int dm_stats_get_current_region_start(const struct dm_stats *dms,
|
||||
uint64_t *start);
|
||||
|
||||
uint64_t dm_stats_get_current_region_len(const struct dm_stats *dms,
|
||||
uint64_t *len);
|
||||
int dm_stats_get_current_region_len(const struct dm_stats *dms,
|
||||
uint64_t *len);
|
||||
|
||||
uint64_t dm_stats_get_current_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *area_len);
|
||||
int dm_stats_get_current_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *area_len);
|
||||
|
||||
/*
|
||||
* Current area properties: start and length.
|
||||
@@ -873,10 +883,13 @@ uint64_t dm_stats_get_current_region_area_len(const struct dm_stats *dms,
|
||||
*
|
||||
* All values are returned in units of 512b sectors.
|
||||
*/
|
||||
uint64_t dm_stats_get_current_area_start(const struct dm_stats *dms,
|
||||
uint64_t *start);
|
||||
int dm_stats_get_current_area_start(const struct dm_stats *dms,
|
||||
uint64_t *start);
|
||||
|
||||
uint64_t dm_stats_get_current_area_len(const struct dm_stats *dms,
|
||||
int dm_stats_get_current_area_offset(const struct dm_stats *dms,
|
||||
uint64_t *offset);
|
||||
|
||||
int dm_stats_get_current_area_len(const struct dm_stats *dms,
|
||||
uint64_t *start);
|
||||
|
||||
/*
|
||||
@@ -2396,6 +2409,11 @@ int dm_report_object_is_selected(struct dm_report *rh, void *object, int do_outp
|
||||
*/
|
||||
int dm_report_compact_fields(struct dm_report *rh);
|
||||
|
||||
/*
|
||||
* Returns 1 if there is no data waiting to be output.
|
||||
*/
|
||||
int dm_report_is_empty(struct dm_report *rh);
|
||||
|
||||
int dm_report_output(struct dm_report *rh);
|
||||
|
||||
/*
|
||||
|
@@ -1586,7 +1586,7 @@ static int _node_send_messages(struct dm_tree_node *dnode,
|
||||
}
|
||||
|
||||
/* Error if there are no stacked messages or id mismatches */
|
||||
if (trans_id != (seg->transaction_id - have_messages)) {
|
||||
if ((trans_id + 1) != seg->transaction_id) {
|
||||
log_error("Thin pool %s transaction_id is %" PRIu64 ", while expected %" PRIu64 ".",
|
||||
_node_name(dnode), trans_id, seg->transaction_id - have_messages);
|
||||
return 0;
|
||||
|
@@ -4305,6 +4305,11 @@ static int _output_as_columns(struct dm_report *rh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_report_is_empty(struct dm_report *rh)
|
||||
{
|
||||
return dm_list_empty(&rh->rows) ? 1 : 0;
|
||||
}
|
||||
|
||||
int dm_report_output(struct dm_report *rh)
|
||||
{
|
||||
if (dm_list_empty(&rh->rows))
|
||||
|
@@ -1280,7 +1280,7 @@ uint64_t dm_stats_get_current_area(const struct dm_stats *dms)
|
||||
return dms->cur_area;
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
int dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id)
|
||||
{
|
||||
if (!dms || !dms->regions)
|
||||
@@ -1289,7 +1289,7 @@ uint64_t dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
int dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id)
|
||||
{
|
||||
if (!dms || !dms->regions)
|
||||
@@ -1298,51 +1298,68 @@ uint64_t dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_region_area_len(const struct dm_stats *dms, uint64_t *step,
|
||||
uint64_t region_id)
|
||||
int dm_stats_get_region_area_len(const struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id)
|
||||
{
|
||||
if (!dms || !dms->regions)
|
||||
return_0;
|
||||
*step = dms->regions[region_id].step;
|
||||
*len = dms->regions[region_id].step;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_current_region_start(const struct dm_stats *dms,
|
||||
uint64_t *start)
|
||||
int dm_stats_get_current_region_start(const struct dm_stats *dms,
|
||||
uint64_t *start)
|
||||
{
|
||||
return dm_stats_get_region_start(dms, start, dms->cur_region);
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_current_region_len(const struct dm_stats *dms,
|
||||
uint64_t *len)
|
||||
int dm_stats_get_current_region_len(const struct dm_stats *dms,
|
||||
uint64_t *len)
|
||||
{
|
||||
return dm_stats_get_region_len(dms, len, dms->cur_region);
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_current_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *step)
|
||||
int dm_stats_get_current_region_area_len(const struct dm_stats *dms,
|
||||
uint64_t *step)
|
||||
{
|
||||
return dm_stats_get_region_area_len(dms, step, dms->cur_region);
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_area_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id, uint64_t area_id)
|
||||
int dm_stats_get_area_start(const struct dm_stats *dms, uint64_t *start,
|
||||
uint64_t region_id, uint64_t area_id)
|
||||
{
|
||||
struct dm_stats_region *region = &dms->regions[region_id];
|
||||
if (!dms || !dms->regions)
|
||||
return_0;
|
||||
*start = dms->regions[region_id].step * area_id;
|
||||
*start = region->start + region->step * area_id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_current_area_start(const struct dm_stats *dms,
|
||||
uint64_t *start)
|
||||
int dm_stats_get_area_offset(const struct dm_stats *dms, uint64_t *offset,
|
||||
uint64_t region_id, uint64_t area_id)
|
||||
{
|
||||
if (!dms || !dms->regions)
|
||||
return_0;
|
||||
*offset = dms->regions[region_id].step * area_id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dm_stats_get_current_area_start(const struct dm_stats *dms,
|
||||
uint64_t *start)
|
||||
{
|
||||
return dm_stats_get_area_start(dms, start,
|
||||
dms->cur_region, dms->cur_area);
|
||||
}
|
||||
|
||||
uint64_t dm_stats_get_current_area_len(const struct dm_stats *dms,
|
||||
uint64_t *len)
|
||||
int dm_stats_get_current_area_offset(const struct dm_stats *dms,
|
||||
uint64_t *offset)
|
||||
{
|
||||
return dm_stats_get_area_offset(dms, offset,
|
||||
dms->cur_region, dms->cur_area);
|
||||
}
|
||||
|
||||
int dm_stats_get_current_area_len(const struct dm_stats *dms,
|
||||
uint64_t *len)
|
||||
{
|
||||
return dm_stats_get_region_area_len(dms, len, dms->cur_region);
|
||||
}
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#ifdef HAVE_REALTIME
|
||||
|
||||
#include <time.h>
|
||||
#include <bits/time.h>
|
||||
|
||||
struct dm_timestamp {
|
||||
struct timespec t;
|
||||
|
@@ -63,6 +63,8 @@ dmstats \(em device-mapper statistics management
|
||||
.RB [ \-\-units
|
||||
.IR units ]
|
||||
.RB [ \-\-nosuffix ]
|
||||
.RB [ \-\-nosuffix ]
|
||||
.RB [ \-v | \-\-verbose \ [ \-v | \-\-verbose ]
|
||||
.br
|
||||
.B dmstats print
|
||||
.RI [ device_name ]
|
||||
@@ -302,11 +304,15 @@ the list of report fields.
|
||||
.RI [ device_name ]
|
||||
.RB [ \-\-allprograms ]
|
||||
.RB [ \-\-programid
|
||||
.RB [ \-v | \-\-verbose \ [ \-v | \-\-verbose ]]
|
||||
.IR id ]
|
||||
.br
|
||||
List the statistics regions registered on the device. If the
|
||||
\fB\-\-allprograms\fP switch is given all regions will be listed
|
||||
regardless of region program ID values.
|
||||
|
||||
If \fB\-v\fP or \fB\-\-verbose\fP is given the report will include
|
||||
a row of information for each area contained in each region displayed.
|
||||
.br
|
||||
.TP
|
||||
.B print
|
||||
|
@@ -164,6 +164,8 @@ fi
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/metadata_profile_template.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/thin-generic.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/thin-performance.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/cache-mq.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/cache-smq.profile
|
||||
%dir %{_sysconfdir}/lvm/backup
|
||||
%dir %{_sysconfdir}/lvm/cache
|
||||
%dir %{_sysconfdir}/lvm/archive
|
||||
|
@@ -63,8 +63,9 @@ vgcreate -s 1M $vg $(cat DEVICES)
|
||||
# Testing dmeventd autoresize
|
||||
lvcreate -L200M -V500M -n thin -T $vg/pool 2>&1 | tee out
|
||||
not grep "WARNING: Sum" out
|
||||
lvcreate -V2M -n thin2 $vg/pool
|
||||
lvcreate -L2M -n $lv1 $vg
|
||||
lvchange -an $vg/thin $vg/pool
|
||||
lvchange -an $vg/thin $vg/thin2 $vg/pool
|
||||
|
||||
# Prepare some fake metadata with unmatching id
|
||||
# Transaction_id is lower by 1 and there are no message -> ERROR
|
||||
@@ -86,7 +87,7 @@ grep expected out
|
||||
check inactive $vg pool_tmeta
|
||||
|
||||
# Prepare some fake metadata prefilled to ~81% (>70%)
|
||||
fake_metadata_ 400 1 >data
|
||||
fake_metadata_ 400 2 >data
|
||||
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
|
||||
|
||||
# Swap volume with restored fake metadata
|
||||
|
@@ -29,8 +29,11 @@ lvcreate -T -L8M $vg/pool -V10M -n $lv1
|
||||
# skip $vg from activation
|
||||
aux lvmconf "activation/volume_list = [ \"$vg1\" ]"
|
||||
|
||||
# We cannot pass - pool volume cannot be manipulated
|
||||
not lvcreate -V10 -n $lv2 -T $vg/pool
|
||||
# We still could pass - since pool is still active
|
||||
lvcreate -V10 -n $lv2 -T $vg/pool
|
||||
|
||||
# but $lv2 is not active
|
||||
check inactive $vg $lv2
|
||||
|
||||
vgchange -an $vg
|
||||
|
||||
|
762
tools/dmsetup.c
762
tools/dmsetup.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user