1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-29 00:23:49 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
David Teigland
0ed54d5b36 enable event autoactivation even when event_activation=0
Setting event_activation=0 no longer enables static autoactivation
(which was removed in commit ee8fb0310c
"remove static autoactivation").  That change could cause systems with
lvm.conf event_activation=0 to fail to boot.  To avoid that, the behavior
of event_activation=0 is changed here to be identical to event_activation=1,
i.e. event based autoactivation is kept enabled for event_eventation=0.
The updated systems will be forced into event autoactivation.

To disable event autoactivation (like event_activation=0 previously did),
set event_activation=2 (a new value.)
2022-02-03 10:22:35 -06:00
54 changed files with 368 additions and 770 deletions

View File

@@ -1 +1 @@
2.03.16(2)-git (2022-02-07)
2.03.15(2)-git (2021-10-20)

View File

@@ -1 +1 @@
1.02.185-git (2022-02-07)
1.02.183-git (2021-10-20)

View File

@@ -1,9 +1,5 @@
Version 2.03.16 -
====================================
Version 2.03.15 - 07th February 2022
====================================
Remove service based autoactivation. global/event_activation = 0 is NOOP.
Version 2.03.15 -
===================================
Improve support for metadata profiles for --type writecache.
Use cache or active DM device when available with new kernels.
Introduce function to utilize UUIDs from DM_DEVICE_LIST.

View File

@@ -1,8 +1,5 @@
Version 1.02.185 -
=====================================
Version 1.02.183 - 07th February 2022
=====================================
Version 1.02.183 -
====================================
Unmangle UUIDs for DM_DEVICE_LIST ioctl.
Version 1.02.181 - 20th October 2021

View File

@@ -1151,11 +1151,16 @@ global {
# lvdisplay_shows_full_device_path = 0
# Configuration option global/event_activation.
# Disable event based autoactivation commands.
# WARNING: setting this to zero may cause machine startup to fail.
# Previously, setting this to zero would enable static autoactivation
# services (via the lvm2-activation-generator), but the autoactivation
# services and generator have been removed.
# Activate LVs based on system-generated device events.
# When a PV appears on the system, a system-generated uevent triggers
# the lvm2-pvscan service which runs the pvscan --cache -aay command.
# If the new PV completes a VG, pvscan autoactivates LVs in the VG.
# When event_activation is disabled, the lvm2-activation services are
# generated and run at fixed points during system startup. These
# services run vgchange -aay to autoactivate LVs in VGs that happen
# to be present at that point in time.
# See the --setautoactivation option or the auto_activation_volume_list
# setting to configure autoactivation for specific VGs or LVs.
# This configuration option has an automatic default value.
# event_activation = 1

View File

@@ -107,8 +107,6 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
int with_flush,
int query_inactive)
{
char vsn[80];
unsigned maj, min;
struct dm_task *dmt;
if (!(dmt = dm_task_create(task)))
@@ -144,11 +142,7 @@ static struct dm_task *_setup_task_run(int task, struct dm_info *info,
case DM_DEVICE_TARGET_MSG:
return dmt; /* TARGET_MSG needs more local tweaking before task_run() */
case DM_DEVICE_LIST:
/* Use 'newuuid' only with DM version that supports it */
if (driver_version(vsn, sizeof(vsn)) &&
(sscanf(vsn, "%u.%u", &maj, &min) == 2) &&
(maj == 4 ? min >= 19 : maj > 4) &&
!dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here
if (!dm_task_set_newuuid(dmt, " ")) // new uuid has no meaning here
log_warn("WARNING: Failed to query uuid with LIST.");
break;
default:
@@ -204,7 +198,7 @@ static int _get_segment_status_from_target_params(const char *target_name,
/* If kernel's type isn't an exact match is it compatible? */
(!segtype->ops->target_status_compatible ||
!segtype->ops->target_status_compatible(target_name))) {
log_warn("WARNING: Detected %s segment type does not match expected type %s for %s.",
log_warn(INTERNAL_ERROR "WARNING: Segment type %s found does not match expected type %s for %s.",
target_name, segtype->name, display_lvname(seg_status->seg->lv));
return 0;
}
@@ -2254,7 +2248,6 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
{
char *dlid, *name;
struct dm_info info, info2;
const struct dm_active_device *dev;
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
return_0;
@@ -2263,20 +2256,15 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
if (!dm->cmd->disable_dm_devs &&
dm->cmd->cache_dm_devs) {
if (!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, &dev)) {
log_debug("Cached as not present %s.", name);
return 1;
}
info = (struct dm_info) {
.exists = 1,
.major = dev->major,
.minor = dev->minor,
};
log_debug("Cached as present %s %s (%d:%d).",
name, dlid, info.major, info.minor);
} else if (!_info(dm->cmd, name, dlid, 0, 0, 0, &info, NULL, NULL))
dm->cmd->cache_dm_devs &&
!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, NULL)) {
log_debug("Cached as not present %s.", name);
return 1;
}
if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
return_0;
/*
* For top level volumes verify that existing device match
* requested major/minor and that major/minor pair is available for use
@@ -2947,10 +2935,6 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
for (s = start_area; s < areas; s++) {
/* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
but this knot of logic is too complex to pull apart without careful deconstruction. */
if ((seg_type(seg, s) == AREA_PV &&
(!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
!(name = dev_name(seg_dev(seg, s))) || !*name ||
@@ -2969,10 +2953,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
return_0;
num_error_areas++;
} else if (seg_type(seg, s) == AREA_PV) {
struct device *dev = seg_dev(seg, s);
name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev);
if (!dm_tree_node_add_target_area(node, name, NULL,
if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL,
(seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s)))))
return_0;
num_existing_areas++;

View File

@@ -767,7 +767,10 @@ static int _process_config(struct cmd_context *cmd)
init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
cmd->check_pv_dev_sizes = find_config_tree_bool(cmd, metadata_check_pv_device_sizes_CFG, NULL);
cmd->event_activation = find_config_tree_bool(cmd, global_event_activation_CFG, NULL);
cmd->event_activation = find_config_tree_int(cmd, global_event_activation_CFG, NULL);
if (!cmd->event_activation)
log_warn("WARNING: event_activation=0 has been removed, please update lvm.conf (using 1.)");
if (!process_profilable_config(cmd))
return_0;

View File

@@ -200,11 +200,11 @@ struct cmd_context {
unsigned print_device_id_not_found:1; /* print devices file entries not found */
unsigned ignore_device_name_mismatch:1; /* skip updating devices file names */
unsigned backup_disabled:1; /* skip repeated debug message */
unsigned event_activation:1; /* whether event_activation is set */
unsigned udevoutput:1;
unsigned online_vg_file_removed:1;
unsigned disable_dm_devs:1; /* temporarily disable use of dm devs cache */
int event_activation; /* 1 enabled, 0 enabled (to handle compat), 2 disabled */
/*
* Devices and filtering.
*/

View File

@@ -522,9 +522,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
if (!(dev->flags & DEV_REGULAR) || size2)
use_plain_read = 0;
/* Ensure there is extra '\0' after end of buffer since we pass
* buffer to funtions like strtoll() */
if (!(buf = zalloc(size + size2 + 1))) {
if (!(buf = zalloc(size + size2))) {
log_error("Failed to allocate circular buffer.");
return 0;
}

View File

@@ -1118,12 +1118,16 @@ cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_pa
"Previously this was always shown as /dev/vgname/lvname even when that\n"
"was never a valid path in the /dev filesystem.\n")
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 1, vsn(2, 3, 1), 0, 0, NULL,
"Disable event based autoactivation commands.\n"
"WARNING: setting this to zero may cause machine startup to fail.\n"
"Previously, setting this to zero would enable static autoactivation\n"
"services (via the lvm2-activation-generator), but the autoactivation\n"
"services and generator have been removed.\n")
cfg(global_event_activation_CFG, "event_activation", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 1, vsn(2, 3, 1), 0, 0, NULL,
"Disable event based autoactivation commands by setting to 2.\n"
"Disabling this (setting to 2) may cause machine startup to fail.\n"
"Previously, setting this to 0 would disable event based autoactivation\n"
"and enable static autoactivation services (via lvm2-activation-generator).\n"
"Now that static autoactivation services have been removed, setting this\n"
"to 0 will keep event based autoactivation enabled (so 0 and 1 are the\n"
"same.) Setting this to 2 disables both event and static autoactivation\n"
"commands (the lvm udev rule will continue to run those commands, but they\n"
"will exit when they detect this setting.\n")
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), 0, vsn(2, 3, 0), NULL,
NULL)

View File

@@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash)
goto out;
}
if (!(path = _strdup(path)) ||
if (!(path = dm_pool_strdup(_cache.mem, path)) ||
!(sl = _zalloc(sizeof(*sl)))) {
log_error("Failed to add allias to dev cache.");
return 0;
@@ -1162,17 +1162,6 @@ static int _insert(const char *path, const struct stat *info,
return 1;
}
static void _drop_all_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str);
dm_hash_remove(_cache.names, strl->str);
dm_list_del(&strl->list);
}
}
void dev_cache_scan(struct cmd_context *cmd)
{
log_debug_devs("Creating list of system devices.");
@@ -1382,6 +1371,59 @@ int dev_cache_add_dir(const char *path)
return 1;
}
/* Check cached device name is still valid before returning it */
/* This should be a rare occurrence */
/* set quiet if the cache is expected to be out-of-date */
/* FIXME Make rest of code pass/cache struct device instead of dev_name */
const char *dev_name_confirmed(struct device *dev, int quiet)
{
struct stat buf;
const char *name;
int r;
if ((dev->flags & DEV_REGULAR))
return dev_name(dev);
while ((r = stat(name = dm_list_item(dev->aliases.n,
struct dm_str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
if (r < 0) {
if (quiet)
log_sys_debug("stat", name);
else
log_sys_error("stat", name);
}
if (quiet)
log_debug_devs("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
else
log_warn("Path %s no longer valid for device(%d,%d)",
name, (int) MAJOR(dev->dev),
(int) MINOR(dev->dev));
/* Remove the incorrect hash entry */
dm_hash_remove(_cache.names, name);
/* Leave list alone if there isn't an alternative name */
/* so dev_name will always find something to return. */
/* Otherwise add the name to the correct device. */
if (dm_list_size(&dev->aliases) > 1) {
dm_list_del(dev->aliases.n);
if (!r)
_insert(name, &buf, 0, obtain_device_list_from_udev());
continue;
}
/* Scanning issues this inappropriately sometimes. */
log_debug_devs("Aborting - please provide new pathname for what "
"used to be %s", name);
return NULL;
}
return dev_name(dev);
}
struct device *dev_hash_get(const char *name)
{
return (struct device *) dm_hash_lookup(_cache.names, name);
@@ -1410,23 +1452,26 @@ static void _remove_alias(struct device *dev, const char *name)
* deactivated LV. Those old paths are all invalid and are dropped here.
*/
static void _verify_aliases(struct device *dev)
static void _verify_aliases(struct device *dev, const char *newname)
{
struct dm_str_list *strl, *strl2;
struct stat st;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
/* newname was just stat'd and added by caller */
if (newname && !strcmp(strl->str, newname))
continue;
if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) {
log_debug("Drop alias for %d:%d invalid path %s %d:%d.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str,
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev));
log_debug("Drop invalid path %s for %d:%d (new path %s).",
strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: "");
dm_hash_remove(_cache.names, strl->str);
dm_list_del(&strl->list);
}
}
}
static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing)
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
{
struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name);
struct stat st;
@@ -1440,18 +1485,13 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
if (dev && (dev->flags & DEV_REGULAR))
return dev;
if (dev && dm_list_empty(&dev->aliases)) {
/* shouldn't happen */
log_warn("Ignoring dev with no valid paths for %s.", name);
return NULL;
}
/*
* The requested path is invalid, remove any dev-cache info for it.
* The requested path is invalid, remove any dev-cache
* info for it.
*/
if (stat(name, &st)) {
if (dev) {
log_debug("Device path %s is invalid for %d:%d %s.",
log_print("Device path %s is invalid for %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
dm_hash_remove(_cache.names, name);
@@ -1459,17 +1499,11 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
_verify_aliases(dev);
_verify_aliases(dev, NULL);
}
return NULL;
}
if (dev && dm_list_empty(&dev->aliases)) {
/* shouldn't happen */
log_warn("Ignoring dev with no valid paths for %s.", name);
return NULL;
}
if (!S_ISBLK(st.st_mode)) {
log_debug("Not a block device %s.", name);
return NULL;
@@ -1480,110 +1514,26 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
* Remove incorrect info and then add new dev-cache entry.
*/
if (dev && (st.st_rdev != dev->dev)) {
struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
log_debug("Device path %s does not match %d:%d %s.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev));
/*
* lvm commands create this condition when they
* activate/deactivate LVs combined with creating new LVs.
* The command does not purge dev structs when deactivating
* an LV (which it probably should do), but the better
* approach would be not using dev-cache at all for LVs.
*/
dm_hash_remove(_cache.names, name);
log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev),
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
_remove_alias(dev, name);
_drop_all_aliases(dev);
/* Remove any other names in dev->aliases that are incorrect. */
_verify_aliases(dev, NULL);
if (dev_by_devt) {
log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.",
(int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt),
(int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name);
_drop_all_aliases(dev_by_devt);
}
#if 0
/*
* I think only lvm's own dm devs should be added here, so use
* a warning to look for any other unknown cases.
*/
if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
log_warn("WARNING: new device appeared %d:%d %s",
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
}
#endif
if (!_insert_dev(name, st.st_rdev))
return_NULL;
/* Get the struct dev that was just added. */
dev = (struct device *) dm_hash_lookup(_cache.names, name);
if (!dev) {
log_error("Failed to get device %s", name);
return NULL;
}
goto out;
/* Add new dev-cache entry next. */
dev = NULL;
}
if (dev && dm_list_empty(&dev->aliases)) {
/* shouldn't happen */
log_warn("Ignoring dev with no valid paths for %s.", name);
return NULL;
}
if (!dev && existing)
return_NULL;
/*
* This case should never be hit for a PV. It should only
* happen when the command is opening a new LV it has created.
* Add an arg to all callers indicating when the arg should be
* new (for an LV) and not existing.
* FIXME: fix this further by not using dev-cache struct devs
* at all for new dm devs (LVs) that lvm uses. Make the
* dev-cache contain only devs for PVs.
* Places to fix that use a dev for LVs include:
* . lv_resize opening lv to discard
* . wipe_lv opening lv to zero it
* . _extend_sanlock_lv opening lv to extend it
* . _write_log_header opening lv to write header
* Also, io to LVs should not go through bcache.
* bcache should contain only labels and metadata
* scanned from PVs.
* Either add a new struct dev for st_rdev and name,
* or add name as a new alias for an existing struct dev
* for st_rdev.
*/
if (!dev) {
/*
* This case should only be used for new devices created by this
* command (opening LVs it's created), so if a dev exists for the
* dev_t referenced by the name, then drop all aliases for before
* _insert_dev adds the new name. lvm commands actually hit this
* fairly often when it uses some LV, deactivates the LV, then
* creates some new LV which ends up with the same major:minor.
* Without dropping the aliases, it's plausible that lvm commands
* could end up using the wrong dm device.
*/
struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev);
if (dev_by_devt) {
log_debug("Dropping aliases for %d:%d before adding new path %s.",
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
_drop_all_aliases(dev_by_devt);
}
#if 0
/*
* I think only lvm's own dm devs should be added here, so use
* a warning to look for any other unknown cases.
*/
if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) {
log_warn("WARNING: new device appeared %d:%d %s",
(int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name);
}
#endif
if (!_insert_dev(name, st.st_rdev))
return_NULL;
@@ -1594,9 +1544,10 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
log_error("Failed to get device %s", name);
return NULL;
}
_verify_aliases(dev, name);
}
out:
/*
* The caller passed a filter if they only want the dev if it
* passes filters.
@@ -1626,23 +1577,63 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
return dev;
}
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f)
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered)
{
return _dev_cache_get(cmd, name, f, 1);
}
char path[PATH_MAX];
const char *sysfs_dir;
struct stat info;
struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
int ret;
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f)
{
return _dev_cache_get(cmd, name, f, 0);
}
if (filtered)
*filtered = 0;
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt)
{
struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt);
if (!d) {
sysfs_dir = dm_sysfs_dir();
if (sysfs_dir && *sysfs_dir) {
/* First check if dev is sysfs to avoid useless scan */
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d",
sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) {
log_error("dm_snprintf partition failed.");
return NULL;
}
if (lstat(path, &info)) {
log_debug("No sysfs entry for %d:%d errno %d at %s.",
(int)MAJOR(dev), (int)MINOR(dev), errno, path);
return NULL;
}
}
log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d",
(int)MAJOR(dev), (int)MINOR(dev));
dev_cache_scan(cmd);
d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev);
if (!d)
return NULL;
}
if (d->flags & DEV_REGULAR)
return d;
if (!f)
return d;
ret = f->passes_filter(cmd, f, d, NULL);
if (ret == -EAGAIN) {
log_debug_devs("get device by number defer filter %s", dev_name(d));
d->flags |= DEV_FILTER_AFTER_SCAN;
ret = 1;
}
if (ret)
return d;
if (filtered)
*filtered = 1;
if (dev)
return dev;
log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt));
return NULL;
}
@@ -1712,10 +1703,8 @@ int dev_fd(struct device *dev)
const char *dev_name(const struct device *dev)
{
if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases))
return dm_list_item(dev->aliases.n, struct dm_str_list)->str;
else
return unknown_device_name();
return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
unknown_device_name();
}
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt)

View File

@@ -53,8 +53,8 @@ int dev_cache_has_scanned(void);
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);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered);
struct device *dev_hash_get(const char *name);

View File

@@ -58,9 +58,6 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size)
const char *name = dev_name(dev);
struct stat info;
if (dm_list_empty(&dev->aliases))
return_0;
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
name, dev->size);
@@ -90,7 +87,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size)
int do_close = 0;
if (dm_list_empty(&dev->aliases))
return_0;
return 0;
if (dev->size_seqno == _dev_size_seqno) {
log_very_verbose("%s: using cached size %" PRIu64 " sectors",
@@ -308,13 +305,6 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_EXCL))
need_excl = 1;
if (dm_list_empty(&dev->aliases)) {
/* shouldn't happen */
log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
return 0;
}
name = dev_name(dev);
if (dev->fd >= 0) {
if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
@@ -324,7 +314,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (dev->open_count && !need_excl)
log_debug_devs("%s: Already opened read-only. Upgrading "
"to read-write.", name);
"to read-write.", dev_name(dev));
/* dev_close_immediate will decrement this */
dev->open_count++;
@@ -337,7 +327,11 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if (critical_section())
/* FIXME Make this log_error */
log_verbose("dev_open(%s) called while suspended", name);
log_verbose("dev_open(%s) called while suspended",
dev_name(dev));
if (!(name = dev_name_confirmed(dev, quiet)))
return_0;
#ifdef O_DIRECT_SUPPORT
if (direct) {
@@ -378,9 +372,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
}
#endif
if (quiet)
log_debug("Failed to open device path %s (%d).", name, errno);
log_sys_debug("open", name);
else
log_error("Failed to open device path %s (%d).", name, errno);
log_sys_error("open", name);
dev->flags |= DEV_OPEN_FAILURE;
return 0;
@@ -421,12 +415,10 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
if ((flags & O_CREAT) && !(flags & O_TRUNC))
dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
if (!quiet) {
log_debug_devs("Opened %s %s%s%s", name,
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
}
log_debug_devs("Opened %s %s%s%s", dev_name(dev),
dev->flags & DEV_OPENED_RW ? "RW" : "RO",
dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
dev->flags &= ~DEV_OPEN_FAILURE;
return 1;

View File

@@ -966,9 +966,6 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
if (dm_list_empty(&dev->aliases))
goto_out;
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
goto out;

View File

@@ -40,7 +40,6 @@
#define DEV_IS_NVME 0x00040000 /* set if dev is nvme */
#define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */
#define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */
#define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */
/*
* Support for external device info.
@@ -204,6 +203,9 @@ 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);
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);

View File

@@ -347,8 +347,6 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u
}
else if (idtype == DEV_ID_TYPE_DEVNAME) {
if (dm_list_empty(&dev->aliases))
goto_bad;
if (!(idname = strdup(dev_name(dev))))
goto_bad;
return idname;
@@ -911,7 +909,7 @@ struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid)
return NULL;
}
struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname)
static struct dev_use *_get_du_for_devname(struct cmd_context *cmd, const char *devname)
{
struct dev_use *du;
@@ -957,10 +955,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_
if (!dev_get_partition_number(dev, &part))
return_0;
/* Ensure valid dev_name(dev) below. */
if (dm_list_empty(&dev->aliases))
return_0;
/*
* When enable_devices_file=0 and pending_devices_file=1 we let
* pvcreate/vgcreate add new du's to cmd->use_devices. These du's may
@@ -1114,7 +1108,7 @@ id_done:
du_pvid = get_du_for_pvid(cmd, pvid);
/* Is there already an entry using this device's name? */
du_devname = get_du_for_devname(cmd, dev_name(dev));
du_devname = _get_du_for_devname(cmd, dev_name(dev));
/* Is there already an entry using the device_id for this device? */
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
@@ -1535,7 +1529,7 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev)
struct dev_use *du;
/* First check the du entry with matching devname since it's likely correct. */
if ((du = get_du_for_devname(cmd, dev_name(dev)))) {
if ((du = _get_du_for_devname(cmd, dev_name(dev)))) {
if (_match_du_to_dev(cmd, du, dev))
return 1;
}
@@ -1583,7 +1577,7 @@ void device_ids_match_device_list(struct cmd_context *cmd)
dm_list_iterate_items(du, &cmd->use_devices) {
if (du->dev)
continue;
if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
log_warn("Device not found for %s.", du->devname);
} else {
/* Should we set dev->id? Which idtype? Use --deviceidtype? */
@@ -1631,7 +1625,7 @@ void device_ids_match(struct cmd_context *cmd)
* the du/dev pairs in preparation for using the filters.
*/
if (du->devname &&
(dev = dev_cache_get_existing(cmd, du->devname, NULL))) {
(dev = dev_cache_get(cmd, du->devname, NULL))) {
/* On successful match, du, dev, and id are linked. */
if (_match_du_to_dev(cmd, du, dev))
continue;
@@ -1752,13 +1746,6 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
continue;
/*
* The matched device could not be read so we do not have
* the PVID from disk and cannot verify the devices file entry.
*/
if (dev->flags & DEV_SCAN_NOT_READ)
continue;
/*
* du and dev may have been matched, but the dev could still
* have been excluded by other filters during label scan.
@@ -1841,16 +1828,6 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
if (scanned_devs && !dev_in_device_list(dev, scanned_devs))
continue;
/*
* The matched device could not be read so we do not have
* the PVID from disk and cannot verify the devices file entry.
*/
if (dev->flags & DEV_SCAN_NOT_READ)
continue;
if (dm_list_empty(&dev->aliases))
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
dev_name(dev), dev_filtered_reason(dev));
@@ -2234,14 +2211,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
dm_list_iterate_items(dil, &search_pvids) {
char *dup_devname1, *dup_devname2, *dup_devname3;
if (!dil->dev || dm_list_empty(&dil->dev->aliases)) {
if (!dil->dev) {
not_found++;
continue;
}
found++;
dev = dil->dev;
devname = dev_name(dev);
found++;
if (!(du = get_du_for_pvid(cmd, dil->pvid))) {
/* shouldn't happen */

View File

@@ -41,7 +41,6 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname);
char *devices_file_version(void);
int devices_file_exists(struct cmd_context *cmd);

View File

@@ -2601,7 +2601,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
fmt->ops = &_text_handler;
fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS;
strncpy(fmt->orphan_vg_name, ORPHAN_VG_NAME(FMT_TEXT_NAME), sizeof(fmt->orphan_vg_name));
fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME);
fmt->features = FMT_SEGMENTS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE | FMT_CONFIG_PROFILE |

View File

@@ -410,7 +410,6 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
{
struct lvmcache_vgsummary vgsummary;
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
struct lvmcache_info *info;
const struct format_type *fmt = labeller->fmt;
struct label_header *lh = (struct label_header *) label_buf;
@@ -434,7 +433,6 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
pvhdr = (struct pv_header *) ((char *) label_buf + xlate32(lh->offset_xl));
memcpy(pvid, &pvhdr->pv_uuid, ID_LEN);
strncpy(vgid, FMT_TEXT_ORPHAN_VG_NAME, ID_LEN);
/*
* FIXME: stop adding the device to lvmcache initially as an orphan
@@ -451,8 +449,8 @@ static int _text_read(struct cmd_context *cmd, struct labeller *labeller, struct
* Other reasons for lvmcache_add to return NULL are internal errors.
*/
if (!(info = lvmcache_add(cmd, labeller, pvid, dev, label_sector,
vgid,
vgid, 0, is_duplicate)))
FMT_TEXT_ORPHAN_VG_NAME,
FMT_TEXT_ORPHAN_VG_NAME, 0, is_duplicate)))
return_0;
lvmcache_set_device_size(info, xlate64(pvhdr->device_size_xl));

View File

@@ -236,7 +236,6 @@ static int _touch_newhints(void)
return_0;
if (fclose(fp))
stack;
log_debug("newhints created");
return 1;
}
@@ -500,8 +499,6 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
if (!(iter = dev_iter_create(NULL, 0)))
return 0;
while ((dev = dev_iter_get(cmd, iter))) {
if (dm_list_empty(&dev->aliases))
continue;
if (!(hint = _find_hint_name(hints, dev_name(dev))))
continue;
@@ -509,19 +506,6 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints)
if (!hint->chosen)
continue;
/*
* label_scan was unable to read the dev so we don't know its pvid.
* Since we are unable to verify the hint is correct, it's possible
* that the PVID is actually found on a different device, so don't
* depend on hints. (This would also fail the following pvid check.)
*/
if (dev->flags & DEV_SCAN_NOT_READ) {
log_debug("Uncertain hint for unread device %d:%d %s",
major(hint->devt), minor(hint->devt), dev_name(dev));
ret = 0;
continue;
}
if (strcmp(dev->pvid, hint->pvid)) {
log_debug("Invalid hint device %d:%d %s pvid %s had hint pvid %s",
major(hint->devt), minor(hint->devt), dev_name(dev),

View File

@@ -687,8 +687,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
dm_list_iterate_items_safe(devl, devl2, devs) {
devl->dev->flags &= ~DEV_SCAN_NOT_READ;
/*
* If we prefetch more devs than blocks in the cache, then the
* cache will wait for earlier reads to complete, toss the
@@ -704,7 +702,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
dm_list_del(&devl->list);
dm_list_add(&reopen_devs, &devl->list);
devl->dev->flags |= DEV_SCAN_NOT_READ;
continue;
}
}
@@ -728,7 +725,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
log_debug_devs("Scan failed to read %s.", dev_name(devl->dev));
scan_read_errors++;
scan_failed_count++;
devl->dev->flags |= DEV_SCAN_NOT_READ;
lvmcache_del_dev(devl->dev);
if (bb)
bcache_put(bb);
@@ -1130,12 +1126,11 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
* sure to find the device.
*/
if (try_dev_scan) {
log_debug("Repeat dev cache scan to translate devnos.");
dev_cache_scan(cmd);
dm_list_iterate_items(po, &pvs_online) {
if (po->dev)
continue;
if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) {
if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno, NULL, NULL))) {
log_error("No device found for %d:%d PVID %s",
(int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid);
goto bad;
@@ -1394,10 +1389,6 @@ int label_scan(struct cmd_context *cmd)
* filter", and this result needs to be cleared (wiped) so that the
* complete set of filters (including those that require data) can be
* checked in _process_block, where headers have been read.
*
* FIXME: devs that are filtered with data in _process_block
* are not moved to the filtered_devs list like devs filtered
* here without data. Does that have any effect?
*/
log_debug_devs("Filtering devices to scan (nodata)");
@@ -1723,7 +1714,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_devt(cmd, devt)))
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
label_scan_invalidate(dev);
}
}
@@ -1737,19 +1728,13 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
struct lv_list *lvl;
dev_t devt;
/*
* FIXME: this is all unnecessary unless there are PVs stacked on LVs,
* so we can skip all of this if scan_lvs=0.
*/
log_debug("invalidating devs for any pvs on lvs");
if (get_device_list(NULL, &devs, &devs_features)) {
if (devs_features & DM_DEVICE_LIST_HAS_UUID) {
dm_list_iterate_items(dm_dev, devs)
if (dm_dev->uuid &&
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
devt = MKDEV(dm_dev->major, dm_dev->minor);
if ((dev = dev_cache_get_by_devt(cmd, devt)))
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
label_scan_invalidate(dev);
}
/* ATM no further caching for any lvconvert command
@@ -1886,24 +1871,10 @@ int label_scan_open_rw(struct device *dev)
int label_scan_reopen_rw(struct device *dev)
{
const char *name;
int flags = 0;
int prev_fd = dev->bcache_fd;
int fd;
if (dm_list_empty(&dev->aliases)) {
log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
return 0;
}
name = dev_name(dev);
if (!name || name[0] != '/') {
log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd);
return 0;
}
if (!(dev->flags & DEV_IN_BCACHE)) {
if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) {
/* shouldn't happen */
@@ -1933,7 +1904,7 @@ int label_scan_reopen_rw(struct device *dev)
flags |= O_NOATIME;
flags |= O_RDWR;
fd = open(name, flags, 0777);
fd = open(dev_name(dev), flags, 0777);
if (fd < 0) {
log_error("Failed to open rw %s errno %d di %d fd %d.",
dev_name(dev), errno, dev->bcache_di, dev->bcache_fd);

View File

@@ -272,8 +272,6 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg,
i = 0;
dm_list_iterate_items(pvl, &vg->pvs) {
if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for VG %s", vg->name);
@@ -343,8 +341,6 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg,
dm_list_iterate_items(pvl, &vg->pvs) {
if (lv_is_on_pv(lv, pvl->pv)) {
if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases))
continue;
lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv));
if (!lock_pvs->path[i]) {
log_error("Fail to allocate PV path for LV %s/%s",

View File

@@ -371,7 +371,7 @@ struct format_type {
struct labeller *labeller;
const char *name;
const char *alias;
char orphan_vg_name[ID_LEN];
const char *orphan_vg_name;
struct volume_group *orphan_vg; /* Only one ever exists. */
uint32_t features;
void *library;

View File

@@ -2197,7 +2197,7 @@ static int _validate_lock_args_chars(const char *lock_args)
static int _validate_vg_lock_args(struct volume_group *vg)
{
if (!vg->lock_args || !_validate_lock_args_chars(vg->lock_args)) {
if (!_validate_lock_args_chars(vg->lock_args)) {
log_error(INTERNAL_ERROR "VG %s has invalid lock_args chars", vg->name);
return 0;
}

View File

@@ -1231,23 +1231,14 @@ int remove_mirrors_from_segments(struct logical_volume *lv,
const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr)
{
struct lv_segment *seg;
struct device *dev;
dm_list_iterate_items(seg, &lv_mirr->segments) {
if (!seg_is_mirrored(seg))
continue;
if (seg_type(seg, 0) == AREA_PV) {
dev = seg_dev(seg, 0);
if (!dev || dm_list_empty(&dev->aliases))
return NULL;
return dev_name(dev);
}
if (seg_type(seg, 0) == AREA_LV) {
dev = seg_dev(first_seg(seg_lv(seg, 0)), 0);
if (!dev || dm_list_empty(&dev->aliases))
return NULL;
return dev_name(dev);
}
if (seg_type(seg, 0) == AREA_PV)
return dev_name(seg_dev(seg, 0));
if (seg_type(seg, 0) == AREA_LV)
return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
}
return NULL;

View File

@@ -152,11 +152,6 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
struct pv_list *new_pvl = NULL, *pvl2;
struct dm_list *pe_ranges;
if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) {
log_error("Failed to create PV entry for missing device.");
return 0;
}
pvname = pv_dev_name(pvl->pv);
if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) {
log_warn("WARNING: Physical volume %s not allocatable.", pvname);

View File

@@ -679,11 +679,6 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return r;
}
if (!pv->dev || dm_list_empty(&pv->dev->aliases)) {
log_error("No device found for PV.");
return r;
}
log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv));
if (pv_pe_alloc_count(pv)) {

View File

@@ -108,7 +108,6 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0)
FIELD(LVS, lv, NUM, "WCacheBlkSize", lvid, 0, writecache_block_size, writecache_block_size, "The writecache block size", 0)
/*
* End of LVS type fields
*/

View File

@@ -353,8 +353,6 @@ GET_PV_STR_PROPERTY_FN(pv_device_id_type, pv->device_id_type)
#define _writecache_writeback_blocks_get prop_not_implemented_get
#define _writecache_error_set prop_not_implemented_set
#define _writecache_error_get prop_not_implemented_get
#define _writecache_block_size_set prop_not_implemented_set
#define _writecache_block_size_get prop_not_implemented_get
#define _vdo_operating_mode_set prop_not_implemented_set
#define _vdo_operating_mode_get prop_not_implemented_get

View File

@@ -3346,26 +3346,6 @@ static int _integritymismatches_disp(struct dm_report *rh __attribute__((unused)
return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64));
}
static int _writecache_block_size_disp(struct dm_report *rh __attribute__((unused)),
struct dm_pool *mem,
struct dm_report_field *field,
const void *data,
void *private __attribute__((unused)))
{
struct logical_volume *lv = (struct logical_volume *) data;
uint32_t bs = 0;
if (lv_is_writecache(lv)) {
struct lv_segment *seg = first_seg(lv);
bs = seg->writecache_block_size;
}
if (!bs)
return dm_report_field_int32(rh, field, &GET_TYPE_RESERVED_VALUE(num_undef_32));
return dm_report_field_uint32(rh, field, &bs);
}
static int _datapercent_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)

View File

@@ -168,11 +168,6 @@ int id_write_format(const struct id *id, char *buffer, size_t size)
assert(ID_LEN == 32);
if (id->uuid[0] == '#') {
(void) dm_strncpy(buffer, (char*)id->uuid, size);
return 1;
}
/* split into groups separated by dashes */
if (size < (32 + 6 + 1)) {
if (size > 0)

View File

@@ -18,7 +18,6 @@
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h> /* help musl C */
#include <pthread.h>
#include <sys/file.h>
#include <sys/stat.h>

View File

@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
.br
[ \fB--segments\fP ]
.br
[ \fB--separator\fP \fIString\fP ]
@@ -330,6 +332,16 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.br
Overrides current output format for reports which is defined globally by
the report/output_format setting in \fBlvm.conf\fP(5).
\fBbasic\fP is the original format with columns and rows.
If there is more than one report per command, each report is prefixed
with the report name for identification. \fBjson\fP produces report
output in JSON format. See \fBlvmreport\fP(7) for more information.
.
.HP
\fB--segments\fP
.br
.

View File

@@ -178,9 +178,9 @@ concurrent commands attempt to activate a VG at once.
.SS static autoactivation
.P
A static autoactivation method is no longer provided by lvm.
Setting event_activation=0 still disables event based autoactivation.
WARNING: disabling event activation without an alternative may prevent a
system from booting. A custom systemd service could be written to run
Setting event_activation=0 now leaves event based autoactivation
enabled, and disabling event based autoactivation requires setting
event_activation=2. A custom systemd service could be written to run
autoactivation during system startup, in which case disabling event
autoactivation may be useful.
.

View File

@@ -240,59 +240,18 @@ The writecache block size should be chosen to match the xfs sectsz value.
It is also possible to specify a sector size of 4096 to mkfs.xfs when
creating the file system. In this case the writecache block size of 4096
can be used.
.P
The writecache block size is displayed by the command:
.br
lvs -o writecacheblocksize VG/LV
.P
.SS dm-writecache memory usage
.P
The amount of main system memory used by dm-writecache can be a factor
when selecting the writecache cachevol size and the writecache block size.
.P
.IP \[bu] 2
writecache block size 4096: each 100 GiB of writecache cachevol uses
slighly over 2 GiB of system memory.
.IP \[bu] 2
writecache block size 512: each 100 GiB of writecache cachevol uses
a little over 16 GiB of system memory.
.
.SS dm-writecache settings
.
To specify dm-writecache tunable settings on the command line, use:
.br
--cachesettings 'option=N' or
.br
--cachesettings 'option1=N option2=N ...'
.P
For example, --cachesettings 'high_watermark=90 writeback_jobs=4'.
.P
To include settings when caching is started, run:
Tunable parameters can be passed to the dm-writecache kernel module using
the --cachesettings option when caching is started, e.g.
.P
.nf
# lvconvert --type writecache --cachevol fast \\
--cachesettings 'option=N' vg/main
--cachesettings 'high_watermark=N writeback_jobs=N' vg/main
.fi
.P
To change settings for an existing writecache, run:
.P
.nf
# lvchange --cachesettings 'option=N' vg/main
.fi
.P
To clear all settings that have been applied, run:
.P
.nf
# lvchange --cachesettings '' vg/main
.fi
.P
To view the settings that are applied to a writecache LV, run:
.P
.nf
# lvs -o cachesettings vg/main
.fi
.P
Tunable settings are:
Tunable options are:
.
.TP
high_watermark = <percent>
@@ -342,14 +301,11 @@ writecache. Adding cleaner=0 to the splitcache command will skip the
cleaner mode, and any required flushing is performed in device suspend.
.SS dm-writecache using metadata profiles
.
In addition to specifying writecache settings on the command line, they
can also be set in lvm.conf, or in a profile file, using the
allocation/cache_settings/writecache config structure shown below.
.P
It's possible to prepare a number of different profile files in the
\fI#DEFAULT_SYS_DIR#/profile\fP directory and specify the file name
of the profile when starting writecache.
Writecache allows to set a variety of options. Lots of these settings
can be specified in lvm.conf or profile settings. You can prepare
a number of different profiles in the \fI#DEFAULT_SYS_DIR#/profile\fP directory
and just specify the metadata profile file name when writecaching LV.
.P
.I Example
.nf
@@ -371,10 +327,11 @@ writeback_jobs=1024
EOF
.P
# lvcreate -an -L10G --name fast vg /dev/fast_ssd
# lvcreate --type writecache -L10G --name main --cachevol fast \\
# lvcreate -an -L10G --name wcache vg /dev/fast_ssd
# lvcreate --type writecache -L10G --name main --cachevol wcache \\
--metadataprofile cache_writecache vg /dev/slow_hdd
.fi
.
.SS dm-cache with separate data and metadata LVs
.

View File

@@ -322,8 +322,7 @@ Find a device with the PVID and add the device to the devices file.
.HP
\fB--check\fP
.br
Checks the content of the devices file.
Reports incorrect device names or PVIDs for entries.
Check the content of the devices file.
.
.HP
\fB--commandprofile\fP \fIString\fP

View File

@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
.br
[ \fB--separator\fP \fIString\fP ]
.br
[ \fB--shared\fP ]
@@ -318,6 +320,16 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.br
Overrides current output format for reports which is defined globally by
the report/output_format setting in \fBlvm.conf\fP(5).
\fBbasic\fP is the original format with columns and rows.
If there is more than one report per command, each report is prefixed
with the report name for identification. \fBjson\fP produces report
output in JSON format. See \fBlvmreport\fP(7) for more information.
.
.HP
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.

View File

@@ -15,8 +15,6 @@ pvscan \(em List all physical volumes
.P
.ad l
\fB-a\fP|\fB--activate\fP \fBy\fP|\fBn\fP|\fBay\fP
.br
\fB--autoactivation\fP \fIString\fP
.br
\fB--cache\fP
.br
@@ -93,50 +91,59 @@ like
or
.BR pvdisplay (8).
.P
When --cache is used, pvscan updates runtime lvm state on the system, or
with -aay performs autoactivation.
When the --cache and -aay options are used, pvscan records which PVs are
available on the system, and activates LVs in completed VGs. A VG is
complete when pvscan sees that the final PV in the VG has appeared. This
is used by event-based system startup (systemd, udev) to activate LVs.
.P
The four main variations of this are:
.P
.B pvscan --cache
.I device
.P
If device is present, lvm records that the PV on device is online.
If device is present, lvm adds a record that the PV on device is online.
If device is not present, lvm removes the online record for the PV.
pvscan only reads the named device.
In most cases, the pvscan will only read the named devices.
.P
.B pvscan --cache -aay
.IR device ...
.P
This begins by performing the same steps as above. Afterward, if the VG
for the specified PV is complete, then pvscan will activate LVs in the VG
(the same as vgchange -aay vgname would do.)
.P
.B pvscan --cache
.P
Updates the runtime state for all lvm devices.
.P
.B pvscan --cache -aay
.I device
.P
Performs the --cache steps for the device, then checks if the VG using the
device is complete. If so, LVs in the VG are autoactivated, the same as
vgchange -aay vgname would do. (A device name may be replaced with major
and minor numbers.)
This first clears all existing PV online records, then scans all devices
on the system, adding PV online records for any PVs that are found.
.P
.B pvscan --cache -aay
.P
Performs the --cache steps for all devices, then autoactivates any complete VGs.
This begins by performing the same steps as pvscan --cache. Afterward, it
activates LVs in any complete VGs.
.P
.B pvscan --cache --listvg|--listlvs
.I device
To prevent devices from being scanned by pvscan --cache, add them
to
.BR lvm.conf (5)
.B devices/global_filter.
For more information, see:
.br
.B lvmconfig --withcomments devices/global_filter
.P
Performs the --cache steps for the device, then prints the name of the VG
using the device, or the names of LVs using the device. --checkcomplete
is usually included to check if all PVs for the VG or LVs are online.
When this command is called by a udev rule, the output must conform to
udev rule specifications (see --udevoutput.) The udev rule will use the
results to perform autoactivation.
.P
Autoactivation of VGs or LVs can be enabled/disabled using vgchange or
lvchange with --setautoactivation y|n, or by adding names to
Auto-activation of VGs or LVs can be enabled/disabled using:
.br
.BR lvm.conf (5)
.B activation/auto_activation_volume_list
.P
See
.BR lvmautoactivation (7)
for more information about how pvscan is used for autoactivation.
For more information, see:
.br
.B lvmconfig --withcomments activation/auto_activation_volume_list
.P
To disable auto-activation, explicitly set this list to an empty list,
i.e. auto_activation_volume_list = [ ].
.P
When this setting is undefined (e.g. commented), then all LVs are
auto-activated.
.
.SH USAGE
.
@@ -208,8 +215,6 @@ Record that a PV is online and autoactivate the VG if complete.
.br
[ \fB--noudevsync\fP ]
.br
[ \fB--autoactivation\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -234,8 +239,6 @@ Record that a PV is online and list the VG using the PV.
.br
[ \fB--udevoutput\fP ]
.br
[ \fB--autoactivation\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -339,14 +342,6 @@ Auto-activate LVs in a VG when the PVs scanned have completed the VG.
(Only \fBay\fP is applicable.)
.
.HP
\fB--autoactivation\fP \fIString\fP
.br
Specify if autoactivation is being used from an event.
This allows the command to apply settings that are specific
to event activation, such as device scanning optimizations
using pvs_online files created by event-based pvscans.
.
.HP
\fB--cache\fP
.br
Scan one or more devices and record that they are online.

View File

@@ -24,8 +24,6 @@ vgchange \(em Change volume group attributes
.nh
\%\fBcontiguous\fP|\:\fBcling\fP|\:\fBcling_by_tags\fP|\:\fBnormal\fP|\:\fBanywhere\fP|\:\fBinherit\fP
.hy
.br
\fB--autoactivation\fP \fIString\fP
.br
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.br
@@ -288,8 +286,6 @@ Activate or deactivate LVs.
.br
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--autoactivation\fP \fIString\fP ]
.br
[ \fB--ignoremonitoring\fP ]
.br
[ \fB--noudevsync\fP ]
@@ -520,14 +516,6 @@ which PVs the command will use for allocation.
See \fBlvm\fP(8) for more information about allocation.
.
.HP
\fB--autoactivation\fP \fIString\fP
.br
Specify if autoactivation is being used from an event.
This allows the command to apply settings that are specific
to event activation, such as device scanning optimizations
using pvs_online files created by event-based pvscans.
.
.HP
\fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP
.br
Specifies if metadata should be backed up automatically after a change.

View File

@@ -58,6 +58,8 @@ and more, using a more compact and configurable output format.
.br
[ \fB--readonly\fP ]
.br
[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
.br
[ \fB--shared\fP ]
.br
[ \fB--separator\fP \fIString\fP ]
@@ -310,6 +312,16 @@ device-mapper kernel driver, so this option is unable to report whether
or not LVs are actually in use.
.
.HP
\fB--reportformat\fP \fBbasic\fP|\fBjson\fP
.br
Overrides current output format for reports which is defined globally by
the report/output_format setting in \fBlvm.conf\fP(5).
\fBbasic\fP is the original format with columns and rows.
If there is more than one report per command, each report is prefixed
with the report name for identification. \fBjson\fP produces report
output in JSON format. See \fBlvmreport\fP(7) for more information.
.
.HP
\fB-S\fP|\fB--select\fP \fIString\fP
.br
Select objects for processing and reporting based on specified criteria.

View File

@@ -1,224 +0,0 @@
#!/usr/bin/env bash
# Copyright (C) 2020 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
test_description='devices file editing with lvmdevices'
. lib/inittest
aux lvmconf 'devices/scan = "/dev"'
aux prepare_devs 1
# The tests run with system dir of "/etc" but lvm when running
# normally has cmd->system_dir set to "/etc/lvm".
DFDIR="$LVM_SYSTEM_DIR/devices"
mkdir -p "$DFDIR" || true
DF="$DFDIR/system.devices"
aux lvmconf 'devices/use_devicesfile = 1'
losetup -h | grep sector-size || skip
which fallocate || skip
fallocate -l 2M loopa
fallocate -l 2M loopb
setup_loop_devs() {
for i in {1..5} ; do
LOOP1=$(losetup -f loopa --show || true)
test -n "$LOOP1" && break
done
for i in {1..5} ; do
LOOP2=$(losetup -f loopb --show || true)
test -n "$LOOP2" && break
done
}
setup_loop_devs
# Tests of devices without PV on them.
# add/del with default idtype loop_file
lvmdevices --adddev "$LOOP1"
grep "$LOOP1" $DF
lvmdevices --adddev "$LOOP2"
grep "$LOOP2" $DF
grep "IDTYPE=loop_file" $DF
not grep "IDTYPE=devname" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
# add/del with non-default idtype devname
lvmdevices --adddev "$LOOP1" --deviceidtype devname
grep "$LOOP1" $DF
lvmdevices --adddev "$LOOP2" --deviceidtype devname
grep "$LOOP2" $DF
grep "IDTYPE=devname" $DF
not grep "IDTYPE=loop_file" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
# add/del when dev is missing, using default idtype
lvmdevices --adddev "$LOOP1"
grep "$LOOP1" $DF
lvmdevices --adddev "$LOOP2"
grep "$LOOP2" $DF
losetup -D
grep "$LOOP1" $DF
grep "$LOOP2" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
not lvmdevices --adddev "$LOOP1"
not lvmdevices --adddev "$LOOP2"
not grep "$LOOP1" $DF
not grep "$LOOP2" $DF
setup_loop_devs
rm $DF
# add/del when dev is missing, using devname idtype
lvmdevices --adddev "$LOOP1" --deviceidtype devname
grep "$LOOP1" $DF
lvmdevices --adddev "$LOOP2" --deviceidtype devname
grep "$LOOP2" $DF
losetup -D
grep "$LOOP1" $DF
grep "$LOOP2" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
setup_loop_devs
rm $DF
# Tests of devices with PV on them.
touch $DF
pvcreate "$LOOP1"
pvcreate "$LOOP2"
# PVID without dashes for matching devices file fields
PVID1=`pvs "$LOOP1" --noheading -o uuid | tr -d - | awk '{print $1}'`
PVID2=`pvs "$LOOP2" --noheading -o uuid | tr -d - | awk '{print $1}'`
# PVID with dashes for matching pvs -o+uuid output
OPVID1=`pvs "$LOOP1" --noheading -o uuid | awk '{print $1}'`
OPVID2=`pvs "$LOOP2" --noheading -o uuid | awk '{print $1}'`
grep "$LOOP1" $DF
grep "$LOOP2" $DF
grep "$PVID1" $DF
grep "$PVID2" $DF
rm $DF
# add/deldev with default idtype loop_file
lvmdevices --adddev "$LOOP1"
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --adddev "$LOOP2"
grep "$LOOP2" $DF
grep "$PVID2" $DF
grep "IDTYPE=loop_file" $DF
not grep "IDTYPE=devname" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
# add/delpvid with default idtype loop_file
lvmdevices --addpvid "$PVID1"
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --addpvid "$PVID2"
grep "$LOOP2" $DF
grep "$PVID2" $DF
grep "IDTYPE=loop_file" $DF
not grep "IDTYPE=devname" $DF
lvmdevices --delpvid "$PVID1"
not grep "$LOOP1" $DF
not grep "$PVID1" $DF
lvmdevices --delpvid "$PVID2"
not grep "$LOOP2" $DF
not grep "$PVID2" $DF
# add/deldev with non-default idtype devname
lvmdevices --adddev "$LOOP1" --deviceidtype devname
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --adddev "$LOOP2" --deviceidtype devname
grep "$LOOP2" $DF
grep "$PVID2" $DF
grep "IDTYPE=devname" $DF
not grep "IDTYPE=loop_file" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
# add/delpvid with non-default idtype devname
lvmdevices --addpvid "$PVID1" --deviceidtype devname
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --addpvid "$PVID2" --deviceidtype devname
grep "$LOOP2" $DF
grep "$PVID2" $DF
grep "IDTYPE=devname" $DF
not grep "IDTYPE=loop_file" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
# add/deldev when dev is missing, using default idtype
lvmdevices --adddev "$LOOP1"
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --adddev "$LOOP2"
grep "$LOOP2" $DF
grep "$PVID2" $DF
losetup -D
grep "$LOOP1" $DF
grep "$LOOP2" $DF
lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
not grep "$PVID1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
not grep "$PVID2" $DF
setup_loop_devs
rm $DF
# add/delpvid when dev is missing, using devname idtype
lvmdevices --addpvid "$PVID1" --deviceidtype devname
grep "$LOOP1" $DF
grep "$PVID1" $DF
lvmdevices --addpvid "$PVID2" --deviceidtype devname
grep "$LOOP2" $DF
grep "$PVID2" $DF
losetup -D
grep "$LOOP1" $DF
grep "$LOOP2" $DF
lvmdevices --delpvid "$PVID1"
not grep "$LOOP1" $DF
not grep "$PVID1" $DF
lvmdevices --delpvid "$PVID2"
not grep "$LOOP2" $DF
not grep "$PVID2" $DF
setup_loop_devs
rm $DF
# TODO: add/rem of partitions of same device
losetup -D
rm loopa loopb

View File

@@ -33,8 +33,6 @@ aux udev_wait
ls -la "${LOOP}"*
test -e "${LOOP}p1"
aux lvmconf 'devices/scan = "/dev"'
aux extend_filter "a|$LOOP|"
aux extend_devices "$LOOP"

View File

@@ -32,7 +32,7 @@ _clear_online_files() {
aux prepare_devs 8 16
# Check 'pvscan' is ignored when event_activation is 0
pvscan --cache -aay -v --config 'global/event_activation=0' 2>&1 | tee out
pvscan --cache -aay -v --config 'global/event_activation=2' 2>&1 | tee out
grep "Ignoring pvscan" out
vgcreate $vg1 "$dev1" "$dev2"

View File

@@ -75,7 +75,7 @@ wait_lvm_activate() {
local vgw=$1
local wait=0
while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do
while systemctl status lvm-activate-$vgw | grep "active (running)" && test "$wait" -le 30; do
sleep .2
wait=$(( wait + 1 ))
done
@@ -382,6 +382,7 @@ lvcreate -l1 -an -n $lv1 $vg9
lvcreate -l1 -an -n $lv2 $vg9
mdadm --stop "$mddev"
systemctl stop lvm-activate-$vg9 || true
_clear_online_files
mdadm --assemble "$mddev" "$dev1" "$dev2"
@@ -404,6 +405,17 @@ mdadm --stop "$mddev"
aux udev_wait
wipe_all
systemctl stop lvm-activate-$vg1
systemctl stop lvm-activate-$vg2
systemctl stop lvm-activate-$vg3
systemctl stop lvm-activate-$vg4
systemctl stop lvm-activate-$vg5
systemctl stop lvm-activate-$vg6
systemctl stop lvm-activate-$vg7
systemctl stop lvm-activate-$vg8
systemctl stop lvm-activate-$vg9
# no devices file, filter with symlink of PV
# the pvscan needs to look at all dev names to
# match the symlink in the filter with the
@@ -427,6 +439,7 @@ udevadm trigger --settle -c add /sys/block/$BDEV1
ls /dev/disk/by-id/lvm-pv-uuid-$OPVID1
vgchange -an $vg10
systemctl stop lvm-activate-$vg10
_clear_online_files
aux lvmconf "devices/filter = [ \"a|/dev/disk/by-id/lvm-pv-uuid-$OPVID1|\", \"r|.*|\" ]"

View File

@@ -19,9 +19,6 @@ _clear_online_files() {
aux prepare_devs 4
# skip rhel5 which doesn't seem to have /dev/mapper/LVMTESTpv1
aux driver_at_least 4 15 || skip
DFDIR="$LVM_SYSTEM_DIR/devices"
mkdir -p "$DFDIR" || true
DF="$DFDIR/system.devices"

View File

@@ -222,8 +222,6 @@ vgextend $vg "$dev2"
lvcreate -n $lv1 -l 8 -an $vg "$dev1"
lvcreate -n $lv2 -l 4 -an $vg "$dev2"
lvconvert --yes --type writecache --cachevol $lv2 --cachesettings "block_size=4096" $vg/$lv1
lvs -o writecacheblocksize $vg/$lv1 |tee out
grep 4096 out
lvchange -ay $vg/$lv1
mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1" |tee out
grep "sectsz=4096" out

View File

@@ -190,9 +190,9 @@ command-lines-input.h: $(srcdir)/command-lines.in Makefile
$(Q) set -o pipefail && \
( cat $(srcdir)/license.inc && \
echo "/* Do not edit. This file is generated by the Makefile. */" && \
echo -en "static const char _command_input[] =\n\n\"" && \
echo -en "const char _command_input[] =\n\n\"" && \
$(EGREP) -v '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
echo "\\n\\n\";" \
echo "\\n\";" \
) > $@
$(SOURCES:%.c=%.d) $(SOURCES2:%.c=%.d): command-lines-input.h command-count.h cmds.h

View File

@@ -355,7 +355,7 @@ arg(checkcomplete_ARG, '\0', "checkcomplete", 0, 0, 0,
"and print \"complete\" or \"incomplete\" for each listed\n"
"VG or LV. This option is used as a part of event-based\n"
"autoactivation, so pvscan will do nothing if this option\n"
"is set and event_activation=0 in the config settings.\n")
"is set and event_activation=2 (disabled) in the config settings.\n")
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0,
"Used to pass options for special cases to lvmlockd.\n"
@@ -862,13 +862,12 @@ arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0,
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0,
"Specifies tunable kernel options for dm-cache or dm-writecache LVs.\n"
"Use the form 'option=value' or 'option1=value option2=value', or\n"
"repeat --cachesettings for each option being set.\n"
"These settings override the default kernel behaviors which are\n"
"usually adequate. To remove cachesettings and revert to the default\n"
"kernel behaviors, use --cachesettings 'default' for dm-cache or\n"
"an empty string --cachesettings '' for dm-writecache.\n"
"Specifies tunable values for a cache LV in \"Key = Value\" form.\n"
"Repeat this option to specify multiple values.\n"
"(The default values should usually be adequate.)\n"
"The special string value \\fBdefault\\fP switches\n"
"settings back to their default kernel values and removes\n"
"them from the list of settings stored in LVM metadata.\n"
"See \\fBlvmcache\\fP(7) for more information.\n")
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,

View File

@@ -2549,7 +2549,7 @@ static const char *_man_long_opt_name(const char *cmdname, int opt_enum)
}
if (strchr(long_opt, '[')) {
for (i = 0; *long_opt && i < sizeof(long_opt_name) - 1; ++long_opt, ++i) {
for (i = 0; i < sizeof(long_opt_name) - 1; ++long_opt, ++i) {
if (i < (sizeof(long_opt_name) - 8))
switch(*long_opt) {
case '[':

View File

@@ -383,27 +383,28 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
* No filter because we always want to allow removing a device
* by name from the devices file.
*/
if ((dev = dev_cache_get(cmd, devname, NULL))) {
/*
* dev_cache_scan uses sysfs to check if an LV is using each dev
* and sets this flag is so.
*/
if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
if (!arg_count(cmd, yes_ARG) &&
yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
log_error("Device not removed.");
goto bad;
}
}
if ((du = get_du_for_dev(cmd, dev)))
goto dev_del;
}
if (!(du = get_du_for_devname(cmd, devname))) {
log_error("No devices file entry for %s.", devname);
if (!(dev = dev_cache_get(cmd, devname, NULL))) {
log_error("No device found for %s.", devname);
goto bad;
}
dev_del:
/*
* dev_cache_scan uses sysfs to check if an LV is using each dev
* and sets this flag is so.
*/
if (dev_is_used_by_active_lv(cmd, dev, NULL, NULL, NULL, NULL)) {
if (!arg_count(cmd, yes_ARG) &&
yes_no_prompt("Device %s is used by an active LV, continue to remove? ", devname) == 'n') {
log_error("Device not removed.");
goto bad;
}
}
if (!(du = get_du_for_dev(cmd, dev))) {
log_error("Device not found in devices file.");
goto bad;
}
dm_list_del(&du->list);
free_du(du);
device_ids_write(cmd);

View File

@@ -1652,8 +1652,8 @@ static int _get_autoactivation(struct cmd_context *cmd, int event_activation, in
return 1;
}
if (!event_activation) {
log_print_pvscan(cmd, "Skip pvscan for event with event_activation=0.");
if (event_activation == 2) {
log_print_pvscan(cmd, "Skip pvscan for event with event_activation=2.");
*skip_command = 1;
return 1;
}
@@ -1680,32 +1680,32 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
cmd->ignore_device_name_mismatch = 1;
event_activation = find_config_tree_bool(cmd, global_event_activation_CFG, NULL);
event_activation = find_config_tree_int(cmd, global_event_activation_CFG, NULL);
if (do_activate && !event_activation) {
log_verbose("Ignoring pvscan --cache -aay because event_activation is disabled.");
if (do_activate && (event_activation == 2)) {
log_verbose("Ignoring pvscan --cache -aay because event_activation is disabled (2).");
return ECMD_PROCESSED;
}
/*
* lvm udev rules call:
* pvscan --cache --listvg|--listlvs --checkcomplete PV
* when PVs appear, even if event_activation=0 in lvm.conf.
* when PVs appear, even if event_activation=2 in lvm.conf.
*
* The udev rules will do autoactivation if they see complete
* VGs/LVs reported from the pvscan.
*
* When event_activation=0 we do not want to do autoactivation
* When event_activation=2 we do not want to do autoactivation
* from udev events, so we need the pvscan to not report any
* complete VGs/LVs when event_activation=0 so that the udev
* complete VGs/LVs when event_activation=2 so that the udev
* rules do not attempt to autoactivate.
*/
if (arg_is_set(cmd, checkcomplete_ARG) && !event_activation) {
if (arg_is_set(cmd, checkcomplete_ARG) && (event_activation == 2)) {
if (arg_is_set(cmd, udevoutput_ARG))
printf("LVM_EVENT_ACTIVATION=0\n");
else
log_print_pvscan(cmd, "Ignoring pvscan with --checkcomplete because event_activation is disabled.");
log_print_pvscan(cmd, "Ignoring pvscan with --checkcomplete because event_activation is disabled (2).");
return ECMD_PROCESSED;
}
@@ -1734,9 +1734,9 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv)
if (!_pvscan_cache_all(cmd, argc, argv, &complete_vgnames))
return ECMD_FAILED;
} else {
if (!arg_is_set(cmd, checkcomplete_ARG) && !event_activation) {
if (!arg_is_set(cmd, checkcomplete_ARG) && (event_activation == 2)) {
/* Avoid doing anything for device removal: pvscan --cache <devno> */
log_verbose("Ignoring pvscan --cache because event_activation is disabled.");
log_verbose("Ignoring pvscan --cache because event_activation is disabled (2).");
return ECMD_PROCESSED;
}

View File

@@ -829,7 +829,7 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
* user may want to take charge of activation changes to the VG
* and not have the system autoactivation interfere.
*/
if (!is_change_activating(activate) && cmd->event_activation &&
if (!is_change_activating(activate) && (cmd->event_activation != 2) &&
!cmd->online_vg_file_removed) {
cmd->online_vg_file_removed = 1;
online_vg_file_remove(lv->vg->name);
@@ -1488,7 +1488,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv,
goto out;
}
if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) {
if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) {
log_error("Failed to find device "
"\"%s\".", argv[opt]);
ret_max = ECMD_FAILED;
@@ -3925,7 +3925,7 @@ static int _get_arg_devices(struct cmd_context *cmd,
return ECMD_FAILED;
}
if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) {
if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) {
log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str));
ret_max = EINIT_FAILED;
} else {
@@ -5261,7 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
struct device *dev;
/* No filter used here */
if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) {
if (!(dev = dev_cache_get(cmd, pd->name, NULL))) {
log_error("No device found for %s.", pd->name);
dm_list_del(&pd->list);
dm_list_add(&pp->arg_fail, &pd->list);

View File

@@ -755,8 +755,8 @@ static int _vgchange_autoactivation_setup(struct cmd_context *cmd,
return 1;
}
if (!find_config_tree_bool(cmd, global_event_activation_CFG, NULL)) {
log_print("Skip vgchange for event and event_activation=0.");
if (find_config_tree_int(cmd, global_event_activation_CFG, NULL) == 2) {
log_print("Skip vgchange for event and event_activation disabled (2).");
*skip_command = 1;
return 1;
}

View File

@@ -72,7 +72,7 @@ ENV{SYSTEMD_READY}="1"
# and uses temp files under /run/lvm to check if
# other PVs in the VG are present.
#
# If event_activation=0 in lvm.conf, this pvscan
# If event_activation=2 in lvm.conf, this pvscan
# (using checkcomplete) will do nothing, so that
# no event-based autoactivation will be happen.
#